haxe_3.4.4.orig/.merlin0000664000175000017500000000004613166552354014703 0ustar andyandy00000000000000S src/** B src/** S libs/** B libs/** haxe_3.4.4.orig/CONTRIBUTING.md0000664000175000017500000000422613166552354015651 0ustar andyandy00000000000000## 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 https://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` subdirectory. ## Is this the right repository to report the issue? This repository is about the Haxe compiler itself and the Haxe standard library. Here's an overview of repositories that are part of the Haxe ecosystem: * The haxelib command line tool or lib.haxe.org: * Something on try.haxe.org: * Something under haxe.org/manual: * Something on api.haxe.org: For content this is probably the right repository. If it's about the representation, try instead. * Something else on haxe.org: ## 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.4.4.orig/Makefile0000664000175000017500000006461213166552354015065 0ustar andyandy00000000000000# 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=$(DESTDIR)/usr INSTALL_BIN_DIR=$(INSTALL_DIR)/bin INSTALL_LIB_DIR=$(INSTALL_DIR)/lib/haxe INSTALL_STD_DIR=$(INSTALL_LIB_DIR)/std PACKAGE_OUT_DIR=out INSTALLER_TMP_DIR=installer PACKAGE_SRC_EXTENSION=.tar.gz PLATFORM?=unix OUTPUT=haxe EXTENSION= OCAMLOPT?=ocamlopt OCAMLC?=ocamlc LFLAGS= STATICLINK?=0 CFLAGS= -bin-annot ALL_CFLAGS= $(CFLAGS) -g -w -3 -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 -I libs/pcre \ -I src -I src/context -I src/generators -I src/macro -I src/optimization -I src/syntax -I src/typing -I src/display 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 libs/pcre/pcre ifneq ($(STATICLINK),0) LIB_PARAMS= -cclib '-Wl,-Bstatic -lpcre -lz -Wl,-Bdynamic ' else LIB_PARAMS?= -cclib -lpcre -cclib -lz endif NATIVE_LIBS=-cclib libs/extc/extc_stubs.o -cclib libs/extc/process_stubs.o -cclib libs/objsize/c_objsize.o -cclib libs/pcre/pcre_stubs.o -ccopt -L/usr/local/lib $(LIB_PARAMS) 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) $(ALL_CFLAGS) -c $< CC_PARSER_CMD = $(COMPILER) -pp camlp4o $(ALL_CFLAGS) -c src/syntax/parser.ml RELDIR=../../.. MODULES=json version globals path context/meta syntax/ast display/displayTypes typing/type typing/error \ syntax/lexer context/common generators/genxml \ syntax/parser typing/abstract typing/typecore display/display optimization/optimizerTexpr \ optimization/optimizer typing/overloads typing/typeload sourcemaps generators/codegen generators/gencommon generators/genas3 \ generators/gencpp generators/genjs generators/genneko generators/genphp generators/genphp7 generators/genswf9 \ generators/genswf generators/genjava generators/gencs generators/genpy macro/macroApi macro/interp generators/hlcode generators/hlopt generators/hlinterp generators/hl2c \ generators/genlua \ optimization/dce optimization/analyzerConfig optimization/analyzerTypes optimization/analyzerTexpr \ optimization/analyzerTexprTransformer optimization/analyzer generators/genhl \ optimization/filters macro/hlmacro macro/macroContext typing/typer typing/matcher display/displayOutput server 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 \ if [ "$$(uname)" = "Darwin" ]; then \ date -u -r $$(git show -s --format=%ct HEAD) +%Y%m%d%H%M%S; \ else \ date -u -d @$$(git show -s --format=%ct HEAD) +%Y%m%d%H%M%S; \ fi \ ) PACKAGE_FILE_NAME=haxe_$(COMMIT_DATE)_$(COMMIT_SHA) HAXE_VERSION=$(shell $(OUTPUT) -version 2>&1 | awk '{print $$1;}') # 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 tools 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) make -C libs/pcre OCAMLOPT=$(OCAMLOPT) OCAMLC=$(OCAMLC) $(TARGET_FLAG) haxe: $(MODULES:%=src/%.$(MODULE_EXT)) $(COMPILER) -o $(OUTPUT) $(NATIVE_LIBS) $(NATIVE_LIB_FLAG) $(LFLAGS) $(LIBS:=.$(LIB_EXT)) $(MODULES:%=src/%.$(MODULE_EXT)) haxelib: (cd $(CURDIR)/extra/haxelib_src && $(CURDIR)/$(OUTPUT) client.hxml && nekotools boot run.n) mv extra/haxelib_src/run$(EXTENSION) haxelib$(EXTENSION) tools: haxelib install: uninstall mkdir -p $(INSTALL_BIN_DIR) mkdir -p $(INSTALL_LIB_DIR)/lib cp -rf std $(INSTALL_STD_DIR) cp -rf extra $(INSTALL_LIB_DIR) cp haxe $(INSTALL_LIB_DIR) ln -s $(INSTALL_LIB_DIR)/haxe $(INSTALL_BIN_DIR)/haxe cp haxelib $(INSTALL_LIB_DIR) ln -s $(INSTALL_LIB_DIR)/haxelib $(INSTALL_BIN_DIR)/haxelib chmod -R a+rx $(INSTALL_LIB_DIR) chmod 777 $(INSTALL_LIB_DIR)/lib 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 if [ -d "$(INSTALL_LIB_DIR)/lib" ] && find "$(INSTALL_LIB_DIR)/lib" -mindepth 1 -print -quit | grep -q .; then \ echo "The local haxelib repo at $(INSTALL_LIB_DIR)/lib will not be removed. Remove it manually if you want."; \ find $(INSTALL_LIB_DIR)/ ! -name 'lib' -mindepth 1 -maxdepth 1 -exec rm -rf {} +; \ else \ rm -rf $(INSTALL_LIB_DIR); \ fi # Modules # context src/context/common.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/display/displayTypes.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT) src/context/meta.$(MODULE_EXT): src/globals.$(MODULE_EXT) # display src/display/display.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/path.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) src/display/displayTypes.$(MODULE_EXT) src/display/displayTypes.$(MODULE_EXT) : src/globals.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/display/displayOutput.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/typing/typer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/display/display.$(MODULE_EXT) # sourcemaps src/sourcemaps.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) # generators src/generators/codegen.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/generators/genxml.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/genas3.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/gencommon.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/typing/overloads.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT) src/generators/gencpp.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/gencs.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/generators/gencommon.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT) src/generators/genjava.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/generators/gencommon.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/genjs.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/genneko.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/genlua.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/genphp.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/genpy.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/genswf.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/generators/genswf9.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/hlinterp.$(MODULE_EXT): src/context/common.$(MODULE_EXT) src/generators/hlcode.$(MODULE_EXT) src/macro/interp.$(MODULE_EXT) src/generators/hlopt.$(MODULE_EXT) src/macro/macroApi.$(MODULE_EXT) src/generators/genphp7.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/sourcemaps.$(MODULE_EXT) src/generators/hl2c.$(MODULE_EXT): src/generators/hlcode.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/hlopt.$(MODULE_EXT): src/generators/hlcode.$(MODULE_EXT) src/generators/genhl.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/hlcode.$(MODULE_EXT) src/generators/hlinterp.$(MODULE_EXT) src/generators/hl2c.$(MODULE_EXT) src/generators/hlopt.$(MODULE_EXT) src/generators/genswf9.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/genxml.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) # macro src/macro/interp.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/generators/genneko.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/genswf.$(MODULE_EXT) src/generators/genjava.$(MODULE_EXT) src/generators/gencs.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT) src/macro/macroApi.$(MODULE_EXT) libs/pcre/pcre.$(LIB_EXT) src/macro/macroContext.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/optimization/optimizerTexpr.$(MODULE_EXT) src/typing/overloads.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/typeload.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) src/optimization/optimizer.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/macro/interp.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/optimization/filters.$(MODULE_EXT) src/generators/genjs.$(MODULE_EXT) src/display/display.$(MODULE_EXT) src/macro/hlmacro.$(MODULE_EXT) src/macro/macroApi.$(MODULE_EXT) src/macro/hlmacro.$(MODULE_EXT): src/generators/hlinterp.$(MODULE_EXT) src/generators/genhl.$(MODULE_EXT) src/macro/macroApi.$(MODULE_EXT) src/macro/macroApi.$(MODULE_EXT): src/generators/genjs.$(MODULE_EXT) src/generators/gencs.$(MODULE_EXT) src/generators/genjava.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) # optimization src/optimization/analyzer.$(MODULE_EXT): src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/optimization/optimizer.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/optimization/analyzerConfig.$(MODULE_EXT) src/optimization/analyzerTypes.$(MODULE_EXT) src/optimization/analyzerTexpr.$(MODULE_EXT) src/optimization/analyzerTexprTransformer.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/optimization/analyzerConfig.$(MODULE_EXT): src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/optimization/analyzerTexpr.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/optimization/analyzerConfig.$(MODULE_EXT) src/optimization/optimizerTexpr.$(MODULE_EXT) src/generators/genphp7.$(MODULE_EXT) src/optimization/analyzerTexprTransformer.$(MODULE_EXT): src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/optimization/analyzerConfig.$(MODULE_EXT) src/optimization/analyzerTypes.$(MODULE_EXT) src/optimization/analyzerTexpr.$(MODULE_EXT) src/optimization/analyzerTypes.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/optimization/analyzerConfig.$(MODULE_EXT) src/optimization/dce.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/path.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/optimization/filters.$(MODULE_EXT): src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/optimization/analyzer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/optimization/dce.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/optimization/optimizer.$(MODULE_EXT): src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/optimization/optimizerTexpr.$(MODULE_EXT) src/display/display.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/optimization/optimizerTexpr.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) # syntax src/syntax/ast.$(MODULE_EXT): src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/syntax/lexer.ml src/syntax/ast.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/path.$(MODULE_EXT) src/syntax/parser.ml src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) $(CC_PARSER_CMD) # typing src/typing/abstract.$(MODULE_EXT): src/context/meta.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/typing/error.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/typing/matcher.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/optimization/optimizer.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/typing/typer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/typing/overloads.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/typing/type.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/json.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/typing/typeload.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/optimization/optimizerTexpr.$(MODULE_EXT) src/typing/overloads.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) src/optimization/optimizer.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/json.$(MODULE_EXT) src/display/display.$(MODULE_EXT) src/typing/typer.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/optimization/optimizerTexpr.$(MODULE_EXT) src/typing/overloads.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/typeload.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) src/optimization/optimizer.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/macro/interp.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/optimization/filters.$(MODULE_EXT) src/generators/genjs.$(MODULE_EXT) src/display/display.$(MODULE_EXT) src/macro/macroContext.$(MODULE_EXT) # main src/main.$(MODULE_EXT): src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/path.$(MODULE_EXT) src/optimization/filters.$(MODULE_EXT) src/typing/matcher.$(MODULE_EXT) src/typing/typer.$(MODULE_EXT) src/typing/typeload.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) src/optimization/optimizer.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/macro/interp.$(MODULE_EXT) src/generators/genxml.$(MODULE_EXT) src/generators/genswf.$(MODULE_EXT) src/generators/genphp.$(MODULE_EXT) src/generators/genphp7.$(MODULE_EXT) src/generators/genneko.$(MODULE_EXT) src/generators/genjs.$(MODULE_EXT) src/generators/genlua.$(MODULE_EXT) src/generators/gencpp.$(MODULE_EXT) src/generators/genas3.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/generators/genjava.$(MODULE_EXT) src/generators/gencs.$(MODULE_EXT) src/generators/genpy.$(MODULE_EXT) src/generators/genhl.$(MODULE_EXT) src/display/display.$(MODULE_EXT) src/server.$(MODULE_EXT) src/display/displayOutput.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT) src/globals.$(MODULE_EXT): src/version.$(MODULE_EXT) src/path.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/server.$(MODULE_EXT): src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/typer.$(MODULE_EXT) src/typing/typeload.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/display/displayOutput.$(MODULE_EXT) src/version.$(MODULE_EXT): $(MAKE) -f Makefile.version_extra -s --no-print-directory ADD_REVISION=$(ADD_REVISION) BRANCH=$(BRANCH) COMMIT_SHA=$(COMMIT_SHA) COMMIT_DATE=$(COMMIT_DATE) > src/version.ml $(COMPILER) $(ALL_CFLAGS) -c src/version.ml # Package package_src: mkdir -p $(PACKAGE_OUT_DIR) # use git-archive-all since we have submodules # https://github.com/Kentzo/git-archive-all curl -s https://raw.githubusercontent.com/Kentzo/git-archive-all/1.15/git_archive_all.py -o extra/git_archive_all.py python extra/git_archive_all.py $(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_src$(PACKAGE_SRC_EXTENSION) package_unix: mkdir -p $(PACKAGE_OUT_DIR) 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 $(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_bin.tar.gz $(PACKAGE_FILE_NAME) rm -r $(PACKAGE_FILE_NAME) package_bin: package_$(PLATFORM) $(INSTALLER_TMP_DIR): mkdir -p $(INSTALLER_TMP_DIR) $(INSTALLER_TMP_DIR)/neko-osx64.tar.gz: $(INSTALLER_TMP_DIR) wget http://nekovm.org/media/neko-2.1.0-osx64.tar.gz -O installer/neko-osx64.tar.gz install_dox: haxelib git hxparse https://github.com/Simn/hxparse master src haxelib git hxtemplo https://github.com/Simn/hxtemplo haxelib git hxargs https://github.com/Simn/hxargs haxelib git markdown https://github.com/dpeek/haxe-markdown master src haxelib git hxcpp https://github.com/HaxeFoundation/hxcpp haxelib git hxjava https://github.com/HaxeFoundation/hxjava haxelib git hxcs https://github.com/HaxeFoundation/hxcs haxelib git dox https://github.com/HaxeFoundation/dox package_doc: mkdir -p $(PACKAGE_OUT_DIR) cd $$(haxelib path dox | head -n 1) && haxe run.hxml && haxe gen.hxml haxelib run dox -theme haxe_api -D website "http://haxe.org/" --title "Haxe API" -o $(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_doc.zip -D version "$$(haxe -version 2>&1)" -i $$(haxelib path dox | head -n 1)bin/xml -ex microsoft -ex javax -ex cs.internal -D source-path https://github.com/HaxeFoundation/haxe/blob/$(BRANCH)/std/ deploy_doc: scp $(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_doc.zip www-haxe@api.haxe.org:/data/haxeapi/www/v/dev/api-latest.zip ssh www-haxe@api.haxe.org "cd /data/haxeapi/www/v/dev && find . ! -name 'api-latest.zip' -maxdepth 1 -mindepth 1 -exec rm -rf {} + && unzip -q -o api-latest.zip" # Installer package_installer_mac: $(INSTALLER_TMP_DIR)/neko-osx64.tar.gz package_unix $(eval DOCFILE := $(shell pwd)/$(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_doc.zip) $(eval OUTFILE := $(shell pwd)/$(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_installer.tar.gz) $(eval PACKFILE := $(shell pwd)/$(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_bin.tar.gz) $(eval VERSION := $(shell haxe -version 2>&1)) $(eval NEKOVER := $(shell neko -version 2>&1)) bash -c "rm -rf $(INSTALLER_TMP_DIR)/{resources,pkg,tgz,haxe.tar.gz}" mkdir $(INSTALLER_TMP_DIR)/resources # neko - unpack to change the dir name cd $(INSTALLER_TMP_DIR)/resources && tar -zxvf ../neko-osx64.tar.gz mv $(INSTALLER_TMP_DIR)/resources/neko* $(INSTALLER_TMP_DIR)/resources/neko cd $(INSTALLER_TMP_DIR)/resources && tar -zcvf neko.tar.gz neko # haxe - unpack to change the dir name cd $(INSTALLER_TMP_DIR)/resources && tar -zxvf $(PACKFILE) mv $(INSTALLER_TMP_DIR)/resources/haxe* $(INSTALLER_TMP_DIR)/resources/haxe cd $(INSTALLER_TMP_DIR)/resources && tar -zcvf haxe.tar.gz haxe # scripts cp -rf extra/mac-installer/* $(INSTALLER_TMP_DIR)/resources cd $(INSTALLER_TMP_DIR)/resources && tar -zcvf scripts.tar.gz scripts # installer structure mkdir -p $(INSTALLER_TMP_DIR)/pkg cd $(INSTALLER_TMP_DIR)/pkg && xar -xf ../resources/installer-structure.pkg . mkdir $(INSTALLER_TMP_DIR)/tgz; mv $(INSTALLER_TMP_DIR)/resources/*.tar.gz $(INSTALLER_TMP_DIR)/tgz cd $(INSTALLER_TMP_DIR)/tgz; find . | cpio -o --format odc | gzip -c > ../pkg/files.pkg/Payload cd $(INSTALLER_TMP_DIR)/pkg/files.pkg && bash -c "INSTKB=$$(du -sk ../../tgz | awk '{print $$1;}'); \ du -sk ../../tgz; \ echo $$INSTKB ; \ INSTKBH=`expr $$INSTKB - 4`; \ echo $$INSTKBH ;\ sed -i '' 's/%%INSTKB%%/$$INSTKBH/g' PackageInfo ;\ sed -i '' 's/%%VERSION%%/$(VERSION)/g' PackageInfo ;\ sed -i '' 's/%%VERSTRING%%/$(VERSION)/g' PackageInfo ;\ sed -i '' 's/%%VERLONG%%/$(VERSION)/g' PackageInfo ;\ sed -i '' 's/%%NEKOVER%%/$(NEKOVER)/g' PackageInfo ;\ cd .. ;\ sed -i '' 's/%%VERSION%%/$(VERSION)/g' Distribution ;\ sed -i '' 's/%%VERSTRING%%/$(VERSION)/g' Distribution ;\ sed -i '' 's/%%VERLONG%%/$(VERSION)/g' Distribution ;\ sed -i '' 's/%%NEKOVER%%/$(NEKOVER)/g' Distribution ;\ sed -i '' 's/%%INSTKB%%/$$INSTKBH/g' Distribution" # repackage cd $(INSTALLER_TMP_DIR)/pkg; xar --compression none -cf ../$(PACKAGE_FILE_NAME).pkg * # tar cd $(INSTALLER_TMP_DIR); tar -zcvf $(OUTFILE) $(PACKAGE_FILE_NAME).pkg # Clean clean: clean_libs clean_haxe clean_tools clean_package 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 make -C libs/pcre clean clean_haxe: rm -f -r $(MODULES:%=src/%.obj) $(MODULES:%=src/%.o) $(MODULES:%=src/%.cmx) $(MODULES:%=src/%.cmi) $(MODULES:%=src/%.cmo) $(MODULES:%=src/%.cmt) src/syntax/lexer.ml src/version.ml $(OUTPUT) clean_tools: rm -f $(OUTPUT) haxelib clean_package: rm -rf $(PACKAGE_OUT_DIR) # SUFFIXES .ml.cmx: $(CC_CMD) .ml.cmo: $(CC_CMD) .mll.ml: ocamllex $< .PHONY: haxe libs version.cmx version.cmo haxelib haxe_3.4.4.orig/Makefile.version_extra0000664000175000017500000000066613166552354017753 0ustar andyandy00000000000000# 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) endifhaxe_3.4.4.orig/Makefile.win0000664000175000017500000000704113166552354015652 0ustar andyandy00000000000000PLATFORM=win include Makefile OUTPUT=haxe.exe EXTENSION=.exe PACKAGE_SRC_EXTENSION=.zip 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) $(ALL_CFLAGS) -c $< 2>tmp.cmi && $(FILTER)) || ($(FILTER) && exit 1) CC_PARSER_CMD=($(OCAMLOPT) -pp camlp4o $(ALL_CFLAGS) -c src/syntax/parser.ml 2>tmp.cmi && $(FILTER)) || ($(FILTER) && exit 1) endif PACKAGE_FILES=$(OUTPUT) haxelib$(EXTENSION) std "$$(cygpath -w "$$(which zlib1.dll)")" "$$(cygpath -w "$$(which libpcre-1.dll)")" package_win: 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) 7z a -y -tzip -mx0 temp.zip $(PACKAGE_FILES) > log.txt || type log.txt cd extra && 7z a -y -tzip -mx0 ../temp.zip LICENSE.txt CONTRIB.txt CHANGES.txt > log.txt || type log.txt 7z x -y temp.zip -o$(PACKAGE_FILE_NAME) > log.txt || type log.txt rm temp.zip # archive 7z a -r -tzip out/$(PACKAGE_FILE_NAME)_bin.zip $(PACKAGE_FILE_NAME) > log.txt || type log.txt rm -r $(PACKAGE_FILE_NAME) rm log.txt extra/log.txt package_choco: mkdir -p OUTPUT 7z x -y out/$(PACKAGE_FILE_NAME)_bin.zip -oout > log.txt || type log.txt mv out/$(PACKAGE_FILE_NAME) out/choco sed -e 's/@SNAPSHOT_VERSION@/$(HAXE_VERSION)-SNAP$(COMMIT_DATE)/g' extra/choco/haxe.nuspec > out/choco/haxe.nuspec cd out/choco && choco pack mv out/choco/haxe.*.nupkg out rm -rf out/choco $(INSTALLER_TMP_DIR)/neko-win.zip: $(INSTALLER_TMP_DIR) wget http://nekovm.org/media/neko-2.1.0-win.zip -O installer/neko-win.zip package_installer_win: $(INSTALLER_TMP_DIR)/neko-win.zip package_win $(eval OUTFILE := $(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_installer.zip) $(eval VERSION := $(shell haxe -version 2>&1 | cut -d ' ' -f1)) rm -rf $(INSTALLER_TMP_DIR)/resources # neko mkdir $(INSTALLER_TMP_DIR)/resources cd $(INSTALLER_TMP_DIR) && 7z x -y neko-win.zip rm $(INSTALLER_TMP_DIR)/neko-win.zip mv $(INSTALLER_TMP_DIR)/neko* $(INSTALLER_TMP_DIR)/resources/neko # haxe 7z x -y $(PACKAGE_OUT_DIR)/$(PACKAGE_FILE_NAME)_bin.zip -o$(INSTALLER_TMP_DIR)/resources mv $(INSTALLER_TMP_DIR)/resources/haxe* $(INSTALLER_TMP_DIR)/resources/haxe # haxesetup.exe haxelib path hxcpp || haxelib install hxcpp cd extra; haxelib run hxcpp build-haxesetup.xml cp extra/haxesetup.exe $(INSTALLER_TMP_DIR)/resources/haxe # extra cp extra/*.nsi $(INSTALLER_TMP_DIR) cp extra/*.nsh $(INSTALLER_TMP_DIR) cp -rf extra/images $(INSTALLER_TMP_DIR) # nsis sed -i "s/%%VERSION%%/$(VERSION)/g" $(INSTALLER_TMP_DIR)/installer.nsi sed -i "s/%%VERSTRING%%/$(VERSION)/g" $(INSTALLER_TMP_DIR)/installer.nsi sed -i "s/%%VERLONG%%/$(VERSION)/g" $(INSTALLER_TMP_DIR)/installer.nsi cd $(INSTALLER_TMP_DIR) && makensis installer.nsi 7z a -r -tzip $(OUTFILE) $(INSTALLER_TMP_DIR)/*.exe dir $(PACKAGE_OUT_DIR) haxe_3.4.4.orig/README.md0000664000175000017500000001123113166552354014671 0ustar andyandy00000000000000 # [Haxe logo](https://haxe.org) - [The Cross-Platform Toolkit](https://haxe.org) [![TravisCI Build Status](https://travis-ci.org/HaxeFoundation/haxe.svg?branch=development)](https://travis-ci.org/HaxeFoundation/haxe) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/HaxeFoundation/haxe?branch=development&svg=true)](https://ci.appveyor.com/project/HaxeFoundation/haxe) [![SauceLabs Test Status](https://saucelabs.com/buildstatus/haxe)](https://saucelabs.com/u/haxe) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](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 * Lua * [HashLink](http://hashlink.haxe.org/) 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](https://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 standard library is released under the MIT license. * The Neko virtual machine is released under the MIT license. Its bundled runtime libraries (ndll) and tools are released under open source licenses as described in https://github.com/HaxeFoundation/neko/blob/master/LICENSE For the complete Haxe licenses, please see https://haxe.org/foundation/open-source.html or [extra/LICENSE.txt](extra/LICENSE.txt). ## Installing Haxe The latest stable release is available at [https://haxe.org/download/](https://haxe.org/download/). Pre-built binaries are available for your platform: * **[Windows installer](https://haxe.org/download/file/latest/haxe-latest-win.exe/)** * **[Windows binaries](https://haxe.org/download/file/latest/haxe-latest-win.zip/)** * **[OSX installer](https://haxe.org/download/file/latest/haxe-latest-osx-installer.pkg/)** * **[OSX binaries](https://haxe.org/download/file/latest/haxe-latest-osx.tar.gz/)** * **[Linux Software Packages](https://haxe.org/download/linux/)** * **[Linux 32-bit binaries](https://haxe.org/download/file/latest/haxe-latest-linux32.tar.gz/)** * **[Linux 64-bit binaries](https://haxe.org/download/file/latest/haxe-latest-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](https://haxe.org/documentation/introduction/building-haxe.html). ## Using Haxe For information on on using Haxe, consult the [Haxe documentation](https://haxe.org/documentation/): * [Haxe Introduction](https://haxe.org/documentation/introduction/), an introduction to the Haxe toolkit * [The Haxe Manual](https://haxe.org/manual/), the reference manual for the Haxe language * [Haxe Code Cookbook](http://code.haxe.org), code snippets / learning resource * [Haxe API](http://api.haxe.org), documentation for the Haxe standard and native APIs * [Haxelib](https://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: * [Haxe on Stack Overflow](http://stackoverflow.com/questions/tagged/haxe) * the [official Haxe Google Group](https://groups.google.com/forum/#!forum/haxelang) * [#Haxe on Twitter](https://twitter.com/hashtag/haxe?src=hash) * the [Haxe IRC chatroom](http://unic0rn.github.io/tiramisu/haxe), #haxe on chat.freenode.net :+1: Get notified of the latest Haxe news, follow us on [Twitter](https://twitter.com/haxelang), [Facebook](https://www.facebook.com/haxe.org) or [Google+](https://plus.google.com/+HaxeOrg) ## Version compatibility Haxe | neko ---- | ----- 2.* | 1.* 3.0.0 | 2.0.0 3.1.3 | 2.0.0 3.2.0 | 2.0.0 3.3.0 | 2.1.0 3.4.0 | 2.1.0 ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md) for more. Thank you! haxe_3.4.4.orig/extra/CHANGES.txt0000664000175000017500000024566213166552354016367 0ustar andyandy000000000000002017-10-08: 3.4.4 Bugfixes: flash : fixed flash target broken when compiled with OCaml 4.05 (#6589) php7 : fixed accessing `static inline var` via reflection (#6630) js : fixed js syntax error for `value.iterator--` (#6637) cpp : fixed evaluation order problem when constructing enums (#6643) 2017-09-10: 3.4.3 Bugfixes: all : fixed DCE issue with interface fields (#6502) cpp : fixed return typing for embedded closures (#6121) php7: fixed `@:enum abstract` generation without `-dce full` (#6175) php7: fixed using enum constructor with arguments as a call argument (#6177) php7: fixed accessing methods on dynamic values (#6211) php7: fixed `null` property access (#6281) php7: fixed setting values in a map stored in another map (#6257) php7: implemented `php.Lib.mail()` php7: implemented `php.Lib.loadLib()` php7: implemented `php.Lib.getClasses()` (#6384) php7: fixed exception on `Reflect.getProperty(o, field)` if requested field does not exist (#6559) php/php7: fixed accessing enum constructors on enum type stored to a variable (#6159) php/php7: fixed "cannot implement previously implemented interface" (#6208) php: fixed invoking functions stored in dynamic static vars (#6158) php: fixed field access on `new MyClass()` expressions wrapped in a `cast` (#6294) macro : fixed bug in addClassPath that overwrites macro class paths with context class paths 2017-03-20: 3.4.2 Bugfixes: cpp : fixed issue with @:native names being prefixed with :: (#6086) cpp : fixed issue with return type handling (#6103) cpp : fixed inaccurate line numbers that threw off debugging php7 : fixed generation of `[][0]` constructs (#6090) 2017-03-17: 3.4.1 New features: php7 : added source maps generation with `-D source_map` flag. General improvements and optimizations: cpp : added cpp.Star and cpp.Struct to help with extern typing lua : cleaned up various parts of the standard library Bugfixes: all : fixed compilation server issue with two identical @:native paths on extern abstracts (#5993) all : fixed invalid inling in a specific case (#6067) all : fixed various display related issues all : fixed inline super() calls missing field initializations (#6097) all : consider UNC paths to be absolute in haxe.io.Path.isAbsolute (#6061) cpp : improved typing of some Function/Callable-related types cpp : fixed problem with line numbers when debugging hl : various fixes and improvements php : fixed FileSystem.stat() for directories on Windows (#6057) php/php7 : fixed invalid result of Web.getPostData() (#6033) php7 : fixed invalid access to length of string in some cases (#6055) php7 : fixed infinite recursion on MysqlConnection.close() (#6056) 2017-01-31: 3.4.0 General improvements and optimizations: all : support completion for static extensions (#5766) all : removed neko dependency for macros, use PCRE instead all : disabled analyzer optimizations by default, re-enable with -D analyzer-optimize php7 : generate native `$v instanceof MyType` instead of `Std.is(v, MyType)` where possible for better performance php7 : added @:phpNoConstructor meta for externs which do not have native php constructors and yet can be constructed php7 : greatly reduced amount of generated tmp vars php7 : `Array` performance improvements hl : made various improvements Bugfixes: all : fixed `using` picking up non-static abstract functions (#5888) all : fixed issue with side-effect detection when optimizing (#5911) all : fixed issue with zlib bindings causing zlib_deflate errors (#5941) php7 : Allow user-defined modules in `php` package (#5921) php7 : Dereference some of `php.Syntax` methods if required (#5923) php : fixed assigning a method of dynamic value to a variable (#5469) php : fixed missing initialization of dynamic methods in classes with empty constructors (#4723) 2016-12-24: 3.4.0-RC2 New features: js : added API documentation to HTML externs (#5868) php : added php7 target, enabled with -D php7 Bugfixes: all : fixed top-down inference infinite recursion issue (#5848) all : fixed regression in Compiler.include (#5847) all : fixed Not_found exception related to try/catch (#5851) all : fixed metadata completion showing up in trace arguments (#5775) all : fixed problem with useless pattern detection (#5873) all : fixed issue with toString handling in trace arguments (#5858) all : fixed inline constructor scoping (#5855) cpp : fixed issue with cpp.Pointer variables being eliminated (#5850) js : added Notification API to HTML externs (#5852) js : fixed several options structures in HTML externs (#5849) php/cs : FileSystem.deleteFile() and FileSystem.deleteDirectory() now throw on non-existent path (#5742) php/lua : fixed field access on `null` (#4988) php : fixed static field access on a `Class` stored to a field (#5383) php : fixed invalid detection of `NativeArray` by `Std.is()` (#5565) php : fixed `stdin()`, `stdout()`, `stderr()` of `Sys` to use predefined constants for corresponding channels (#5733) php : fixed Std.parseInt() on hexstrings for PHP7+ (#5521) php : fixed typed cast in assign operations (#5135) php : fixed exception thrown by `Reflect.fields(o)` when `o` is `Class` (#5608) php : fixed json encoding of empty objects (#5015) php : fixed checking floats for equality (#4260) php : throw if invalid json string supplied to Json.parse() (#4592) php : fixed ssl connections (#4581) php : fixed writing bytes containing zero byte to MySQL & SQLite (#4489) php : fixed call()() cases for PHP5 (#5569) 2016-11-29: 3.4.0-RC1 New features: all : support metadata completion all : support type-hint completion all : added @signature display mode (#4758) all : finalized HashLink (HL) target General improvements and optimizations: all : greatly improved support for display mode in general all : made --times output look much nicer all : remove calls to functions that have no side-effect all : hid private property accessors from completion (#5678) js : updated jQuery extern (js.jquery.*) for jQuery 1.12.4 / 3.1.0 support. js : jQuery extern (js.jquery.*) now includes deprecated fields marked with @:deprecated. js : no longer rewrite `o["s"]` to `o.s` (#5724) cpp : greatly improved ObjC output and integration options lua : greatly improved code output quality Bugfixes: all : fixed various optimization issues all : fixed various issues with side-effect detection all : fixed performance drain in the DCE implementation (#5716) all : fixed issue with assignments when inlining constructors (#5340) all : fixed major inlining issue when using compilation server (#5320) all : fixed pattern matching evaluation order issue (#5274) cpp : fixed various minor code generation issues js : fixed issue regarding iterating over abstracts (#5385) python : fixed evaluation order issue for array writing (#5366) Standard Library: all : added Any type (#5500) all : added haxe.extern.AsVar all : added haxe.macro.CompilationServer (experimental) all : fixed haxe.Template.resolve (#5301) 2016-05-27: 3.3.0-RC1 New features: all : support @:resolve on abstracts (#3753) all : support extern abstracts and extern @:enum abstracts (#4862) all : support completion on { if the expected type is a structure (#3907) all : support (expr is Type) with mandatory parentheses (#2976) all : allowed passing package dot-paths on command line (#4227) all : support import.hx modules that define per-directory import/using directives (#1138) all : support parsing of postfix ! operator (can be used by abstract operator overloading and macros) (#4284) all : support parsing of ||= and &&= operators (can be used by abstract operator overloading and macros) (#4427) all : support @:structInit classes (#4526) all : reworked static analyzer and enabled it by default flash : update flash externs to version 21 hl : added HL target (interpreter and C output) lua: added lua target js : introduced new jQuery extern (js.jquery.*) for jQuery 1.12.4 / 2.2.4 support. (#4377) js : introduced new SWFObject extern (js.swfobject.SWFObject) for SWFObject 2.3.20130521 (#4451) js : added js.Lib.rethrow (#4551) cs/java : added -D fast_cast as an experimental feature to cleanup casts Bugfixes: all : properly disallowed assigning methods to structures with read-accessors (#3975) all : fixed a bug related to abstract + Int/Float and implicit casts (#4122) all : disallowed duplicate type parameter names (#4293) all : made UInt's >>> behave like >> (#2736) all : fixed various type loading issues all : fixed code generation problems with `inline` (#1827) php/as3 : support run-time metadata on interfaces (#2042) php : fixed argument passing to closures (#2587) neko/cpp : fixed various sys.Filesystem issues with Windows drive paths (#3266) as3 : fixed problem with covariant return types (#4222) as3 : fixed rare problem with static initialization order (#3563) python : fixed various reflection problems General improvements and optimizations: all : added support for determining minimal types in Map literals (#4196) all : allowed @:native on abstracts to set the name of the implementation class (#4158) all : allowed creating closures on abstract inline methods (#4165) all : type parameter declarations can now have metadata (#3836) all : optimize Math.ceil/floor on constant arguments (#4223) all : allowed extern classes to have field names being used for both static and instance (#4376) all : added haxe.Constraints.Constructible (#4761) all : rewrote pattern matcher to improve output in many cases (#4940) python : use spaces instead of tabs to indent the output (#4299) cpp : reworked backend to improve overall code output quality and fix various issues swf : added scene-tag to allow creating accessible SWF files Standard Library: all : added Lambda.flatten and Lambda.flatMap (#3553) all : added haxe.Constraints.Constructible (#4761) sys : proper quoting/escaping (can be opt-out) for Sys.command and sys.io.Process (#3603) js : added position parameter to haxe.macro.Compiler.includeFile js : removed -D embed-js (#4074) js : updated HTML externs Macro features and changes: macro : added overloads field to ClassField (#3460) macro : added Context.getLocalImports (#3560) macro : added Context.onAfterTyping (#4714) macro : added Context.resolveType 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 read) 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 constraints (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.4.4.orig/extra/CONTRIB.txt0000664000175000017500000000513313166552354016402 0ustar andyandy00000000000000Contributor 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.4.4.orig/extra/EnvVarUpdate.nsh0000664000175000017500000002410113166552354017613 0ustar andyandy00000000000000/** * 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.4.4.orig/extra/ImportAll.hx0000664000175000017500000000751513166552354017013 0ustar andyandy00000000000000/* * Copyright (C)2005-2016 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. */ import haxe.macro.Context; class ImportAll { public static function run( ?pack ) { if( pack == null ) { pack = ""; haxe.macro.Compiler.define("doc_gen"); } switch( pack ) { case "php7": if( !Context.defined("php7") ) return; case "php": if( !Context.defined("php") || Context.defined("php7") ) 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 "hl": if( !Context.defined("hl") ) return; case "lua": if( !Context.defined("lua") ) 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") && file.substr(0, file.length - 3).indexOf(".") < 0 ) { var cl = full.substr(0, full.length - 3); switch( cl ) { case "ImportAll", "neko.db.MacroManager": continue; case "haxe.TimerQueue": if( Context.defined("neko") || Context.defined("php") || Context.defined("cpp") ) continue; case "Sys": if( !(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; } if( Context.defined("php7") && cl.indexOf("php7.") == 0 ) { cl = "php." + cl.substr("php7.".length); } Context.getModule(cl); } else if( sys.FileSystem.isDirectory(p + "/" + file) ) run(full); } } } } haxe_3.4.4.orig/extra/LICENSE.txt0000664000175000017500000004011513166552354016363 0ustar andyandy00000000000000Haxe Licenses ------------- For details about Haxe Licenses, please read http://haxe.org/foundation/open-source.html The Haxe Standard Library MIT License : -------------------------- Copyright (C)2005-2016 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 haxe_3.4.4.orig/extra/all.hxml0000664000175000017500000000100313166552354016173 0ustar andyandy00000000000000--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 -D php7 -php all_php7 -xml php7.xml --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 -hl all_hl -xml hl.xml --next -xml cross.xml haxe_3.4.4.orig/extra/all.hxproj0000664000175000017500000000321513166552354016544 0ustar andyandy00000000000000 haxe all.hxml haxe_3.4.4.orig/extra/bintray.tpl.json0000664000175000017500000000171413166552354017703 0ustar andyandy00000000000000{ "package": { "name": "haxe", "repo": "snapshot", "subject": "::packageSubject::" }, "version": { "name": "::versionName::", "desc": "::versionDesc::", "released": "::gitDate::", "attributes": [ {"name": "repo", "values" : ["::gitRepo::"], "type": "string"}, {"name": "branch", "values" : ["::gitBranch::"], "type": "string"}, {"name": "commit", "values" : ["::gitCommit::"], "type": "string"} ], "gpgSign": false }, "files": [ {"includePattern": "out/(.*)_src\\.(.*)", "uploadPattern": "::os::/::gitBranch::/haxe_::versionName::_src.$2"}, {"includePattern": "out/(.*)_bin\\.(.*)", "uploadPattern": "::os::/::gitBranch::/haxe_::versionName::_bin.$2"}, {"includePattern": "out/(.*)_doc\\.(.*)", "uploadPattern": "::os::/::gitBranch::/haxe_::versionName::_doc.$2"} ], "publish": true }haxe_3.4.4.orig/extra/build-haxesetup.xml0000664000175000017500000000052213166552354020363 0ustar andyandy00000000000000 haxe_3.4.4.orig/extra/choco/haxe.nuspec0000664000175000017500000000401613166552354017777 0ustar andyandy00000000000000 haxe @SNAPSHOT_VERSION@ Haxe Haxe Foundation Haxe Foundation http://haxe.org/foundation/open-source.html http://haxe.org/ http://haxe.org/manual/introduction.html https://groups.google.com/forum/#!forum/haxelang https://github.com/HaxeFoundation/haxe/issues https://github.com/HaxeFoundation/haxe https://github.com/HaxeFoundation/haxe/tree/master/extra/choco http://haxe.org/img/haxe-logo.svg false Haxe is an open source toolkit based on a modern, high level, strictly typed programming language, a cross-compiler, a complete cross-platform standard library and ways to access each platform's native capabilities. Haxe is an open source toolkit based on a modern, high level, strictly typed programming language, a cross-compiler, a complete cross-platform standard library and ways to access each platform's native capabilities. This package will install haxe and haxelib. After installation, you should run `haxelib setup <path>`, where `<path>` is the haxelib repository folder for placing third-party libraries. The folder should be created manually before running the command. https://github.com/HaxeFoundation/haxe/blob/master/extra/CHANGES.txt haxe programming development foss cross-platform haxe_3.4.4.orig/extra/clean-whitespace0000775000175000017500000000027613166552354017706 0ustar andyandy00000000000000#!/bin/sh # # Remove trailing whitespace from Haxe files # Exclude generated js.html.* for now find -path ./std/js/html -prune -o -name '*.hx' -print0 | xargs -0 perl -pi -e "s/[ \t]+$//" haxe_3.4.4.orig/extra/deploy_key.enc0000664000175000017500000000630013166552354017371 0ustar andyandy00000000000000Salted__Žk‘½‰56yÿÉ1)s/õ¾zó”øÆ ™+oØ ¡©ZõWœ¢G#‰Yâ%wèh;T`Üæޓ=®0¯„®“^héMÃ*çT˜Ôm?vöK”‡rßÉE(,û]ŸO÷Ý'ÛŽöìm‰wÖ$¨HGóüìågcûD½[˜EËyBwï¡þQ V ¹¤˜­J¨:Pú‡Pk„ľ˜{ºT«ƒ áò5àã×kÊÔ-qß:ÁLþ ‘~-U—)g«8Ç 9š[F·4(Î}Í$XUÏ–­ÌaR.1‹¼s‰[x9Äi±öIàFΙɢââF^G@8Ÿzí:–Ïâ/í¡àÆ £Ëmt+B„îÀQ°ÎéÒêo«tðôæ»bГΗî0¯=öþ@–dpÚ€øO®„öUOkœÆ3âÈ´NöùÿÿÛ';9ÞpʇŽþ‡ðw8ußLRdD: »éæf éTTùjöÔ‹û$8¡ ¢ø©“|—K<šäIu²à‚l:’$m÷ºkM/—áHAòóÀd§ˆªwcþfw hùÜ—œÝoô[ ó–Ø^H ¬2ûÖš:n'­ãÞsní^=Š,ŸxP¤¼, 6’>…“‹KÓÒ4~–C6G]ßa]½ ½T’ di3QY;I½õõ ’s(î/JbÕú½'4Ý:2¤öh=)ƒ4àò2‹Ì\=ùÎr'¯¯êX\´4s:Þ¶9—ò"Ò-â™ÏÚ)£zÅbH5ÝE-:BÑQêqû ­'ÚˆØpªPßþNæû"P[¨­G‚Æú5oßy©Ë$¡]ó;h ËþSµìt»¨91±{Ân–q÷b8ì¤Ó~!ÅÞÄÀ8 ššá0µÜjåì¸îTÒ…±i|fCô×Õ@ÊJ®ÝŽôŒ’Ny?±¶‹‹Ÿú»bƒÀÑ©†à¦ý5θ›^ð}wz—PLú4§oXDdª(â·GÌÃ~wðǦÀ™H¸áù¡¾’Fd¾6¾«õtxHl03£!êðl,ˆËíS¤=Ìýow¤vùÕ’.cTMO‚SÏÿ‘kÍáO´RRÑ øÌ{S% 4øè{JÓ¤ ÖnP°í¯£ì¶Å–Õ“l'E;ÅÉé‰ÇŠo÷· e®c­Ÿ—‡WŠ-e"Ÿ¶ô½L*] Nòã+CÅS§&†b,<™íÆÒ×h¬ˆf+…Ks`¾•Eµ­±Ô½ð]0 äDõ¶ò“ŽPÏ®Ü,-.'EKõÓNÀXêfÜ„`à • +`&_O:äûGEÁ-œ&ÏÿfiP{¡^ÏŸ³¤åªºË“ñ€Í±XF‹Q“vïS·¥ä‹eüýJF¯Ê(Ж:„}§ãÀTÄGØ­¡ü´ŽkI…œ~Û.€#r ÞóÕÅJ8ä#ú·+àDv[ïgN·øwáW8{mXë†RÈ´öõàd€3³:Ryu@Š 8†>Vôzãõ‡qÍw½ü¬ •uÚx~&@P#ovКµ¯ÌhE¸i»àþ¼ù 3×¾~ØÑÚUD€ÉzNµÈ¦ õ+&v:“úteJŸL|*òüJŽUÛ (`mc74Æ| F^ÕV*©l_?ÖHî¬ÒŒ ]R–V4nAa¦  ‡ÙRAá¬cìõ»£ûܯ\d>Ô­„0¾Á¿s*àP7ÕS;Ç.¹E 7É.c¬™I‹ƒ.Ù‡‰ÀåûóàÐ<NÛ„YZá01!©p¥Í= ÓÖ„—øtvW7ï’i¡I†½K¨2¦R-æˆÂY¿!Ë‹ºÄÏÏ{PMÓå`ŸU™àl<{ׯ¡hò’­sd=»µiï!ñ!NjKåIŠÌŸTc>V^N®¿›áÎI9ú¬ª& ®LÛë’s´”ŽXÀ2‚/.ŸmÜÍ/øÆw¦Â8[m."Ù“4±uëFN´s]¨Ì‹|¼˜ùÐàH¯¤d L¹-W©@…&¼5Ö!¯!Î(¥ïàFð2Õþe}Aq,Ò焈Éã³±"¤BГ´†P¤ê¾»$ÊpÁ|É¿ã>™“~—Á¦µ—oØÅàÊv*e>±&Ú«?¤íó´ÜN^âr´áü-†×ŽW£ hS(Kx§ŸÆcº.‡È´=óÅuˆ2igu5°òd·w+ÏJ‘}0Dwo"9'‡ùjFÞüç_9ÚVz„Ššì´²YÚ´É–GîºJi9’V*ÿæ¨véáÙ¥ ™±Ü)–ž±E~N/äˆÃ0ºƒev"pº„|Ì‹Èuµˆ¸Q|JÜ~CÂ’Y¡k#Ïƒß â½È’ëIU˜$½zྸRú'àÜÆøšaÔêç ¯ÃXf癩xÄnülÅyq¼Î'XˆQ†Ñr__ÅG$zücŸÛ‘_ø3‰äyî5(­LÊ@7€9û ÏÔ¿î~€‘7ƒ,ñ¦Ø[[X‡Ïùömàx5ªpz®°À_–ÉG,š<º,Hp5ëBk_Ð\·¿q”㤶#‡À ÌV!’SîoÃh-±ž´!÷š?Ø7P¨®’$ë *}t?ã\KÁbùœ‚·$To4•€nÁ€ ²”ÿ AkwËܯÜ'(Ô·û6`ž(jL;‡U¥ÚÖ€ð/WAz w¦œV¹Žví\dØœ5?Zßp@"›BÓ˜Þ\ÚSÔú´êÊ{¢èVu´~µáfè¦F.K¸ìÏuĘGÝâÆGu‹qxŽ4JÅ9>܇› Ûåù¼Ø š…E çpzɬÎïºôUTnLüR ÙE¢/®Z‚¹GÛ[jOW¢•ÔÈà9"Gpâw£»°VhŒ%úšS¥î§}u"£wø%à74 ÉqÂåxE¨‹ÔØO(Z}Ée]/‹;׃D'ïö>ÞYRVIQ´IÃ>»Hõj­hü=Yù+°|0ÓË é2|V(™‡d3òæ£]vøÞ§^ÁµB·’©ŽM¢mׇ¿šÒ»+×zÝΨü³ÕKõÜ… hvEmi¯¼;­àv5ÆrqתÀ]seúéœU¢(¬¢8‘ŽÁçå¾|@§ž´}šÂêûùL[½¶Æ]×P|5Ä<×»Ç+•Ï'ó{§ÐNo‡Ò‘ÕîUŒ/¥ûâJ˜^o‰2¯ ©«d~ÑE®ÞÕl=ñûs—5ˆŠ››49™[,´Ë³éQ”ðáE|_üÚ EŽÑáÃ&»*Æ#ĉ·¦ Ëá®·€G/Õíp‡ÌÀ$:RQ‰±¿JÐOꆋ.á–-JFŠcÚµÿØÒþ$<ìöמìµèT8ÃÖµîÀT3tr4ñh5®ª™dwËüPA}fºè!ÜlD­th´'PÁöSu}Ì‘Oν‚¯¿b#k¢+:ºmr½QòHo¡å[ˆÀsC^%T÷¼ýX½DI"ÎÆtòm¹v^t$6lè´ñ +š}-÷äC5ë“ Ù(o‹ev[ÂwB.°÷žï¹?& ¬ àY_÷cÉ[P³÷("vBÅmɧ¦»)à‰Cf„¹‘*ÉÈÅf¯u}¥}z¬K9pl¹u³¹Dà²JzÁ÷¼MÛÓeÉÈ/ÈÕ*J6.صØ>W—ãv†Çvq$ãEÁQp HâfÌÀHa€¨£]òãÚfêÀ!ºæ/b4CÒI§¸•“o¹ìäÀ”-ÿÔzUó‹I;%ü>Ü(Tˆ¥b¢pR<–2#A‰éžùîhÌÖhaxe_3.4.4.orig/extra/extract.hxml0000664000175000017500000000074013166552354017104 0ustar andyandy00000000000000# To rebuild Flash externs (quoting ncannasse): # - Remove haxe/std/flash/DIR where DIR is all directories except _std # - Place library.swf (extracted from playerglobal.swc) next to extract.hxml # - Run haxe extract.hxml # - Restore removed haxe/std/flash/DIR directories # - Copy directories from hxclasses/flash to haxe/std/flash, overwriting restored ones -debug -swf-lib library.swf -swf test.swf -swf-version 15 --macro patchTypes("../extra/extract.patch") --gen-hx-classes haxe_3.4.4.orig/extra/extract.patch0000664000175000017500000014760513166552354017247 0ustar andyandy00000000000000// types patches configuration for playerglobal.swc flash.display.DisplayObject.filters : Array; -flash.accessibility.Accessibility.new @:require(flash10_1) flash.accessibility.ISearchableText @:require(flash10_1) flash.accessibility.ISimpleTextSelection @:require(flash10_1) flash.automation.ActionGenerator @:require(flash10_1) flash.automation.AutomationAction @:require(flash10_1) flash.automation.Configuration @:require(flash10_1) flash.automation.KeyboardAutomationAction @:require(flash10_1) flash.automation.MouseAutomationAction @:require(flash10_1) flash.automation.StageCapture @:require(flash10_1) flash.automation.StageCaptureEvent -flash.desktop.Clipboard.new flash.desktop.Clipboard.formats : Array; flash.desktop.Clipboard.$format : ClipboardFormats; flash.desktop.Clipboard.$transferMode : ClipboardTransferMode; enum flash.desktop.ClipboardFormats; enum flash.desktop.ClipboardTransferMode; enum flash.display.PixelSnapping; enum flash.display.BlendMode; @:require(flash10) flash.desktop.Clipboard @:require(flash10) flash.desktop.ClipboardFormats @:require(flash10) flash.desktop.ClipboardTransferMode flash.display.Bitmap.pixelSnapping : PixelSnapping; flash.display.Bitmap.$pixelSnapping : PixelSnapping; flash.display.BitmapData.$blendMode : BlendMode; flash.display.BitmapData.$redArray : Array; flash.display.BitmapData.$greenArray : Array; flash.display.BitmapData.$blueArray : Array; flash.display.BitmapData.$alphaArray : Array; flash.display.BitmapData.$offsets : Array; @:require(flash10) flash.display.BitmapData.setVector @:require(flash10) flash.display.BitmapData.getVector @:require(flash10) flash.display.BitmapData.histogram @:require(flash10_1) flash.display.Loader.uncaughtErrorEvents; @:require(flash10_1) flash.display.LoaderInfo.isURLInaccessible; @:require(flash10_1) flash.display.LoaderInfo.uncaughtErrorEvents; @:require(flash10_1) flash.display.ColorCorrection @:require(flash10_1) flash.display.ColorCorrectionSupport @:require(flash10_1) flash.display.FocusDirection @:require(flash10_1) flash.display.NativeMenu @:require(flash10_1) flash.display.NativeMenuItem @:require(flash10) flash.display.DisplayObject.blendShader @:require(flash10) flash.display.DisplayObject.rotationX @:require(flash10) flash.display.DisplayObject.rotationY @:require(flash10) flash.display.DisplayObject.rotationZ @:require(flash10) flash.display.DisplayObject.scaleZ @:require(flash10) flash.display.DisplayObject.z @:require(flash10) flash.display.DisplayObject.globalToLocal3D @:require(flash10) flash.display.DisplayObject.local3DToGlobal -flash.display.DisplayObject.new flash.display.DisplayObject.blendMode : BlendMode; flash.display.DisplayObject.opaqueBackground : Null; flash.display.DisplayObjectContainer.getObjectsUnderPoint : Array; @:require(flash10_1) flash.display.Sprite.startTouchDrag; @:require(flash10_1) flash.display.Sprite.stopTouchDrag; @:require(flash10_1) flash.display.Stage.wmodeGPU; enum flash.display.GradientType; enum flash.display.CapsStyle; enum flash.display.JointStyle; enum flash.display.GraphicsPathWinding; enum flash.display.TriangleCulling; enum flash.display.InterpolationMethod; enum flash.display.LineScaleMode; enum flash.display.ShaderParameterType; enum flash.display.ShaderPrecision; enum flash.display.SpreadMethod; enum flash.display.StageAlign; enum flash.display.StageDisplayState; enum flash.display.StageQuality; enum flash.display.StageScaleMode; -flash.display.SWFVersion.new flash.display.Graphics.$type : GradientType; flash.display.Graphics.$colors : Array; flash.display.Graphics.$spreadMethod : SpreadMethod; flash.display.Graphics.$interpolationMethod : InterpolationMethod; flash.display.Graphics.$scaleMode : LineScaleMode; flash.display.Graphics.$caps : CapsStyle; flash.display.Graphics.$joints : JointStyle; flash.display.Graphics.$winding : GraphicsPathWinding; flash.display.Graphics.$culling : TriangleCulling; @:require(flash10) flash.display.Graphics.beginShaderFill @:require(flash10) flash.display.Graphics.copyFrom @:require(flash10) flash.display.Graphics.drawGraphicsData @:require(flash10) flash.display.Graphics.drawPath @:require(flash10) flash.display.Graphics.drawTriangles @:require(flash10) flash.display.Graphics.lineBitmapStyle @:require(flash10) flash.display.Graphics.lineShaderStyle flash.display.GraphicsGradientFill.type : GradientType; flash.display.GraphicsGradientFill.colors : Array; flash.display.GraphicsGradientFill.spreadMethod : SpreadMethod; flash.display.GraphicsGradientFill.interpolationMethod : InterpolationMethod; flash.display.GraphicsGradientFill.alphas : Array; flash.display.GraphicsGradientFill.ratios : Array; flash.display.GraphicsGradientFill.$type : GradientType; flash.display.GraphicsGradientFill.$colors : Array; flash.display.GraphicsGradientFill.$spreadMethod : SpreadMethod; flash.display.GraphicsGradientFill.$interpolationMethod : InterpolationMethod; flash.display.GraphicsGradientFill.$alphas : Array; flash.display.GraphicsGradientFill.$ratios : Array; flash.display.GraphicsGradientFill.$matrix : flash.geom.Matrix; flash.display.GraphicsPath.winding : GraphicsPathWinding; flash.display.GraphicsPath.$winding : GraphicsPathWinding; flash.display.GraphicsStroke.scaleMode : LineScaleMode; flash.display.GraphicsStroke.caps : CapsStyle; flash.display.GraphicsStroke.joints : JointStyle; flash.display.GraphicsStroke.$scaleMode : LineScaleMode; flash.display.GraphicsStroke.$caps : CapsStyle; flash.display.GraphicsStroke.$joints : JointStyle; flash.display.GraphicsTrianglePath.culling : TriangleCulling; flash.display.GraphicsTrianglePath.$culling : TriangleCulling; @:require(flash10) flash.display.Loader.unloadAndStop enum flash.display.ActionScriptVersion; enum flash.display.ColorCorrection; enum flash.display.ColorCorrectionSupport; -flash.display.LoaderInfo.new flash.display.LoaderInfo.parameters : Dynamic; flash.display.LoaderInfo.actionScriptVersion : ActionScriptVersion; -flash.display.MorphShape.new @:require(flash10) flash.display.MovieClip.currentFrameLabel flash.display.MovieClip.currentLabels : Array; flash.display.MovieClip.scenes : Array; flash.display.Scene.labels : Array; flash.display.Scene.$labels : Array; @:require(flash10) flash.display.Shader; flash.display.Shader.precisionHint : ShaderPrecision; -flash.display.ShaderParameter.new flash.display.ShaderParameter.type : ShaderParameterType; -flash.display.Stage.new flash.display.Stage.align : StageAlign; flash.display.Stage.quality : StageQuality; flash.display.Stage.scaleMode : StageScaleMode; flash.display.Stage.colorCorrection : ColorCorrection; flash.display.Stage.colorCorrectionSupport : ColorCorrectionSupport; flash.display.Stage.displayState : StageDisplayState; flash.display.Stage.displayState : StageDisplayState; @:require(flash10) flash.display.Stage.colorCorrection @:require(flash10) flash.display.Stage.colorCorrectionSupport @:require(flash10_1) flash.errors.DRMManagerError @:require(flash10_1) flash.events.AccelerometerEvent @:require(flash10_1) flash.events.DRMAuthenticateEvent @:require(flash10_1) flash.events.DRMAuthenticationCompleteEvent @:require(flash10_1) flash.events.DRMAuthenticationErrorEvent @:require(flash10_1) flash.events.DRMCustomProperties @:require(flash10_1) flash.events.DRMErrorEvent @:require(flash10_1) flash.events.DRMStatusEvent @:require(flash10_1) flash.events.GeolocationEvent @:require(flash10_1) flash.events.GestureEvent @:require(flash10_1) flash.events.GesturePhase @:require(flash10_1) flash.events.PressAndTapGestureEvent @:require(flash10_1) flash.events.TouchEvent @:require(flash10_1) flash.events.TransformGestureEvent @:require(flash10_1) flash.events.UncaughtErrorEvent; @:require(flash10_1) flash.events.UncaughtErrorEvents; @:require(flash10) static flash.events.Event.CLEAR; @:require(flash10) static flash.events.Event.COPY; @:require(flash10) static flash.events.Event.CUT; @:require(flash10) static flash.events.Event.EXIT_FRAME; @:require(flash10) static flash.events.Event.FRAME_CONSTRUCTED; @:require(flash10) static flash.events.Event.PASTE; @:require(flash10) static flash.events.Event.SELECT_ALL; @:require(flash10) flash.events.ContextMenuEvent.isMouseTargetInaccessible @:require(flash10) flash.events.FocusEvent.isRelatedObjectInaccessible @:require(flash10) flash.events.MouseEvent.isRelatedObjectInaccessible flash.events.IEventDispatcher.$listener : Dynamic -> Void; flash.events.EventDispatcher.$listener : Dynamic -> Void; enum flash.events.EventPhase; enum flash.events.GesturePhase; flash.events.Event.eventPhase : EventPhase; flash.events.KeyboardEvent.keyLocation : flash.ui.KeyLocation; flash.events.KeyboardEvent.$keyLocationValue : flash.ui.KeyLocation; flash.events.KeyboardEvent.$keyLocation : flash.ui.KeyLocation; @:require(flash10_1) flash.events.ErrorEvent.errorID; @:require(flash10_1) flash.events.HTTPStatusEvent.responseHeaders; @:require(flash10_1) flash.events.HTTPStatusEvent.responseURL; @:require(flash10_1) static flash.events.HTTPStatusEvent.HTTP_RESPONSE_STATUS; @:require(flash10_1) flash.events.IMEEvent.imeClient; @:require(flash10_1) static flash.events.IMEEvent.IME_START_COMPOSITION; -flash.events.WeakFunctionClosure.new -flash.external.ExternalInterface.new enum flash.filters.BitmapFilterType; enum flash.filters.DisplacementMapFilterMode; flash.filters.BevelFilter.type : BitmapFilterType; flash.filters.BevelFilter.$type : BitmapFilterType; flash.filters.DisplacementMapFilter.mode : DisplacementMapFilterMode; flash.filters.DisplacementMapFilter.$mode : DisplacementMapFilterMode; flash.filters.GradientGlowFilter.type : BitmapFilterType; flash.filters.GradientGlowFilter.$type : BitmapFilterType; enum flash.geom.Orientation3D; flash.geom.Matrix3D.$orientationStyle : Orientation3D; @:require(flash10) flash.geom.Matrix3D; @:require(flash10) flash.geom.Utils3D; @:require(flash10) flash.geom.Vector3D; @:require(flash10) flash.geom.PerspectiveProjection; @:require(flash10) flash.geom.Transform.matrix3D; @:require(flash10) flash.geom.Transform.perspectiveProjection; @:require(flash10) flash.geom.Transform.getRelativeMatrix3D; -flash.geom.Utils3D.new @:require(flash10_1) static flash.media.Camera.isSupported; @:require(flash10_1) static flash.media.Camera._scanHardware; enum flash.media.SoundCodec; flash.media.Microphone.codec : SoundCodec; @:require(flash10) flash.media.Microphone.codec; @:require(flash10) flash.media.Microphone.encodeQuality; @:require(flash10) flash.media.Microphone.framesPerPacket; @:require(flash10_1) flash.media.Microphone.enableVAD; @:require(flash10_1) flash.media.Microphone.noiseSuppressionLevel; @:require(flash10_1) static flash.media.Microphone.isSupported; @:require(flash10) flash.media.Sound.extract; @:require(flash10_1) flash.media.Sound.isURLInaccessible; @:require(flash10) flash.net.FileReference.data; @:require(flash10) flash.net.FileReference.load; @:require(flash10) flash.net.FileReference.save; -flash.media.SoundMixer.new @:require(flash10_1) flash.net.LocalConnection.isPerUser; @:require(flash10_1) static flash.net.LocalConnection.isSupported; flash.net.FileReference.$typeFilter : Array; flash.net.FileReferenceList.fileList : Array; flash.net.FileReferenceList.$typeFilter : Array; @:require(flash10_1) flash.net.GroupSpecifier; @:require(flash10_1) flash.net.NetGroup; @:require(flash10_1) flash.net.NetGroupInfo; @:require(flash10_1) flash.net.NetStreamMulticastInfo; @:require(flash10) flash.net.NetConnection.farID; @:require(flash10) flash.net.NetConnection.farNonce; @:require(flash10) flash.net.NetConnection.maxPeerConnections; @:require(flash10) flash.net.NetConnection.nearID; @:require(flash10) flash.net.NetConnection.nearNonce; @:require(flash10) flash.net.NetConnection.protocol; @:require(flash10) flash.net.NetConnection.unconnectedPeerStreams; @:require(flash10) flash.net.NetStream.farID; @:require(flash10) flash.net.NetStream.farNonce; @:require(flash10) flash.net.NetStream.info; @:require(flash10) flash.net.NetStream.maxPauseBufferTime; @:require(flash10) flash.net.NetStream.nearNonce; @:require(flash10) flash.net.NetStream.peerStreams; @:require(flash10) flash.net.NetStream.onPeerConnect; @:require(flash10) flash.net.NetStream.play2; @:require(flash10) static flash.net.NetStream.CONNECT_TO_FMS; @:require(flash10) static flash.net.NetStream.DIRECT_CONNECTIONS; @:require(flash10_1) flash.net.NetStream.audioReliable; @:require(flash10_1) flash.net.NetStream.audioSampleAccess; @:require(flash10_1) flash.net.NetStream.backBufferLength; @:require(flash10_1) flash.net.NetStream.backBufferTime; @:require(flash10_1) flash.net.NetStream.bufferTimeMax; @:require(flash10_1) flash.net.NetStream.dataReliable; @:require(flash10_1) flash.net.NetStream.inBufferSeek; @:require(flash10_1) flash.net.NetStream.multicastAvailabilitySendToAll; @:require(flash10_1) flash.net.NetStream.multicastAvailabilityUpdatePeriod; @:require(flash10_1) flash.net.NetStream.multicastFetchPeriod; @:require(flash10_1) flash.net.NetStream.multicastInfo; @:require(flash10_1) flash.net.NetStream.multicastPushNeighborLimit; @:require(flash10_1) flash.net.NetStream.multicastRelayMarginDuration; @:require(flash10_1) flash.net.NetStream.multicastWindowDuration; @:require(flash10_1) flash.net.NetStream.videoReliable; @:require(flash10_1) flash.net.NetStream.videoSampleAccess; @:require(flash10_1) flash.net.NetStream.appendBytes; @:require(flash10_1) flash.net.NetStream.appendBytesAction; @:require(flash10_1) flash.net.NetStream.attach; @:require(flash10_1) flash.net.NetStream.step; @:require(flash10_1) flash.net.NetStreamInfo.videoLossRate; @:require(flash10_1) flash.net.NetStreamPlayOptions.offset; @:require(flash10_1) static flash.net.URLRequestMethod.DELETE; @:require(flash10_1) static flash.net.URLRequestMethod.HEAD; @:require(flash10_1) static flash.net.URLRequestMethod.OPTIONS; @:require(flash10_1) static flash.net.URLRequestMethod.PUT; @:require(flash10) flash.net.Socket.timeout; @:require(flash10) flash.net.XMLSocket.timeout; -flash.net.ObjectEncoding.new -flash.net.URLRequestMethod.new enum flash.net.URLLoaderDataFormat; flash.net.Socket.endian : flash.utils.Endian; flash.net.URLLoader.dataFormat : URLLoaderDataFormat; flash.net.URLRequest.requestHeaders : Array; flash.net.URLStream.endian : flash.utils.Endian; enum flash.printing.PrintJobOrientation; flash.printing.PrintJob.orientation : PrintJobOrientation; @:require(flash10_1) static flash.printing.PrintJob.isSupported; -flash.sampler.DeleteObjectSample.new -flash.sampler.NewObjectSample.new -flash.sampler.Sample.new flash.sampler.Sample.stack : Array; -flash.sampler.StackFrame.new @:require(flash10_1) flash.sampler.NewObjectSample.size; @:require(flash10_1) flash.sampler.StackFrame.scriptID; -flash.system.Capabilities.new -flash.system.IME.new -flash.system.FSCommand.new enum flash.system.IMEConversionMode; static flash.system.IME.conversionMode : IMEConversionMode @:require(flash10) flash.system.ApplicationDomain.domainMemory; @:require(flash10) static flash.system.ApplicationDomain.MIN_DOMAIN_MEMORY_LENGTH; @:require(flash10) static flash.system.Capabilities.isEmbeddedInAcrobat; @:require(flash10) static flash.system.Capabilities.maxLevelIDC; @:require(flash10_1) static flash.system.Capabilities.cpuArchitecture; @:require(flash10_1) static flash.system.Capabilities.supports32BitProcesses; @:require(flash10_1) static flash.system.Capabilities.supports64BitProcesses; @:require(flash10_1) static flash.system.Capabilities.touchscreenType; static flash.system.Capabilities.touchscreenType : TouchscreenType; enum flash.system.TouchscreenType; @:require(flash10_1) static flash.system.IME.isSupported; @:require(flash10_1) static flash.system.IME.compositionAbandoned; @:require(flash10_1) static flash.system.IME.compositionSelectionChanged; @:require(flash10) flash.system.JPEGLoaderContext; @:require(flash10_1) flash.system.LoaderContext.allowCodeImport; @:require(flash10_1) flash.system.LoaderContext.allowLoadBytesCodeExecution; @:require(flash10_1) static flash.system.Security.APPLICATION; @:require(flash10_1) static flash.system.Security.duplicateSandboxBridgeInputArguments; @:require(flash10_1) static flash.system.Security.duplicateSandboxBridgeOutputArgument; @:require(flash10_1) static flash.system.System.currentTime; @:require(flash10_1) static flash.system.System.freeMemory; @:require(flash10_1) static flash.system.System.preciseStartupTime; @:require(flash10_1) static flash.system.System.privateMemory; @:require(flash10_1) static flash.system.System.totalMemoryNumber; @:require(flash10_1) static flash.system.System.disposeXML; @:require(flash10_1) static flash.system.System.nativeConstructionOnly; enum flash.system.SecurityPanel; -flash.system.Security.new flash.system.Security.$panel : SecurityPanel -flash.system.SecurityDomain.new -flash.system.System.new flash.system.SystemUpdater.$typer : SystemAdapterType; enum flash.text.AntiAliasType; enum flash.text.GridFitType; enum flash.text.FontStyle; enum flash.text.FontType; enum flash.text.TextDisplayMode; enum flash.text.TextFieldType; enum flash.text.TextFieldAutoSize; enum flash.text.TextFormatAlign; enum flash.text.TextFormatDisplay; enum flash.text.TextColorType; flash.text.Font.fontStyle : FontStyle; flash.text.Font.fontType : FontType; static flash.text.Font.enumerateFonts : Array; flash.text.TextField.autoSize : TextFieldAutoSize; flash.text.TextField.antiAliasType : AntiAliasType; flash.text.TextField.gridFitType : GridFitType; flash.text.TextField.type : TextFieldType; flash.text.TextFormat.align : TextFormatAlign; flash.text.TextFormat.blockIndent : Null flash.text.TextFormat.bold : Null; flash.text.TextFormat.bullet : Null; flash.text.TextFormat.color : Null; flash.text.TextFormat.display : TextFormatDisplay; flash.text.TextFormat.indent : Null; flash.text.TextFormat.italic : Null; flash.text.TextFormat.kerning : Null; flash.text.TextFormat.leading : Null; flash.text.TextFormat.leftMargin : Null; flash.text.TextFormat.letterSpacing : Null; flash.text.TextFormat.rightMargin : Null; flash.text.TextFormat.size : Null; flash.text.TextFormat.tabStops : Array; flash.text.TextFormat.underline : Null; flash.text.TextFormat.$size : Null; flash.text.TextFormat.$color : Null; flash.text.TextFormat.$bold : Null; flash.text.TextFormat.$italic : Null; flash.text.TextFormat.$underline : Null; flash.text.TextFormat.$align : TextFormatAlign; flash.text.TextFormat.$leftMargin : Null; flash.text.TextFormat.$rightMargin : Null; flash.text.TextFormat.$indent : Null; flash.text.TextFormat.$leading : Null; @:require(flash10) static flash.text.TextField.isFontCompatible; -flash.text.TextRenderer.new static flash.text.TextRenderer.antiAliasType : AntiAliasType; static flash.text.TextRenderer.displayMode : TextDisplayMode; flash.text.TextRenderer.$fontStyle : FontStyle; flash.text.TextRenderer.$colorType : TextColorType; @:require(flash10_1) static flash.text.engine.FontDescription.isDeviceFontCompatible; @:require(flash10_1) flash.text.engine.SpaceJustifier.maximumSpacing; @:require(flash10_1) flash.text.engine.SpaceJustifier.minimumSpacing; @:require(flash10_1) flash.text.engine.SpaceJustifier.optimumSpacing; @:require(flash10_1) flash.text.engine.TextBlock.recreateTextLine; @:require(flash10_1) flash.text.engine.TextBlock.releaseLineCreationData; @:require(flash10_1) flash.text.engine.TextLine.hasTabs; flash.text.engine.ContentElement.textRotation : TextRotation; flash.text.engine.ContentElement.$textRotation : TextRotation; flash.text.engine.EastAsianJustifier.justificationStyle : JustificationStyle; flash.text.engine.EastAsianJustifier.$justificationStyle : JustificationStyle; flash.text.engine.EastAsianJustifier.$lineJustification : LineJustification; enum flash.text.engine.BreakOpportunity; enum flash.text.engine.CFFHinting; enum flash.text.engine.DigitCase; enum flash.text.engine.DigitWidth; enum flash.text.engine.FontLookup; enum flash.text.engine.FontPosture; enum flash.text.engine.FontWeight; enum flash.text.engine.JustificationStyle; enum flash.text.engine.Kerning; enum flash.text.engine.LigatureLevel; enum flash.text.engine.LineJustification; enum flash.text.engine.RenderingMode; enum flash.text.engine.TabAlignment; enum flash.text.engine.TextBaseline; enum flash.text.engine.TextLineCreationResult; enum flash.text.engine.TextLineValidity; enum flash.text.engine.TextRotation; enum flash.text.engine.TypographicCase; flash.text.engine.ElementFormat.alignmentBaseline : TextBaseline; flash.text.engine.ElementFormat.breakOpportunity : BreakOpportunity; flash.text.engine.ElementFormat.digitCase : DigitCase; flash.text.engine.ElementFormat.digitWidth : DigitWidth; flash.text.engine.ElementFormat.dominantBaseline : TextBaseline; flash.text.engine.ElementFormat.kerning : Kerning; flash.text.engine.ElementFormat.ligatureLevel : LigatureLevel; flash.text.engine.ElementFormat.textRotation : TextRotation; flash.text.engine.ElementFormat.typographicCase : TypographicCase; flash.text.engine.ElementFormat.$alignmentBaseline : TextBaseline; flash.text.engine.ElementFormat.$breakOpportunity : BreakOpportunity; flash.text.engine.ElementFormat.$digitCase : DigitCase; flash.text.engine.ElementFormat.$digitWidth : DigitWidth; flash.text.engine.ElementFormat.$dominantBaseline : TextBaseline; flash.text.engine.ElementFormat.$kerning : Kerning; flash.text.engine.ElementFormat.$ligatureLevel : LigatureLevel; flash.text.engine.ElementFormat.$textRotation : TextRotation; flash.text.engine.ElementFormat.$typographicCase : TypographicCase; flash.text.engine.FontDescription.cffHinting : CFFHinting; flash.text.engine.FontDescription.fontLookup : FontLookup; flash.text.engine.FontDescription.fontPosture : FontPosture; flash.text.engine.FontDescription.fontWeight : FontWeight; flash.text.engine.FontDescription.renderingMode : RenderingMode; flash.text.engine.FontDescription.$cffHinting : CFFHinting; flash.text.engine.FontDescription.$fontLookup : FontLookup; flash.text.engine.FontDescription.$fontPosture : FontPosture; flash.text.engine.FontDescription.$fontWeight : FontWeight; flash.text.engine.FontDescription.$renderingMode : RenderingMode; flash.text.engine.GraphicElement.$textRotation : TextRotation; flash.text.engine.GroupElement.$textRotation : TextRotation; flash.text.engine.SpaceJustifier.$lineJustification : LineJustification; flash.text.engine.TabStop.alignment : TabAlignment; flash.text.engine.TabStop.$alignment : TabAlignment; flash.text.engine.TextBlock.baselineZero : TextBaseline; flash.text.engine.TextBlock.lineRotation : TextRotation; flash.text.engine.TextBlock.textLineCreationResult : TextLineCreationResult; flash.text.engine.TextBlock.$baselineZero : TextBaseline; flash.text.engine.TextBlock.$lineRotation : TextRotation; flash.text.engine.TextBlock.$textLineCreationResult : TextLineCreationResult; flash.text.engine.TextElement.$textRotation : TextRotation; flash.text.engine.TextJustifier.lineJustification : LineJustification; flash.text.engine.TextJustifier.$lineJustification : LineJustification; flash.text.engine.TextLine.baseline : TextBaseline; -flash.trace.Trace.new -static flash.xml.XMLList.length -static flash.xml.XML.length -flash.text.engine.TextElement.text -flash.ui.Keyboard.new -flash.ui.Mouse.new enum flash.ui.MultitouchInputMode; -flash.ui.Multitouch.new flash.ui.Multitouch.inputMode : MultitouchInputMode; @:require(flash10) flash.ui.ContextMenu.clipboardItems; @:require(flash10) flash.ui.ContextMenu.clipboardMenu; @:require(flash10) flash.ui.ContextMenu.link; @:require(flash10_1) static flash.ui.ContextMenu.isSupported; @:require(flash10) static flash.ui.Mouse.cursor; static flash.ui.Mouse.cursor : Dynamic; @:require(flash10_1) static flash.ui.Keyboard.A; @:require(flash10_1) static flash.ui.Keyboard.B; @:require(flash10_1) static flash.ui.Keyboard.C; @:require(flash10_1) static flash.ui.Keyboard.D; @:require(flash10_1) static flash.ui.Keyboard.E; @:require(flash10_1) static flash.ui.Keyboard.F; @:require(flash10_1) static flash.ui.Keyboard.G; @:require(flash10_1) static flash.ui.Keyboard.H; @:require(flash10_1) static flash.ui.Keyboard.I; @:require(flash10_1) static flash.ui.Keyboard.J; @:require(flash10_1) static flash.ui.Keyboard.K; @:require(flash10_1) static flash.ui.Keyboard.L; @:require(flash10_1) static flash.ui.Keyboard.M; @:require(flash10_1) static flash.ui.Keyboard.N; @:require(flash10_1) static flash.ui.Keyboard.O; @:require(flash10_1) static flash.ui.Keyboard.P; @:require(flash10_1) static flash.ui.Keyboard.Q; @:require(flash10_1) static flash.ui.Keyboard.R; @:require(flash10_1) static flash.ui.Keyboard.S; @:require(flash10_1) static flash.ui.Keyboard.T; @:require(flash10_1) static flash.ui.Keyboard.U; @:require(flash10_1) static flash.ui.Keyboard.V; @:require(flash10_1) static flash.ui.Keyboard.W; @:require(flash10_1) static flash.ui.Keyboard.X; @:require(flash10_1) static flash.ui.Keyboard.Y; @:require(flash10_1) static flash.ui.Keyboard.Z; @:require(flash10_1) static flash.ui.Keyboard.ALTERNATE; @:require(flash10_1) static flash.ui.Keyboard.BACKQUOTE; @:require(flash10_1) static flash.ui.Keyboard.BACKSLASH; @:require(flash10_1) static flash.ui.Keyboard.COMMA; @:require(flash10_1) static flash.ui.Keyboard.COMMAND; @:require(flash10_1) static flash.ui.Keyboard.CharCodeStrings; @:require(flash10_1) static flash.ui.Keyboard.EQUAL; @:require(flash10_1) static flash.ui.Keyboard.LEFTBRACKET; @:require(flash10_1) static flash.ui.Keyboard.MINUS; @:require(flash10_1) static flash.ui.Keyboard.NUMBER_0; @:require(flash10_1) static flash.ui.Keyboard.NUMBER_1; @:require(flash10_1) static flash.ui.Keyboard.NUMBER_2; @:require(flash10_1) static flash.ui.Keyboard.NUMBER_3; @:require(flash10_1) static flash.ui.Keyboard.NUMBER_4; @:require(flash10_1) static flash.ui.Keyboard.NUMBER_5; @:require(flash10_1) static flash.ui.Keyboard.NUMBER_6; @:require(flash10_1) static flash.ui.Keyboard.NUMBER_7; @:require(flash10_1) static flash.ui.Keyboard.NUMBER_8; @:require(flash10_1) static flash.ui.Keyboard.NUMBER_9; @:require(flash10_1) static flash.ui.Keyboard.NUMPAD; @:require(flash10_1) static flash.ui.Keyboard.PERIOD; @:require(flash10_1) static flash.ui.Keyboard.QUOTE; @:require(flash10_1) static flash.ui.Keyboard.RIGHTBRACKET; @:require(flash10_1) static flash.ui.Keyboard.SEMICOLON; @:require(flash10_1) static flash.ui.Keyboard.SLASH; @:require(flash10_1) static flash.ui.Keyboard.hasVirtualKeyboard; @:require(flash10_1) static flash.ui.Keyboard.physicalKeyboardType; enum flash.ui.KeyboardType; enum flash.ui.KeyLocation; static flash.ui.Keyboard.physicalKeyboardType : KeyboardType; @:require(flash10_1) flash.ui.Multitouch; static flash.ui.Multitouch.inputMode : MultitouchInputMode; @:require(flash10_1) flash.ui.MultitouchInputMode; @:require(flash10_1) static flash.ui.Keyboard.STRING_BEGIN; @:require(flash10_1) static flash.ui.Keyboard.STRING_BREAK; @:require(flash10_1) static flash.ui.Keyboard.STRING_CLEARDISPLAY; @:require(flash10_1) static flash.ui.Keyboard.STRING_CLEARLINE; @:require(flash10_1) static flash.ui.Keyboard.STRING_DELETE; @:require(flash10_1) static flash.ui.Keyboard.STRING_DELETECHAR; @:require(flash10_1) static flash.ui.Keyboard.STRING_DELETELINE; @:require(flash10_1) static flash.ui.Keyboard.STRING_DOWNARROW; @:require(flash10_1) static flash.ui.Keyboard.STRING_END; @:require(flash10_1) static flash.ui.Keyboard.STRING_EXECUTE; @:require(flash10_1) static flash.ui.Keyboard.STRING_F1; @:require(flash10_1) static flash.ui.Keyboard.STRING_F10; @:require(flash10_1) static flash.ui.Keyboard.STRING_F11; @:require(flash10_1) static flash.ui.Keyboard.STRING_F12; @:require(flash10_1) static flash.ui.Keyboard.STRING_F13; @:require(flash10_1) static flash.ui.Keyboard.STRING_F14; @:require(flash10_1) static flash.ui.Keyboard.STRING_F15; @:require(flash10_1) static flash.ui.Keyboard.STRING_F16; @:require(flash10_1) static flash.ui.Keyboard.STRING_F17; @:require(flash10_1) static flash.ui.Keyboard.STRING_F18; @:require(flash10_1) static flash.ui.Keyboard.STRING_F19; @:require(flash10_1) static flash.ui.Keyboard.STRING_F2; @:require(flash10_1) static flash.ui.Keyboard.STRING_F20; @:require(flash10_1) static flash.ui.Keyboard.STRING_F21; @:require(flash10_1) static flash.ui.Keyboard.STRING_F22; @:require(flash10_1) static flash.ui.Keyboard.STRING_F23; @:require(flash10_1) static flash.ui.Keyboard.STRING_F24; @:require(flash10_1) static flash.ui.Keyboard.STRING_F25; @:require(flash10_1) static flash.ui.Keyboard.STRING_F26; @:require(flash10_1) static flash.ui.Keyboard.STRING_F27; @:require(flash10_1) static flash.ui.Keyboard.STRING_F28; @:require(flash10_1) static flash.ui.Keyboard.STRING_F29; @:require(flash10_1) static flash.ui.Keyboard.STRING_F3; @:require(flash10_1) static flash.ui.Keyboard.STRING_F30; @:require(flash10_1) static flash.ui.Keyboard.STRING_F31; @:require(flash10_1) static flash.ui.Keyboard.STRING_F32; @:require(flash10_1) static flash.ui.Keyboard.STRING_F33; @:require(flash10_1) static flash.ui.Keyboard.STRING_F34; @:require(flash10_1) static flash.ui.Keyboard.STRING_F35; @:require(flash10_1) static flash.ui.Keyboard.STRING_F4; @:require(flash10_1) static flash.ui.Keyboard.STRING_F5; @:require(flash10_1) static flash.ui.Keyboard.STRING_F6; @:require(flash10_1) static flash.ui.Keyboard.STRING_F7; @:require(flash10_1) static flash.ui.Keyboard.STRING_F8; @:require(flash10_1) static flash.ui.Keyboard.STRING_F9; @:require(flash10_1) static flash.ui.Keyboard.STRING_FIND; @:require(flash10_1) static flash.ui.Keyboard.STRING_HELP; @:require(flash10_1) static flash.ui.Keyboard.STRING_HOME; @:require(flash10_1) static flash.ui.Keyboard.STRING_INSERT; @:require(flash10_1) static flash.ui.Keyboard.STRING_INSERTCHAR; @:require(flash10_1) static flash.ui.Keyboard.STRING_INSERTLINE; @:require(flash10_1) static flash.ui.Keyboard.STRING_LEFTARROW; @:require(flash10_1) static flash.ui.Keyboard.STRING_MENU; @:require(flash10_1) static flash.ui.Keyboard.STRING_MODESWITCH; @:require(flash10_1) static flash.ui.Keyboard.STRING_NEXT; @:require(flash10_1) static flash.ui.Keyboard.STRING_PAGEDOWN; @:require(flash10_1) static flash.ui.Keyboard.STRING_PAGEUP; @:require(flash10_1) static flash.ui.Keyboard.STRING_PAUSE; @:require(flash10_1) static flash.ui.Keyboard.STRING_PREV; @:require(flash10_1) static flash.ui.Keyboard.STRING_PRINT; @:require(flash10_1) static flash.ui.Keyboard.STRING_PRINTSCREEN; @:require(flash10_1) static flash.ui.Keyboard.STRING_REDO; @:require(flash10_1) static flash.ui.Keyboard.STRING_RESET; @:require(flash10_1) static flash.ui.Keyboard.STRING_RIGHTARROW; @:require(flash10_1) static flash.ui.Keyboard.STRING_SCROLLLOCK; @:require(flash10_1) static flash.ui.Keyboard.STRING_SELECT; @:require(flash10_1) static flash.ui.Keyboard.STRING_STOP; @:require(flash10_1) static flash.ui.Keyboard.STRING_SYSREQ; @:require(flash10_1) static flash.ui.Keyboard.STRING_SYSTEM; @:require(flash10_1) static flash.ui.Keyboard.STRING_UNDO; @:require(flash10_1) static flash.ui.Keyboard.STRING_UPARROW; @:require(flash10_1) static flash.ui.Keyboard.STRING_USER; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_BEGIN; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_BREAK; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_CLEARDISPLAY; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_CLEARLINE; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_DELETE; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_DELETECHAR; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_DELETELINE; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_DOWNARROW; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_END; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_EXECUTE; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F1; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F10; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F11; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F12; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F13; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F14; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F15; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F16; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F17; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F18; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F19; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F2; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F20; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F21; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F22; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F23; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F24; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F25; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F26; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F27; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F28; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F29; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F3; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F30; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F31; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F32; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F33; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F34; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F35; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F4; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F5; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F6; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F7; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F8; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_F9; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_FIND; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_HELP; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_HOME; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_INSERT; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_INSERTCHAR; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_INSERTLINE; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_LEFTARROW; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_MENU; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_MODESWITCH; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_NEXT; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_PAGEDOWN; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_PAGEUP; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_PAUSE; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_PREV; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_PRINT; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_PRINTSCREEN; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_REDO; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_RESET; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_RIGHTARROW; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_SCROLLLOCK; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_SELECT; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_STOP; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_SYSREQ; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_SYSTEM; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_UNDO; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_UPARROW; @:require(flash10_1) static flash.ui.Keyboard.KEYNAME_USER; @:require(flash10_1) static flash.ui.Mouse.supportsCursor; enum flash.utils.Endian; @:native("RegExp") flash.utils.RegExp; -static flash.utils.RegExp.length; flash.utils.ObjectInput.endian : Endian; flash.utils.ObjectOutput.endian : Endian; flash.utils.ByteArray.endian : Endian; flash.utils.IDataInput.endian : Endian; flash.utils.IDataOutput.endian : Endian; @:require(flash10) flash.utils.ByteArray.clear; @:require(flash10) flash.utils.ByteArray.deflate; @:require(flash10) flash.utils.ByteArray.inflate; @:require(flash10) flash.utils.SetIntervalTimer.clearArrayEntry; -flash.utils.Namespace.toString -flash.utils.Namespace.valueOf -static flash.utils.Namespace.length -flash.utils.QName.toString -flash.utils.QName.valueOf -static flash.utils.QName.length enum flash.xml.XMLNodeType; flash.xml.XMLNode.nodeType : XMLNodeType; flash.xml.XMLNode.$type : XMLNodeType; flash.xml.XML.namespace : flash.utils.Namespace; flash.xml.XML.parent : XML; flash.xml.XMLList.namespace : flash.utils.Namespace; flash.xml.XMLList.parent : XML; flash.xml.XMLTag.type : XMLNodeType; enum flash.system.SystemUpdaterType; @:require(flash10_1) flash.system.SystemUpdater; flash.system.SystemUpdater.$type : SystemUpdaterType; @:require(flash10_1) flash.sensors.Accelerometer; @:require(flash10_1) flash.sensors.Geolocation; @:require(flash10_1) flash.globalization.Collator; @:require(flash10_1) flash.globalization.CurrencyFormatter; @:require(flash10_1) flash.globalization.DateTimeFormatter; @:require(flash10_1) flash.globalization.LocaleID; @:require(flash10_1) flash.globalization.StringTools; @:require(flash10_1) flash.globalization.NumberFormatter; @:require(flash10_1) flash.globalization.NumberParseResult; enum flash.globalization.CollatorMode; enum flash.globalization.DateTimeNameContext; enum flash.globalization.DateTimeNameStyle; enum flash.globalization.DateTimeStyle; enum flash.globalization.LastOperationStatus; enum flash.globalization.NationalDigitsType; flash.globalization.Collator.lastOperationStatus : LastOperationStatus; flash.globalization.Collator.$initialMode : CollatorMode; flash.globalization.CurrencyFormatter.lastOperationStatus : LastOperationStatus; flash.globalization.DateTimeFormatter.lastOperationStatus : LastOperationStatus; flash.globalization.DateTimeFormatter.$dateStyle : DateTimeStyle; flash.globalization.DateTimeFormatter.$nameStyle : DateTimeNameStyle; flash.globalization.DateTimeFormatter.$timeStyle : DateTimeStyle; flash.globalization.DateTimeFormatter.$context : DateTimeNameContext; flash.globalization.DateTimeFormatter.getDateStyle : DateTimeStyle; flash.globalization.DateTimeFormatter.getTimeStyle : DateTimeStyle; flash.globalization.DateTimeFormatter.getDateTimePattern : DateTimeStyle; flash.globalization.LocaleID.lastOperationStatus : LastOperationStatus; flash.globalization.NumberFormatter.lastOperationStatus : LastOperationStatus; flash.globalization.NumberFormatter.digitsType : NationalDigitsType; flash.globalization.StringTools.lastOperationStatus : LastOperationStatus; // FP 10.2 @:require(flash10_2) flash.ui.MouseCursorData; @:require(flash10_2) flash.events.StageVideoEvent; @:require(flash10_2) flash.events.VideoEvent; @:require(flash10_2) flash.media.MicrophoneEnhancedMode; @:require(flash10_2) flash.media.MicrophoneEnhancedOptions; @:require(flash10_2) flash.media.StageVideo; @:require(flash10_2) flash.display.Stage.color; @:require(flash10_2) flash.display.Stage.stageVideos; @:require(flash10_2) flash.media.Microphone.enhancedOptions; @:require(flash10_2) static flash.media.Microphone.getEnhancedMicrophone; @:require(flash10_2) flash.system.Capabilities.allowsFullScreen; @:require(flash10_2) static flash.ui.Keyboard.AUDIO; @:require(flash10_2) static flash.ui.Keyboard.BACK; @:require(flash10_2) static flash.ui.Keyboard.BLUE; @:require(flash10_2) static flash.ui.Keyboard.CHANNEL_DOWN; @:require(flash10_2) static flash.ui.Keyboard.CHANNEL_UP; @:require(flash10_2) static flash.ui.Keyboard.DVR; @:require(flash10_2) static flash.ui.Keyboard.EXIT; @:require(flash10_2) static flash.ui.Keyboard.FAST_FORWARD; @:require(flash10_2) static flash.ui.Keyboard.GREEN; @:require(flash10_2) static flash.ui.Keyboard.GUIDE; @:require(flash10_2) static flash.ui.Keyboard.HELP; @:require(flash10_2) static flash.ui.Keyboard.INFO; @:require(flash10_2) static flash.ui.Keyboard.INPUT; @:require(flash10_2) static flash.ui.Keyboard.LAST; @:require(flash10_2) static flash.ui.Keyboard.LIVE; @:require(flash10_2) static flash.ui.Keyboard.MASTER_SHELL; @:require(flash10_2) static flash.ui.Keyboard.MENU; @:require(flash10_2) static flash.ui.Keyboard.NEXT; @:require(flash10_2) static flash.ui.Keyboard.PAUSE; @:require(flash10_2) static flash.ui.Keyboard.PLAY; @:require(flash10_2) static flash.ui.Keyboard.PREVIOUS; @:require(flash10_2) static flash.ui.Keyboard.RECORD; @:require(flash10_2) static flash.ui.Keyboard.RED; @:require(flash10_2) static flash.ui.Keyboard.REWIND; @:require(flash10_2) static flash.ui.Keyboard.SEARCH; @:require(flash10_2) static flash.ui.Keyboard.SETUP; @:require(flash10_2) static flash.ui.Keyboard.SKIP_BACKWARD; @:require(flash10_2) static flash.ui.Keyboard.SKIP_FORWARD; @:require(flash10_2) static flash.ui.Keyboard.STOP; @:require(flash10_2) static flash.ui.Keyboard.SUBTITLE; @:require(flash10_2) static flash.ui.Keyboard.VOD; @:require(flash10_2) static flash.ui.Keyboard.YELLOW; @:require(flash10_2) static flash.ui.Mouse.registerCursor; enum flash.media.MicrophoneEnhancedMode; flash.media.MicrophoneEnhancedOptions.mode : MicrophoneEnhancedMode; enum flash.display.FocusDirection; // FLASH 11 FEATURES -flash.automation.Configuration.new @:require(flash11) flash.display.DisplayObjectContainer.removeChildren; @:require(flash11) flash.display.Graphics.cubicCurveTo; @:require(flash11) flash.display.GraphicsPath.cubicCurveTo; @:require(flash11) flash.display.InteractiveObject.needsSoftKeyboard; @:require(flash11) flash.display.InteractiveObject.softKeyboardInputAreaOfInterest; @:require(flash11) flash.display.InteractiveObject.requestSoftKeyboard; @:require(flash11) flash.display.MovieClip.isPlaying; @:require(flash11) flash.display.Stage.displayContextInfo; @:require(flash11) flash.display.Stage.softKeyboardRect; @:require(flash11) flash.display.Stage.stage3Ds; @:require(flash11) flash.display.Stage3D; -flash.display.Stage.constructor; -flash.display.Stage.hasOwnProperty; -flash.display.Stage.isPrototypeOf; -flash.display.Stage.propertyIsEnumerable; -flash.display.Stage.setPropertyIsEnumerable; -flash.display.Stage.toLocaleString; -flash.display.Stage.valueOf; enum flash.display3D.Context3DBlendFactor; enum flash.display3D.; @:require(flash11) static flash.events.Event.CONTEXT3D_CREATE; @:require(flash11) static flash.events.Event.TEXT_INTERACTION_MODE_CHANGE; @:require(flash11) static flash.events.StageVideoEvent.RENDER_STATUS_AVAILABLE; @:require(flash11) static flash.events.StageVideoEvent.STAGE_VIDEO_STATE; @:require(flash11) flash.geom.Matrix3D.copyColumnFrom; @:require(flash11) flash.geom.Matrix3D.copyColumnTo; @:require(flash11) flash.geom.Matrix3D.copyFrom; @:require(flash11) flash.geom.Matrix3D.copyRawDataFrom; @:require(flash11) flash.geom.Matrix3D.copyRawDataTo; @:require(flash11) flash.geom.Matrix3D.copyRowFrom; @:require(flash11) flash.geom.Matrix3D.copyRowTo; @:require(flash11) flash.geom.Matrix3D.copyToMatrix3D; @:require(flash11) flash.geom.Matrix.copyColumnFrom; @:require(flash11) flash.geom.Matrix.copyColumnTo; @:require(flash11) flash.geom.Matrix.copyFrom; @:require(flash11) flash.geom.Matrix.copyRowFrom; @:require(flash11) flash.geom.Matrix.copyRowTo; @:require(flash11) flash.geom.Matrix.setTo; @:require(flash11) flash.geom.Point.copyFrom; @:require(flash11) flash.geom.Point.setTo; @:require(flash11) flash.geom.Rectangle.copyFrom; @:require(flash11) flash.geom.Rectangle.setTo; @:require(flash11) flash.geom.Vector3D.copyFrom; @:require(flash11) flash.geom.Vector3D.setTo; @:require(flash11) flash.media.Sound.loadCompressedDataFromByteArray; @:require(flash11) flash.media.Sound.loadPCMFromByteArray; @:require(flash11) flash.net.Socket.bytesPending; -flash.display3D.Context3DClearMask.new; enum flash.display3D.Context3DCompareMode; enum flash.display3D.Context3DProgramType; enum flash.display3D.Context3DRenderMode; enum flash.display3D.Context3DStencilAction; enum flash.display3D.Context3DTextureFormat; enum flash.display3D.Context3DTriangleFace; enum flash.display3D.Context3DVertexBufferFormat; -flash.display.Stage3D.new; -flash.display3D.Context3D.new; -flash.display3D.IndexBuffer3D.new; -flash.display3D.Program3D.new; -flash.display3D.VertexBuffer3D.new; -flash.display3D.textures.CubeTexture.new; -flash.display3D.textures.TextureBase.new; -flash.display3D.textures.Texture.new; flash.display3D.Context3D.$sourceFactor : Context3DBlendFactor; flash.display3D.Context3D.$destinationFactor : Context3DBlendFactor; flash.display3D.Context3D.$format : Context3DTextureFormat; flash.display3D.Context3D.$triangleFaceToCull : Context3DTriangleFace; flash.display3D.Context3D.$triangleFace : Context3DTriangleFace; flash.display3D.Context3D.$passCompareMode : Context3DCompareMode; flash.display3D.Context3D.$compareMode : Context3DCompareMode; flash.display3D.Context3D.$programType : Context3DProgramType; flash.display3D.Context3D.$actionOnBothPass : Context3DStencilAction; flash.display3D.Context3D.$actionOnDepthFail : Context3DStencilAction; flash.display3D.Context3D.$actionOnDepthPassStencilFail : Context3DStencilAction; flash.display3D.Context3D.$setVertexBufferAt__format : Context3DVertexBufferFormat; @:require(flash11) flash.net.NetStream.useHardwareDecoder; @:require(flash11) flash.net.NetStream.videoStreamSettings; @:require(flash11) flash.net.SecureSocket; @:require(flash11) flash.net.NetMonitor; @:require(flash11) static flash.system.Capabilities.hasMultiChannelAudio; @:require(flash11) flash.system.LoaderContext.imageDecodingPolicy; @:require(flash11) flash.system.LoaderContext.parameters; @:require(flash11) flash.system.LoaderContext.requestedContentParent; enum flash.system.ImageDecodingPolicy; flash.system.LoaderContext.imageDecodingPolicy : ImageDecodingPolicy; @:require(flash11) static flash.system.Security.pageDomain; @:require(flash11) static flash.system.System.processCPUUsage; @:require(flash11) static flash.system.System.pauseForGCIfCollectionImminent; @:require(flash11) static flash.ui.Mouse.supportsNativeCursor; @:require(flash11) static flash.ui.Mouse.unregisterCursor; -flash.ui.MouseCursor.new; @:require(flash11) flash.utils.CompressionAlgorithm; enum flash.utils.CompressionAlgorithm; @:require(flash11) flash.xml.XML.toJSON; @:require(flash11) flash.xml.XMLList.toJSON; flash.utils.ByteArray.$algorithm : CompressionAlgorithm; @:require(flash11) flash.text.TextField.textInteractionMode; enum flash.text.TextInteractionMode; flash.text.TextField.textInteractionMode : TextInteractionMode; // 11.2 enum flash.display.BitmapCompressColorSpace; @:require(flash11_2) flash.display.BitmapData.compress; @:require(flash11_2) flash.media.Camera.position; @:require(flash11_2) flash.net.NetStream.dispose; @:require(flash11_2) flash.display.StageWorker; @:require(flash11_2) flash.display.Worker; @:require(flash11_8) flash.events.GameInputEvent; @:require(flash11_2) flash.events.ThrottleEvent; flash.events.ThrottleEvent.$type : ThrottleType; enum flash.events.ThrottleType; @:require(flash11_8) flash.ui.GameInput; @:require(flash11_8) flash.ui.GameInputDevice; -flash.ui.GameInput.new; @:require(flash11_2) flash.utils.Telemetry; enum flash.ui.GameInputFinger; enum flash.ui.GameInputHand; enum flash.ui.GameInputControlType; flash.ui.GameInputControl.finger : flash.ui.GameInputFinger; flash.ui.GameInputControl.hand : flash.ui.GameInputHand; flash.ui.GameInputControl.type : flash.ui.GameInputControlType; // 11.2 @:require(flash11_2) flash.display3D.Context3D.setProgramConstantsFromByteArray @:require(flash11_2) flash.display.Stage.mouseLock; @:require(flash11_2) flash.events.MouseEvent.movementX; @:require(flash11_2) flash.events.MouseEvent.movementY; @:require(flash11_2) static flash.events.MouseEvent.CONTEXT_MENU; @:require(flash11_2) static flash.events.MouseEvent.MIDDLE_CLICK; @:require(flash11_2) static flash.events.MouseEvent.MIDDLE_MOUSE_DOWN; @:require(flash11_2) static flash.events.MouseEvent.MIDDLE_MOUSE_UP; @:require(flash11_2) static flash.events.MouseEvent.RIGHT_CLICK; @:require(flash11_2) static flash.events.MouseEvent.RIGHT_MOUSE_DOWN; @:require(flash11_2) static flash.events.MouseEvent.RIGHT_MOUSE_UP; // 11.3 @:require(flash11_3) flash.display.BitmapData.drawWithQuality flash.display.BitmapData.$quality : StageQuality; enum flash.display.BitmapEncodingColorSpace; flash.display.JPEGXREncoderOptions.$colorSpace : BitmapEncodingColorSpace; flash.display.JPEGXREncoderOptions.colorSpace : BitmapEncodingColorSpace; @:require(flash11_3) flash.display.BitmapData.encode @:require(flash11_3) flash.display.Stage.allowsFullScreenInteractive @:require(flash11_3) static flash.events.Event.FRAME_LABEL; @:require(flash11_3) static flash.events.Event.SUSPEND; @:require(flash11_3) static flash.events.FullScreenEvent.FULL_SCREEN_INTERACTIVE_ACCEPTED; @:require(flash11_3) flash.events.FullScreenEvent.interactive; @:require(flash11_3) static flash.events.MouseEvent.RELEASE_OUTSIDE; @:require(flash11_3) flash.net.NetStream.useJitterBuffer; @:require(flash11_3) flash.system.ApplicationDomain.getQualifiedDefinitionNames; @:require(flash11_3) flash.system.SecurityDomain.domainID; @:require(flash11_3) flash.system.ApplicationInstaller; @:require(flash11_3) flash.system.AuthorizedFeatures; @:require(flash11_3) flash.system.AuthorizedFeaturesLoader; @:require(flash11_3) static flash.events.Event.TEXTURE_READY; // 11.4 @:require(flash11_4) flash.display.BitmapData.copyPixelsToByteArray; @:require(flash11_4) flash.concurrent.Mutex; @:require(flash11_4) flash.concurrent.Condition; enum flash.display3D.Context3DProfile; flash.display.Stage3D.$profile : flash.display3D.Context3DProfile; @:require(flash11_4) flash.display.LoaderInfo.childSandboxBridge; @:require(flash11_4) flash.display.LoaderInfo.parentSandboxBridge; @:require(flash11_4) flash.display.Stage.contentsScaleFactor; @:require(flash11_4) flash.media.Camera.copyToByteArray; @:require(flash11_4) flash.media.Camera.copyToVector; @:require(flash11_4) flash.media.Camera.drawToBitmapData; @:require(flash11_4) flash.media.StageVideo.attachCamera; @:require(flash11_4) flash.net.URLStream.diskCacheEnabled; @:require(flash11_4) flash.net.URLStream.length; @:require(flash11_4) flash.net.URLStream.position; @:require(flash11_4) flash.net.URLStream.stop; @:require(flash11_4) flash.system.AuthorizedFeatures.enableDiskCache; @:require(flash11_4) flash.system.AuthorizedFeatures.isFeatureEnabled; @:require(flash11_4) flash.system.AuthorizedFeatures.isNegativeToken; @:require(flash11_4) flash.system.AuthorizedFeaturesLoader.makeGlobal; @:require(flash11_4) flash.utils.ByteArray.shareable; @:require(flash11_4) flash.utils.ByteArray.atomicCompareAndSwapIntAt; @:require(flash11_4) flash.utils.ByteArray.atomicCompareAndSwapLength; //not supported @:require(flash11_4) flash.utils.CompressionAlgorithm.LZMA; @:require(flash11_4) flash.system.Worker; @:require(flash11_4) flash.system.WorkerDomain; @:require(flash11_4) flash.system.MessageChannel; -flash.system.Worker.new; -flash.system.MessageChannel.new; flash.system.Worker.state : WorkerState; flash.system.MessageChannel.state : MessageChannelState; enum flash.system.WorkerState; enum flash.system.MessageChannelState; // --- 11.6 API enum flash.display3D.Context3DMipFilter enum flash.display3D.Context3DTextureFilter enum flash.display3D.Context3DWrapMode enum flash.system.ApplicationInstallerMode @:require(flash11_6) flash.display3D.Context3D.setSamplerStateAt flash.display3D.Context3D.$wrap : Context3DWrapMode; flash.display3D.Context3D.$filter : Context3DTextureFilter; flash.display3D.Context3D.$mipfilter : Context3DMipFilter; -flash.display.DisplayObject.metaData @:require(flash11_6) flash.display.Graphics.readGraphicsData @:require(flash11_7) flash.media.StageVideo.attachAVStream; @:require(flash11_7) static flash.net.SharedObject.preventBackup; @:require(flash11_7) flash.system.AuthorizedFeatures.enableHLSPlayback; @:require(flash11_7) flash.system.AuthorizedFeaturesLoader.loadAuthorizedFeaturesFromData; // requires com.adobe.tvsdk.mediacore.MediaPlayer which we don't include flash.system.AuthorizedFeatures.$enableMediaPlayerHLSPlayback__player : Dynamic; @:require(flash11_8) flash.display.DisplayObjectContainer.stopAllMovieClips @:require(flash11_8) flash.display3D.Context3D.createRectangleTexture @:require(flash12) flash.display.Stage3D.requestContext3DMatchingProfiles @:require(flash12) flash.display3D.Context3D.profile flash.display3D.Context3D.$bufferUsage : Context3DBufferUsage enum flash.display3D.Context3DBufferUsage @:native("flash.profiler.Telemetry") flash.utils.Telemetry @:require(flash12) flash.display3D.Context3DBufferUsage haxe_3.4.4.orig/extra/haxeci_sec.gpg.enc0000664000175000017500000001472013166552354020101 0ustar andyandy00000000000000Salted__gޝ¤dU µÅC—á” ƒ%¼¢™2ªPüÑvm!/“wè=v»ÈÊøS™%pÚ–s-PÔ§a–¯oÒÝc=w1æNNZ¹È\d‹p„åÓ/ËŸLж³“µ? Œ’Ãb3À†d>ÑÈ5mÝr•îߢW›'#°—äî™Tiô’zÏÈÁT0lwÑ š‚ä#†ªIïÿžŽò DšÜEÛ¿EXÞ#ì(E$Ùi$on…W™ë;•N¿GW©Eã 2ÎŽ«£­mÖ¥éœ.µ²»ƒ²V5æ=³Ý&­píH­3#¥ü&÷¾Y žÁèë *ÿwæ%Ã3ÿþÅÀÅÚ­À $ä „úîî'ø>êh¿`ÀMOJꄽ©…ׯóÁ÷·¸áŸ{²Wõ›Èª3KNÆ£áiæŽúçœÀ…ö5ü”˜ùÓ(Ì´Ö&É$úUºŒò⸾ÖÜÿåî5¬à<<_JÌåE¹…dFöÄÿ€¾,MЙP0Ž|HÅ<ñÉ …%––ò:AKz¼#6RI„ÆÊS¹7üeçÁÄ °¢¡âó¾l=ÇzÉy³øï˜Vƒ*èÁ†²(+ñ2HaÝm ›tç£~¼Ä^’MúiÃ{w [(vÃîÙ‡_7ž½Õ!MÑ\âV‚&)]ŽÛŠüT‡?só6 °½n-ÀùÜ™ágç5 ª öâÁm#2UOóÃì%½/òZb£ÀÍ´8…9s7lÉYÙH³Ÿ²ð§Ñ“jfÉ9 ¿ßz”ã© ¹}ˇ: m9V ìÕ>'Hµó­MTW<ú‘Qn*îlrf—°º&È­ÕœëÑf¼Ïg²“ÏQ¢*Xà®"羦KbµÜV¹ÉªÒ†–ûŽHøƒ± “ñ —Æï?›)Ð/3‹˜ ‚;ËEC™öRqëÉé7sRĈ6™´z—±Bž&Dýêd°‡¶ĨºVpî7S’7.p?¾º?ŸÝé¾"XdS8^P»-G”v1>ÉÛôñ¯Yøpº}ýÉ!8l-aÅç H ÂIv qKä˜içLýœŸÒžÄCrÅ ¡ðL—ÕŒ0ìÜÀƽmµ$²¹EIžD!@ª'¿§ç<&¤^pÐþ£€} ­WÓå!¿jlå84·DÚ‰‚¯°}’fû²ƒ7H“ €kië]ž"3íU+ùå>ãâ€&trãtøêfàIG8%!:Ù:ƒÔôÂWºD6¸áØØÐxÖ<Æ1¢I —}bD­Û4(»îÛÉWÕµŽÂ¿½Ú}‘ÂÇõ¬©×ùõ÷ôb`׏д'Œ÷mÉî½Û4pŸ€ÄFkÀ“½önx°nqõ|ļziëêWxo 9n¬%h*f˜wOú$6Óó¸LDb‹ëUÉAZ™ì»˜\Ü|šÔ½v& ìæÙÛŠT¿²h¯>á†Á ;}´Éï'–åà­÷0ê߈aÁh@ó™>.Ÿ–-M ÉOظ*}JÖ)(¿óqkxë&ïZÄ÷QZ= K_L÷ÍTÒQŽ¡»®YF%¢` ·ExŽ6+.cU,ÍìÊxç'n!„7è9zi!ÒýþNÔšÙþö°‰’˜¢³=+¹/W‡Ç¹*]cÀîR)F¼%?Zf³baOçá›°Osgž¬e7û=Š3,’>½Z`6p°UØÅÀù™k÷bÈú¸Fo‹C_¬Mpb ¬&,W²ÖÖ¾ˆÊóàt¥ f1èÌ ÍSå–óßbN: ‹8O«rÆC àD&ñ-B¤!He ¢Ìs­ß"¾3ó~+¼Ç€8¤RSs}.ÀóupZ2=8°?ìÚ¬&[:;±›ÆXVü^µ¦²LIßl×ÅÁT\QÚàÖèÁN)PX%-[5nºÝÜÅûË.»°!¶ÌQ¾£Š“°*ªj)¤òWö§!·HÞìßðÅÄòÜ…‘žY±ëdh›ìW÷ÿªJd|?0o*wD$ýÅçž™8¦šÏþ7kœPRzב€H¬ÔÜ{gvèEÙ,1w8ùY®¶öO’ÀÇY–u—'v\»˜Ã»sÿè,6ì8%{²×"sYY±I™¼W†Re…f;{QűcÎÿ ÊÃx¦Ñ.TD‡íR\ò©1@Ž*eH‡x~|JÅép/¶ Úªnž¤B|Wî–é³Ñq eß…'l³m(/‰c©âIð™%Ð0￘±´+Ï4kIFZé.¿ f4 IöÄÔŠº¨¤Î²ÌÆú%ZiOã©züÊÏ©ËA¡“]ðâl⢞NˆáŽ»šØfнÅbàÐ=»÷ó2ò&?¡Ã?bt«âŠ$9¤ù¢OMê;u£4‹ÃÞZájJm©Ùm’Ôòóö€HÝ‘AÀèwPƒÂÂMøOûl8ÏC( ½ÑÝ|®l@I\‘ª—y¡T´ƒaº¦z§ÉÍ(‰²Q)*<2YYÍ™#bàû?QK’xéÇÊ{ŸšŽÙ¼ÅC‹†s¿e0-ýÙ‘¢™ñãs*õ±WÀØÇ_E_A Æ^+\ô@ñºÒM­ÙöCø‹|¹Œir6Ö‡¨çÒ†-ö¿F‘§áL-»áõ×¼§s²·†ë4ˆ ñÛè³´Ò;L¹ÂhײKÿ6HÔ&àì;¬g®ƒ€Ãè)À‚£}5( E΂f9uEPYµn@Ϥüç7!R ›7‹„„?Uëllh\шêÍžS¬´&.¼ÛºÑûEµq¢ â‡úG ÞÍäv éÛú1 ßÓ¨£qˆ†ÌüÁ£Ê¡¾á:se9˜‘aÀ‘Þ;3çgÑM5 ‘÷êÖýIü–=y¤~Û¦Äb rÆË’»9Só KñÇ8‘û›¿gJÑ\Bó\þ½Ü• ÁÝb£—§S¶{²9,wë’z“o!s&GQ·ÞCÜõHè<É’¤Õ[K§;¢o207à; Úò‰n|5YCH`Z¿G(â<¢­’r€gl®+’íÃgmY4z—Åÿ‚ÆÃž­\f¤*[ßí§Ù|ñ·ÄcpK @ìK™öçÀé?ǶaywLŒf·Â&ñãx1|Ó0‹NTèÛŸ3sÙ[+L`']dk‚†G©lð­&ƒÖ9çTG‹7>öN(÷ß„â~Qµ¦ªyŒ™¿rõ©i5¾êµkq·ßÈ •˜Ä| ÝêNï[)à#RjæeǼ¡ …låõÜä~~ód銎Ñ;ïL7ðù„¶b ÚÒÂ:'f Mpà$Vê.œÉãR’ª†ÿâðåéȤU¨QÈÎWUqÃ;qëenf„·A)ÂÖ« 1ã)FS`øT*Kƒ6 î»êÜwº„œŠÅb¦ˆ…ͱÕXUI–jžlª½ÒUy¤'ÿ&tüYÛûÍ:ÞŒ ,?á.ƒÂ}ø—¨Ñ¶Þ…%‹åÛ“X:3ÏW|ÎÕ÷³Qÿ£/o[¦m$ûÔ²T–âwíà,Û+µéòRUà{«PZHbÝBŸ£ô[¬Ž l=°ÛŸNSǵ‡1O iUEgö¹¬¬œÙÚnë;]S¬×”z²1èQYa[UîÛ„NæûfùHßmCÀÔtxGè߸sYÍ({ašq+úœÉç5çãTG][s×; ÎhWÍeƒjÞ#Îø¼ùéQÉ‘ãŽ×°¨µ¿9éÌoÀÎãr‰8—f÷s…ÿý>jûÿäY%a3+Q¿ ¾¯¬Ò\Æ/Úx:cœmÇÖѦŒ öÔ¼ÕA±\Ã|Â÷òáeO±²Ÿ¾¿þH9–kCÆÆD*Ò(ÿøôá«?þïZe±¼£Ob`Ò~Ýð±,¢Ið Ñæ'Áb´íŸÌbl9WÂ!e/=ƒÉìÈq½„ÿö±ñ2*'”@37XÀ+ÅÝ»¬xÁq¡ã+Ú^c¼]´À¨··)Båî6Rθž4€n tÖjó­4 „Þ_©LÈo ¶IòØ&*Ó’—8¾$spöv 3T41kw~K¡>‘8÷‚® Y2MH'D|+ä_¼Ùƒ)‚‡Ìwa6E±H=˜Ùé×SLž?†‘µàô­®mëæà¾j+˜¦›g½ŒFw›$ÎÜ_ö+°¹?¾™çwHk´“:[ç^xUì=VÞIâj%Yêô£ €¢†²€œguUBd§RÑ Ë ®òqlÚu•á)»"¯‚Îõƒ'ø%EVÞˆŒñ|2Ý$""qO“ëQ9Y¥Úر¼ºÕ¶§KÝæ›ééÞjž!ýZþe5Ï+ÖÓþ `G/q Ípp5«‡Ê_29¿Ð’ñ_,O•—Ï_gø»áfºˆËí _¿¯U¤;ý>ÍØ3NÒ ˜EöÉšÓ ¡AT̪¹©¤7©Œy8z3³ñ ·e SâùïFþéNw9–­ü!ž ¹]BŒ“8Ì!©Vž´ÿûÜš ¦ð†0‡<ù^øY¹û>šWØ53ëËîµàr2O iz¹ú3æñ‡Ñ¬6sƒ&ײúų±çµø¿3Ä#n$ÓÒ»òq—€yüa¶kÍFƒl‚ZÔ ùÊ©ŠöG­IÀx÷3¬ÐrI~9a™ÿ;óQI“׆9oq[(Òãæx§ãÕOÁþ„íö IïI/„§PQì&7ކ5è¶]z5éhÆQ§h@ŽŸRn¦Èúd8Œ9ˆÝÉ(µ[¡Uט€k¿ÿ}ÝoÃ.þÁ0áe¼†'­”I»j –³¬Œóâxøƒ €§ù@±Ý4ôô‡hn1†w³o¡Šç”ÐËâÉ¢UÐû8HeŸƒð‚mŒH!ñ }ѥΖ–t÷°ÐæKªÙÕ2W¡ò÷‘õS¶tL4Œü÷ùÝêÎÃMî­µ‹ÅdµÚU XçØË!6ÁŠèIxþfÐæ£=>ê©¡ä ߦވV?i¸eà Ïð“õ\b;ˆœé¨B/Uâj´ãÅ6Fv Æ0`‘ÙËæyÅSð„›LÁüêµ7N¬nB±$ÂØ: UŽ0Cv'Ép7INêÓ7m#iÑù´X¬ú)kAÓx¹ë˜}GàwœÒÅ0댟½¸DÑYe½Ê?bóà_÷å{Ï1ô½I'\p"ß*ãz !uœÊצj˜§]çJ%À4‰…Mú‰zvÜ¡P¯HˆhXía‡R6ÒeæÞSÒc;»LLëQ«Ûr‰¢-_G P$æ|psÑü®Kͼk!Gy]!“Ñwx%ÄD¹ºæBL¾v,á–áü ,9Ñi)x«`—RÒ‘ò}E.×ѵ´¸2Á ÑG…äN&64›Ùü T–ŒÁìù)ê*šéŒüFIDEMž­ÍâѰRÿäkÙ=¼\)„…q­ ŽøÖÀx~ƒ•ˆ4lY°ìÇÂM‘« MاŠp8_úÏU¿X’XQÕTfü¹ùòß3@峺dQ\*²¨äCªNÓÖ;PW,êÃ\ 3‚Yå–$–_æ WÈêðCô!ÏfýõJý—›dI(¤ek”o‚à ł*¼gûy‘`M)MåzÏ¡D,0gƒ{ÊFÇWàÕK¾Iã_¬{ú,U¦iµ;0ˆìäûme,\ÞQ6½‘ÓÀc°Ô¯CÀ”–Y ¦P¢Í9ˆ‚¶øÖ̯ÿ`†³V"7f«0Çck=©È‡—µ¹rè!ÃËÅÝb¸- ´gÍÚˆ¦@Æ.ÁtÞ‰V7”⌬»ËR´èd/õè(;P=ˆÏrVl½Vr3Ý@0ª*I$ )>O%QÆZÈO‘Z㔦PBõ¿»§šUNÈÈŸ=¬¢ïšÙOöµy5jY¤øza”r®•^ëñ.ÃÓNlÎòŒ÷ë°,.µN"D‚WMà”Î{•W¿ qÿD1WvUè–Úò踴x³¾CÐ'Â1Wý=SgÁÉÂFÕá÷ÃýIw†Ã[Ë*;´£­:#Ô]åMI0R¸Lêc#E¶½{J ˆq¬Ñ};µJ¾¤Í–ìB,"™“ù¿”7‘Pó>zu&\*9E9¹bØ–1wÄ ÙÅœ²Q2wE*Ø]Õ_“‹ÍÁ®±í„e¦:›îò–Øëþ‹Z)oã¬Þ¥û‡æ¹›Ê{¢O{{w½Ñ˜Ÿ[v´’$ôxݹå-‹½â$<Z±‚]‹„¡)¿˜ªîRAQyË Ø%·g0l.ý»fUÞï葵¾#×Å ò“´µ†kßS…„½M9—mP†JQö“ÄB^að È·;ÊGèNÿª4”~BN|ñ¹pŠ$y³zVu1*?GKwͰÃ_ ºý̆µ¾u S÷|Ž 7“Ù+÷EJ–€p«ÔÝ˰}"áªLƒ]–€Öv¾Í¹X??•ðÙ‚{ ðê.¢g2š‰Úo²;d¥à]#õª\õaEåÝÙšJnoá‚^¾%]±}©çòû\j¸-ŽÂ21àáB`DíDñöŒ;ÚB°ùUì3Å™i@ãDL¿}©êi'ÞRÖ˜ïpìÊVÓ]`¼ò•(Â]¥žèı‹'ÂÂŽ"©—{Uþ…¹-:$CÁ‹†÷þö ÜwÉ`?+K¶QhhÜì0Y;숀Íý ؉øÑøqÙ;*=‚qwódß¶,ZÔu€˜£¢ I-ÚÁ’ŽŽý}›Ô”Wls­p†èiz’‘ãõ"X‡‘ðñ;#ØÑ½î˜äùVÑ»á=®×&óa`<ÓËYO{*E kÁö§+ {o\Êh ›³Çµ<* …Òíf+Pk*vóÈoù…jÇ,øNËÇíi?”²´cJ^¡Ü,ð<-yÞkÆxÔX%'É9ÿn.ÒÞl•púo¹¬¡Dû5¢i¦G©´BÚ¦æÔí2Ö0‰‘ÉÏàëë´e=ƒ.“Òes6ßB‘£´ .ÀÑ»¡¤4G•k *$Ÿæ!¬·ïf ]9@‚Ä“TÄ4ƒ¾Þ÷l©ƒ'î3{A¨Hi ‚-“•|¤°·7®üÊqœO p‘×<Ã­Ž¿’­-Á´ ¡ðöY:ùÿ€fm§‰ñ=êMØ+ñÅݱl:Fޝ¡ 3lx¥Ïg×¢Z+ €U®IC ƒZc‡W…R™åZÕj= %©t†L.âúûœ )}ýÆÇUïNýòþм”°#L.ç·ÙÓE˜Ÿ¨À“,ÊÌÆá,žé7‰²ôNÅF$´q³3 40f¨"ôcÂG•«™Zn*Zôû$ÍåE#<Á—ÁëŽÞ¨=B›ãÊ뤳± ‹cð6§&N¬Ê“`IÎÕ®/Û@½í!JKé¸ClÛq¾5V#?onÇ\%v‰°ÅÈõ6©®û0UÊu‚"¾–NùšQ…a/™€óéyPCp([GwîûüìíŒ×`U£ór”ÄêÒˆ±í¹àÒ¤WÃéФ†§ÔÔñ¡&]’¦>;ZAaáóG¥‚‚ïnjê AkÿUåj1Æc¾‚ÊTnGb?H.à|O—X^hìål5c3„Ï ÛÍI£‡jž‘þ†[fdÎÑuvV€T¡”•õÕâòØaíaΰã‡^²ë%±Æ´Ýê…^ÔÒV`×ðVâm+55B·XÞ-ñ2s—…>oÑÌáððÛY{©îÃÉŽ˜¯=´eÀ'³S lôPºË³ªMÛÑEÎÙðRVH ç}+eïªk‚ŽÓy^NÊ5sU ‚4yo;=Q?¬ŠÂ{h¹F·1‰É÷A6šÑWìÍaas¨B,;ŸˆZÑbÏ©W¯ý|FgóÞ@ƒ©}s‘D¯ªèBÌj7¤¬ÂÅŸÌei„,î« k95ôó—yɰŠëÑÄ!|«»Í}Œp"ÊvÝäi·÷3Û)gòô¯‘õMÏÅíojpà X¾^©Ü3žÓÇv]LS˼!8AT߬æû{¼¿FK•&*o•° ¸e#Z±óÃK—ˆ¦x´•é\{?“)/ÞYÝ}]ϱH¯Ï™#ùºù÷.€Ùà¿Іâ¼D¶±#k¼‡š·å>7°ÜÆÑºM*õØ5ÿö ´èÁêîæÑàŸÕ3Ðò#|ªb‹ß|fê:Ó¤Fø5[&7µÇŽÆˆ¡ ãòóº")Ìîײ@‡)²ø‰;‚‹É¤¤°ÅXî‚ÖÁ{2ýœ;€ ÒîAðB@o©Æ;:Q?·P> µ’e—`kš•8œG°$Å*󮣦æt+ú»G£w‚BªŠI»èEÝŽàíÓÞÆÞ³ Ð«Õå¼z'<  3¢ç‘2¡cÅxÿ•v"Û6*»‰a‰#9ùöô)(CøÒÎ+Ó$  ÷SC_йÊuX¤¹Z¿–> •æu®F“ŽqÒh \#riåU|R? ËÏrü:£¿Š)ÁÀAÒ½H èR´1HÅ4 #ödÂôC€’jÅlש(œ5†#Ëc;§Á¨TTŠʤ²˜áó/" ®Ç»¦%NvþÇÞRy!Ú O¤qû…ëäfæ ¤;ôO:à ´þ\ŠÎ¿ 7 ×®Í©M7š….“P¸»[,ÆZåWb?f=0-ˆ¼‡K‘±ÿÔdib\’, IÆ¥ýôƒa•‹yz‘ëËÈ*c­ÅïA^H3ÒmÿÆ5¹Ég'×W^ËÞ¥é8 ¼sÀІ(³ &rRƒÓt"8Y­ ôör‰»® ^§Éaµ øhYß!¥¼ýìÒ4ŽŽ Yéœ4€ XXp®®BçÔpgù^9WVæfj;v ÞHÁHh7Ù Én|u¬`Û³™øº£ÜC 2ìõ#‚Þ³ŽÈPÐõÃ$k´ŽŽ F~ÂR\o5™ÆÖ‹–tš®PLÍ.Ïo¨SÇö±û ÌNd@·Æý«Ýñ‹yÁQNð­‡ (¿"®ÙÂb6Dlñ ÚÒ‹=»˜#~ý)Cr²DÙ…#nøSPÁx60ÅÇ*˜â¿®¾`úOÎ^·Kd)”XçFÖߘ<ˆ¨FÈÊ_e–€²ó¢xlκºz?„Æ£×äa.Oª¤ÁX ××lB¡`­~oüŽå¸Tmí8*&^è>…Oˆ}*`Píï?·àÍÕ¡¸®@ n©B¥¢£‡c×9+ê\'*#ÕK0èÉYö]cŽ”hIPÃ]€.Xæôß]¼æueVC`QMÌ4YTƘiR)_0nS×Ïé¶Ž8è«t„B¿ß]Ðá‘’Ó7ÖB´Un‚?³mÀ \Ì`$Áþé3a˜‚±}uŽÂœšÉR¥ ý=´˜¤sà×Ïͤ>@èPÁ™›‘ñm¼^”H—ØÑ¥¸°™âÝíÜÇý2…¾?aJ™*ˆ€`ÃvvÎ|Ó€év…ƒáúùÍQ_¬š—M¥Ýá/.¸Ï6 $fòžùÆ8º5ŽªÀšÚ½Ð×;GÔc ;ÛÙSòêÓ‘óï>ã9ŸÔ%gϦ÷V•ve-˜¤˜¾'ȾK¬•Áý«5fXUÓÈè%a¶\Ë›AŽžNmb3cµVtg>2*T§7=!êÅä\ÒP"„GSƒ| &*–+x»|ØNæÀR˜j¢#ÐÉW^ýfR<°&½bZô–ÉPÖ'ù¤KV槃Ðz„²½ß£±zŒÒ€ÏxW7ñíÆ4ÅééÑœÐD8YÍ8÷š:– O`ÝHù:€»1wXDó¹ôìó#ðXà~ŠT\®Æf*xÁÚÎÕhaxe_3.4.4.orig/extra/haxeserver.bat0000664000175000017500000000007313166552354017403 0ustar andyandy00000000000000@echo off nekotools server -p 2000 -h localhost -d .\ pausehaxe_3.4.4.orig/extra/images/Banner.bmp0000664000175000017500000006233413166552354017721 0ustar andyandy00000000000000BMÜd6(–9¦d  9448448448448337337337226226115114004004//3..2..1--1,,0++/++.**.))-((,((+''+&&*%%)$$($$(##'""&""&!!% $$##""""!!""""""ÿÿÿÿÿ9448448448337337337227226225115114004//3//2..2--1--1,,0,,/++.**.))-((,''+&&*&&*%%)$$(##'""&""&!!%!!% $##"""!!!!!!!!""ÿÿÿ9448448448337337337226226115115114004//3//2..2--1--0,,0++/**.**-)),((+''+&&*%%)%%($$'##'""&!!%!!% $##""!!!!     !!!ÿÿÿÿÿÿ9448448448337337337226226115115004004//3..2..2--1,,0,,0++/**.))-((,((+''+&&*%%)$$(##'##&""&!!% $$#""!!!         !ÿÿ9448448448337337337226226225115004004//3//2..1--1,,0,,/++.**.))-((,((+&&*&&)%%)$$(##'""&!!%!!% $#""!!       ÿÿd]ÃWÀ M¿!F¾!EÁ B°)W"P…sÂtÄqÃkÂdÂ]Ã-[ÿÿ944944844844733733"½ä˜ú¢ù–÷‡ö xô!jò"]ñ D¹0;i500349O€‚ã…õ |ô!ró!hò"_ñ"Yð#Wð,x1--1,,0++/++.**-))-((,''+&&*%%)%%($$(##'""&!!% $ $#""!!    ÿÿ «Æ‘øžø¤ù©ù¨ù¡ø•÷†õ wôR·'QIzqÜ só!hò"`ñ"Yð#Vð"Wð"[ñ"`ñ"\ñ)l!¹Æžø˜øøøø ø¥ù©ù§ù ø—÷e³ YË"Zñ"Zð#Vð"Wð"[ñ"]ñ"^ñ"^ñ"^ñ"bñ"Wð(lÿÿ944844844833833733)ÌÍ®ø‘øøøøøøøø¥ø ù‘÷ {ô"Wð#Wð"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"bñ#Rð(l1--1,,oll‘ŽŒŒ™——‘d``.**-))[WW‘˜––ŽŒŒ‘daa% ™——˜••ŽŒŒŽŽ”’’)$$(##:66ŽŽ–””ŽŒŒŽŒŒ¥££¦¤¤ŽŒŒ•’’ŽŒŒ‘vss$trr‘ŽŒŒ“‘‘ŽŒŒœššSOO($$ŽŽ“‘‘ŽŒŒŽŒŒ’ŽŒŒŽŒŒ’ŽŒŒŽŒŒ’ŽŒŒŽŽ…ƒƒ ÿÿ#ÏÊ Áøøøøøøøø¢ø˜ø…ö…ö‘÷ƒö"[ð"Xð"_ñ"^ñ"^ñ"^ñ"^ñ"_ñ"_ñ#Mï)pº¸¸ÿÿÿÿÿÿÿÿÿÿÿÿÄÃð®®ÿÿÿÿÿÿÿÿÿÿÿÿº¹¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿXUUžœœÿÿÿÿÿÿÿÿÿÿÿÿíííáááÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>::944ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ833RNNÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ#ÕÐ"Õø‘øøøøøø¢ø˜÷…ö†öˆöˆö‘÷ƒõ"Zð"Xð"_ñ"^ñ"^ñ"^ñ"`ñ"\ñ#Hï*o¢  ÿÿÿÿÿÿÿÿÿÿÿÿ«©©š˜˜ÿÿÿÿÿÿÿÿÿÿÿÿ¶´´œššÿÿÿÿÿÿÿÿÿÿÿÿ°®®,'','','',''-((ÞÝÝÿÿÿÿÿÿÿÿÿÿÿÿfbbÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎÍÍÅÄÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿyvvfbbÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæåå944844844844733733/ŽŽ#çøø˜øøøø¢ø˜÷…ö…ö‰öˆöˆöˆö‘÷õ"Yð"Xð"_ñ"^ñ"^ñ"bñ"Wð#Fí+1--1,,«©©ÿÿÿÿÿÿÿÿÿÿÿÿ«©©.**-))š˜˜ÿÿÿÿÿÿÿÿÿÿÿÿ»ººC??ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿööö÷öööööööö÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@<<}zzÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿb__$WTTÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍÌÌ"d``ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùùÿÿ$éë­ø’øøø¢ø™ø…ö…ö‰öˆöˆöˆöˆöˆö‘÷ €õ"Yð"Xð"_ñ"^ñ"bñ#Rð/Ž¢  ÿÿÿÿÿÿÿÿÿÿÿÿ«©©š˜˜ÿÿÿÿÿÿÿÿÿÿÿÿ´³³àààÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÊÊÐÏÏÿÿÿÿÿÿÿÿÿÿÿÿäãã"ÒÑÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0++c``ÿÿÿÿÿÿÿÿÿÿÿÿýýýìììêêêëëëëëëëëëëëëëëëîííÕÔÔ€~Àøøø¢ø™ø…ö…öˆöˆöˆöˆöˆöˆöˆöˆö’÷ €õ"Yñ"Yð"`ñ"_ñ#Mð"¢  ÿÿÿÿÿÿÿÿÿÿÿÿ©§§˜––ÿÿÿÿÿÿÿÿÿÿÿÿ´³³‹ˆˆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿtqq2..ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×ÖÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ|yyc``ÿÿÿÿÿÿÿÿÿÿÿÿçææ$944844844844833733722!Ìïø¡øšø†ö…öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‘÷ õ"Xð"[ñ"]ñ3”2--1--0,,«©©ÿÿÿÿÿÿÿÿÿÿÿÿ žž.))-))‹‹ÿÿÿÿÿÿÿÿÿÿÿÿº¹¹EAAÿÿÿÿÿÿÿÿÿÿÿÿùùùº¹¹»ºº¼»»ÿÿÿÿÿÿÿÿÿÿÿÿýýý'""&!!%!!€}}ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒÑÑ""c``ÿÿÿÿÿÿÿÿÿÿÿÿæåå ÿÿx¡ø–÷…ö…ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö’÷ ~õ"\ð#Rï$¢  ÿÿÿÿÿÿÿÿÿÿÿÿãââ°®®±°°±°°°®®ÝÜÜÿÿÿÿÿÿÿÿÿÿÿÿ´³³ÎÍÍÿÿÿÿÿÿÿÿÿúùù:66ÿÿÿÿÿÿÿÿÿÿÿÿº¹¹ÐÏÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ2..c``ÿÿÿÿÿÿÿÿÿÿÿÿüüüçæææååæååæååæååæååëëë¼»»“Ùyö†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö’÷ ‚õ2‚¢  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ´³³vssÿÿÿÿÿÿÿÿÿÿÿÿ|yy•’’ÿÿÿÿÿÿÿÿÿÿÿÿc``400òòòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~{{c``ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãââ944844844833833733722!×vö „ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‡ööø1o2--1--0,,«©©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿº¹¹+&&'##þþþÿÿÿÿÿÿÿÿÿÂÀÀÑÐÐÿÿÿÿÿÿÿÿÿöõõ&!!%!!ŒŠŠÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáàà""c``ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖÖÖððbg½û ù!€õ „ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöŒö‡ö zõ![㢠 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ´³³»ººÿÿÿÿÿÿÿÿÿæååGCCòòòÿÿÿÿÿÿÿÿÿ¨§§ÉÈÈÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóóóNJJc``ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÝÝððÈá«ú»û£ù!€õ …ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöŒö‡ö!rô!tô!mó,y¢  ÿÿÿÿÿÿÿÿÿÿÿÿèçç½¼¼¿¾¾À¾¾½¼¼ãââÿÿÿÿÿÿÿÿÿÿÿÿ´³³a^^ÿÿÿÿÿÿÿÿÿûûûØ××ÿÿÿÿÿÿÿÿÿÿÿÿPLL£¡¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñððc``ÿÿÿÿÿÿÿÿÿÿÿÿìììMIIJFFJFFJFFJFFJFFOKK>::ÿ÷944844844833833733722dcÏù¥ú³ú»û¢ø!õ …ö‰öˆöˆöˆöˆöˆöˆöˆöŒöˆö!sô!oô!uô!uô"Lå2-/1--1,,«©©ÿÿÿÿÿÿÿÿÿÿÿÿ£¡¡.**-))‘ÿÿÿÿÿÿÿÿÿÿÿÿº¹¹*&&õõõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿééé'""&!!%!!URRÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª¨¨""c``ÿÿÿÿÿÿÿÿÿÿÿÿááá ÿÿ$ÛÜÁù©ú²ú³ú¼û¡ù!õ …ö‰öˆöˆöˆöˆöˆöŒöˆö!sô!oô!sô!sô!zõ"Xñ(t¢  ÿÿÿÿÿÿÿÿÿÿÿÿ¨§§—••ÿÿÿÿÿÿÿÿÿÿÿÿ´³³§¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜––ñððÿÿÿÿÿÿÿÿÿÿÿÿ³²²ÛÚÚÿÿÿÿÿÿÿÿÿÿÿÿVSSc``ÿÿÿÿÿÿÿÿÿÿÿÿøøøº¸¸¶´´¸¶¶¸¶¶¸¶¶¸¶¶¸¶¶¼»»ƒ€€ððcd#ëø´ú®ú²ú²ú´ú¼û ù!õ …ö‰öˆöˆö‡öŒöˆö!tô!oô!tô!sô!sô!{õ"cò"?ߢ  ÿÿÿÿÿÿÿÿÿÿÿÿ«©©š˜˜ÿÿÿÿÿÿÿÿÿÿÿÿ´³³MIIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB==³²²ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿgccÿÿÿÿÿÿÿÿÿÿÿÿñððc``ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊÉÉGL944844844833833733*ÐÏ Þù«ú±ú²ú²ú²ú´ú»ûŸø!õ …ö‰ö‡öŒöˆö!tô!oô!tô!sô!sô!sô!xõ!ló#Gï'e1--1,,«©©ÿÿÿÿÿÿÿÿÿÿÿÿ«©©.**-))š˜˜ÿÿÿÿÿÿÿÿÿÿÿÿº¹¹*&&*%%åääÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝÜÜ'""&!!eaaÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$ïîîÿÿÿÿÿÿÿÿÿÿÿÿ¬ªª"d``ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³²²I$ÐÎÐù§ú²ú²ú²ú²ú±ú´ú¼ûžø!õ …öŒö‰ö!tô!oô!sô!sô!sô!sô!sô!uô!tô#Nð)sº¸¸ÿÿÿÿÿÿÿÿÿÿÿÿð®®ÿÿÿÿÿÿÿÿÿÿÿÿÎÍÍ’ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿˆ……LIIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûollÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~{{nkkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌÊÊðð#ÄÆÂú¨ú²ú²ú²ú²ú²ú±ú´ú»û›ø!€õ!õ!rô!oô!sô!sô!sô!sô!sô!sô!sô!zõ"Xñ&kyvvº¸¸º¸¸º¸¸º¸¸||sppº¸¸º¸¸º¸¸º¸¸…ƒƒ611º¸¸º¸¸º¸¸º¸¸º¸¸1--~~ÇÆÆº¸¸º¸¸º¸¸º¸¸fbb¨§§º¸¸º¸¸º¸¸¾½½«©©EAAº¸¸º¸¸º¸¸º¸¸º¸¸º¸¸º¸¸º¸¸º¸¸º¸¸º¸¸º¸¸º¸¸ƒðï944844844833833733'Ã͵ú®ú²ú²ú²ú²ú±ú¯ú­ú±ú»û•ä vò#fó$có$eó"ló!qô!sô!sô!sô!sô!{õ"bò&k1--1,,0++/**.**-)),((+''+&&*%%)$$(##'""&""%!!% $#""!   ïò²Æ«ú±ú±ú°ú®ú®ú°ú´úºú±èmƒ.9«÷‰ö wô#ió$bó$fó"mó!rô!yõ!kó(lððµÖ¡ú®ú°ú´ú¹ú¾ûÃû»ëo‡ #AI–³Âû°ù›÷‡ö!uô#hó$dò#jó,sðð944844844844833733!™Ä©ì´ìºï½íÀí¼ær‹"&511500400CN¦ÁÌîÅî·î¥ì’êé3i1--1,,0,,/++.**-))-((,''+&&*%%)$$($$'##&""&!!% $#""!!   ððññ9449448448448337337336226115115004004//3//2..1--1,,0,,/++.**.))-((,''+&&*%%)%%($$'##'""&!!% $##"!!    ÿÒ¦¦9448448448448337337226226115115004004//3//2..2--1,,0,,/++.**.))-((,((+&&*&&)%%)$$(##'""&!!%!!$ $#""!!      ƒm§§9559448448448337337226226225115004004//3//2..2--1--0,,0++/**.))-((,((+''+&&*%%)$$(##'""&""&!!% $##""!!        !`eûû9559448448448337337337226225115114004//3//2..2--1--0,,0++/**.**-))-((,''+&&*%%)%%($$(##'""&!!%!!$ $##""!!        !!Üðÿÿ9559448448448337337337226226115115004003//3..2..1--1,,0++/++.**-))-((,''+&&*&&)%%)$$(##'""&""&!!% $$#"""!!!!!!!!!!!ððhaxe_3.4.4.orig/extra/images/Wizard.bmp0000664000175000017500000045566013166552354017764 0ustar andyandy00000000000000BM°[6(¤:z[           !   !     !!     !!!      !!!!      !"!!!       !!""!!!       !!!""!!!!        !!!!#"""!!!!       !!!!"#""""!!!!         !!!!""##""""!!!!          !!!!"""####"""!!!!!           !!!!!"""#$####""""!!!!!             !!!!!""""##$$####""""!!!!!!                   !!!!!!""""###$$$####"""""!!!!!!!                    !!!!!!""""####$% $ $$#####"""""!!!!!!!!!           !!!!!!!!!"""""####$$% % $ $$$#####"""""!!!!!!!!!!!!!!!!!!!!!!!!!"""""#####$$$%!!% % % $$$$#####"""""""!!!!!!!!!!!!!!!!!"""""""#####$$$$% &!!&!!% % % $$$$######"""""""""""!"""!""""""""""#######$$$$ % % &!!&!!&!!%!!% % % $$$$#######""""""""""""""""""""########$$$$ % % % %!!&""&!!&!!&!!%!!% % % $ $$$$##########"""""""""###########$$$$$% % % %!!&!!&!!'""&""&""&!!&!!&!!%!!% % % $ $$$$$########################$$$$$$% % % % %!!&!!&!!&!!'""'""'""&""&!!&!!&!!&!!%!!% % % % $ $$$$$$#################$$$$$$$ % % % % %!!&!!&!!&!!&!!&""'##'##'""'""'""&""&!!&!!&!!&!!%!!% A=={xx€}}yvvyvv€}}zxx`]]% $ hee{xxyvv||yvvyvv‚833„zwwyvv||yvvzww||&!!$$$ZVV{xx||yvvyvv||yvvŽŒŒ„yvvyvv||yvvyvv~~0,,$${xxzxxyvv||yvvyvv||ƒVSS$nkkzxx||yvvyvv||yvvyvv||yvvyvv||yvvyvv}}yvvyvv€}}{xxYUU% % % %!!%!!&!!&!!&!!&!!&""'""'""ƒ€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÔÔÖÕÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿwttñññÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿjggñððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹··fbbÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿYUUúùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂÀÀ{xxÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÇÇÉÈÈÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ|yy‹ˆˆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ´³³EAAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;77ÄÃÃÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿSOOíííÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤¢¢ëëëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·µµ(##(##'##'""'""'""&""&""&!!&!!&!!&!!zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÃÃ% % ÈÇÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzww:77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóóó7222---((-((722-((%  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊÉÉ=88ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâââ$$Œ‰‰ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæææ+&&çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³²²% %!!%!!&!!&!!&!!&!!&""&""'""'""'""zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÃÃÅÄÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzwwÄÃÃÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúùùñððôôôôôôôôôôôôîííÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿspp†„„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ||+&&þþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIEEçææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³²²zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÃÃÅÄÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzwwjggÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúùù&!!ÑÐÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûû'##±°°ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿš˜˜çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÊÊ(##(##(##'##'##'""'""'""&""&""&!!&!!zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÃÃ&!!%!!ÈÇÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzww% ôôôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµ´´% 400ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ722ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãââ% +&&çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃÁÁ«©©®¬¬®¬¬²°°®¬¬®¬¬²±±®¬¬®¬¬²±±±°°}zz&!!&!!&!!&!!&!!&""'""'""'""'""'##(##zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÃÃÅÄÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzwwª¨¨ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ[WW€}}ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúùùìììÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿEAAçææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ=99zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼¼¾½½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzwwTPPÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôôôíííñðððïïíííÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïîîËÊÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ”‘‘çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ2..)$$($$(##(##(##'##'##'""'""'""'""&""zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÐÐTPPJFFJFFTPPJFFJFFÔÓÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzww%!!çççÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÛÛ$)%%3..\XXÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿžœœ% % % 1--þþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÞÞ% % +''çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ±¯¯œšš–””–””œšš–””–””œšš–””–””œšš*&&&!!&!!&""&""'""'""'""'""'##'##(##(##zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzww“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþ0,,ƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿGCCqnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿC??çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ=99zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzww:66ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‹ˆˆÖÖÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝÜÜÂÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‹‹çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ833)$$)$$($$($$(##(##(##'##'##'""'""'""zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzww&!!&!!ÑÐÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÒÒ;77ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿˆ……%!!%!!&!!)$$èççÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÊÊ&!!&!!,''çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ833&""'""'""'""'""'""'##'##(##(##(##($$zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzwwzwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ^ZZÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ400èèèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÐÐçææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ955zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzww*&&üüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿZVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÇÇÍÌÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©§§çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöööïîîòòòòòòòòòòòòòòòòòòòòòôôôóóó611)%%)$$)$$)$$($$(##(##(##(##'##'##'""zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóóóÒÑÑÐÏÏÑÐÐÔÓÓÐÏÏÏÎÎôôôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzww&!!&!!¸¶¶ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖÖÖâááÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿyuu&!!&!!&!!†„„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ[WW&!!&!!,''çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿa^^411,'',''844,'',''944,''.)):55'""'""'""'##'##'##(##(##(##($$($$)$$zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂÀÀÃÁÁÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzww^ZZÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùù$C??ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòòò çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ/**zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃÁÁÃÂÂÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzwwíííÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ´³³äããÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³²²çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿxuuHDDKGGKGGKGGKGGKGGKGGKGGKGGLIIMII)%%*%%)%%)%%)$$)$$)$$($$(##(##(##(##'##zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÃÃ'##'""ÉÈÈÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzww'""'""¢¡¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\XX&""&!!&""§¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúIEEÞÝÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿeaa'"",((çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿhee'##'##'##(##(##(##(##($$)$$)$$)$$)%%zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÃÃÅÄÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzwwD@@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëëëZVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ•““qnnÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷÷'""çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿgddzwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÃÃÅÄÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzwwÙØØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ››#óóóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóóó!áááÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ¾¾çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿeaa*%%*%%*%%)%%)%%)$$)$$)$$($$($$(##(##zwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÃÃ(##'##ÉÈÈÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzww'""'""'""ƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿGCC'""'""'""¼»»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~{{'""[WWÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿvss-((çææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿeaa(##(##(##(##(##($$)$$)$$)$$)%%)%%*%%…ƒƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙØØÚÙÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ…ƒƒ2..ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæåå‹‹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäããÏÎÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿFBB ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿnkkgccÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒ¤¢¢¤¢¢ÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒgcc£¡¡ÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒroo.))ÓÒÒÖÕÕÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒURREAAÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÞÝÝ™——¿¾¾ÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒÓÒÒVSS*&&*&&*%%*%%*%%)%%)%%)$$)$$)$$)$$($$(##(##(##(##(##(##(##'##'##'##'##'##'##'##'##'""'""'""'##'##'##'##'##'##'##'##(##(##(##(##(##(##($$($$)$$)$$)$$)%%)%%*%%*%%*%%+&&+&&*&&*&&*%%*%%*%%)%%)%%)%%)$$)$$)$$)$$($$($$(##(##(##(##(##(##(##(##(##'##(##(##(##(##(##(##(##(##(##(##(##(##(##(##(##($$($$)$$)$$)$$)$$)%%)%%*%%*%%*%%*%%*&&+&&+&&+&&+&&*&&*&&*%%*%%*%%*%%)%%)%%)%%)$$)$$)$$)$$)$$($$($$($$($$(##(##(##(##(##(##(##(##(##(##(##(##(##($$($$($$($$)$$)$$)$$)$$)$$)%%)%%*%%*%%*%%*%%*%%*&&*&&+&&+''+''+&&+&&+&&+&&*&&*&&*%%*%%*%%*%%*%%)%%)%%)%%)$$)$$)$$)$$)$$)$$)$$)$$)$$($$)$$($$($$($$($$)$$($$)$$)$$)$$)$$)$$)$$)$$)%%)%%)%%*%%*%%*%%*%%*%%*%%*&&*&&+&&+&&+&&'8C…84~2~3~6788888888888888:…2nBnPˆLLLLLLLLLLLLLLLNOONL‚F„#@,'',''+''+''+&&+&&+&&+&&*&&*&&*&&*%%Zk¤ù–ø‹ö |ô!nó"`ñ#Wð#Sð#Uð"Zñ"]ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ!TÔ3q)'+)%%)%%)$$)$$)$$)$$)$$)$$)$$)$$)$$)$$)&(DqwÔˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö÷÷Œö…õ {ô!qó!hò"`ñ"Zñ0|*%%*%%*%%*%%*&&*&&+&&+&&+&&+&&+''+''_`ªø™ù§ù¨ù£ù™ø‹ö|õ!mó"`ñ#Wð#Sð#Uð"Yð"]ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ!UÕ3qCpx׈öˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö÷÷Œö„õ {ô!qó!hò"_ñ"Yð#Wð"Xð"^ñ"Zñ*ob`¼øøøøžø¢ù§ù¨ù£ù™øŒö|ô nó"bò#Xð#Sð#Uð"Zñ"]ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ!VØ4tDrzÛˆöˆöˆöˆöˆöˆöˆöˆö‰ö‹ö÷÷Œö„õ {ô!qó!hò"_ñ"Yñ#Wð"Xð"[ñ"]ñ"^ñ"^ñ"añ#Uð)o,((,((,'',''+''+''+&&+&&+&&+&&+&&+&&b`!Ðø‘øøøøøøøžø¢ù¦ù¨ù¤ùšøö~õ!nó"añ#Wð#Sð#Uð"Yñ"]ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ!TÔ5u*&'*%%)%%)%%)%%)%%)%%)%%)%%)%&FuxÖˆöˆöˆöˆöˆöˆö‰öŒö÷÷Œö„õ {õ!ró!hò"_ñ"Xð"Wð"Xð"[ñ"]ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ#Pð)o*&&*&&*&&+&&+&&+&&+&&+&&+''+'','',''``#ãøšøšøøøøøøøøøøžø¢ø¦ù¨ù£ù™øŒö}ô oó"añ#Wð#Sð#Uð#Yñ"]ñ"^ñ"^ñ"^ñ"^ñ!TÒ4sEtwÔˆöˆöˆöˆö‰öŒöŽ÷÷Œö…õ |õ!ró!hò"_ñ"Yñ"Wð"Xð"[ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"_ñ"^ñ#Lï)o^`$òø©ø”øøøøøøøøøøøøøøžø¢ù¦ù¨ù£ù™øŒö}ô nó!añ#Wð#Sð#Uð"Yñ"]ñ"^ñ"^ñ!TÔ2nBnwÔˆöˆö‰ö‹öŽ÷÷‹ö…ö |õ!qó!hò"_ñ"Yð"Wð"Xð"\ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ"Zð#Hï)o-((-((,((,((,'','',''+''+''+&&+&&+&&]`%üø¼øøøøøøøøøøøøøøøøøøøžø¢ø¦ù¨ù£ù™øŒö~ô nó"añ#Xð#Sð#Uð"Zñ"]ñ!UÕ3q*&)*%%*%%*%%*%%*&'Cpy؉ö‹öŽ÷÷‹ö…õ |õ qó!hò"_ñ"Yñ#Vð"Xð"[ñ"]ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ"Uð#Fï*o+&&+&&+&&+&&+&&+&&+''+'','','','',((]`%ýø!Ðøøœøøøøøøøøøøøøøøøøøøøøøžø¢ù¦ù¨ù¤ùš÷Œö}õ!oó"añ#Xð#Sð#Uð!QÖ3sDq|ÙŽ÷÷‹ö…ö |ô!qó!hò"_ñ"Yñ#Wð"Xð"[ñ"]ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ#Pð#Fï*o]`%øø#âøšøšøøøøøøøøøøøøøøøøøøøøøøøøøžø¢ù¦ù¨ù¤ùšøŒö}ô nó"añ#Wð"JÑ/oHt|ÔŒ÷…ö |ô!ró!hò"_ñ"Yð"Vð"Xð"[ñ"]ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"_ñ"^ñ#Lï#Gï*o-((-((-((-((,((,((,'','',''+''+''+'']`$òø$ñø©ø”øøøøøøøøøøøøøøøøøøøøøøøøøøøøøžø¢ù¦ù¨ù£ù™÷Œö|ô!nó SÈ.j*&&*'(EpsÓ |ô ró!hò"_ñ"Yð"Wð"Xð"[ñ"]ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ"Zñ#Hï#Hï*o+&&+&&+''+''+''+'','','',((,((,((-((]`$ïø%ûø»øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøžø¢ù¦ù¨ù£ù™ø‹ökÌ5_4b cÑ!iò"_ñ"Yð"Wð"Xð"[ñ"]ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"bñ"Uð#Fï#Iï*o]`$ïø%ýø!Ðøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøžø¡ø¨ù«ù—ø!ró#Oï"Uð"\ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ#Pð#Fï#Iï*o-))-))-((-((-((-((,((,((,((,'','','']`$ïø%øø#âøšøšøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøŸø ø÷†ö÷ yô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"_ñ"^ñ#Kï#Gï#Iï*o+''+'','','','','',((,((,((-((-((-((]`$ïø$òø$ñø©ø”øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøŸø øŽ÷ƒö‡ö‰ö‘÷ xô"Vð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"`ñ"Zð#Hï#Hï#Iï*o]`$ïø$ïø%ûø»øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøŸø ø÷ƒöˆöˆöˆö‰ö‘÷ xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"bñ"Uð#Fï#Iï#Iï*o.)).))-))-))-((-((-((-((-((,((,((,((]`$ïø$ïø%ýø!ÏøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøŸø øŽ÷„öˆöˆöˆöˆöˆö‰ö‘÷!xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ#Pï#Fï#Iï#Iï*o,'','',((,((,((,((-((-((-((-((-))-))]`$ïø$ïø%øø#âø™øšøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøŸø øŽ÷ƒöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"_ñ"^ñ#Lï#Gï#Iï#Iï*o]`$ïø$ïø$òø$òø©ø”øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøŸø øŽ÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ yô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"`ñ"Zñ#Hï#Hï#Iï#Iï*o.**.)).)).)).))-))-))-((-((-((-((-((]`$ïø$ïø$ïø%ûø»øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøŸø øö„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ xô"Wð"Zñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"bñ"Uð#Eï#Iï#Iï#Iï*o,((,((-((-((-((-((-((-((-))-))-)).))]`$ïø$ïø$ïø%ýø!Ïø‘øøøøøøøøøøøøøøøøøøøøøøøøøøøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ xô"Wð"[ð"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ#Pð#Fï#Iï#Iï#Iï*o]`$ïø$ïø$ïø%ùø#âøšøšøøøøøøøøøøøøøøøøøøøøøøøøøøøŸø øŽö„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö÷ xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"_ñ"^ñ#Lï#Gï#Iï#Iï#Iï*o.**.**.**.)).)).)).))-))-))-((-((-((fi$ïø$ïø$ïø$òø$òøªø”øøøøøøøøøøøøøøøøøøøøøøøøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"`ñ"Zñ#Hï#Iï#Iï#Iï#Iï,x-((-((-((-((-((-))-))-)).)).)).)).))HK$ïø$ïø$ïø$ðø%üø¼øøøøøøøøøøøøøøøøøøøøøøøøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"bñ#Uð#Fï#Iï#Iï#Iï#Iï%Z!½Ä$ïø$ïø$ïø%ýø!ÏøøøøøøøøøøøøøøøøøøøøøøøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö÷ wô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ#Pð#Eï#Iï#Iï#Iï :°/**/**.**.**.**.)).)).)).)).))-))-))EG$ïø$ïø$ïø%øø#âøšøšøøøøøøøøøøøøøøøøøøøøøøŸø øŽ÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷!wô"Vð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"_ñ"^ñ#Lï#Gï#Iï#Iï#Iï:-((-))-))-))-)).)).)).)).)).**.**.**!¼Ã$ïø$ïø$óø$òø©ø”øøøøøøøøøøøøøøøøøøøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö÷ xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"`ñ"Zñ#Hï#Hï#Iï#Iï :°FH$ïø$ïø$ïø%üø¼øøøøøøøøøøøøøøøøøøøøøŸø øŽ÷ƒöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ"Uð#Fï#Iï#Iï#Iï:/++/++/**/**.**.**.**.**.)).)).)).)).))"ÀÇ$ïø$ïø%ýø!ÏøøøøøøøøøøøøøøøøøøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ xô"Vð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ#Pð#Fï#Iï#Iï :±-))-)).)).)).)).)).)).)).**.**.**/**/**HJ$ïø$ïø%øø#âøšøšøøøøøøøøøøøøøøøøøŸø ø÷ƒöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ wô"Vð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"_ñ"^ñ#Lï#Gï#Iï#Iï9"¿Æ$ïø$óø$ñø©ø”øøøøøøøøøøøøøøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö÷!wô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ"Zñ#Hï#Hï#Iï 9¯0++/++/++/++/**/**/**.**.**.**.**.)).))GI$ïø$ðø%ûø»øøøøøøøøøøøøøøøøŸø øŽ÷ƒö‡öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ"Uð#Fï#Iï#Iï8.)).)).)).)).**.**.**.**/**/**/**/**/++"ÀÇ$ïø%ýø!ÏøøœøøøøøøøøøøøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ#Pð#Fï#Iï :°GI$ïø%øø#áø™øšøøøøøøøøøøøøŸø¡ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"_ñ"^ñ#Lï#Gï#Iï;0++0++0++0++/++/++/++/**/**/**.**.**.**.**"¾Å$óø$ñø¨ø”øøøøøøøøøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ wô"Vð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ"Zð#Hï#Hï :±.**.**.**.**.**.**.**/**/**/**/++/++/++0++FH$ïø%ûø»øøøøøøøøøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ wô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"bñ"Uð#Fï#Iï:"¾Å%ýø!Ïø‘øøøøøøøøøŸø¡ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ xô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"^ñ"añ#Pð#Eï :²0,,0,,0++0++0++0++/++/++/++/++/**/**/**.**HK%øø#âøšøšøøøøøøøŸø¡ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ wô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"^ñ"_ñ"^ñ#Lï#Gï;.**.**.**/**/**/**/**/++/++/++/++0++0++0++"ÃÈ$ñø©ø”øøøøøøŸø ø÷ƒöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö÷ wô"Wð"[ñ"_ñ"^ñ"^ñ"^ñ"^ñ"añ"Zñ#Hï 9±HJ%ûø¼øøøøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷!wô"Vð"[ñ"_ñ"^ñ"^ñ"^ñ"bñ#Vð#Eï91,,0,,0,,0,,0,,0++0++0++0++/++/++/++/++/**/**"ËÇ!Ðø‘øøøøŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö÷ wô"Wð"[ñ"_ñ"^ñ"^ñ"añ#Pð 8°/**/**/**/**/++/++/++/++0++0++0++0++0++0,,0,,JJ#âøšøšøøŸø¡ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ wô"Wð"[ñ"_ñ"_ñ"^ñ#Kï;"ÁÇ©ø”øŸø ø÷„öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöŠö‘÷ wô"Vð"[ñ"añ"Zð :³1,,1,,1,,0,,0,,0,,0,,0++0++0++0++0++0++/++/++JI»ø‘ø ø÷ƒöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‘÷ wô"Vð"_ñ#Vð</++/++/++/++/++0++0++0++0++0++0,,0,,0,,0,,0,,¥Â”ø÷„ö‡öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö÷!wô"Zñ =°<@‰ö ~öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö“÷ xó21--1,,1,,1,,1,,1,,0,,0,,0,,0,,0,,0++0++0++0++,^bšø!}õ †öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŽ÷ ô-3U0++0++0++0++0++0++0,,0,,0,,0,,0,,0,,1,,1,,1,,»Ø°ûžø!€õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö {õ!vô LÇ^^ÆùªúºûŸø!€õ †öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‹ö |õ!nô!yõ"dò!N1--1--1--1--1,,1,,1,,1,,1,,0,,0,,0,,0,,0,,0,,"ÑÙ¹ú¬ú´ú»ûŸø €õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöŠöŒö |õ!oô!rô!xõ!mó!>Æ0++0++0,,0,,0,,0,,0,,0,,0,,1,,1,,1,,1,,1,,1--__!ãù®ú°ú²ú´ú»ûžø!€õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!uô!uô#Pð L$ÛÚÕù©ú²ú²ú²ú´úºûžø!€õ †öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö {õ!oô!rô!sô!sô!sô!zõ"Yñ!9Â2--2--1--1--1--1--1--1,,1,,1,,1,,1,,1,,0,,,lo&÷øÆú¨ú²ú²ú²ú²ú´úºûžø!€õ†öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!sô!sô!sô!sô!sô!zõ"cò#Cî-3^0,,0,,0,,1,,1,,1,,1,,1,,1,,1,,1--1--1--1--#ÔÙ$ïø¹ú­ú²ú²ú²ú²ú±ú´úºûžø!€õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöŠöŒö |õ!oô!rô!sô!sô!sô!sô!sô!xõ!mô#Hï!=Ä\_&÷ø!ãø®ú±ú²ú²ú²ú²ú²ú²ú´ú»ûžø €õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!uô!uô#Pð#Dî"N2--2--2--2--1--1--1--1--1--1--1--1,,1,,1,,"ÐØ&úøÔù¨ú²ú²ú²ú²ú²ú²ú²ú²ú´úºûžø €õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö {õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!zõ"Yñ#Bî!?Å1,,1,,1,,1,,1,,1,,1,,1--1--1--1--1--2--2--Z\$ïø&÷øÆù¨ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´úºûžø!õ †ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!zõ"cò#Cî#Iï"M"ÐØ%òø$ïø¸ú¬ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú´úºûžø!€õ†öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!wô!mó#Hï#Gï!?Å2..2..2..2--2--2--2--2--1--1--1--1--1---lo$ïø&÷ø!ãù®ú°ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú´úºûžø!€õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöŠöŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!tô!uô#Oð#Dî#Iï-4_1,,1--1--1--1--1--1--1--2--2--2--2--2--"ÑÙ$ïø&úøÕù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú´úºûžø!€õ†öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!yõ"Yñ#Bî#Iï!>Ã[^$ïø$ïø&÷øÆú¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú´ú»ûø!€õ †öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!zõ"cò#Cî#Iï#Iï!J3..2..2..2..2..2--2--2--2--2--2--2--1--"ÐØ$ïø%òø$ïø¸ú¬ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú´úºûø!€õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!xô!mó#Hï#Gï#Iï!>Â1--1--1--1--2--2--2--2--2--2--2..2..2..[^$ïø$ïø&÷ø"ãø®ú°ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´úºûžø!€õ†öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰ö‹ö |õ!nô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!tô!uô#Pð#Dî#Iï#Iï"L"ÐØ$ïø$ïø&úøÕù§ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú´ú»ûžø €õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!yõ"Yñ#Bî#Iï#Iï!?Ä3//3..3..2..2..2..2..2..2..2--2--2--.km$ïø$ïø$ðø&øøÆù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú´ú»ûø!€õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!zõ"cò#Cî#Iï#Iï#Iï.4^2--2--2--2--2--2..2..2..2..2..2..3.."ÎÖ$ïø$ïø%òø$ïø¹ú¬ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´úºûø!õ †öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!wô!mó#Hï#Gï#Iï#Iï!>ÃY\$ïø$ïø$ïø&÷ø"ãø¯ú°ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú´úºûø!€õ†öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!uô!uô"Pð#Dî#Iï#Iï#Iï"L3//3//3//3..3..3..3..2..2..2..2..2.."ÎÖ$ïø$ïø$ïø&úøÕù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´úºûø!€õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöŠöŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!zõ"Yñ#Bî#Iï#Iï#Iï!?Ä2--2--2..2..2..2..2..2..3..3..3..3//SU$ïø$ïø$ïø$ðø&øøÆù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´ú»ûø!€õ†öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!zõ"cò#Cî#Iï#Iï#Iï#Iï(fdg$ïø$ïø$ïø%òø$ðø¹ú¬ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´úºûø!õ †öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!wô!mó#Hï#Gï#Iï#Iï#Iï,v4//3//3//3//3//3//3//3..3..2..3..2..]`$ïø$ïø$ïø&÷ø"ãù®ú°ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú´úºûø!€õ†ö‰öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!tô!uô#Pð#Dî#Iï#Iï#Iï*o2..2..2..2..2..3..3..3..3//3//3//3//]`$ïø$ïø$ïø&úøÕù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´úºûø!€õ†öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!yõ"Yñ#Bî#Iï#Iï#Iï*o]`$ïø$ïø$ïø&÷øÆù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú´úºûø!€õ†öˆöˆöˆöˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!zõ"cò#Cî#Iï#Iï#Iï*o4//4//4//4//3//3//3//3//3//3//3//3..]`$ïø$ïø%òø$ïø¹ú¬ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú´úºûø!€õ†ö‰öˆöˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!xõ!mô#Hï#Gï#Iï#Iï*o2..3..3..3..3//3//3//3//3//3//3//4//]`$ïø$ïø&÷ø"ãø®ú°ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´úºûœø!€õ †öˆöˆöˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!uô!uô#Pð#Dî#Iï#Iï*o]`$ïø$ïø&ùøÕù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´úºûœø!€õ†öˆöˆöˆöˆö‰öŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!zõ"Yñ#Bî#Iï#Iï*o4004//4//4//4//4//3//3//3//3//3//3//]`$ïø$ïø&÷øÆù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´úºûø!€õ†öˆöˆö‰öŒö |õ!nô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!zõ"cò#Bî#Iï#Iï*o3//3//3//3//3//3//3//3//4//4//4//4//]`$ïø%òø$ïø¸ú¬ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´úºûø!€õ†öŠöŒö |õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!wõ!mó#Hï#Gï#Iï*o]`$ïø&öø!ãù®ú°ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú´úºûœø!€õ ˆö {õ!oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!uô!tô#Oð#Dî#Iï*o4004004004004//4//4//4//4//4//4//4//]`$ïø&úøÕù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú¯ú°ú·ûŸù!xõ$có$có#ió"oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!yõ"Yñ#Bî#Iï*o3//3//3//3//4//4//4//4//4//4//4//400]`$ïø&÷øÆù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú¯ú®ú¯ú²ú¶ú»ú“¶7F1B€³–÷‚õ!qô#hó$dó#hó"oô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!zõ"cò#Cî#Iï*o]`%òø$ïø¹ú¬ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú¯ú®ú¯ú²ú¶ú»úÁûÅû—¼DQCL—¹½ú¬ù˜÷„ö!sô#hó$dó#hó"oô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!wô!mó#Hï#Gï*o5004004004004004004004//4//4//4//4//]`&öø!ãø®ú°ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú¯ú®ú¯ú²ú¶ú»úÁûÅûÊûÌû™¼*Ua3//3//*V`ž¹ ÖüÎü¿ú«ù—÷ƒõ!rô$gó$dó#hó"oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!tô!uô#Pð#Eî*o4//4//4//4//4//4//4//4//400400400400]`&úøÕù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú¯ú®ú¯ú²ú¶ú»úÀûÅûÉûËûËûÊû—»CP@M”¶Ðü Öü ÖüÍü¾ú«ù–÷ƒö!rô#gó$dó#hó"oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!yõ"Yñ#Bî*o]`&øøÇù¨ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú¯ú®ú¯ú²ú¶ú»ûÁûÅûÉûÌûÌûÊûÉûÈû“·FTDR’µÈûÊûÐü Öü ÕüÍû¾ú«ù–÷ƒõ!rô#gó$dó#ió"oô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!zõ"cò#Cî*o5005005005004004004004004004004004//^`$ïø¹ú¬ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú¯ú®ú¯ú²ú¶ú»úÀûÆûÉûËûÌûÊûÉûÈûÈûÈû”¹*Xf4//4//4//4//4//4//+Vc“·ÈûÈûÈûËûÐü Öü ÖüÍû¾ú«ù—÷ƒõ!sô#hó$dó#ió"oô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!sô!xõ!mó#Hï)o4//4//4//4//400400400400400400400500``!ãù®ú°ú²ú²ú²ú²ú²ú²ú²ú²ú²ú±ú¯ú®ú¯ú²ú¶ú»úÁûÅûÉûÌûÌûÊûÉûÈûÈûÈûÈûÈû—¼CQ@M•ºÈûÈûÈûÈûÈûËûÑü Öü ÖüÍû¾ú¬ù—÷ƒõ!rô#gó$dó#hó"oô!rô!sô!sô!sô!sô!sô!sô!sô!sô!uô!uô#Pð(oa`Õù¨ú²ú²ú²ú²ú²ú²ú±ú¯ú®ú¯ú²ú¶ú»úÀûÅûÉûËûÌûÊûÉûÈûÈûÈûÈûÈûÈûÈû—¼AN@L”¸ÈûÈûÈûÈûÈûÈûÈûËûÑü Öü ÖüÍü¾ú«ù—÷‚õ!rô$fó$dó#hó"oô!rô!sô!sô!sô!sô!sô!zõ"Yñ'o511500500500500500500400400400400400``Çú¨ú²ú²ú±ú¯ú®ú¯ú²ú¶ú»ûÀûÅûÉûËûËûÊûÉûÈûÈûÈûÈûÈûÈûÈûÈûÈû”¹*Yg4//4//4//4//4//4//4//4//4//4//+We“·ÈûÈûÈûÈûÈûÈûÈûÈûÈûËûÐü Öü ÕüÍû½úªù–÷ƒõ!rô#gó$dó#ió"oô!sô!sô!zõ"cò(o400400400400400400400500500500500500_a¸ú©ú®ú¯ú²ú¶ú»úÀúÅûÉûÌûÌûÊûÉûÈûÈûÈûÈûÈûÈûÈûÈûÈûÈûÈûޱ@LES’µÈûÈûÈûÈûÈûÈûÈûÈûÈûÈûÈûËûÐü Öü ÖüÍû½ú«ù–÷ƒõ!rô#gó$dó#mô"ió*pXi³ú´ú»úÀûÅûÉûÌûÌûÊûÉûÈûÈûÈûÈûÈûÈûÈûÈûÈûÈûÈûÈûÈû’µ=IBO•ºÈûÈûÈûÈûÈûÈûÈûÈûÈûÈûÈûÈûÈûËûÐü Öü ÖüÍû¾ú«ø–÷„õ wô5{511511511511500500500500500500400400400400400400400400400400400400400400400400400400400400400400400400400400400400400400400400400400400500500500500500500500511511511511511511511511511511511500500500500500500400500400400400400400400400400400400400400400400400400400400400400400400500500500500500500500500500511511511511511511611511511511511511511511511511511511500511500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500511511511511511511511511511511622611611611611511511511511511511511511511511511511511511500500500500500500500500500500500500500500500500500511511511511511511511511511511511511511511511511511611622622622622622611611611511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511611611611611622622622622622622622622622622611611611611611611511511511511511511511511511511511511511511511511511511511511511511511511511511511511511511611611611611622622622622622622722722622622622622622622622622622622611611611611611611611611611511611611511611611511511511511511511511511611611611611611611611611622611622622622622622622622622622722722722722722722622622622622622622622622622622622622622622622622622611611611611611611611611611611611611611622622622622622622622622622622622622622622622722722722733722722722722722722722722722722622622622622622622622622622622622622622622622622622622622622622622622622622622622622622622622622622622622722722722722722722722722733733733733733733722722722722722722722722722722722622622622622622622622622622622622622622622622622622622622622622622622722722722722722722722722722722722733733733733733733733733733733733733733733722722722722722722722722722722722722722722722722722722622722722722722722722722722722722722722722722722722722733733733733733733733733733733733733733733733733733733733733733733733733722722722722722722722722722722722722722722722722722722722722722722722733733733733733733733733733733733733733733833833733733733733733733733733733733733733733733733733733733733733733733733722733733733733733733733733733733733733733733733733733733733733733733733733733733733733833833833833833833833733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733733833833833833haxe_3.4.4.orig/extra/installer.nsi0000664000175000017500000001144713166552354017256 0ustar andyandy00000000000000; Haxe/Neko Install script ; Instructions: ; - put haxe files in resources/haxe ; - put neko files in resources/neko ; - run ;-------------------------------- !include "MUI.nsh" !include "LogicLib.nsh" !include "WordFunc.nsh" !include "winmessages.nsh" !include "EnvVarUpdate.nsh" ;-------------------------------- ; Define version info !define VERSION "%%VERSION%%" !define VERSTRING "%%VERSTRING%%" !define VERLONG "%%VERLONG%%" ; Define Neko info !define NEKO_VERSION "2.1.0" ; Installer details VIAddVersionKey "CompanyName" "Haxe Foundation" VIAddVersionKey "ProductName" "Haxe Installer" VIAddVersionKey "LegalCopyright" "Haxe Foundation 2005-2017" VIAddVersionKey "FileDescription" "Haxe Installer" VIAddVersionKey "ProductVersion" "${VERSION}.0" VIAddVersionKey "FileVersion" "${VERSION}.0" VIProductVersion "${VERSION}.0" ; The name of the installer Name "Haxe ${VERSTRING}" ; The captions of the installer Caption "Haxe ${VERLONG} Setup" UninstallCaption "Haxe ${VERLONG} Uninstall" ; The file to write OutFile "haxe-${VERSTRING}-win.exe" ; Default installation folder InstallDir "C:\HaxeToolkit\" ; Define executable files !define EXECUTABLE "$INSTDIR\haxe\haxe.exe" !define HaxeLIB "$INSTDIR\Haxe\haxelib.exe" !define NEKOEXE "$INSTDIR\neko\neko.exe" ; Vista redirects $SMPROGRAMS to all users without this RequestExecutionLevel admin ; Use replace and version compare !insertmacro WordReplace !insertmacro VersionCompare ; Required props SetFont /LANG=${LANG_ENGLISH} "Tahoma" 8 SetCompressor /SOLID lzma CRCCheck on XPStyle on ;-------------------------------- ; Interface Configuration !define MUI_HEADERIMAGE !define MUI_ABORTWARNING !define MUI_HEADERIMAGE_BITMAP "images\Banner.bmp" !define MUI_WELCOMEFINISHPAGE_BITMAP "images\Wizard.bmp" !define MUI_UNWELCOMEFINISHPAGE_BITMAP "images\Wizard.bmp" !define MUI_PAGE_HEADER_SUBTEXT "Please view the license before installing Haxe ${VERLONG}." !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of $(^NameDA).\r\n\r\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without having to reboot your computer.\r\n\r\n$_CLICK" ;-------------------------------- ; Pages !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH !insertmacro MUI_UNPAGE_WELCOME !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_COMPONENTS !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_FINISH !insertmacro MUI_LANGUAGE "English" ;-------------------------------- ; InstallTypes InstType "Default" InstType "un.Default" InstType "un.Full" ;-------------------------------- ; Functions Function .onInit FunctionEnd ;-------------------------------- ; Install Sections !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' !define env_hkcu 'HKCU "Environment"' Section "Haxe ${VERSION}" Main SectionIn 1 2 RO SetOverwrite on RMDir /r /REBOOTOK "$INSTDIR\haxe\std" SetOutPath "$INSTDIR\haxe" File /r /x .svn /x *.db /x Exceptions.log /x .local /x .multi /x *.pdb /x *.vshost.exe /x *.vshost.exe.config /x *.vshost.exe.manifest "resources\haxe\*.*" ExecWait "$INSTDIR\haxe\haxesetup.exe -silent" WriteUninstaller "$INSTDIR\Uninstall.exe" SectionEnd Section "Neko ${NEKO_VERSION}" Neko SectionIn 1 2 SetOverwrite on SetOutPath "$INSTDIR\neko" File /r /x .svn /x *.db /x Exceptions.log /x .local /x .multi /x *.pdb /x *.vshost.exe /x *.vshost.exe.config /x *.vshost.exe.manifest "resources\neko\*.*" SectionEnd ;-------------------------------- ; Install section strings !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${Main} "Installs Haxe and other core files." !insertmacro MUI_DESCRIPTION_TEXT ${Neko} "Installs Neko, which is required by various Haxe tools." !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------- ; Uninstall Sections Section "un.Haxe" UninstMain RMDir /r "$INSTDIR\haxe" ${un.EnvVarUpdate} $0 "PATH" "R" "HKLM" "%HAXEPATH%" DeleteRegValue ${env_hklm} HAXEPATH SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 SectionEnd Section "un.Neko" UninstNeko RMDir /r "$INSTDIR\neko" ${un.EnvVarUpdate} $0 "PATH" "R" "HKLM" "%NEKO_INSTPATH%" DeleteRegValue ${env_hklm} NEKO_INSTPATH SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 SectionEnd ;-------------------------------- ; Uninstall section strings !insertmacro MUI_UNFUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${UninstMain} "Uninstalls Haxe and other core files." !insertmacro MUI_DESCRIPTION_TEXT ${UninstNeko} "Uninstalls Neko." !insertmacro MUI_UNFUNCTION_DESCRIPTION_END ;-------------------------------- haxe_3.4.4.orig/extra/mac-installer/installer-structure.pkg0000664000175000017500000040772313166552354024045 0ustar andyandy00000000000000xar!H"9xÚìšKoêFÇ÷÷S öÄó~XWªªJ•º¸jÓÍÝçn#Û¤I?}ÇÆC Ø…D¹UVÌxŽç ~sæ›èëór1z²Yž¤«û1¼ã‘]éÔ$«ÙýøÏ‡_&büuú%zVÙôË(*Rí?F‘ά*ü“"YÚ)O€œ@ôHˆDØ÷(8´©îš[ý˜o–£¼xYØûq>Wp\ŽŒ¢Ô¹ÜSu«ºš'ÿ”³GAÕ(§š9ªžKv”¿îfݵ RR.¨YÈ(Z6fdðCDC,½Ùro¦Î̦öf³,ݬ§¯£`ÛÜ^MÌàW_¶ªK›Üf[»ªµ½¶3Û4fËÔØ)à”úÅ”ÍꢱO‰¶«tÊ…8 výj4Y•†PÊð÷mûÕPñ²¶S“dViöU¿Y)ÿ ~·yºÉ´Í£ êW#{aÑVؾÊö•¶¯¶'ÄíR·SÞ.}»¾ ð‘Ĭ-ñk‘íên±ÎÒ¿Z·EƵÈ~ ªPu{-ìjV̧æ—S÷šÁf—6›I­×‹DW;.Hua‹I^ø¸»[ê­Å9Áð`£íöZíªÙnÛ*ÓóäÉšI÷öÅÄ/¥1$£b¥(g b€±SPBA¬Â^°Wí¿Ës‘)¿æë}¼ž©Q6hIÛæÍe4AžfB‚#š[87رÅ^µ »yèN¤¦!m¦/AÝ¢šHF©®±.1m]#ý[9MnˆJÛWt“³tCJˆ¼!Ý $I7Þµ¯!x3# `ÈJ”ÃŒZ&P }èp1BB #•¡’ªkðîïã-ñ¦D© þ_âÍà+ýX~•9Aø¾Ùjí go›ý ìcç#dH>2WÏö!MIñ-³n‘ÌæÅÝúqÖ™žð&;iÓ_‡DÅQXUš ‚9àÇ1¥ÎNK/­€r)ž8G@NÂÄ g•a‚*kÄ•ÀjˆÊœ÷T<¹Nú»8NÚÑä¿'~5œüTâ×a÷>‰ßQéø•1u$~Ç!d ò7AÔÌþºri›ÝVÙa,Î`Œ) ì† cŒ:A®ý @Ùj‡­åFútû&Ü;„œ0PŒ4A±ƒ–ÆW ÜßÅ» Ìz¢Ì~”Io”J——–g&’ߎ`Ž0oÝ ¤•¶Âб,f•´š`"eŒ5‰}ÉqÀý]|<`Úà?t–¬‹üÄœ¡˜óÛ1Ì1íN'J'Ö€).¨B§„ñ1Ü $Ž`àÅu΋+îïâ“àÁãÙÄË"U¦“à®+@ø¶Âë*@:Ìz<å»ÁC RÂüdÅÏUÝ,D@ewÁQ:"8WÔ`ê¤d,f"J‘ÕJ ã”6-¾&Dôwñ¶!¢,šyHð¥Ѳûð!‚ˆ·(8ÈÙ‚ƒÛux¢Þ¨Ü 9챈}ÊT,1vŒ#ÑÖN+ À0¿æ°ëíâ];Ñó°?ÄanYoÐsqݰ`f‚t—•—øbãb…cì§"f¾D"_‘œùêÖs'¯À·¿‹Ï'?ƒñ…7©6ºrµæåuKúæåGïF“Ü€Œß­7oD*{Š/Al° JI#e¦F#€„q&%ÒCgœ‚ú$ÄîïáÃ-„¯zü.B.<~o™½yö{ˆnßì·Ì øëì÷ˆÛ-¶?'žœ$Þ”(íÙÝëíËDAõ_ÿÿÊÊ`ÆC2«0"{¢{ê¡ìB£Ks Haxe Toolkit %%VERLONG%% #haxeToolkitPreflight.pkg #files.pkg BOMStore 4ÏU¨#"<nfotrees treetree€. dextree AíõS¡uîxBomInfoPathsHLIndexVIndex Size64¤õS¡uR'*~ ._.DS_Store¤õSŸvvˆì.DS_Store¤õSŸ³>Ż«ÓQhaxe.tar.gz¤õSŸ³’,M]9neko.tar.gz¤õS¡b«çèVÑscripts.tar.gztree@TïÑ ª4³66q K"¢€"q#^"†`f3^3y3‰ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ3Â3Ý3í3õ44 4(4C4V4ž4^@"15"¡n 3º 3¬3‘‹íP½‚0dæ)Jý:;8˜8_) A(¡Õž^@DÐ.ÆÍx¾Ÿ»ïÒæ¸{S¸˜{^[¹ïͶwpJw]:Œt"~u#ÝÈP(Ã#íëÇñ”ú "!ÓBéð|†*±:¤R‰ €t^¢$¬c;ÏDZKQ†QÖ1C§Ã ¬šúzöBØnà©™EœI#¡¢*-µzpQ’K–5ôü™­.B™·4ègiø³4J©ôàýa0l1o§ò}°Þî6ã8ÖßáÌÛ BOMStore 3^Uˆ#"<nfotreePaths treetree€. dextree AÀõ:OÈ€DIndexBomInfoPathsHLIndexVIndex Size64 ª 66q K"¢€"q#^"†`fn "1‹í< X“GÓoNRÀ0JåÊn”+"Að*Ƽ@$$1 劷TTÛª`­U𨭠~"‚g=@𨢢¨Uª"¢òí&A"þßÿüOû?ß“ÑÍÎÎÎÌλ;;»/ A]QøOœPWggP»º8÷£ÊÁÕÁÁÑÕÉÉAÑtPb±GÐÚèttPmôÞnWðß uQVæä(ö4a|B¼Ë‰ˆXB!rîÍ“÷‚@Áƒb‹&‚d#àn 0™¡>Œ9Œ°iHè#Ÿ(—ƒr3³f ÑïÃá¸jŠ‚ÈÆ‘`É’>öòž£ä`¤§ŽÜÖ@DÒûdÄ) ÑS,IŒDÇ!s1‡µžÜÎ^ÐT“ëP—ëÂÌ8Œ'ÄDƒèh &ÂZo€jÊv°Å—û‰g1&#H ¬IH?PÖÇd&ò“¸|“Ë ¢£ è˜ë:”¡o-ü}fø(uP¾õP¬Q^ ¡H+b%0±DâÁ塯@Ù~sÐÏ~>¯w9„ÑG:Œ€MXСÞÏk(£vŒ CCQä:Ø1Ê‹1P t °òYØ‚„¿¯Ý_Ç|JŸk+ëÀ À§ÈÖbšïW~Jpp(LAú­±olž˜)ÂbĽíåá¾)´…Ž Ã@ý Ô9ªdKoüZȧ¡Èë Ba¡MÖGK‹hÁÙl*kÀWŒBxN#áâà öð6Ä ×볇XÄàeðáq€M ÷I”€£˜‡±ÄX¨@ÀCX<ž€pùà’15!ÓEF…_x3™L¿É~¾XÂâKÂeÙÕ~<–X†Å`"ŒÏÆtÓj¼N!Ð!=Ü› “.™ âØpŒÏA ÅÈ›‰%s%§\4Hb`ëKcof&™Š%K‰j ¨Jy¢YÞ¢Ÿ@˜âÏeC”%J|ŽÉLˆš1v¢cÆa,h²É§Òºÿ×pÔt"Ò jOP|,5˜+IÂéË~@s5qŠÔc%|އéíÈ%<_ŽËRÞ”ã²Ôïr\–Vq\‰~F ‡¹Òðç20µ  m¹‰ÞƒõAl†ìeëÆ+Èä³0æÇ)0ƒ°(' \³Ï¯Öç]Hî!ý}§×S>òK‹#š@£9»ÐœÏúæ¦N5ðr˜÷Ó›žS§¡?´ÊWg x`»ÁÈŒ)·¨‚LÃm#\_: [`Ï y˜}ÿ¿¥qúnaØÂ#·f›lÞî~Äã{«p4c0ßqIÜœ|½"ž„Ûº¡]H^N¯-%]™c³þÆÝ­Y/#'wÅž%zÉ2ª¨™m}Õp#¢óÛ­ªáÌý§gq›'Ÿ÷&7ñ+ r›c'ï<”SÇèì2öËþ´@î²ç„48”“‚¦®x“OÙåÞÜxImhºº–uΔœN]œ¾$MÇãpôa¨–ºš?R Qf%™º¯ÐL¢š‰ï*!àqx<ÎÕýÀ‚SÑ2„¢úp|D8}8jÚõa2F ä³íéãP*$n&'úa"˜,%ÏP¦wŒˆ¸’º1jùÃuå|a„â烚›è¢®¨ÝÉNw§»Ï1Ñ¥;+5Ñ´ÿCQºÜkŸ€ƒQ¹±|àÄŸB3q–Êó‚SC™8èÚøLÙ¾Ó`a^×°ø×cu7eDÅÏþuΨ¼ýî==ç¾iŒ³û”måVMO‹)Ï8nšñ:?œo ­2S?9÷yÔÈÍ3°1-úžÛ¯8}Ž(!•À*ÖWw·=û¸-µeÁñIËß6TŒ. L1ø6qÑ=óC.iOî¾eº¨tÕŽ]gVÿPõfã¯î»ÏŽ 5X^¾àI{ÌJP…‡ÝŸ»\­[nÇ=¾ÃšEkÎÅÿUjq8x›Þë®&»3"bšÙü7“–ïo(ó~j’k:}ÃÑó­v{Ž?œ=5j4æhEØ[¶–š[››‚?µi¿ÞÓ³\͉ùSÖPN¸†þv¾±õô3.˜iq+b²Þgã 8W–qÍØ‡êé5#áp=D"p©Ô¶Ç¶ª­®i£ÜJƒ@@I>ÒÕP¨P3HÐ#Vr¿?™ä;•ø]¤oñtrÎõK”UZ(v!š¢ÆéF6¸ëi½_`ïý}g@Hšæ<Ô2‰4Ôµ)_b•36N"‚À’””¤Ø:`Ñd›Eç³g‹xž×³”}l]°hÄÅïƒ fmYzÖ ¡¼¾£ìÂQ+ôå/òíS{XÝfgDnÑZÂÓ¯iÚ}•ªgÖÞú­¼(îY0inqÿü¾›å¿º7ÿöÞªæ=A“NUO šÈšúúJúâs'››UqnæÊè·Ö“·œîü)®¼¶Óu’›v¶›oMÔÝòoß‹\6Ñï™öå“ÃöXYžU›iXchï"Ô1ºgëQfY'»–íÉçl¿~·Ü¤ÒïýærÌxŽá¼½6v/&½÷M®)O ʽk¹¿‚‡üaˆ/<»#ë……_ÐLB™"(àÿ© à‚:98ƒ@€:º€ à‚ê®hþ-6|nß·®Þ¥E^ÝlÚ®öd^Ê2»v—í3ƒ#KGäÝì â½Ô(·Dñm¦_‡jýžæ³sS×Å31ÅÔxƒ e¿´Ž²>A^¿u±ÎŽéÜËÆ®Žõ'I!猸ëFˆ^Fé]IcnîK8±*$J÷9ÇyÌA_Ì6Û¿®óUñÖó¡Gjf…Æ®Ò<@鬯°¥„U“phþA¿ó¤-^Ù~9òôûs•‡õšæ¾ZïU9aÏ ’²fØ> c{ÉOÝæhãò²…kÂ#jöÒ|ö¿î¾+<{¿,˜±”ºÁ'ï¤$z˜~–O®ã °›g=žCtÈÛ¿Êì&& l\´ÍÑ+MZWg'ß÷™¸Å`F ØùêCíðA7ðgwx&®±…˜‰Ó "(ˆbuØ5šÑZ÷F<ÎØîñ'šqâ3ͨ™±? ãqYàþBÞ!‰ãŠ)ìƒQ¢S(,~ EÈI&'&`b ‹ÍÆ„¹L Á`áSXò¿Ð‰¾/I–ˆC‘`¢ ÀçPØ>‡ ]P …Řm¿„ ›"çìç°B ÜÁØ2L–°l?XøúÚ¥(Ø.ùà“üÍ-%mîXt) VCÎÎÊUäàÚ±k³÷JÛËû {!Þüô‡TŸ2Í©qûÄ®äžøÓ—¸gIÃ)¿»ÜwìÛiÚñ=6ogÿ ¦•jâi`.ùý tŒG@ÙõNûŃÂ[$ÆVgž'$?yPib²³e©¥ó™±WšHWã/o§Ž1è,­X%ΘjÔ\-ÚšŸ_ûOy6ßmë/½ÆÅRV8.èÔÍ<³½ŒÖ¾`.§ší˜Ô9AÃ6²ý:ÉBïúñˆi•M.i5¹M?vðín¼²pëÒÒ°ƒ£~]ëK5´®%™U…ÏcŸJ7 ݽâÊõÖ·´4\JL´@3ÕÌASW„/ÜÀðõß'GÔÁÙE~ᡃ ¼‰Fþ 4A¿¨''† b$I,FšÈ-Òï%õÚóÙxv4DÄŸf;V/fÑ¢n8îøi*¾üe'§o_zü GU¦øVšÿüó'}®>ùm¥ûzú›-M‡Z½ªÖ¾ñ!ÈlÍo7ÕÜ/Züsî¸K•4â8‹@~-qQ˜Qž%i¼Ñ5}»ÔG©Í1;¢ø)&ÚOî8xpÊ&Xï :Ëðq›ïµ+:Èd³íw#ó2¼G=å¾iãÓµ¯¿I]©öDz|É’á®U÷‹žÙŽîÚ–À¿Üýh,ùÁ6—ÚÏÅ^ÈKü¥Š Â;ƒšOÔ{Ó¾|ã‹ÒÔo «ËX_m–0®%YíÝ%ºšnk²'Òñ„áóMsŸ4½'›…íýq—wgDóµwÛ¾•ÐÏÀŒœîÏ4ÒQñ "Ÿ¼×ô¹aGÄ5ámÕÝ¿³Ýˆ.~;ƒ÷ rƒÞsÀ‚ô9uБ©§_Œ{ŽŽWŠqfCÞqþKBœ—üfn¨C ZbŸc;äS³ÁË=þS¼"›¯™Î#ÖQEÖì=êÒŠËÇÿq$ë}¥í«7!© ¼ç\âý´Æº4­|vãAÝâÒãg©7$þôøi~ì%³§\Ãnœì±½=(~¦Óë?ÿhÙHÛ÷UÒpû©?¥R(h7f<üñ–Eƒ¿áµ¢[3I¡éãÛ[î¯æÑÑ©[ü‹ÖÁ“‰kü,OW‡’®V§Yø>í\YW”«ƒ‘Oy—›ßßô@Z¸ð×ÕKë5ƒOï`å§ü‹ôè¹ûêº}ƒW—ܳlö¼lfñ¨c÷úèmÝG§ã^l*¹ý]OjùÈÅÒ ®íM=;"Âë*9!¦ñ¾¸lµ:ŘÕà±TB2¯Å«Ó#Sê2虸 à\;apÌXöDh†Ò[jÿ6’ºÂÀCÚZqü°MHdó¼ÝXiAŒÆjê./ì˜eOèÝNTÓ'¡™Ðº~ƒúƒô©¦¯Fïm][gðÄ9VI~©fõºxQþíçÚ_ݾÂvsÁ´‡!dñÁóGQ{pFÎdýÙQãë¿~N œßÑXq£¨go}×v­w~ÿÚ{kVDÜ Gi–~gØe<«å7_ˆ¢nùÄÞ¸°iÖW×ÐìYo"}ªÞmåÛ¤6Ú&7Nnh÷Ħtù­km°Ý¯U•½‡^Y9á¾þ­ˆõì›e‡ÐWeM©:nM£Zh´šdœ†©½æ]õÛ¼‹—cJ¦=ÊÀ¯Ëx²gÌFÓ£ôïÜ:šïï;ØO#T ü…¾ûÇá3ßýãàˆ:;: Î.²¯¢;}sr°§ EX 'AÆXÈ¾Ý šË§aüE”h–8N;4($(4Ðò´0ŸÐP/Ë_d©­Æžá5ß’ÚÕ’bÇJƬÕ|mn e.…*ç¦ØÅJ((%ÊCvÜkkõê Ïåñ(v޽¼óµc¸ÚÚðg¾Tû£'wDúàTeöa>ÁŒ0 ‹¿gÕþ Õ@J‹307Ad`å››™"‰Ais##cs#4aÐc0@7ÍÐ;À.nhŒÄ rôôq RTTd4Ýo4Ë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 ‰PNG  IHDRúúˆìZ= pHYs × ×B(›xtIMEÝ;M¥Ö IDATxÚí½{x\ÙYæûûÖÞ»j—¤ª’¯}IZÝV‡Û —Ò3À0ÏáÀdæ<œBÚÉðÀL i§d˜pKÂÌIÒîvÈ…û%­Nx’ÃÌ`î¤Õa` [KÝr·ï¶TUªëÞk}罫$Û²-Ë’\%¯7c¹]²ö^ë{×wYïúxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxì Ȱ<ˆ~6F¾¼ƒ*è''C¢T¤˜ŽÊ8*ÆXyaKõ‰r_Û[Ö ælŒì ³±á(<³=W › ùTœ–cN›oº›ñÿô´ŸÌ5'XGøÙ/†:ú—úDÉOèua¼šì¡ÎÆfßã)¾ß{ô+Nò߉|UKU)ê''ßDœ„RLʨŒáDɻꉇáÙ5ŽÏËÁÎÑÜ@‹ˆôä¾¶ê§"ˆŠÈ×.{_m?Áø.ä+Ï Ç!’ƒ®ÎÆcÀ€;†&rS@†H…Ð E×ug g“ªŽ¥O”~~âçj­·NÉØÏ. ëž°è®A¸[ÑH_L£øÏ´QìJÁž£˜ŒIä°‡áôúVgãü˜ìü¿úxÁèl ’Ê×.BQ5˜óÓ_…|ÝߣŸ^BgãPvR «³ñ«€·wßôE]/qƒ@ëî|ÁÚÓq;=OÒ5EíÈSɼüPKž å’ïôD Œ‰Èž^¨íX)j'¼“N(*šº³¦˜*…4À éàùÀÇu6þ¯Àkä`ç)-UvÔ“}í\œðs迎gD¶R-þ¯ ‰ÏÈmœ4ìÙâ²}¶Øs…Ц&&qÙBä–$•X²tÃÊPõÐ:´&Fnë´ôdܬlÄT"’`ŸKÐ"è)â$’‚íbÜíÈ`Õ¿™#ì€oæt6~'ðN9Ø©Yqé/ È×÷ÐÇ‹F·\H¯³ @¶ÑO!/l­”gž(îÕÙøíÀ¿Ëéå€íÏÑskÃe!º¦r.=cO”·íÊHþ9Í¿#ÿZk¤Rα¾Šæb!åÎî~"—Ð3Ñšk¬ êävZ´) zV iHœv$p»"DA0è¶ßäš?|¿ÎƯþ@vê9ÉE^ÔUèÞ2!½~(g»:¢³%‘¶4÷껀—£¼ z@´m$@T,©¨Z1Ú NÛ“q)=Uj»Fp‡¹G7ƒ<].‹&•D[R–qužèë÷’Uв§WÓf¸g -U¢ ìÓ^Ý…¦D¶F!$²!FÇ1š"‚Ûî $À`øS}<þŸ–ƒ¦þ¥@T9ØéûŽ%¼>#/êmt66r°ã U«À7o¾&'¸ÍÇnë‰mP¬tµkBz¦kkQÏž)&îT\p=s‡ NJÑ)*+.ær{T@´Á9 UžèëBÑCÙÓ‹Y“kYQ 0®©')¢J—Ð6$r)[ã”@ —fÞC¶²\åÏÕ¾ áO€_ÔÙør°óièh¾ç„¢ˆÜ×ÝÿTùº.ò¢úx,ŒÜ×±úg§ß¼øîüã½-!¸®ZzB  Àj;°®®Õì¹bÉ/¨¦²K"…@‘ØfäVÀ‰\ógp ‰¬Yn>¼D/8HÄIÙÆiƒd]YÏå«lºq¦¨ÚèyBk$tB'XKè@˜Lìåe˜õ…ÜSü{àå:~Mvær"’Ê}mô‰2r_cä‹lr°“í‹ ýJºÕÇãç#é÷ç$òÇlÉ5÷¸Ù¼dÕq¡£Í q‚h=rn)»%®M Ü&B¨HäúäTä:ç8Õ†(‚ fÚýšÓ%ˆ:¡ìêuõL±¼A‚­ú“f“ ì¡ Ýp £ËÙ6‰ƒÐ-IäB›`tw¾W*¹Éláƒü÷¨ÿx©ÎÆ¿ŠqÈ ;=-†:;¹¯áF5”×÷‘vÐÙb!SýT±‚‘ïä·›`+ûÚ¢B¨`TºY·T»WÅ5"§­`ÁH¨HÑ­,æýùÞ¨µ¶åÊ~„s ‘6e¸‰Þ§©Ùßíééb–OÝXQM.ËÑ`BSi]íh *FCW£`U"›¸2J<ÈÑ.ßQÝÈxkþëùÀÿ3ÿ§ÎÆÇä`çù7,€IÕÙrp4ä´úx yQýT úDÉ}^þ>?¼xá*‚›U‹ßFÉ-ˆ BèÀÉ{¦PrŠm·T¨jËX× Ñž)‰QÁ Ƚ27JÊ~Ø^Ë7؆XÙ%Éû«l5©"tâÖý,ˆq‚ZÄDôB§¢*F-…ô”l‘È”ê%¤— „ø²²”a€o¾FgãïÞ,;¯³ÅHgc'ÛVgÇ‹ÎÜ]Ÿˆ¡KFòÙ8Ä¤È {=-~#ÈÏ퇯³`ƒÔÎÈmrÏ:K;¨ÙqjOÅ×ËÚ3‘vMA­Åd ºDîòœ}“K¯Ú¡×ãûŽËdrR—¢;6)g^Ï"öÃAµ¢¤…‚¶Õ t%²ç)¦©Ò°+'½lðÙÌ*ó+/¾^gãCøF9¸Ü̼»Kä`Wu¶Ršü]ÿ*†äÙá}<Žä`§§=¾GgÍ{€ïÈÓ”Õ‹¢\¹sŠçä6 KµIOÆ%{:vÚ v«‹A%Èë2¡„ÛâZ³t°Ç)RöÝ@”w‹=§ìí†z¡)çtÛŸ!;=•iJÚ cº! BdŸ•È–%Nëˆ>wSÒ ˜~ÒïÒÙø'ä`çƒ:[2Ù).qr_c(¶âô‰¹¯ƒ~:FŸˆ *ÿ¼ÓÓÙø `¨^£Xzm’K>þâšö\qÙž,‰=],ibîDûá;‚®JǶ·–dÀ-K eèß ÿÀÝI„Â5D 7+±H‚çh ­B£‹RL ©HèÊ@|ˆ»èlü èÊÁÎ_¬~Ñÿv…ôúDœe×ÁJ,/ì8¿Egã÷ÏËS’ë{wY{#X¹žŠIO;îL¼å¶ËÔh7ß*qKÒX¹x¢o›¤’§ŸÜ…Κ$§7JðN¿Ë‹‘ƒm—‡è·ÿx3p/™¢­ÿŒ«‹h+j4£JjZº®X­E]{®ˆ=W4šH_jZ–’]‘šfj´áõ’ùÞ6(öO®y¢oFÑ#rû(ÙER³{ÈÂ÷õ_WBwÙ¯4BÖ$²ŽÀED®&Æ]£“—¨ô”•ý÷ðÀ¯cø‘?»÷÷ä O8}"ŽPìŠ×-^wþÞoƒ%;Y‘M1r°“êl/^ ü«üãÙá“Õj4CušÒZn1 ]#´®V°n1JíR!ı{ F‹æÂ$½¦ÔtÈæW KKL^ôDßœ<]­ìé¥z²tsªï›Kú¾aTµ€† ,k`ÉBWÛ’ÈumH E”âªm¼(çÙvÜ·ñ/þáQß'÷uþ*÷ƸTv¯{”2 nIP å¾N’{ño jŠ)@j*–µâjQ×.Æ´áꮀ¢ƒ=íµÔh2R3j@;´°T€‘hwŽÈÀŠìîôøX&Y1»¸bˆŸ¥˜À´+%5N%ÐÀõˆlK"ë] e,÷€&WUÀ÷ÿ»ÎÆ~VvÎèl)ÔÇcÅ9‹1× åu6Î|”j€s"/ê&ú7ñXÞ ¼ Ø—Ó"„¹l îÎ{¶º¥‚ÑfPt­íEDK€rr¯íÙÉ£ÿ&Y~žjJš«ê=Ñ7˧SrEbw'{G$|¿~ògy}„J¤‰@DôÂTEÁ¨•О¡hC)¤‚²kU^ÙA‘ëlü>9Ø~×À»+©~.Vj\Fx-í,Uäà@¶ú&,?„r בçžÛXNÙS¥1{¶Ør‹…=Ú3EíÑT ’ub)¬¡FÛ)s•…íhQÂ0"í+ÑÞÐERéôB1 •LžkP ¨€45ÝPTЏ“RLKRLÛˆÞ‘‡÷÷ïÐÙø{QÞ(;¤OÄuu¬>Qçò;@¶ÈŽÊ:ä`·§Çß¼ Ç—a³`ÖÑN§ÇK…ôTì´íS+Ê*a^`›ÔhC1/®Çy×#%þŒÆƒ*PPË®¤ËÙÝIýzü~¸rN:¸]“@t¹X!Ð ¦t)Ú€ÐíBùj„ÿ¦³ñDZòZùºö3:[ pê²î6 ‹>^2r°mõ¯ÇîÖÇã÷!|{¦F£ëêá{"¶éÉRIÛæöAôÐ/>Ý 5Úäç4‰I$% GÈЋŒÛ26PÊxÈÀô¬ìví´£‹R°NŠé2¡ýVŒ>­³ñ;’·SN;ƒ`úë:“ëlüã¨û œ´íùÂ3öDi<=S HÌ~Œ®ü$ɲٖŒº¶¥K!Øân8·$ÑHÑ*åmD ŒÐc%î@e—vC´îÚÙãí%2ß©ç ÿQÿF¿ûuÔ| ~Ú)Üžˆì…âw „-®VüP¯¶ÃeºÄc£ôØá™1”œRNSjÑEšk‹|íêòWIÓàn’PUùR ö·Ü¢ü.a@÷ï'_â.B‘ÐÝ-ÑЫцÛw×7j£ŽÔÓÆ(§ŠÐA‰½å]•ð«<½ FEÛa==U|©k…hS–¥èvåPuèÕhÃ’ŸwP:£p^íòG¥° ³Ž1ÛóÞü:ˆ/ ‰©¥'‹¶‚PJ64“6@¨ádØ‹ sTÙÓŽ8\ÞÛÝ}ëˆÎx*2–†Xo›ëLxÐD–Ò¥@;A™P+B@Å”]€aé¢ßãÊqR‚ÕvÎõDßZ³c"í!ô¼õ]s´Ëbúl)Ò®L äÃý*zÈ„©¸a†½ëÙäç=A[’2‚w¼šQl†rQtΛåUcÁq!yf¬ =_“ÆÙ)¬ Su„ ¬ô²ó¸–©¦TG1Ñ1#8ÜH%iKlÓU=.¦¯Áq>9>H~õO›ª‹Îf`º-vg]‹DÌhî÷˜‘4ã˜IJ6ȯÂó¸4\w\HŽ•4‘±u{Ø©ºÒ*Ïîɾ:lOÉïùc$‹—f$ÙRM„.ñæx‰IZ“ãcEíÉØ¬aÌT]qUÎî±âÑ•6…‘dÌH]H5)ià-pUýÂÊRòl)ºf¸~5Œ›ª‹VUã=”Ô5åÂĨF:£¹>9 ìŠ®çóôœä‰Ô’gãP;ÁÄ ùâ~®ìB 51‘€—¥”W/Ä}{Ã÷ ™ì51šz’K-9íÙÚfdú!¦ì ';ŽT—I÷£{¢o£q;Ý=!PãIíåMm³•‘½< û-¸kGê(#ÝðÄŒ¬‰; j „z+Êa³7Ne)9›NòËÉ`d×[l¤ÕÕ±Œ¸;1#nì©&[ì å@ñ6ÈÉ·²aæÅ º%n½­7£ 1£®.íuÊ{z·Ò‰é‹o]3Ù†®¸Yn™b.`­Âœ‘ªIŒ•áôéÉëC­xÛ ²¿‚N€Ž¶) ®¸dASá—«3súýÌäcóXk=Ñ7ƒäRm`¤Âyà½d[mkߘPM•ÞÐ…ï+Š7 1Ìf×[†YA—]‰Ü¡'Á5NA~hrfî;÷ß+]#®qÿ&›÷D¿anT²[2úUP©ðûÀcW á•@ŠvŒ±´3D÷¸ôoµ‘Q¼mÅ"7Ì :®-¢ÉšR«¾ðçxîhè²ïÑ9zÁh\-0ê’f–«k}ð¼ϲÖ=a ”\"Õ4’ê{_ñ¶´-=Þ†ìCÚƒNKCºfØÞ7¤WgæþgíÐt89ó¤[<ô%ìùÐ=Ñ7mªYõÁiP*|z•W—Ëót-2‘qânrð¾²Ož)ÞÆGRñ¶£2L :íÑÒŽrÅmµ/ ülþµ˜L¿02CnFéI¥LvuC–óýð¹+R(©%¶Ë71|_­x+îè-´ŽÎ°(è´+¢WÞ”í¿P}t®V;4Vgæ´vhù(žè›>å¼0WEµN(“4€‡X«A…ÆÒ€ñ4¸IáûÎU¼m¾Þ|€v1ô®Ødô Õ™¹‡j‡îPµÀHì¦G'/ÌÕ%Õ:©ð~à®Iô’³7ÏGìdÅÛÖýæ)è,MmÓÆÖ°¤ø±|ývã¯dÚ®|=ê¾öudÛmî"ê(I9íjs»½Ã-¡xÛlÜ, !m¹ôJd—[Ú'ª3sP»ºP™³8;’Ã;’f¨µA® UzZç×€WåE’`ðfí áþ±\ ÙŽ…xeŸ<ÐN0ñW‘^÷ø¥,»†±XªÛbtYšv^zv­ú›ãË€ùÔbQ­ŒÀžùŽðè}¯®5  §5 ÀëFžßé`=.['±K¶%|¿o[QÙØn’ÐÁâØµjaIÈÎT<´ëÃs_p »><§Ý±ÂH¯¡£iš5Ò:F*8­ójày_@Q ˆÎÕt¡TÊÛönµ'7·¤f³Én€”†k‡£º¥ó–Òµ'dYë²3˜5 4 î€UÓ¨F´–”™|lnd‡ud¯dÊINNòøUàoÉŽ:Á‚Lö N·ˆx^ñ¶äÛFZB]–~£qÉE¼±<óÔ¢V~óìH“|¤‰5¨°R!!+ÌõC¯l]Þ•F„ ²$÷Š·­"ûö(è=j¤TòØÖ‘u2ú(¨ÎÌiýБR3ê/·Êñ×À¯ä“•æFS•JzÑtÓIîo[Ư(è6ŸìÕ¦Ìà€TßFÞR}lnpf²23ï‰> ^]çAO‚”HwY©®¯£›ìÅ›æÒ½âmûsö±-‘Ë:TÒÎOLØ<íûðgµûï¥öòé1ŒfG¼ÅmÀÄ€øŸ~ެ1PŠÙÛklÊ]X^ñvó,õRQnÑ­¶ÙÏa˜§|ï«ÎÌ-/½òŒT?<ç‰>4^} h^Ô â·OÓo;p;%WßãðŠ·›OöÂ&)èÔ-ssQwá÷ÿÝ׸?ÉþÖ`ƒd ÝNÁxÆ×©0O~n08½Ý;ÉæoÃÍSЉ6d¢M'ÙYóßü¦7?¥µCÓ2ùèÕw{¢WϽ öB#> |,¿=ÙÓMoˆä·J·QÈÙ7£#q IV1àCÕ™¹ÙÅû˜êÌœ.½bùä'=ч–ð u)±LÖ\¿@I÷R°õ ’Ü+Þ†ì7¨ ÓKûò?þ–_È!ú…o™`òѹ5d;ŠèyèؼAÅ~K({{휼z$¿5{¼ ;6ÞƒN\M\^mwÀoT?2w¼vh:ª>6§·ÝvÛŽ®„®!þx­àŒû›]û ôZ—0æb˜A¸îÅ0ÃêÙ3¹lv&“Ë^ýbGE ôŸÌ9”½(Oô&Ó.„B€:çt×cOí¸¡Úy¡ûÅÒØH*Ì¿Œb™°"W»Æço£ä¦®OA§B—ÓXö]wî{ß‚bÄTÓ€`ÇÕÎ]ðk#e¬Öø†/ÕÏMœ×³Å=W¸ZYQÇbêÅ0£gÉ––«™.Ê®5={¸srÁ‘ÝT}tî[k‡¦ jžéY*}rGÙÁ$Gª‘ùM(*û{Í+èÞû$÷Š·Ñ ã¯ÕƒNp5Y¬¨¾@”tòCŸÇŽÛ;<;–èý«œm§ªü>ÊQIö¡\ÚpàÉ“ãc1^ñ6Ê}µt‚c‰ÏAø•ÊÌügk‡¦£Êcs®vè^výÚS;vXv¼9çj9 NîBôI÷ÕãÔûW‡ïjYJŸ+xO¾Càh¹šé¡L®ÎÏ]CN¸g¤j Üi;´Lˆ%ÝÎ1·¼G¬dJ¶ªË¤>…ðÙ×½ +Y' Vj©W¼í,\ª S„ÕšTP~¢üksuœí²ãI~K½ïÕ¥‚Õe~N&“§‡(šH-õŠ·™³¯VÐeÿÍj›¹ô™èj¯˜ª3s.(ÜÃqK]* K@vx¡«©¼…É$ÑNPKOÆâo;˜ì!RvBHMô$Ô3Òs ¶þŠT>4牾£f:œÔÑÊ獵ŠãÚöŠ·Nv )›Š—@~' Šÿ}ןλê£ó8ÜJæ‹`õÎɹ®Šökªäž]¶pyÖÒ'û® šö04}Î>‚áúBÐÃ]ᘪä^=¦DP‘°ùòçáÚ-OôõæYÈîøT¦:ît1Ê[ÉÌe%Œ÷º˜ìÜŠ»,§Çƒä ž|õ§‘ÔððûìIDATX{yD÷ õû§_693×KÅ…“]`é;3„ßy­¤Î€ì¿¨•ÔóPþáN­E§Ó?ÙÛz[I©£æ!•r¾8x Éû[hχ•k·’êŸb;#gQöŸ¢øE¶Û‚ Ð UøÈΓÅî<^= ÈàÝ~¸úlI³°}}  ª¦l•P8ðú¹!$y›†}Ö(é ¬ë{cí«e^`“ÎV?ü”C5œøÈK¯8à‰>Ôs_Ë/\#2©Öù7ÀKPž;16>Î×òTLÙ­Ýc¨HîNÍ÷ɯ+Š51a¡à{j‡¦ï®ÎÌ%µCÓÂÓw{¢ûÛäd·Z§ ¼˜À(ÔÍ’vMy#F%VžÝ‡ï7+Š7Õë#ù B&3ù÷>?·DE&ÿâ“;N1·cˆ>ðæf0í/þMõw'Æ.ÙT»²{ÝpàrÅÛFÿPb «æò•‹‡¦¿®òØ“néдTfæÑ—=ß}èPÜ•®Zç^àµIÅeD/Å7z‹¡TÒ”¦gÜM"yfúLb¥zƒ5¥08ДÏ5ð½úŠÝfrfN‡P‹ZžèCåͬ‹L/^$ˆzœÐV0Î&ÜÀ‰a2¨¤ Õl;ÖV¼mxÙ"·¡´ÁqíW×uò_$(z¢&É.H´ÎWoÍÃôô™Ò©È&TÍWöÙ+iד}=ùÕo'{4¸»-%ëÏð@í•ÓåÝ3O‘–Ú+§=ч›7²ÛYd t‰x#0XT„ÜÙ¸ƒ•Í4»LAWI{>Œß–pýjŠ·[¿PÔbNôè߉ã_T£ºCZM<Ñ×%goóõÀ÷] D–t)ÚƒJ°Éæ×÷ì‰øÝ¬à\âm£³(RÀ $Y?àAÿsõWL÷÷å©í€ üH}•Ô5Ð&p,ÿs”_¦‡ž-ZMLŠl:d7åÔŠßzÛ\’ç[hé3Æ®ÊÉeÓí?`\V®^6¹“øj§|7ÀÒ¡i©ÎŒþÖ‘Õzé ;WJh×ïÍïlÛ$ûw•%÷ùò8F£-} GÝ-¢‰”½‚nHÞÎöÉoh m}?¯ëê²L‡=«®Ó¶@ Ü0uXNa‚êÌè†ñ£ëÑû-œ…@ëì~>/¨VMâ’.EŽhËŸ' b&œJä=ûfÜmÉsŸ.¢|Îd•ó«€ù©êÌ\ aufŽÚ˞뉾­öÐÈ{À¤Lx˜¸è}Ðó‘ÑfnË[*hÅLXõaü†ËW¼]?BB ó»ÚVþ$ÀáÚ¡é/C„Ú¡B{¢o+\~:­LOë|Ù¾¹¼O??¿Pp´»Îƒ,›U@ª˜²u²ì™{Iäf(Þ6ò£ íûªe€÷U}2Uý"=ð2rDׯà©ûÒ‡òpÝ\d6††Ö¢€ÔŒÝ„Q­šJšú­·ë ùæ)Þ6’.X‰Ô]BôþÁäQ;4ýTgžìÕMéˆl)¢çWм=T€¯Z3\ B­EÁ¶yóKÍG¼‚nÝØ\ÅÛFš1B ±ÆïP Ìh–ZG†èz!oÕÀH…T—©¯Šk½•6Þ6Âä&Ý+èÖ;J[£x»n¯.!BHp…eæyµC~dò±'SÕ,’¬šöDߌåšvÍŸÙñSÀó®`@=£vP½‰oètë ×·Bñ¶‘ð=Ä’^áEZzÅô®êÌ|R;4m*3sè«_艾é!{ „¹7¯ó"²ÜŠ:’èR¡;7¤zÝZ¤ÚjÅÛÆ˜P‘Aé]á÷Šò“ù+€Zýœ'úåçýRȃÀ°ÆÁÓ,lÜ…b8$·¤zÝj’oâmcÏ©%XÓ«÷gì»ë‡¦¿vrf.­:`&{šÚˆ4“z¢kmpüÔä„)pÿŸ_Hµ4u9¢·“üi«¦loMQÍôxÛ®<=‚5ótÉßàNÍû¨ÓÚ+îfTÚ‹ =Ñ¥: »Ó:û€Ã™É`¯÷9=W4bƾ­·¢‚îf(Þ6‚ h¯i[+xEíÐô·O~ø3Цúص(ÌDè>Xûá%Àÿ–OÄÚ§Ñzz¦Ø!tÃÙžùVTÐÝÅÛFf&¤€ k]r»+?P;4]­Î̹Ú!ºoJØ®¹0QÜüÇ«†{§ «K…½y!nxMêVQÐÝDÅÛÆòtzÙ=»WZ²pÀwßÒ½Q8ìb†ýédhåÕd¸ôŠÏmQ=[ìbPÑý­ »™Š·<­‚tb—uühíÐô핺ß8V _ ü8ÙAƒ+7òJwº¨„#£SÜÙ º›­xÛ˜O/r¹âžº!; ýÏ€³Ê£_xÙ´'úuv}°Æ­ïºæó hjzî\qâ’+‘‡Ýçí<]¦xë‹a†g m½^=»Zùj܈r7ôÎÚ¡é;–Pò}ý$onB5RÁÿø6²ÎÁUÖbÕ … ¢Rb´nIÛY º,\_N†H s=]A ôòèñjoi}ÀëD‰ß˜ZiìÐM€.åtV¢üùžnËCv¹ZЕÎî>¯§ã=tD<ú¥a£ ,¹zjÊÄH½A¾…F‡FúLà°TGŒä+T=/ç4aÏ5ž¿KvÖâ^…§DÑTÐ=CXœ*®5̤B¼ xnþœW%9HKOÇá…íW ãGNAw±âmtI¾2 PT»ŽO÷ëEOÎÌ9„pÏÌ‹‡îñýªöÒR Åqø²³æ×ìઠçÒ?Ý¿—‚UœŒ~×¶QéA·"†©Û†¡ßB[ode9çÎËÞu|>Ésöo®ÎÌ}¢v耩ÎÌ]5xh<ºÖ³Þì@$(YG×Ò5Ižß¦fŸ-u èéÌ8 ºU$w;ƒääé„ìÁpzuÌx¯®dILô…C»†î’Æ¡!z^€ ¥BWë¼øæõ›«ÏŽUòýÏÁôQPЭ(ÞÐAòÕT‰µ°ŽÈ·ÿw_Q;4}¸2ódw?»¢Êµˆ&.¬ìœ¿…µJ¬EQ´œ¢gʰÃ¥+ :•€á"{¦xkŒ„âmƒc/ÅjQ×1ojº+¶¶~è€x¢_a¨¤‚ÓeöÕë Ýñ±R~AÃÎì¨n¨˜jš]Ù<,$ﱜUׇ^ñ¶Ñ7„w¢ÔYÿ­}ã ÅÛwÏ|Á)Æ}C¼>ߥ’??ÛAµtgBªA5M1C°Ïžu†IWU×wæ˜+iåo¨ëúž¡õúš®/l9©Ípß¿eEAWM“›FöÅÛ(Ša6†¢šë¤¯x¢ovþ€;^* ânãž—’}{ÛR¶âmÃGŠŒ¡t‘Ñ~×&z~%ò©’Ý1•öë#»Ý–ÝJ·Fz<°·Œ'_aÈ®#|÷Dßäœ,t)Ú{ }5Ù«¦’ºÁÖ›lÉwŠâíF\JQÃQ͈ÒEO¬¸[ðöÒ‹{Ð…ZÇm2ýV+Þ†±ÇÛ¶æé„(n”Ã÷%º@îD\ •[û’ );dßd’ï ÅÛ†U ¨b8?Êáû(½:ž×Z!F%¸¥‰ÞWЕ-›¦ ËÂõúŽS¼m<~ÒUÕw%Ó¶eç¡¢g íâï'¾¨Ýè´#MûL x’ÆDй0Ö{ôm4ëô|¡MϤÞ/šÍê )èòo6»\¡ìÇv0.„Œç`4¥Yf4‡ew¾X%•Ø[áeñÎÆtY·Kð¡ÒÅ“‘"ÅQ ßGè°XZaÀ™PЭÜjšànÉ-´õ0Åi{TÃ÷Ñ¢J_ ·XPmêóóu‘ýê º•[M=ɯ>ª1*@Ë{ôíyâ®.BzAÉ›ãºÈ¾¶‚®OçìVSëI¾ŽA58B:£ŒÚÓ6¥«õ(;Ðâ±²_® »\ñVñ$_W4)iaÃ÷Ñ"z®…Z ‚»ÏG…ì+ º@kX!NÛÔì i~W­'ùzØR ¢tGm¼F‡èYå3¡%Ú Ç|!n£ÖÿŸ¡b&­HISmˆµÏB*åüž1ÅWÙ×åj$¤p…;Ô‡áH-I±z¡ˆx›»*¹W<º UÕIê–L€ã1בH¿S±(3¸—¤ß[Þ‡ñWr6!=B²K™Ä}K‚PmV— ]7áýÏšä$'­¬žwçƒÔž JÚ’yB~4z~ú'ö¯ ÑW»ß”Ðþ'íÈó\]Ú”"ŽÝÈà_¹xÁðè3¦$!V»è(r%ît9W‹ªRt>мt”ŒÜÚ”Sn1ÝÙ íº<h©ò£ÅùÂ/Õ{ÎM¼ý)Ðû½»ÿXšÉÁt1zM0®ïbíq\2æ&¥Çm>=Z 9¯Ùê>Gßl¤$z¡°œµ›ð4xqKÏ-šÓɓљî_/ôþ¶p{z<Øã:Ü |P½½rtþýÝ=WúŠtp¾Í.ˆK—"W:¼ðˆKÜ~„J‘;Í^ÝNÛÛÂ/±ç‚ÛÜi3ƄުàÕ‡ï‘ ‰Fi4FƒèÚ =ójû­JæžÁâ°š’jÛ´ÒgƒS½ŒÎw>7“ÏF·¹³f?°›€.ÂCäËÊÍ¿F­tëG˜ÊÑy—:h™¦sô¹h¨”XpícSÆ‚néðÂkP¾å8º{¥¢·™»ìþðKm=xŽ»Lê³Dô0¤ÅÝrÔW Š­‚\82ÆÞ5=½P(ìð°]Výrô4H ´i]MB{>hiWöK wä…¶“Fù4"o/?4÷û#"©hãÁ”^|©@ë‘»0Æ8k­k›ŠJ‡> |KûØÔw?¼Kì•q… Ý:Ú‘óº,cÚBéQV+)ƒ ž}'S]¨±HˆìÊ0OôMÚT—¢e”ýˆ**;å6Í _`@DÑD–µ+íHÏ5ÕšXW3¢VöH ‚aRŠ ŠE òEïï€_/OFð{ `Òòѹ¤qdšò{Ö¾ÝsìuÇh›¢tx!i›2@X:¼ðÛgÞqçï”Ëá ¼ x> 8R,±„z‡ìVØKJB]Ûâ\S"ºôH$Ò”Ëø5®ÆÝ¥8 ßÁÈÈ8Ñ z*Æ,Bå»ÕV®rîÛ¨(ÒÕ©6Mª)¸†éhSp IEd£€d)‹¢¹ä%;Þóð!àÊGçO4^ww@`Ä™¸W}÷?Ñxý4凮}…oéðBŸì®ùð]½ö±©P?°ðŸÛǦ>¼x%ÂsK€%DØ%ãJPVP½ mƒv¤G´ Ú§)ã"˜AÂH^k}Qø.PƒŽÆb6üDÀJWÏÄ…¼ye‹J>aÕÒÔeÓ³ËA¨Ë‚¶%pMƒö$£{1™!f„Èþ X²›;»À/*ÿô L7’–ß3§­7ÜÅ™×>ŸòCŸY÷ƒ–/P{÷s)Â|*m=2%y8ÿ4ðæö±©ß^¼ó]ùmô)‚Èn‰)é8B“.hOЮ4é`]G”.ã@a°¸BúÑÙ»Ïä°»8OÊ$ ¿®#ªèRa™Dö»áÛ/¦¶æävIb­™Ž¶¤¬])jGD­ŨA@ º ®œ{V2yF1§Æ ðþòÑù?¨9à&ŽÎ'KGî¡ydš±wÏmèÑ«oxfÊZ:¼´™ EJ¯yúñö¯O=AßF8 ¼4ÿ¶.PPtEc7N”½“”5!%‘C"mK˵q4¥ƒ_.éá2¼óœi D *Ú#”#Atw²ä†8l¿T‰–©Ñ„D—eÑ.ã–L ]©hŠ!‘J±Ÿ¿®*¦­•ï%9¹‹À,ðV”?/?<ßʽ¸”ÎÛÓGÐ:¯#—WÓ7 ñƒÇáÁã´ß;Eém¿w XJ?´Ð>Þ~ï]†ÊËw‘‰G’ܦäÊó‰ „ù"³/˜PƒRÔDλeI´!!]v!—~Xæ?/ȱC Ëä°§ÃMtmÏÐ3wQª°]úRQíqÁ¬;oR×4“Àmù1’äõ©ܪïøyï?:_ëÿeýõ÷P6=£oyÛÖßÃ]z`}ÛóiKB3¦uì.ƧôÀñðÁö±çþ˜Ÿ^»ŠÒrÍE¼oƒÙX¤¨»ƒ¢*»1ê8«M ´!MmÉ탭»á ß°ÚöýƼ¹=^*c2Ï>$!ºº†9å.˜’;´5åÎ5 ðFTÐø/à,}z®qäž0Ñó VˆßóìöÛõÛV {í÷Þµòõ±)j¥Ã ´M½x?ðÏ7h[}¥=°O* Ý ´´#g´!±.‹QË.tpe…ÜL•"É(}¸•q‚º“¥v¶ë6ýÌþ¯¬–lQíHËžÎ%ŸÎtÿªØHþ!ºÓž v©ãÎU{źÁå¬ð· /.ÿ·*ÁBãÈ`‚Ϧå£óº|ä•÷Ìßôi)=Ðß¿‹Òá…VÚ>6ŠÊçK‡¾ xðÙ¼ˆxå Äz—WeLb}ŽÙïö÷ÚrxÀž ö¹sRÒE,™îÜnóaÛüu\%ö}CèšsºÝA¸Åa{×Ñ#E4«]±vÑ,kÍ\Äbtf0bkU‡eïÏç€GÊGçß›…ç ÆÙdâá§µqä˘8:?tÓS:|<ÿjŒÒá…´}lJ:Lâà ¿ü^û‘©7#¼8ÀÅm’å:æf¥žïr› ¸]v)Á§guÙ„Ú«ÊX1šâpß»u–£%"ž¥ÇsbùÌð]óUÜ€ž(9Œn^Ø®«â˜¾'NikGT»격kCŠvÑ´4‘}ê8r%š¦v㦣yÞßw}xÌ8ó3ã<Ù¬™ŽçÊÍ÷j¯?€¾úNäèSC–/PÿÀHO4~ÝÓ½ö±©@ RzíÂ;ÛLý2Â[s/Ǫô$¸îåXV£²O&©(‹Ú¸Žtµ%$ ‰)ѪZÀæ‡ï±ÆÚî]ßá#ºäùx ØgK悾ՙuV@Œ:íHݵMQ›ÒÓ¦1nYœk˜e¯ e)”h’{’I›//Ð~“LÑö€Æ‘¡—Xgh¾þnÆšg”PùÁYþñð¬I‘ö#SQéu g#ícwýÈÀ!2}¸»ôñbÒ+BŠ*ì"SRØ£z´´-‘v¤§] t%Ñ”xÕ6Þ Wó¥(¢¹dhX½úðÝåº#KC—¢Ý×9tËU H ¢NšÚ§u“¸–ÄÚqmQmK(’ 6$ÒˇÍYÿ•lŸ9Êÿü[À¯”΢OpÀ–Î\{¢µ?¸°ú½sý¼˜Òá§gïk›úmàßß‘îê[rëÍ•eU¥Ä¡Xb ±”©jJJ—®àº(]9§m)i— ».Šð®oï>³N£» å<6—ùz¢¯ƒ­OUOÆŠJpM’¯©M®D3Š&²ä–Œs5#Ú”B~PÄh*1:–)ÑVy]Ãxn½Ü{EÀ'€wŸ(o.>x„"Ò'øVî‡ß,äÅ:§¿¹Ö±)”Äàé·Mýð­d'ä¾6vܪÅðF£BYå8ÈτĊT-=‰4EéRw-I´-†.“ƒ¶Z×CzŠji‰'úºÑ ¡’†îDI¯Ø»lµßî+ÑŒ¢-9åΘ’] ºÚ‘IMDÈ 3`(®¡DÛŠ©±¹/fy¸¼ô¿—ΟÉH})‘+¾û º|äGçwÉûÅ:ýÀ´Úã¯{Úµ™¢óÞ)?°°|¤}lêÏsÏþN B&§ØªÝ Íg&ˆ)P`Œ$(k¬CÊ¢6ÑmmÉ>$ÏëÍ%Vw±Í€‰‰\sÐ{Ïýšs!Šá¤.æ+uîŒÜW3‹vÑDî‚1Xö©pŒ£«Š/ÛwäàÒ0ý-À/•Ψ¾‡ 4L<4çÞMý_ÊÄ»>ÏN†ä¹{óá» GñµÇ]çØÝ$ô(^8¼¯ýÈ]CäõÀ7)œ_ßLõå¹$ T¥äÀQÆÑr-YfYB×”Žê%[¯“>`ø h艾˜{ºªsÅP¹<2 5{.HÜy“¸†©¢Ü>˜´ÕÛ)ÛBõmðaAdâèSÏôÿ²qdšòÑ9꯻‡åžfâ=sÜJðé¬XwìnRRʇOÒ96E|xÒëŽ?üHûØÔ/ÿjU±n{fRsºö˃†²©èÅ(©ö8éêRÐe£$ì½ì©‘cºì‹qëæº;Qjce@בEw.pڑݘ5žûæçFøÀkÊGç?ÕøáiÓxð€˜Èèø»ž¤|4#vå‘§¸•~zðuñ\~xæè~4ˆEŸ{pá[ÛǦ^ < Ü{³’üÿ#)rG°Oa¿…”s®aÐeA»ìé×x¤¨M·h†2xšÒ[ˆÄL%ªJ5ùÈwç‚=ìÙ°ÓçbpyMÓ1\§š„l»ìmå£ó¿~á _.‘톢.™xøi.¼ú9ìºsò" ©Ç Zï{.ñé*æmŸ¡ýÞ)A K‡’¬˜7õ£À ææo[­ÖQ Š¢œÐ†\CZÚcŸäÛ&?6ÿlí{˜êoÎ;OôKÐ>ö”ÿúù¯ –ÞÒÝ¥âÆMÙ9³?5bH54+¬ ’NrzïN¤õ#ŠIùè¼[~ã4®ë¨{ʳyè¼wŠfö¼iö±©!,=°Ðm›w09\…¤¬¨§©(B(eU3®Æi›_/_ˆ>öiï _BáÝ_ð»æø½í‹#ùÜ;7È÷ÃY<ò%,¹ÇOæFüG¦²ßß=EûØT”÷±-;æe>t¿zÿõv ß~ Õ2­·í[™n¯ŠV~JëÞCåaïÁ7'›ê÷²•S]Q>YÔ±}žÖÝËØûŸôéáááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááááá±øÿ=“Gû^”ªIEND®B`‚haxe_3.4.4.orig/extra/mac-installer/scripts/haxe-postinstall.sh0000664000175000017500000000056313166552354024620 0ustar andyandy00000000000000#!/bin/sh rm -f /usr/bin/haxe rm -f /usr/local/bin/haxe rm -f /usr/bin/haxedoc rm -f /usr/local/bin/haxedoc rm -f /usr/bin/haxelib rm -f /usr/local/bin/haxelib rm -f ~/.haxelib rm -f $HOME/.haxelib ln -s /usr/local/lib/haxe/haxe /usr/local/bin/haxe cp /usr/local/lib/haxe/haxelib /usr/local/bin/haxelib mkdir -p /usr/local/lib/haxe/lib chmod 777 /usr/local/lib/haxe/lib haxe_3.4.4.orig/extra/mac-installer/scripts/haxe-preinstall.sh0000664000175000017500000000030113166552354024407 0ustar andyandy00000000000000#!/bin/sh #ensure no conflicting version is left there rm -rf /usr/lib/haxe/std rm -rf /usr/lib/haxe/doc rm -f /usr/lib/haxe/haxe rm -rf /usr/local/lib/haxe/std rm -rf /usr/local/lib/haxe/doc haxe_3.4.4.orig/extra/mac-installer/scripts/install.sh0000664000175000017500000000057713166552354022774 0ustar andyandy00000000000000#!/bin/sh cd $(dirname $0) # haxe chmod +x * ./haxe-preinstall.sh rm -f /usr/lib/haxe rm -f /usr/local/lib/haxe mkdir -p /usr/local/lib/haxe mkdir -p /usr/local/bin cp -Rf ../haxe/* /usr/local/lib/haxe ./haxe-postinstall.sh ./neko-preinstall.sh rm -f /usr/local/lib/neko mkdir -p /usr/local/lib/neko cp -Rf ../neko/* /usr/local/lib/neko ./neko-postinstall.sh cd ../ rm -Rf /tmp/haxe haxe_3.4.4.orig/extra/mac-installer/scripts/neko-postinstall.sh0000664000175000017500000000131713166552354024625 0ustar andyandy00000000000000#!/bin/sh rm -f /usr/bin/neko rm -f /usr/bin/nekoc rm -f /usr/bin/nekoml rm -f /usr/bin/nekotools rm -f /usr/lib/libneko.dylib rm -f /usr/local/bin/neko rm -f /usr/local/bin/nekoc rm -f /usr/local/bin/nekoml rm -f /usr/local/bin/nekotools rm -f /usr/local/lib/libneko*.dylib ln -s /usr/local/lib/neko/neko /usr/local/bin/neko ln -s /usr/local/lib/neko/nekoc /usr/local/bin/nekoc ln -s /usr/local/lib/neko/nekoml /usr/local/bin/nekoml ln -s /usr/local/lib/neko/nekotools /usr/local/bin/nekotools ln -s /usr/local/lib/neko/libneko.dylib /usr/local/lib/libneko.dylib ln -s /usr/local/lib/neko/libneko.2.dylib /usr/local/lib/libneko.2.dylib ln -s /usr/local/lib/neko/libneko.2.1.0.dylib /usr/local/lib/libneko.2.1.0.dylib haxe_3.4.4.orig/extra/mac-installer/scripts/neko-preinstall.sh0000664000175000017500000000007213166552354024423 0ustar andyandy00000000000000#!/bin/sh rm -rf /usr/lib/neko rm -rf /usr/local/lib/neko haxe_3.4.4.orig/extra/osx_installer_template.zip0000664000175000017500000025776513166552354022072 0ustar andyandy00000000000000PK >C Haxe Toolkit Installer Template/UX ‚IRaIRõPK>C)Haxe Toolkit Installer Template/.DS_StoreUX ‚IRaIRõí™ÏjÛ@Æge·‘û'èêCKÏNdCRèÁ’[A†šÒJ–‰De­°¤:EuëJÞ¦}…>A¾MWÒ¤uÇ!¤$ÌϬ¿µv4æ™]­ ¬“º@T(U{ Q±AA} “çpè¯Þ-ÎEAÄ ÃJQÏY÷ ‚¸ÃäóGm£NKe8® VgÎÑP9juZ*Ã8µŠª¢j¨µ:-'-†›†ßÌp‡Â4TŽÚ¾”e‚¸Sä{÷§°6ÂàŸý»‰ü¼ !IJgËcŒÁD0WFõƒÃê‹aTdRNޝ’k(º]7Mú?ý¿ŠŒWÈåþ·\‘7ã±R¼¯‚‡¹Ö¡)cõ¢­Ëèq9pdÜ7' ü8Ñõ¦Tª÷µšúhÏ]1îˆ4tãW–'Æ–ï{ôºè'v’Æ{TŒ¼´ÏÁ~Oˆ@ö÷1zÏwïö$Ëž n4[“Ï67õo5·&“šªÖ´êÚ³;=;û8ùô¹¼à§(<žû%]äì½5 @9ý¯Êª d …7o¾ ¦tÞ4õUøzù*,q6W…Š<šB2ã÷û5ø­g™¡› n¶Ìe—=÷;½Àð—¿&æ¬ÑúO·˜r5ƒz¾ÿß>ÿù?A·VíZÝüy x†|­å²½==–ß°™? éF€ ‚ ‚ ‚ ‚ ®ŸßPKdè 0PK >C __MACOSX/UX ™IR™IRõPK >C)__MACOSX/Haxe Toolkit Installer Template/UX ™IR™IRõPK>C4__MACOSX/Haxe Toolkit Installer Template/._.DS_StoreUX ‚IRaIRõc`cg`b`ðMLVðVˆP€'±ƒøA L…VPK¾CŠ *RPK Y:C=Haxe Toolkit Installer Template/Haxe Toolkit Installer.pmdoc/UX ™IRYÉCRõPKY:CPHaxe Toolkit Installer Template/Haxe Toolkit Installer.pmdoc/01haxe-contents.xmlUX ‚IRYÉCRõí]sã6¶®ÿJ*÷“LÒ39ÙU{v•¬¶:–­ˆ²»kßtÁ$$!¦$ÝV~ýÁHJêÎÎáû*ÉÉìäÂU¾Ð€ø\XXÿY>mÿ–Ú¢ÖE]}V•:ý×ç_}ñÕןÿ×n>+þõùN½è¿½úâï_üýo¶zùü3û¯Ï?¨B§OŸ¶ý×çU­6›Ï?+=óÍ·ÿçÿøÿê}þå}¥]õeüÙ—KgÐi]}yíKúlmmþdêÏæ…Gó\»/?®`ÿ¯Ïk×èÏ?ó%mL®»†Œ¯G·¯§ÉõKý?·âÕ«¯¾ýöó/[$³éÿ«Áí/Ûøë÷ Uü鵪vê1×_ìê}>´Ý¾ø÷ó}™¿J}¹iÉ‘sêÕˆQšêª‚¸+?0ÎXEZí噪êy­ª­ƒª¸1Ðï =tŽ,m>¸úá[©"³{¨E®®ÍÐ^2:Ïæ~¢oµ»±ö©)¡š~Ûìµ3)UJÿ™Ïû-žèÇfëëÚ9Ñ?6Øz{b“ƦOØznjý~Ó”½ûðõÎi•ȵŸvàµÎ±µüV«§•ÞÀSå'3tÛ}éÐ]l–7Õ"H¾¥ÿž‰ª±Ž@Mì»&‡Bí 6­§Eƒm=<¨\lÓ•ÞBÀÆ»¡'³?–†îÐ+­rù9<'U8-Í£ÉM}XÙè”ÁèSR¤½÷’Šª-ørüþRjWM«y¢•Kƒ@³Ö/ƒ{®e4^¸Dç^">àØõMm÷áÛ÷»üøµ.á`ÔW6‚ZÛnGÅÆl‡Ôwúðh•Ë.ª~a›J_TBR«­«²n¶ÀOÁ鳟«ð(#«²ßÓÆ¹á¼ÌàŠœãý×dºzªíàc,7e~P¸n©™u~ıUÝÃk§Šj£ÝÂfƒ‡üø™¦*s5|?”ÞORgÊúÁßáÝìañÕÂ>lj^™z¯0©7"p1¶¹uI©R¦^”+ïTQhìÂé©—W2SlÙ–çºÈùg”*«¤>€2ehâØúuÌl·glÒ”¥uØ&2‰øîQÔ<é·–Z™”Ýg6mª‰a>}æÔ^ߨGpz¼v*3~Ç\Jð¶äT¹3)¶ÇtPœ”33ür|†O‹Œf»¦ Xª»+œ‚~ÙûkÍ¿5…,cŠOv*ÓŽþîÄæ†ïö¤vö‰›akgT±Í5Üñóó]û®”EŠºíæëÔX7Šðy÷åðQÑ“ð8Íéé=¿`ˆEä”ßìž5±áº´ymºÞY¬ŸßXSÔøõf9}}Éœ>œÇÚ±ø»Õ¥ x·º  7þ`KR•kX$¸±²ȼØXðêãÊßòÀc-H“" CÔ­’)¼ÐECbóZcZ—¥yÑyR¨²DƒåíE³×ãÌœ$õwpŒØÁ3&"ðæ±yQ6Ø6¹7{CˆÔR‰ØVSس°ìÖò^Ì4ð• _RQãsÕÔ5ZU)jibc÷ ¬A]¯&83ÊÍ–PÂ´× ÿ?óiß7 Ö9ÛçúÖº'tf¿1z€ND7yŽî‡X+?Vt¼š ×5Õú¥'LO…øÌ‹J ö²/`œkåªÂÞ¬Ž¸?2”Ã'B_ÀÂÈ}Ýéz¼} £á­ß+á}²/`å;SˆóI­‹Ôäœ9!óÆéKú°+"(É"Ú…6C5H} ~yû®šÍÆßE/hÉ[ë€d­\ˆí©:öx5thu;HP5+s ÃÂÀ0WªÂ5ħ`xwö¸vκ¡:rÛFÞɦaÊ<½1Ex ØÕb¡ :œÞÍ'žUŽSó<×[•ß•:>h%¾b“ùcž`ïpf¡÷Öpnå—“&0í'µßê 4>‚¬Í^Û†˜¯‰N/ôŸêEµôéîY»Mn?ø¡¨Õ ÎÉaŒS÷EX•~ý¤3_ÍqÈoXfƒuìq·’—ÏÁ»Ušê\;.uЛiÿ˜ö,S'«C‘†$ØQЈz†aý>i6ºª¥ †_v7"°©8ÒßL÷ÉS§;œoeÑûà°¨5jµ5õÎc&¥z뼿÷Ë… ׿JQäÌó匛ª¶{ÒŒÅóýlRýÚÙ¦äqZÃó5/t­2v>°³Ÿl.IˆÖCùUÞy»Üòéñýoé¬És~k]àìkµ×AçH Úæ¶]B\Á¦9§ Þ¹×ëõ’tóK&Ã|1%j¼#'zg¸…“ÁZ ÇnuÍ Œê ]X/‰1äYvÜ5µ_)á.®+‚_ 6*²µ*éùÏמ(92¹±:“ï ^4™±,AmúèjÕÛ²aCÙh[ˆŽÄ=-Ì9tÊz´ÑøÆ>z˜•hªmAŒüèÁFÆfć.)ñÑÕÊDoEVÓYbš‰xš‚Â{ Én•ÐÕcN¥OðŒýôv˜=êõ×ßüãFDG˜bŒ¥„ ·ÔömK×µßg@o‰É+ÜNÛ¤^4ßYpŽØ´Ø©"Õ¸{Ú§EPͶÝ;Á¸òEÐ&æÑ°hEψ_˜ôö!'“Õu¿‚¶WÓà>&íJƒe Vh/D›¨Úáo27ôÚ8ʲµ=y;m¿ÛÏÞ‘ KñŸyÖ&çÕb#GÁ>çÏÇðûo´2#±DA€—Y¡mÖäz|Hs¹?TÞóEˆ8òèOQ9Å£Ñ~@K¸_ÝLì‡"÷»9b¢‰Æ›Þb¿N剿¢RW5ÙÍ»2ˆeÓ¢1rbØÄÈ2­åÅ!¾ËAm˜y…Pj Ö[Ùñä©ÀWï°E•:5ƒ>?_ÞYñVü[P7:Kös­ TX·ºæI|gë X–ìÀ•Nµ8Ö¡á‘/óö<ðg­¿6m±ã²+'a¢&œÂÄýëø2bÄ%ª§Feé›{u¨uE89ôÅ0#É…ï'?dUÍ!§s8+ H¼/$º?wa:@uqUÚv’ƒØôIæÎ_•pwíS0D\#ä_¢½^T ¼Ž{JD:ÂOÅó+‰@3GìZ3mnaBö0±xêA9#±°|·¸ÁƲ=Jg ‘x^3–òsÔ9·ƒ(éŽ=¾9ÁßXK!7ô&UL%1X£/!v®M´XüÆ™ÀòÍ2ˆ86„°8xÿ·ÖVCߨD§» –ÕÄžöîŸÿûÄË£~N7¦ÚéìhrWœ´øÜ¢œªNÝ0!úh°Š·ñPÕz°n¡ì¸‰Ý+F;Ò}€ê‹ €å@ÑKX'~.3­‚á…8q ŽUÕh°m}èõ¨izkê]B8ËÏ*xÎ^|åu”£–Ö¶ÇÍSô÷b!ÖáA–P,¼j–'þâ/ñ -ô9Š¿*u–¬D¬æ]*Xß¶¹/3[뜒¸9¦htªà‚³D˜†ˆƒAhÒô'€Lò¡û¿—G¹QøÃþ8YPO_ºØšBlÞ•—³ŸîBl¦@—Âx6»Ž0†E õ4Æ6s±‘£îzk20œØÔßáG•QÅ›¦ªqe[û}Ämæ;h¢«à† _ô,KßcþªæÐ0ŠÂ-m»í ÷V›íÕ}†oÌÔ‰^qØŽ~§„C 4¾Ó®@WÈÙA s—xhg õ7¢¼ñ­Å£ìH Wn¬ÕcˆCŒ“Úbó\¼$VlmÀM´œ(ˆ9'Ù›ž¼a>N ±? H“ ®ˆ…¿„•Þ“Ú$*z ¼²Dz*K4ÙTc¥—dƒ7>|Šˆ‹+QRqÎì‡Jâym£ŽyTûÃ㱩uˆWÝ[äâ’&0»ˆo&…Cÿ‡HvÔßJ=ÑÄŠ=ÙFMƒ·Ö°‡¼ÔÌ2äp”„êOü£©"$¥#†‡²;²íÈÀt3–¸n÷û%!t…Ý.ÕÄá°jðn’èžÕŽÈLRûˆ5#¾7C“M„ºÀo+‘»jLî]"¤‚ Žeô¹ .*ÒÚûös”TíÀüjÃøùÕí’8væ¥YT7ܱרƯó0¦ ¸§¤c4šË‘·“Ç=Šáä55%mˆÚÒ¡¦aÇ)ÜR °&ºàá }0è¿è‚‡$îA}mˆWaØ_ÚßпÞ]`–[°7vêeèëÉûiÑìg¹Ú•‹ûß¿—îïá¯y]×CÇJ^‚j²ãÞ¯µo¢ª‡öÅô¥tkû¤Ñ‡®X‰ÐˆTÕÔXåb² ”¤îPÖvh·g¹v¯0ͦÇŒáXU.«YdÿD°¯à.Ά®…÷¯åL5iÌ)2—w`@w²ˆTµó7®u¶¿fWl”†W“Bvž¾èGžñ òFóÕœŒuÑ H©NÞ‡è¦ÿnýž­4+ù•ÊC„šµÓØ&!NhðÌxß®´±F>Ÿ¬Pl—&`Í ñlS¸Mp Ô†V$ +Ù‰‰víàúÊN€g!²î|î⨈IèLSO|óˆ0CEˆ˜  þ÷8«Ã9غ PägS»Á~O¤3ƒ_m‰÷Z4#{Üy ¶õëûMns7³²ß«Ô ¥Û üz_Í0¤°¸ë”Èí8d Ð~ö½K–Œ>á°Â!`ßP_("ë¾4¨+nLSõBUÖrøé3¶âõËeÀôþ²p‚ÃNp¸*2ä¦ezâȉãÀ#jÒzÂÇ´¦\Ë}›ŽW² „ùÊÕü/å.H®•øbÄœ ±Š-±Hä˜^™•Ea†Û°ë í¶<”¹©©ÚƒÃû3A†‡$œŠiϪ.r“Å+–) C I|Ýî¹— u(§ÍuA1w›„Îm7±\àN¯»*5y.bÜ„¥LKB8ív¥Õ¾UÏ:Ù©’¨ZÐ5"WEég|;`Îè+åà„ebtÊÕUi i˱²_˜„£Wzcÿw|Â^å £÷•ÍÔ÷­(*DÌaÈ3ᜠ»(º C‰Æù²TN ül_c)aÆ“Ñz”0&;%—GDŒ1’W¨ÿƒo }°R²~[€W˜¤Ø!˜.5SaQYð²Aî Év™ÈÀ cÌØ6°â8¸ cH’ÈÔ¬t ¿x4ÊÁE F}—ÎTª™jç{É\ÂßéÃF²]ÂV LóJÄ7¦º¥?%)Ι½é}LQš©Q|‡J’C,0ý¾ŠïÆ-Ï4˜ ÆáÉ>jÕ¹÷ÅSa?L“©ú„LSÕvïÊr,JeTz ÏÆ¾Õ¶jø†¿X €ÕT¿°%Sbµ•œëM­LN‰p1²v›F_=_XîüôIrR¶ˆ.óÇ }jšËë(A}bž)ŒžÜLpÕš9µ¥aØNor·8I<9VéæÇþ¦6}I5îíîaÂãn!®@°Lî9yž £I¬Ÿ»ÅÂìq¿Í=îaâ-Z¨¼Ù‚JØž¢šÉÅJ `]‹¾%DæÁ÷q_@ð[æIôÓƒt[ïWXœf`Oìbv¬–Ë?&Ätÿ¨3ªÞ¢FCG„‹\vüì" nS (õÈ7VÜZ¹-(ƒŒ„{Ÿ”’0¯¹©6±8bâA€¡9îÕ×ø&ÀoþA€¤vVQŠ“û4 ’Óe3Ôã('ÂFFç(<ò=NL¸X¸ni±ÑõÞLXc OÔ#F}ßÿ:¼>9'¨údë A|(z ߨ„„…ï@QÇšDÄÕ#F÷jÄ©Â,ç>ÂèGnðEîýhcûwOIÁU*ìÙ¡eàãüµ¶9“FËs%U@¢Ë‰õÖx#¹ö;9sÒ 'Ö% êûÓ‚È5õ†y½^ÜŒò|lsæÚ'4‹úß² Žáø*²f“ u› C7ž­-"oM½ÃÕÄ¢8y„ó²·¹÷«ž˜ó"ÓØÛ š¦ÀÿÏ€#A&þs@®ÔÅ䊉bÍ0A9®ðI~_n@oµÎ4ayñ äÉc·Ì3œõdšÓ÷“ù ˆX(ªœ믾Áöޒ¾ũ7êYEÃ/E ¢«9Ø?àÓΓ[MäܨGMG7Ú×H‰7sŠ2ÅÅQIKUÉÔµPίxja„'÷Vo‰Æú;µÚ$@ø0?å. áHXÚÔ÷v‡ QJ™­`qeæBィÛGJÂ7nT•ßÎ[ie†3€K4¸Üõ¸oô×Q ´Ôò,ÝÒÔí#&qïî`¾Ú»ÇJ;4þA¯tjAÛ=I¯šÍrðq(Pb¾{ݪg³Åƒß£Ø.»‚qÑù[Ÿj"^=d6†8OOÁ±† Oñ¥v{rYS‹$^~˜%}ÇšRøKûkgJ¢ˆ~Š ·)Òï¿(ñ}d¶ô²)IAFøpï#mlÅ!ÊßþÊóÙÁ›Š}wI`Wô%÷„kw&8fÚ±„µÙ› !‚gmôc›ˆ‡=12­î’Z³ŒË›g$W·£Äù£Ý¼¨j×Pñð¶âúEÖYxœ¾olM}ðJµnŒðI„+°Á©ñ`†V‡Óû?‡[=5“V¯¯ðЮNªlE‡Ãˆð'a#B¯«yê{±ÈL†ZQž‚xƒC„ÊïDâ>wG^|#ÌÝa#ëUô:ñ|QÓC ¸Ú ì÷þ^B*+þ‡2¨IûiYIqG‹Ø•¡5HÀ]uãå8õ" pŸHæ˜ àJ—¨Þ åªÒߎñS§ÁüŽQL}bç:¼AíËÎHÜe9Ø¿R-©ØywS WNAÆù!*󈈧 ¼ F˜êßRQ—ǤÔ:ݽö²ÎŒÏ~Fâ_èøH7'0/óšl¼¨Á¶D ‚OèQ‚ˆ‹WÜeágæ§EƒqR=$Ÿ”Lõã/üô!š6, NÂæìû0‚¼1IŸ' ]uO­ì|!‰ŽAö,Z¶4/ç±¶'Ü¥õþ*‡'ÕG,mQ'Æ%¨%BË[Má÷²Žïí“BDw!~\È}xŠã ñ%8ôsò…€á"„c¸/óÀçÁ)\¨syý:?”»‰Þ\‚_Š1Jp ^3¢.Le¼PgtÍÙ•µ¹ƒ¢v¬dh`¼;~îo h( Ž½ÑÅÌÁpŽâÑ[ü¶Ù?’Ž(]óÒéð¨<ªJ½\IÇSåÀšÛŒû"…ö‘د¿`y´~î|}ã/ 0JÅž1.åÎ $YG¸ˆ7¨r=Äó)Äq° ÄÐåM¤ªöÌ\X„ N¡J7×þ *Œl™ìãµ%[ákëÌO^Qù¯TÌEŸrü ïÐ ?¤+„n ¼±naŸù‘Œ0Ñâš­wSàO…K›¶œXМs.}'|•_" ¶ñÜ¢O†0áí±7`Þ®’ÓR$µ¥4dPOyㆅ]þýþºÏ%Œ¤fÈÃþÑRñ$15˜I]¿ÔdPœåX94°­Ï©ÏZ›š› ý{!GÁ“–\]“5k{_˜–›÷«9âõž{·ˉ&ƒX É[»Ù4ß 2 ëmÑB.¬±¢i#¯sn× 0¹ã Kƒ+î¹(°m¦!vƒ6ÓgØ¢a{A¡ÚÏ)~žànT=5ƒœ‚øÙÁ8iö:8X‚C;¶I1=F ˆa ïŽàúƧŒÏÜ%îïk§õ[•£N1÷s¼ª{ÃÅ㎠È%‘+`ã\íK4ñ¡Í™CÆ*7™© œÉþÁdšÊÅø`MF™ ÐÛ_øñ¹Ym*OxÎGÜժ˙ª3Ù§“Wë1XBð #ßC[šI/óØlãÝXãÙ1-f"Úaíè²Þµ]Ówë‹Ê£ÂT¶v¶4`”bq©Äú5–‰âÆVšñù»›&½1Z¦_îQ-”ç“ö…}¢y]Øù"ºž–û(+êEýö¿øð *¦ìÍ3g11¦¥ÚŒ³Ÿ@–N§F<¢£Y,i¡+Çß'ÃÅ— MøÉ`ú†ïDoõcbÓ'ÐÿâíN3A"?]ÞC7’TÏF” önqs]×%èöåŒOÏËàÿœ—s_úݳ_õ$~ýz!æ'pÈßٳʼóÊu\DƒÀ@±·‰üæhмÀ.±ï’›uŸU^öo~ħě“@®u^‚½rc°¬×I*AÆÀW&rzòvFœœ² ]¶¨µÌ0Ÿ:<8 =qÚúɼ\¡ Йr¤.ü 9Â…¨ÐõÀoŸ„˜›7Ö–‰ÄLÛðÔz¿Þ9­²XÆÀ cUr%•B¡*ˆëÛ¹DW¶ß_]òíËArøù!Æ>ï8pD¯¬ôÞJ• qõtá~]ù«ˆÅ¤ùçýÀy2¹»ÃaWÅ Kø¹ö_ ¾Oy ˜e34IrDˆÆ-šL-' ­[çàK™an0P?™¡»k§?ÂtySa§ã}‘‚É·÷ßÛ€Ûc¹ÚðaRîÞˆ7¸6ç£y¿œÜ U4æ9²äJUš#'W½˜ j½Å$ ÿed8Orí]^//h°<„£àñTŸÜÁ½“+p1z(é‚ÀÀ-äî‘×ÖÅûmý…}‹jüÿ ÁI•“W¥„¸¹‡ÇQnÒ›-“;p‰.ŽÈU³!¨µµàA]†&1}L[8à;S î±~d†Ÿ"‹ “Ǥdr,¼“/t1ñÂB¥ÎäǼ‹u€×çaÒ¯ÉH¬.Ìi€ù®aD ñ{˜ÁJq¤CÎj‚Ãïï§3‹W:ǵð!ÄI(¹2Û9¸G ‚Z½^™BJÔD‚Ä}«NàÌoB€ÆÉBˆUFMýý(£g$Ü #f¹Bµ>øl‚Î1x‚ÝX/“Lb·5{¸ºˆÝÃÜ­~²ýûØ'ð7žÂ6.1p0³$Ù«ýyn~Aqsþó_ü©_dÿñO¿Èö6û/ÿ§ÿóKùïĘb>žÞ&Ó/ê—_X©é¹êlèsCÔ¦¾ ~+‰ÚìÁ¿OË¡Ï6ï‡7:Þá·aº’ЃþËÓæ¬!ÙÐãs"ðˆÚŒ‰²ç`是]|€zº‘r_o¾[Õ+¬ïÏàÞ šçÁÌpýñ©ø6¸øÁÂ[’—{"ë@Lwô†z‘éáK<Ô‡q{¤mÍù>¸šx¤ þy84¡š©ª>¦Ö\Qx_üëá£M›°ÅÜZí n«k3x1è¼ k~cíSƒì™¾•ê&%Êè?°1zl¶A;?¸­YÒàß‹QÒðIÌ„ÿ¼5ÜAvÉæ…|ngé3È‘ÕúV«'¶€ãËØß Ÿ„Ñúføizb{ïméà'ÐßNŠüm¸°¦áàÏ(ö}ó‰FÔ€¤ø{Èp }ÿ^BßUÌŠ†ƒÃ®ˆó_oa ÔVv´Œ\¿tïùƒB"o`÷¦¨ÃÃ+¸¾§/€Ð-ÂhK†®«H!+ë¨ý„ø3¹á§¶Þm˜ùØ1€m°"x[7y5¬B ¼Bp£#qe$ä׳øÈ"Õ¤þF …K&ãA–üÄ$<ù§ÚœUÐùÕQƒ;üÔlª²P]LŸÍB†Ë±Å³q¶ˆv½Ã©£iîðÎk¿È€}Èý‰þl°•4xç§…&PÏĨ8þ|”—eŽÐI¤ P>ƒ¿gòbCHÈ2!í=¢Ð{?@0&¯¢wÎl 2»ñZ°Ò ›Ô{ëÌàáxlÛTåb&¹1u’C’%x˺+CBÀb ß=–¹ª%’Ã|‚œæ°./Þý6X…RTµkdɃ+d¡ëÍ®B dkZ* ûRk …ýä¨Co bFˆÝqÞJR™cT€¡2ÁJo‡êöήquPØùF¬Qðà b·¿íªÁGæÙ×€º© DG@hõ#?ú¿Êl“«j÷ëëÿzyýe=4®´ÃÞ^·ÇÔß\7£‚\fMnêÃà Û ƒ\ÚN¹ù¾ŒÑ³(‚Ÿ•â%êRÄqHBœ'Z¹t'÷¦h€ Fš-ÔIÀ¬Ã›ÚƪÀõدuk…F}U#ôBê%…Ù6œïôáÑJÎ0¾ê…m*}ŸÔ!Sz£oQX ç·Tr¦¶Hç|=Ãe·Ì ]9üQñè5§«§zpÈIÌ™[/ÅÈÊíÑ.éð[ÛñCöÎá{ôyÌ.É>‘~X|µðw~d"^™zxèžGC²×6cXDtú! ñN…F4Бí„p®Í’¼µûõ]…¤ÐVè7¶ÎÁZ½È¤)KëM"&š=À/gœDËS¦€.è3›6UÔaŸbvÞ¨Gh2tÉI@aÇcå.놑8ýfz5éài‘‘d÷¡$¾ÄÔ§˜ßöª@véSú­)À»rGÇ8šä÷&67lWû›ƒ}bfÓÚ%>[`gÏÏwá;øE²-`âÔT¡/ >Àóî‹Ám¿çÀ‘™“ÓxN©Ø9Lã°Â–6:*GE@¿‘§<ô y³œ¾æçÐÑ7Öqð»Õe•¿[ÑÕK¶³$U°¾ û¨îS2aû :œ‚Ô'â*üȼÐECAsPGm^tžª,±­}y{Á,õ0=K’Ôß‘ßïÐg‰€Ûa„PÃ…H½±ˆ B“ºÓó$(g} #±š‚v媩k¬šRôÞð&í1©¤ƒŠýý+ä (£Üla…G+ò'5¦eì÷5ycvìv¿‡SogøÝ»äÆMžc;Ò¾Õ ¯&Ãõ9ò\Mž wß™J1}`s­œä³¦`¿ù+‡|/LÓB0pkõN¢’®Üûz<& `?:©u‘šœQÃÆÎj\R@›È€( ]N3LKÓó1?AÌÛ·⭿ €ƒ²sÄz¡ÅÖNˆ©c/}C7ºÏ1¸I¯†GibøË¿!žøÐNìaíœuC»qä¶¼$MBÔdzcŠ˜S %W‹6JNïf0‚þþYå(3Ïs½Uykñ‚wȼx–Uþ †É;”ˆQ(r×ÁP—§ヘ1Úž—‰N/šÂŸè…«ôéîY»Mn?Àð¡¨Õ JÉqŠ2÷EXu1œ ¯æ(â7"³A:ó¸ É;àà](Mu® W,à±fz–!G¹êP¤áÓ`òA”!¢ ÁI¿÷™®j)§—Ý=Gk*†ƒÃ6=5H·²‡hXPTT 0³ZŒšzç!“}tŽû\Äõ\ÿ Q³Ì—2nªÚî)C OOô³Iõkg›’mÀi8Íֺеʸñçf9ÕPê÷¢kP~%A7‘@.w˜ix‡DÛ8ó~þj] äkµ.H0¨mÞ¦ÃÑ 499Åн^¯—ÜôšóC?_LáÚî¨éÜ™¡\°9B¡[]3¼Çâ5žÖKNx·x’ôèY÷QÞ8àí¡Q‘­UIÎr¶æDɡnjΙì ÃASSvS³÷”];ÀÚØxô¬L®¢M%܆¾‚$&e""/Èœd„Î윭%{9ɪF¹,Âsç4ç9 ã9ëö䪼/RÕlw5µF>…‰šfbÞ¹ns[a°`OÞ– öx‰|ÝÙãσÂf°²µ¯nΖ¡—Ö+ÅÍa­ro>Åcø›Ó) .­«¼q„ê<·n¡jg^µû³Í™p0_òÒ`¿ zùgyPg>ñ·59Ìì¸ú×9µ†qÜtìhªêÞB ÷EÜj;ÔÇ=L¦~ßE$Ó0azµ¸s¦óÃÀ^Hü>Sê`_åµ`cÑð€yø`Î:䈪M^A=ñܨáWŽmnE ЏƒH|ФCÐ×ËàŸâk¸¶ìR¹.{¦7 !˜š;öÖßåûDáÚïu,Êݨªî^¢HŒÐâ­!GãÛP“Ê'fkê ‘ópääj)lR/8ï,ÔóGhZìT‘jÔ©éÓÛZÛ@Îá÷¸ÛWÄüç!‘T-·ñ=À ó‚Ý b$Ç£*ìb-ªAŽB»–@é„^ÇȘÁÚ¨rx¼åÌ Q–ek{òŽØ~ ²¿ž½¥Â¶Ê?ó¬ ‹¶«E€Š´p?B_A»”‰Ôgp…Ø9}|HsMDÛòˆñèOB9CÅïÍ~ÀøûÕÍÄ~(r¿_Qcô ]´Ñ-ôkTâ*áÈþÜ•/ŽŒ‘ˆ¸?“C¡ö&mm p¤U Ì+ŽêíÃXîÆ@÷ãæSêÔl ö{i}\¼ëxO=M¼Š¼^²ºcu(÷uØJ§Zœ±0ùíH—y»»ó¨Ã¥$¸Wü) ߇ޝÒ_kzfT–¾¡!©)lPß‚pä¾wü U5[€œ/¸|~†ÉÔ EDX"¥-@W:yF×HžNïüõuÖ=ÅBÌXN…[êyØû´gDƒ} <½’„Ðq„®Ñ G–V= /oÏ<(gÄ÷¸w‹4MàJgŠzxh½¥üs×ìÂI¶#ï2à×UÁþÅ ½Ý”ÑùH¦²è{ÅšÕb…×h4϶¿$‰bD˜ }ÞZ }Çýè&ØøÂ»Õ»þýï/9úùÛ˜j§³ÛÁÍíøÿ8©þТœsNÍâQ÷hR‰¶ >^öB×Äî.÷„þG9–ççpPr€uâG1Ó*xž]Ã'ÚX•Q]Úu‡žŽš·¦Þ%°£ô,!žìÅOZGùgi}ßCÁÖSì×1R¸h0ÀA•`¬º“åþâ-ñï`î9ˆ¾¿tÖ–¯Ö\*PgŽÀ}™)Ðå”CEƒR£w„ñ#wÄ€ ÂDuy™n”…>j“ñ@¤‹­)†Ö½òòðÓ]ˆ×Ø”Ïf×QZE ¨ëÆ «Èæ,VcÌ­ 0oMvšú[ô¨2ªxÓT5ªÐj¿ ¾EÍ|·LtÜ3ÁÐvžÄ3yÈ_Ÿ¦N¨¥­@Wm¡Þj³ÝaÅ\ Ÿ&ÑŸ ÆÚ±îÔ\˜1ÂwÚØ*¸1Û Ú oΑꬩ¾D”%·Œ"0™µ°V!f 8Kj‹Ìf±¢—H mAÀr,f0؇g—PTzîÿ(AÆ~_§ ]ºF,áWz †·iññ»ÇÎAW¼íÏT‰ˆ!ÛÅðãá˜k×bN| ' CT"L¢”Ù=õÅûÖF]mŸÌ&D"@îr™È ’Z„-“‚!ÎC§'; iC¥Žhâ Š­žk#W›eØ^j|{™ÿFB’'þ¶Ì°D·À’ÍBˆÉv,@¶³ _uû=‘ÂZx£_5hçH”Äj74¾ûñââ;eèF!Öwè–Ú Íä}½ADJ2úa–“P¸öc }äö Ê\öÞÜ #Õ: EþEO¢¶6 9ó2'¦cíÈkL“ÖyœØ+»´ÀQ)%îÜèïÇ«°8DG ´¨ ȵ¨l(( ‘ù ¿–¡êŠC §;튰“o­3õY¯TÌi‘]ãñ¾s^t'9B_£aœÓSPe¯©ù 9þ&¹»Ežïü>Sé`#€ Ã)&7÷ 2M¿_èüupúeÊÒQ {Vyp$‡$¹g×вê8 Æ+}Ùuš~·¸Až?7›6 nÁS µž'n1y¸%Ь_‹›àU…ô­gÖj &í,_Èh÷íÀqRÚýYrÔuæ¿}ú86˜-  ;&íw-ù].3XÖ*4ŸS?žA¥’éÌËÝÈCØ_!.:ìOiâO%âîáC¡ï0lÁµƒ¿‰‚ܧyίVBàcz¶Üî%÷;û¹ô³ç·Øø˜0ïó¿F†4oGsÁ<%Á$iò‡™ÏavaÇ/ÔT 0-¢ßŰWŠc^vö­Šy7Â8âmt:öNÜ}µî.“c•‹Ù"dœºCYÛŒ²\»Wˆ^NL,Æ`¬—BU,²bûÖWà ¾£%s‚åE½Ryˆs°vé¤iÑìTÞhì‚Ro›$תÚaý.êŠ;Ôî Ôopª¾dQ¡ô:Ëd´) G(e]ƒãøÍ?€ß›¡[IL¦‚ª¸ƒ§$úûXJ¡¤…¡>VØOíù5œþ|u€ß°œ©qÍ­ê—Ô› Ún,b¹Wþ5ø ½/ æPS¼ˆÒ]á¸ÇÄô%x–½IÂñF䛾”èÏÑ/‚åÀð%˜+àBÆÔ1‡«ö>~9jl…M—~¥,mU´Ì齜NG‹uIaF™*±~_áD?6[G_T©šðeÞ#(ÕõDçê 3ª‰rœ‚gò8÷¦¢Xrø) 4òZ9tÆÄ›$UUD}…µM!£°JÖÂô+R®½'o‹lÐÕõ`“Bp—•t8ØK$ò¤}Ôù›ZH,†@ø“s\Dm,Äåk`Ï®u…º_ BøTb [€]Uµ©DÀ¹—€ øÐÜ×›oŸÐ{¹Kd=ê«þDZŒwR0̤KƒMD€ýµÿÚŸL9ðk§fqtí/¤{ÈÒÏKg²ªç~qC£ ¾¤ â)9ëÌXd^Ôó¾jü ž‡4¬uPÓÐ ¶½NW¹Wþ™l‡P Ó1&¦Bø­M“â§ÃÀUƒèqªÃÐá–×Jøùh°ân†Å.ž…ßx CÆŒUì·À™4üíøÚBGúÖsúð÷Û)p«8к-(Dó©TÃ1¥ÂS"Ë_¿ÀïÛóéªAtâ(ôÒnm 3ì¸çL‡j ú 0xcT ÏðZ²ÚÉt±"ô°÷,1dzÖòûÁr²r_}ƒ½Ç ¿xé8Û„~úÉYÿrV?¬~C{ÖΙ šÐ8ñévè]9û»ŽýéeoØÕƒïÞ£ÇJ¼uk8Ò¨HwÖá‘*F…Ù£n='@ï@ÐE"Ôi" ÇÈiÅP~¯ƒßO¨£‘`íø¹’t?C§“—æ~vƒî?!£ÞGJŒ™13•:&§aÚŒ¿«´É“$†e˜™L­¯ÁpÂÈ Ð˜Î3pLûB’'ŠW2;ÑU.85†WÆ àY4ŠÑ6ðßB»-Ë&enj¢æàùð sáqebðûªóp¶h¥2UAd!©ÈÚ]”ÚPJ7.än³‘OíR³æº«R‚Õ/eš PB¼µ« ®ò­zÖÉN•pµ®‡_eŽtÒ·èbÇÏØ+åÀÀõbŒÊÔSi ÇIJðÄ1WzcGtb^ååÿ•ÍÄw­&¸=âÜXϪb¹ÎQ —aè07Máú€y„yÆÏð5Jx<­G nJ²SraÐhìÉk…Ý (Á÷aw ÆVpNx Ç ]h4¼²¢²¶Ž†ê/.ºým¹ƒK$‰LÁJ׫ëŠ$‰’^0…Aß3•j¼Êù^"ßâÜwú°‘`üFÁ/TMü²•YÔü™ót­LN[1Î[›]!^XæôŒìIr®€.‚ì {r˜œƒzbž ˆœÄx€ ™9µ%QPI?¹[œ$«tÒccꟓ1u‘ñˆ¸$ ¹Gïb¿F^#w‹…Ù£Á”N(øñínÙ “7[H‘Ù3D·õ€Õá~mŸ4úŠ xx­b9ì­Ïcd+ïWH1Àùañ}¨%ÄÞI:Ý?ꌨ³¨±hN`‚D„]=¨ß3Û\‰ƒÀ%¨õ} ÖÊm!á5ö$Ì+a”®©´§=B‹Uõ«¯ÑM1`ßüÆ(í¦%÷X£¦Æf¨õÆQš͹ÏAp¤{ž\‘`½ÒV£+â•ížð{tJ!â»ìW¡uÉŽOÔ%Û‰¡ß3è$(†8š({å#Död„‰nÓ…!²©›*^jË»E°föï~‚½Tˆz¾%ÐÌñh:ÍŽêtô%‘Oäm ¿"H’bü´Jì%pÐ÷!–ÅöšxÅ»^/nFy>¶9~õ–ë}Î5µÍWLÕj²¡þw£röFcóG@r‹¢JVQP<‚ÙïZ„ÚÇáDÊó"ÓÈÛ…ÑÿÍOÔfföŸQ¥.&WxH0œ e…Nåûr뼈x«u¦a‹‚‡˜ø•ÛÏ`ÎétNÞBŠ\ô÷ J/0DÓÄG‚Á꯾Aiá÷Hñ@™7êYEC%€¬ãÝZ oûèóÜVf%7êQ‡ÊöµÇúÍœ`LñDPDŠE$¿\(çW31ùÃãr«ÿÃb"ZÂx— Ÿ\4ÎãÀrp`¾o´;\JÁh‰‰*c’tÐfOâË3c~Yp|ø¶Äb?Ê}‹ù6$0Kì[!ð3ÜMÝ>âÁ·Ýe«¼{¬´{Æær‹®tj!Û2Iƒ“ÍrèÑ$0b†‹½ݪgIþ íD ±¯üŽC/á¼*¸eÝâ9^=¤<>ÅÆ4};…—ÚíMÈ F,„xÁìg"à/ÊdìxÅ&¸àñKp~uoü¢Cwˆe؞˦¤D¡ÃÝ‹²ñç™mÿÜàwC`¾“$h"ö‚yBµ;ÅìȯÍóéD“?ø±Lü–NËVH¬ÉEeÂ3Ž©×böÑ÷j^Tµkˆˆt[q¢jŽ$82ß7¶&>t¥Z—6ðDAUCá÷ŒZ ´oµ$½Ÿk¸I³fõú Måêt ÊSô$¸p}BÁväÚ™§¾ïŠÌd˜eß)†65D<ñUƒïUPÔµ3¢Ì2’’ïò?B/htàQQ²¦ïý]Rü%ÓóÓ’’&¤¡cŽ l~ <"hÌs;ÑUPß] M—“œùäÀáGFÀVºÄnë-U•¶ú¤r ê”:­¡n ½I|Zç*ºÁ,¢Î8Ô=5Øam ùÖXn…ÅèˆùŠà˜§nPUdp„S ÜÜ"Jôi©ˆK\Rjî^{ e¯ <åÐ/ l|BŽ1û K5[”LÛ5Bø„å!ÊšxM]R zî}Z5'ÃðI à`T? ¦sÁ:qžu(c‡†üžºÅH?'=oϬìt¹ÈÝ^v#R*,+•q¯ì'Ôeuþ Í'ÐG$iÿ%fØ›{KÀÛHÄÀ—¤Šíá“"D[Ê}\Ä}x¢bŠñð3²`ár‚B¨÷êB7ôçÁ‰Hˆ`^yý:?”»‰Þð0OŠó(” KŒõM:¨ŒØp:#kÍ®¬Í5½#%îsÚÑ’¶ ÍÒ‘7ºØBA¨ÏA4z] ß6ûGª¹$k]:žUGUé/z+él¢PÚaptÈìý๯¦AëÉÌâ}³/ÄHÄ1.eÎ Ê" ݘh$˜r:ÄX)Ä­¬uªï:U‹ZÆÍ}C9ÇWéïâ´M{dÊ øTø .±iî§ ‹‹ò|l³PuI„*ya1N#¶³éUNþͦažÇ(,þÑ´§ © ³© ƒòß01›MSùI²ÝÕ”sƒQ•¹JHÙ+†"ü\­C+(ÞÙ’UYΦ³Ü2XôÛ!´FðŠ_³ áT2›¾VMUU\å 5¿I;ìÙ4Äú¤AÑ“S°uåÎo ["pÈlz·ÙT”ô4ØXÐó?ñÂ_“‹¾–_ÆIiù¬ #¡x®qM.Þü”c9em¹>¶UâwžL¹Lâ4›Ç‹À63õÚJ, +‹8˰^Ý1,OÆl­<Ë9ˆ·tâa«ƒï¡üàµÙ¬Å±Ó’ …€­%FF“ðÂûÎË^¤óãÕQl“RA’,|‘§.ð7¦ÐÊñý(<é &£Y(yëdB*Â]OØù(U™`G.žwË…6”¢f©@ãIê[„J $+-1réè9ñŽÜ 20k¹õL3ß¡{Öµ7†kói\ãO HöÖÖ»‹Û‹¹¤5ß7*%ëE}Òò«´äò¾ù¨(ªU²/×–jED¯­3?yñCå¿J!|Äèƒv¾/ú„®²àv¨…}fÇ.¢p[kJÂMãM> -m~Ø2ºTsJ8¹ìUA̾UÎ T°U6#Û÷ÁÜç!d7òÊÚÿ1𤶄F „(/¼ @ʾZ?7«äƒ©SB4JûGKø“Kr(ݧ~©éøïs'/²õ}¡ôEkS3#ß¿ 1 89ÙGÆ5u_sfš÷…©Ñ,–÷«9óžyÕÝG‰NA8mÄ[»Ù2P0lê­¨BƱ"Ý*#­sf/ (µ‹ Ib+æ9%mžn_Îe .hÛ&ÌBû£5EÏÔ §gÆPP©S Ýô:åÌ^÷;¨KÈÃÃ6)¢7¿‡Y ´‚«sâV¼«óÚiýV嘓Åý­æÞ0±„ƒ! GC Ð8WûRg0Ëùð·¹;ˆƒTå&3õ!©1'É“i"oÛƒ5a¼úA?n§ÀMc*r,;ê¦ÓePÔ™llÓÉ«õâƒ?õ&زxº‹Çfo¥ÍžX1€ÐiéD—õ®í ›¾[·P|J¦²µ³¥âµŠóô#:°¯‘Øù7¶Ò¸gØÝ4éM¨2ýrix<´/ÊíÌsðBÅÐõ®„ ÇHQÕé—°«ÅGOHéc·X&Ù8[á1¼ _œã0°t:5â ÀA¹[þF.x°·OÏ(xCy«›>A–ýowwú‡½5Y?ÍȽA&<Ó»ÅÍu]—xÐs1ˆF%ªÛ½˜¢º-Äÿ-ÛožŠ6ˆ‚Œáð9Û‚~Ë+Uø+Ÿ¶K£7Uõ_ÿPK8šŽš÷C'½PKY:CGHaxe Toolkit Installer Template/Haxe Toolkit Installer.pmdoc/01haxe.xmlUX ‚IRYÉCRõ•TQÚ0 þ+Uµ×6ìÆB$6®Ú¤=œÛÓ¤)S2BÒÅ)ûõsK(9 ¤í¥©ýÙŸ¿Øny½«l¬¡œ¦ƒ|0L“¦QëiZ<Ÿ†Å»Ç¬OŠìm1˜d“b4Êf“óñìýh\ÌŸRÁKk6ª\­ÁxµQà„uU¾•GèKkõNùî=å9ä,Šæp¨¬-8àìbò5`éTí;ƒ½²j‹>S½Ô:ñ§¦©±R&¸ƒßr0küÖ:õG¶ äÁ…³ûdoézÞ5 ö ©{‘Ê{vö”Ù'›åÉçs*8Ößá!³x¤[\Iû KûŠ¿AÇ´Zu©}ÂÒ ¾Ñ²B:¬ÖöeqÚ¯¬VåevHjY@kYîd o„{*ãÁ©©õ,†§²¢/ÀYkv¾sß0o›ð¼–~{#$œsj`I¤§g Ë~M}<À’Ü"vp‡·–Žæ9Âp#O¯øž¦ˆ]ál…V7>VÂ.¨k}Fâ‚ò0x4!ü<Ô¨’ˆ«yÞµÿ¦‹ZÝñ]í^g¶Vî9‹âEouž§æ¶;¤4dZ¡ƒ®üÊ{M»ÔÃm$m`¿/Þt@kõÞ9ÌMy@UÚ²{h-obóÅÏn=#]•³óßGüPK õ;ÿì†PKY:CPHaxe Toolkit Installer Template/Haxe Toolkit Installer.pmdoc/02neko-contents.xmlUX ‚IRYÉCRõ•”QOƒ0…ÿJÓwÚÁâÆÃºÄLâ–˜Å}&DJ‹ôªÌ_oqÓ,&.í[ÎwϹ··]õmZ!(4ÄôP²0¢ëUE”  ZDlÆf6#%ZÐ\AÑRR j0¯*JzË,âåÒžPPþh`0ü(ã÷ƒ~ ßæ#­eÛ Ù)‹J ÿkÐ ZåÒ%¶TÕHøIÂnÒ,E=Àÿ!æó0Ž)?›íõþ6I]å*ä[y¡ú±Å³¹°g×Ú“:ëtéI¼wN¯Nlž¾s•{ºF‹ð×én·IöiâÌv‘M&S¥”®&eï.÷¤æUúW^ÈÔŒ¶ðw^1:É –>+‚ö=W‹j{¯áØi6~–^zƒL¹6ýi7Ûµüô.øùÿ¶þPKŠ/îPKY:CGHaxe Toolkit Installer Template/Haxe Toolkit Installer.pmdoc/02neko.xmlUX ‚IRYÉCRõ•TMÚ0ý+QÔkâ@»HÆR€]µR+A÷T©ò†!¸1vj;,ô×w’˜à•@j/¶Þ¼ù|ž„ÖUi`ÙŠyO“|ö0[M§Ïùb3Zhµ%£b ʉô)Ó=?Awl´–•p©‚J'ã4K± %7=‚±B+Ö’%H·` #j×òÕÚºD(블‘;×0•VF ün„¼q{mÄÞ Ù;?}ˆÇs¦˜‘ïË‘w® ¨È‹Ñ¿ p–|ÁÆ#ßyôµC†²DÛNqM:TØèùkˆo]è°ÑŒî$/-^ZJý¾>Þ´Å7¡*‹ÝÏÖ¼¨x k§ ø9…r`—(= iF±, PÒÂÎÖëfS¯P#Î/ÜíÓ¾­À>×]wÚPd•%þ8óå”q¿Òƒê\7k[ Y‹ÌX «ÁdÑÃf¸ý¬àaߢR·ájÏŽ¸2§–0½~1=X(‰y_ƒ RÎ!˜ì ßPcR2åØjë. Ì 0¸j˜}*5ÛŠý~ìkû®æ¬°Zv-s{ýí¶¯¶å*\ãÇ¡Iç\Ö¡ÊÄoÊ||ÓeL÷`àSxþQâ§ŸûÄ7á¿<ðóSñ "þÀ×Ö“š9 —ȇ^û¾SŸQ€óN¤’çPK"›gyñœ PKY:CG__MACOSX/Haxe Toolkit Installer Template/._Haxe Toolkit Installer.pmdocUX ™IRYÉCRõc`cg`b`ðMLVðVˆP€'±ƒøA È@€+PK%í!Ÿ(RPK >C/Haxe Toolkit Installer Template/haxe-3.0.0-osx/UX ‚IRgIRõPK>C8Haxe Toolkit Installer Template/haxe-3.0.0-osx/.DS_StoreUX ‚IRjIRõí˜=OÃ0E¯C†ˆ.½2„‚øVU6„;”V‚‚5©`ÌOçÙ¾…H HL©Úw$ç$~þJ€™¬çg€P Ù„› ¦YË&¶ñ€ËÓµä¾aŸë¯Äsñ£”û”üç8ÁiL¥”­$wüG¯Wìµ7>ìÇREQv“TŒ††¢([H˜íé&Ù0žÑy«Ž¥íé&Ù°\FçtA[ÚÑžn’9i> {Þ^Œ¥íÿõÊŠ²7$Ù°þ_ü~þWe‡1ùôf:Á÷ CXk¤»Mp5Gw¥Ÿ…Gø‰;ÚÓM²ne(¾PK§N¼PK >C8__MACOSX/Haxe Toolkit Installer Template/haxe-3.0.0-osx/UX ™IR™IRõPK>CC__MACOSX/Haxe Toolkit Installer Template/haxe-3.0.0-osx/._.DS_StoreUX ‚IRjIRõc`cg`b`ðMLVðVˆP€'±ƒøA L…VPK¾CŠ *RPK j>C:Haxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/UX ‚IR˜ IRõPK ú>CIHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/UX ‚IRÈ IRõPKú>CQHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/.currentUX ‚IRÈ IRõ3Ö3Ô3Ð-JÖ3PK€Ãþ PK ú>CTHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/UX ‚IRÈ IRõPKú>C`Haxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/haxelib.jsonUX ™IRÈ IRõMAOÃ0 …ÏôWX9C ì¶‚Iã†&ê&^H“)vÇ$Ä' cp´ßç÷ž?›3p"µ5â¼ë_wDgiN^A‘Dv˶-„Žihhe¼3¸:Ü­êJpà<¿¨ÊÄDjSTKl’Û‰‹¡=GþEï)ñ‘Xè+}y‘Œ^T%‘'d Qjè­;Ç<Ç“º_»ÁIìßÆÒ¾Ó7Öæ›Îxd^¡ŒH<•¸_?=Â6¦ EÃzBïa›3X×tƒ$×ÏÓÏ=š÷k¹< †=© oȹÿ¦ùj¾PKȈuÒéfPK ú>CZHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/UX ‚IRÈ IRõPK ú>CbHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/UX ‚IRÈ IRõPKú>CoHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/ConvertXml.hxUX ‚IRÈ IRõ•UKOÛ@>Ç¿bk!a‹ÈÐk".¥íµ¤ÒÃÆžM–nÖÖ>€å¿wö?€C/‰væ›Ùù¾™Yw´þK×@LÛ ]mè ¾Zf|ÛµÊw®.u+—YV ª5¹hå(s¿Ùk6ëìJðšhC þ1+kÃ[Iê*¸DÜâÖ(.×%Aüìô”Ü‚!¶#f¤F­0äòö×&Q¶6Vž¨"x-9÷Q³\Ò-ä ’çs´Jä¤?b õ`èZãñ÷Ÿpl@׊w®¸kÔÑrVUŸ£YªA¶f˜9!•5­gî@6 kÎüºGëÕòT¯©Òà™ÞÿüA¨lˆFòîìGž/[4Q¨ªsð Z¹ŒÞNµPD ®b\is±á¢)<ÂiT9mБÕLôê!Q )*éÖQØ)Èií¬U¤m„Ë)Ñî;¤Ÿ¹©7Á_¹Ÿ»]Îܳõ$¿ Ø‚4 o}v……—Ác¨ë(êM¡X×䪳zÂ}µOyé‹í­•/FÃ^Nå&9“2J­(Ø4|9 *a‡¬LV¤˜Ü:šÚQÆç?3ºiÕ}67bq~>äà0ïQM¢ôHÎHq@"Ô QBóü€¼&Ü„á>|ç€5GZý2Í}]ó~¸$¾iöÙ£_A· ð9‘þ!Áhgúà½êivר˜ñ…,¾îðr^ÏqÒ±sžçáùrRè•SžIø‹eAe½ªhÓù냗$¢}[n¬£ïöˆ¹%J*0'öW—‡rb~Já%IéçIñAjF…gèÖµ4m Õ§ ½YÙ¡É †ŒJòÍ Kâuj’8ä„䄤)˜´Ç};*í…âlW¼Ÿ=„úNF–!óÉ1æ=b¸öGžÑ±úÖFÜñƒ< Ø}pÆ–£{´ûlÿPK|ÑøÅéPKú>CiHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Data.hxUX ‚IRÈ IRõ½YësÛ6ÿ,ÿާ–jšvÒ¹g×¹‘%:f+KINšëôjˆ-&¡!)+jÆ÷·ß.|è»ùpÔ6€ÅîoØ]€§?ÀЋu=ÌrhvZoÎÎþqòæìõ¸a_8\‹e°< Rñ§ó(Ëp¢ f<åÓ5<¤,Éy`C˜r"ÆÒnC.€%kXð4à bš³(‰’`ÄÊG¹DœÏS&Â|ÅRŽô°,~Ä%Â_Îy’K F1Ï ™Ï8Xc½ÃjÙÄ EœÅ%@ËfVQ>ËRžåiä‰üx³Gó(7ŠJÒ$ñ]f¨ ¡µa.‚(¤ß\ê·XNã(›ÙDÄ}ºÌq2£IŸ'¸‹x¡B§"…ŒÇ11‰P©t‰Ñ–J£ 7׿’¢W31'ZbT¨„æ —i‚‚¹Ü4Ÿ”û‰û9Í÷PıX‘޾H‚ˆTËε'¸Î¦â‘Kµ”ó‘#j…<²(=­—²C¦\›…GÒZ¬¢YJ0²ã!Bg,D*ånjì7.Œדí‘ Þ†£Á{¯ëvÁjqlÙðÁ›Ü î&€£vò×Ðî„_½~×÷·áÈa0"nÞí°ç¹8íõ;½»®×W¸µ?˜@Ï»õ&Èw2257Ï¿[wÔ¹ÁaûÊëy“Òk×Þ¤Oœ¯#hð=šx»^{ûÑp0vD9÷½þõ¹·nâ `œ÷=`|ÓîõH±kß¡# ÁðãÈ{w3›A¯ëâä•‹øÚW=WICí:½¶wkC·}Û~çÊ]d$•$J>ܸ4KRÛø¯3ñ}Ò§3èOF8´QÝѤØýÁ»6´GÞKGBÖÅMÉ·ö]ň,_w’ÐønìÖuÝv9Ži•žœ|z°`þgöÀ1*Eœ93L*q4½8ˆæ@cç¯háŒ8 xº=ï&yº®Oÿ‚‡ãâ`™QhñÔ%â}qp¯<à!Üe<õ’Pdp _,…„Í9œkú 5.ãx×<Ÿ³(Þœ\¤‚NW†óí4eëŸÕêÛ‹ƒ§Rð{<¹ï²1nÉØ%×sJuYe¾Â{¨¼@¯€gþæÜŠO³h†X%<ÝœÔÙk Þ2}Túm®èéÒ6U;¼ÕD9{ ‚fʶÛPLÛû…zìRy{tðc¬:C–ÏöÐw¶£%?òXPÊÞRn¿Úzç‚'O|Jœšâë–Þö`xR†“ˆ¡Ër†6;hÈZäCFUÌðËñ%XúÐ9ŸðàX»(»íU ¿ÌãÝtÝA§Bеy?éÈÅ4éaúHä²pŸþäœí&fñbÆ’åIÿ{úŸßÛ'ÿf'üóOçäãÃSÜS!îy·?Æ´x ¿[ï†=˶zê×Õ¸‹?‡’=þ)ßú£¾«…;zïvÿì·o5Ò‰±ˆñ&ºp™Èž2òfý¸A‹‚µ…Mxe4pæ,÷gM¢kA Wù,+°¼ä‘ÅQ –âZ.OuLtˆ°‘ò+ºdïd‹8Ê›–cµœO"Jš®…4Oû±-“ýèvp¶ ÎÎsœÉo}ÜÚÄÓ4­ÇäA ·Ž­ëXŽG”έoK‹…©òŠeœbp‡9²¼Õ¢B‘6!¤V(ÔœtC¥8x¶²ØÝ5CÇhaÓ‰h™ q¹îÈÞ%mžÙ•¹˜'˜NäqÒ#²Z5Qÿk÷:”ˆŽ-l¾°o~FÛK^Wø»Õ,Œ»Cß—j«N«C£­*´Î2AVͰåäB±i¶ªqˆ•ñyð2cï€ÍòŒûŸqò ±IeTr']èF8 (o]Iß«bÝ¡¾ßV³Ñ˜¢Ÿ /’¨r³BU=½2“ƒE°ò-!Õ­ ¹¹QÚNºù4 C[Z㙃&i:¦í4j$mhlir(ä™S°W˜p-c²÷TŸ(´ !s6ÎÊRV‘upTņãMæ”!÷À-‡¡Ži¾å2A“´É 7hkI; yÀýá× O÷¥Ž.Ô$ÃnZ4²i“®hµîS ®WìFõK¦Ì?rÓT¤äiÊÒ5vžŠÅ|Èãîi×=ð0Jä-H©èHHªý˜ö%óBaO¬xÚAëª8”0zl> ˜a/ðe6ë%Ê6|ZðN^× lRëð«‘ódÑ/¼¶ÀÆEbŒ ‘Ñ Oà]LµŽG -¦’÷UËþ§²gk‹­˜ë^hVäò"Ï«|N2k]‡üÛ–ÊhëÔˆ‹bù 3<Ýœø¹–Pݪíß5*¬áPY‡Ê2KÀzsÎîq|ï˜â°”•ø|‘¯µŸè¥’AÆçt“ñÅoF,Éõb–EdVþØ Šÿ;¨—Ÿ•Ú ÃŽ2æž Ù”KÀXYù3‰q»òaÏTÙÙ‚ûZIun[€k¤3±Dc"âúÉzîFE­7ÐSõÞåõ™+ 5‰—@KÏ‹ÞÒ±G3\Z:6×É'ÝùS7 øË:o:OäÙ’ýòé©|qI¼†<Â.ãÞ´j÷òŠj×X`ÃjÆ1pè¡3KŽÈ]8”Q$?†L×JŒM_µ!AKÄ1EP˜Š9Æuø±lÎeS ¨­þ΂½K#aS‘}”ßb6bPóèQŸ™ ¥fXÉ¢6EvJ<§=ËÔGy±×}L¡‹”?ò$'vH?W¨c*ÇQ²¤€FT!¬8z>Qp’ hK$¿a<¤l õ¤… àÒ2s–Ó fœTœQ»iÌ’ÏÚ£ú!M§tnÓýÕ%uû-øGàde W¯6Ø{YÒmÅó^øJ^ÆTÛ^$6C!Kîyí]x³îÊ+SnŠ®$Õs;,šU89fuðEZÔqGa§¢N¿>>¯ÚþìDX%(‘ú„´Öì)°$p ¬ÿM°ÔÅ7 J¡¯ÚUsÕÑýª¯•›•¦Šõ™Â´P@õµ@±ÔšAU5K5  RLš¤x¼ÅV¹x¶=/0>U^¾e(óÄ}©¯¨Ë4V ;BMÄ6Ê—p³•i´ ä¸ŸE…¨ÎªnÜM£np1ýoÕx»Œv朩Wàëx¥ì^+LUàæåßpÓcÍé‡ꓲkÙb^\àñ]ò9«¤à_öFB1³m¥÷4XËG#ÑåÓ¿þ˦Ùò‹‡þËV•S~ð _r\~$ÐUg+ß.6f$Uù¡¤ønMżòA¤ø[®èOôKc©|¡¡gkŸ7è”Pä«g°§ÿPK?ÖA% { PKú>CwHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/dbconfig.json.exampleUX ‚IRÈ IRõ«VàåâT*-N-RR°RPJI 1uÀ¢‰ÅÅPÑ"š‘_\ÍÉONÌó )‰%‰I‰Å©`ɌĊԜÌ$%^®ZPKü‰{FcPKú>CmHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/haxelib.cssUX ‚IRÈ IRõVQsÛ(~®“¼Üu"Ù±­¸µŸ2ws£ƒ’h0€j»ûï· !¥tÒ‹'±€ÝåÛo¿]eµþˆŒÕ]i;MÑÇõju–ä†~®>´X×L #ÚœV&„‰zXYzµæ¬GTRa©†ÍJ ›U¸eüfVÓsW6Ô¢Ö<<,Lf¨fU°4ì»çM^( ›g\~«µìÝÇüê4ÿ㡱V×ë_i.u½fmíësý¥ÅLä5«þDš*Šmv=­þ]åœÖ¸¼eBZVR—ÍYjBµ»P]‘‘œôøúúSsP8y‡%ÄR¸¦‘þáÎÊø4a¨ða.ŒØV‡¢óËJÉ¥ŽYž~….kå¬?Î4&¬3(B[å-Ã+ÇœVŽÑŠKlã2z.Fï åûÍ/›€S¬{ÿpDgiäeu㽤ðÂÇïÌ0K‰·üµ+›QQ„–Rcˤà ¤ >>6ò;Õ#ȉÐI5gƒióqwmÇsp×·i×fö¦àzh9«øn2®ÂîXŸ‹$ð¶ü’¼X¢Ø£<-^èwFïŸý½}@êáÌa/ÉÀï ãÆ·Ë´=6Ÿ‹ÏŸ^OoïUrlÌd ý¹Û¼Ëô0ûÇ„`Ó@¯>¾¼¼Ìøßn–æÒöþ%RôŸ4ßVIm[I`^û `’ bÂÎ9õÍvœ ­Âêg]/˜ K‡Ã!^B’öšb˜w“Ë&’|Üï÷I;ïµí»§LhëÿPK¼šu˜Ð PKú>CiHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Main.hxUX ‚IRÈ IRõ½}ûWÛH–ðÏðWTôeÇrÛØ¤{fήÓt–é°›H÷ä ÙnaË Ä–<’ a2Ù¿}ï³² Ì|>}‚¤ªºUuëÖ}WyøÝ¦ùÎì‹»2»º®M¼×ý~{ûO[ßo?ûÞ¼N¾¤æU±Ì'I9ÔÄÊ'i9Ϫ >˜¬2×i™^Þ™«2ÉëtÒ7Ó2MM15ã뤼Jû¦.L’ß™EZVР¸¬“,Ïò+“ ¨1ô‹•ëk€TÓú6)S¨?1IUã,fRŒ—ó4¯i fšÍÒÊÄõuj¢3iuû ºš¤ÉÌd¹Áb-5·Y}],kS¦U]fcÓ‡JãÙr‚#ÑâY6Ïj(A ”TwYÁTp´}3/&Ùÿ¦4¿Åòr–U×}3Éú岆~§9´BX0¡aQš*ÍH I»1öiÒÐÑ‘[ º¨ëÛëbŽu kº,sè8¥f“ÐGý~JÇ5~AèÓb6+nqŽã"Ÿd8µj$«xåÉeq“Ò´xñó¢†QóPpEn¥¥¨ºN`—© :Ï[‰7³‡QÕ@,Æ¢(©ßæŒ:Ž×æìøÕù¯»§æðÌœœÿr¸°o¢Ý3xúæ×Ãó×ÇïÎ Ô8Ý=:oŽ_™Ý£÷æ?öûæà/'§ggæø¡¾=ysxŸöÞ¼Û?<úÙ¼„¦GÇçæÍáÛÃs€{~L} ´Ãƒ3„÷öàtï5¼î¾<|sxþžVíÕáùB~u|jvÍÉîéùáÞ»7»§æäÝéÉñÙ b ½:…ŽÞ cøf~söz÷Íì Áí¾ƒiœâ@ÍÞñÉûÓß_Ÿ›×ÇoöàãËßîË7ÜÌnïÍîáÛ¾Ùß}»ûóµ:@4I¬ÉÃ4¿¾>À¯Øë.ü¿w~x|„óÙ;>:?…×>L÷ôܶþõðì ovOÏ`À4ÇÓcè± Ž 4=:`@ˆùp  ¾¿;;F´°û ža{¿>.òps‘Œ?'W)Pe1«×ÀTfÙåóÍÍlŽÄaðÃ`\Þ-êbðvò§çÁ÷ïÂ׬œ$õuøñoÙbpš&“´´ßƒ®ûIآꮼ&rvWÕé<ø ÐýMªÁñ醻¬p'Á&ϯÎ>|KóåÜìæÕmZš¯›ïSø¸qTÀ?»³ÛäÞ¾mnŽgÀÍÌYV§'eñåΤ_ê4ŸTÜC™ÎakåW*û18¶Ù]d?l ê]'«B00ôãe½6öussã&)MaF¢ç\0^–Pt˜ëû<ù¼ÃÖ…éÌ«Y‘À·Í bqc`89ñN“§·qÑÅùn ›fÇà”7òŽÙÆG²cÎ3à“x›/â.À46, Ë»:­âœAaãގɱu6iX;ð¾ÖÒ…o°`ƒ ¿Ž¡j/âÖe„`7ÒY•¶TF=€•ã¨wVOX€%ß=ÛÞlw‡PØíEÿÒ0ßÜl3–e6IÝ´oKX—Ði<æÿŽ‚'ôìñ ª¸ê/ú3†‡ÈGzpµÜ/é¹Lk`ÿ¦|¨£ñ¬¨Ò˜ÁWKàçùòœÆï½`ç5,VsÍ̄֩)pýƒX4CjÒ…¿Ï¶¿ÿ#VŠkzýJ¹Q†Ð*üÖq«í·9âÄË|1Kë(3êy€â>êaG½¨Âu&€½è?_«îEþðº.Êt)ž3šˆîÌœ[­ìºÃ|eßæþ¶Ë¼mG%²«E첺¨õ½}‡™¬O•¼–ÁÀ²çú†e·Ñ;VÞÁ&M¸^IDëÈnŒ®N dªLÍJpãÇ®âËå´CìÏÒÜõó9è'¬äõùÙïós“mH%“óúMˆd"TR’%¸+!½!@.ê®é™è_€ ˜ncÝß‚ºJk[¡j868‰_@b£xNç¿ÀV)¦,â΃gƒí­r<ø¡ƒ¼F»'‡÷¶ƒÁ4›œœí¾=€úƒ(,<;8xP†Ó¾.*¤&¬F²cP”WQŸðA¬ü_·ñe’!ã¨`YÎð9Ë'é—ANŸ’Eƒ"moä w0O>°ÛQÏÿ˜åE ­¾=ºm¿)Xà®ÎnY&w?òLRTÌç n¢‘yzó_MžÌqksµ>*ýÞÛž)²‰Ùú‰þöa‡à¼^‚´4ßhLóÍ‹ÛyŸñ›Êßç>-áNcÒ¡ÑÂÒÁà#î”J:ЬJƒåÝ‘L&{\aaf³­ zêýfs•ݤ9X—eR‚Ýú1~çwT˜§%(ø‰¹þ2Ÿ‘u­À£àø§oè@HÀ=-0¨5M@®€X.ÀB›¤P.OHžÖÂj† ÃÀ0zÔf©Îrµ)Ø>ÓFó3øä@ˆÊc²«®@=éó4ä‡&‚‡7LÃk1Q¥ˆKø@À¿d”å–`ai †,’ÌzHI9¾&`ø KãVvžÔãk2vÍmQNV'•åÓ‚¨fZhk|.ç‰ØLysz-‹R¥%âþ<ƒª¶`ö }$ìò#4FÂoo †X«žð€¥$rK2r#f@mÔ˯Érá­Š’Èç6qA0êëµëF.,` û(Bc^þ2ÇÍ(/ q [ eýö îÕ±AËivÅðà`‘4a÷À#Ç%…øÚãRÐ3Y÷ïÜr‰´ ÿâ¢,Ùµ*Î8›fv·Þ‘ –ÀEaÑÖC›ãÑC=6BU‹jÍÖï€Izeð¯·jð–Ίzl HœtLâ’ò:¨WDRWDO@w>úÈNªõ»a‘yTËëu]/ø3·B3#Ïj b™À'_4¸RVŸEº€4¾P£á0­Åð€0è#ïÉ^øæ×„¨"­†ô € öÛxr¹ „øs™È'+äâиÄÉïyžÒÔ°¡¼ÅÞ0ºØÕŠ‘FD“|î› PŠn'¢m¡™†²rêÛÐßOª½&êVøÀß{½¡N†@AE¤«f_ÐËo õ—Ë) à ôyÙ¯If_¥õÞuRÆLRÜzcœT)(z}ó쇑¹µóós÷}<2 êv°ÛoH·×Èâº\2mnˆ)ƒÔy¡Â-ê}ÿæ4VOUO²<î’®û&ËÓUë7©>Çæ¯Ë´¢72uìZQà°¥ucî†ù0ùh^æ6ñš®Í;Ê£‘‘‘’«B¿ß¹ïìÈЂÄ¨[CpåM õVÚ9^Ôñÿ½ÜÓ·õ…B§¤;¥¢†¸ãcRU9\óØ*œÜŠÕMjˆºæTLü÷ÛÊÊ-+`Ž2'¡ r•¿fü6É¡Bip«ªÒ[Li ³ï··ÿŒîõšîu^IgÞabK¢ü Ãÿh>䑪>† ö¬JÍßãÆ`×ùbuØ®GÌ­èÛ€ðÓïêþL¿dµsdx¶r1+س'éåò Mûî9ëÑž¨… É4€òÕ…f ½>nÛ*'!9oÑ¢ÕÖá`‡o¡ÿzžËZêÝËÏß OTæ 0N¥-™ó ÀÛç`Ý8ÿ=ü¯˜$ÅÅðbØ}ø/xúØëÆ£Û[ÿ/.†/âÁwݧCnˆ³RHkŒ±ƒ® ìû²¸5Ña~“ÌÀ òd!+z¦õ°A/êD Ë—K;F€¦“øû®ëË}ý¡kžHßðeûj`/W)w±ßl@®þ(¥ô‹¦¦ßím·&vUØ6øƒyâ• ‡åWÐibxÝ®'>Ѽ‡oÎà¸øÓd9«y•xU¶¶ž7¨HÙ™¡óIë""v¨ÌGŠìúûöµ£M…M‚J¢ÖŠŸ´RŠ> ôl±¼mŒ*ß6¾™1‘‚A>°`Áöïú`¨›øý¿ãBÿV¦U1#ÉU²ì é êyT»þ)Ø@CÀ‚"€69™¥Höi^-KP”¯Êî ØØP˜–8ú±Ý0ŽRþåA8œb àªyUo´ÕòÖæ f\c[—©ØLž²æA]ð¸&êô/QIåˆJn2¨EGó="CŠlW bÌ µëŽò[R}ÍØä§j꾦,Œ~°æ=Ìa ³fX§{ÒLXG·зŽ"d»ªø+ýFõ9´-0j·J…Û Ì9LŒb®Úµã†æG!àŸ(Š˜UÉ%ZEÂ*74f¹Â76òôs1üs%®§Ú„GЬ¤bµ)U¦± ŸÁ³à·»V¦ú.ÿœÃâëÖCÑ5ŸP;·CQh ‡f þ3{ÇoßîíŸÑ[ó¿ÍMã¤ÛñžpC««ÀÑ{¦ W‚quýjûi5ÖjxöË~M/±o-¾åW¿ÆŽ“k ›û5Žoó´Ôò_üR1´x¸8qüJ§)1Ê74°¶Tµ )ì±í†–ç…u • fbîÒºëiY7¸Ê>¼ Ûͽ!°Æøèi]7$c°•«-3-½Å^²XÑå~¥ëךÚ.› z8Y·Ô>LAâ5Ëß&ÙLËÓ9¼„K(dÛD/°8LGx½–ì}œ.§ dE{]¬`L}V‚5ŒÈi!ñr’sKªåµ[@ÀêÖó€rìº:ܺà«[E¦«ðJ¾¸:hòºò4€‘Åô­ª•¾wµöÐUνJj<£&Ç• a¢:*T˜GÊRŸT3Ò£¤ÿ·“?Ú5.&iŒ_ºêZ”þÄûXÖ§I÷J+ ‹›¸c§ GË$¦½{ŽA²)’ ŒÒ£]Ï¡"lckü-[@ú“û¿³EŒN ½QŠ¿Å­ëoŠ›aNµ<$¶*© ôÖñç= aÆU ¶4(ÑÕ@<`À „ðwvž©ÄÆFkV„ÅÔÈŠ: gsƒI!¢^9êu2ˆ“i «HmõiDg¶ˆTé9Ø ,Z8<Ì“7Éür’€ÂTÅM(ìaî;D%J¤*?Ë™ê(½}G ˆ[ðT¨`büOº$͚Ƀӌ@#SÛ¡)x_¬>ŠNé0»)ðw£§±ôvµBÑ °ãoe!ÍÈ8”{Uƒ=Ѷ=¸E !€(GëQ}i±Á³2±µél§8~F,Ü?>5qÜhöue]…©ö¥¨ ÚÕunÆô‚z-«ï”+O„+ixõ<Ó^7˜§sL´¿®µò'*+I¯D}ìq±Ü‰Q ä{B ÃE.Á¾±˜ëÅ*Ì Ñ:|ÛõN²Ã¹ªVÔ³)n*Y8ÚÖ‘gÞ0>Š3ÉxÔÊÉ &UV›²¹*Å$ÚŽ6ƒìªø[`#НL6%Á |‡Åêh ªxnO4ÚÑ‹‰fO§¤|Â%%b^å°ð”pê\;Nêôsc‘f]ìí¨h¸=v/‹²«Géô¯Ë£"VL6aëô6Ã8&PdM5¨l¢$ åŒNbKú¨#²J)ùQ,ID8ЍkñGã§ØÆBÛzdßуByHÎgO»àzPäeY OVA£ZaxÖésóMëí³<$–Áßptçe’WÓ´ÞHaã~6éã¸\ªÊ½±ÿŠ€ _<õè ЫGÅðŸ(x× 9É­NrÆ¢x±ÁœJëäsjªbÎ&et|GÂ-üŸdµëéĵÅÙø=ÎU÷l{›¼u0 Ih¥h AÚh&ÎëÑÆ¼ºRâ0Ä€Ð{;Ì@›ëŒ<1ÐÐåaþä°å‘6¢G±2›QàÙ†â¥Ä[óÝ€`ÀÖl¸MÕAìØ+æ&à–"(_•Å|w6{ b?®a¹±Ž WrÀü‰LHò×5гj_Àu„é¼d¤€ÞØ¡7­`jCË…(…³ËGÊ—®ç$¨‘¸I™Á{Ó£¹©½»âMàa¡"¹:*üšp†—®Çš@ͰÿIq(#@Ç7Ô&ÁìtË•q¨h@ÌE8ZR¡ë,g!£ å·»Šä‚ç˜VHž/¦ú‡ìAþÕJa/V£Å® x¦ØÙ(}ú^CÉÚ’9Çj[ö¥¸ïIùUó<Ø=^XutÂŽÔó¾yẑþÕ36èÐm+BóÝgV€ë8A~_‹lzgà':ùhä:w˜³rÕÿHÊd8*k6Ušû\¡n*3«ºLèæn*2‚ `2`é^{ºŠ<6Pû\EBt&ž›Pû³;c$²J$8‘~w4ÓZ­;`æ50dxX¯Z–§¨ú`“Aµ˜3Ž8—ÓV¸¬Î•ìD ¿M?jÆØW¶PJ?$œo?Y'¾‰‰{Ro–A"¸ÙªÎcÕW¡Þ€²`eÛoa>^×Ûõ”Û˜ÞQK ‰üI¶;ÛIÐ ¡ŠÎfyåîÈ: êêÃöG¿­ò‹G‚&¦š.‚ò¬+mŸi[&BÖE©ƒyøxS†Ã"Í‹cçTW´å°z•ÖX°KBl$Ãî+EŒ¼A~ó=¹j‰¼Mò»p$ëdi ¥BJzEvš2 5i'†43àt½.jMhôÙNâiWãÚÓU©"^ÛÞ¼x•¥¢"RlM_ M¹¼¥Ó¬VtYÍ|JêBGÝæÍç϶gý%5 ªÐÑ« ,ÁŠZñ>ë1*ͳʅ„,¾µ¯­-mÏÑ! ã ?Þ»·]íq/;(VÎnbñHŒaD5‘ ê¶®›êM{dWáp•©åËù¥ºF“WE1áºçÇûÇ#ŠÒÜ¢å1›%‹*euQ¸dÆÝ“CƒùO/Œ9¬;J(2eêè 8i–·Y•œû¦H&ê“PƒˆrÅþº®¤WúLèÒñ VÑ=snÛÙ`½t¶e]ßô<¡¥NH}äP”F³º›ÀkMÄ„ <]?öU¥n £çp#²z9hCeø.û˜zç6/᫆g,§\æáZ‘ŸTKÃRÏa"TJ-;±~êÜ×ûu ΋OÄAÇ´Œ>#È\ -í±ŸËÃV£ÀËÌÊx|~·Ž·IÝÁ¤ß¿ÿ}åëÅ…|“w g¬I³ã¹¹30`e+ÊZûp1¼¸ø8¼°y`ÇÐD‘û$¡ éÝ,¼+‰xeš¼Íâ@ÕÈV‰mïqà'¼ï‚êÖËÖÖz 1ösV{ xÏÞíÄr”@¥dåò‡5`‡(èÉ’Òk¬]NüuwGàÀ:&Ùtj¶¶PYÚÂu!P˽uÇ žn4R!—;Püö4%ßçu’_¥äX‰EÙ‹A0ƒùIn8à¬Be=‘/¬ƒOr¿—› ø¬pßÁ`±Ç­-Øîl,5?*´‘!—¡îèìgÞ,Öf™×Åç­h’ˆU L»2$œš¯ø‡”ï-’·ÈL +G\~A#¹|ÎúÕØ{(f\|® Ìbî±!ü t3üÜH ¥OOœ°rŸ&ÞÉõUL D xÍUy¯²üa/á26VÛËÛTsÖ¹Hép×·Ÿð¹v<+×—÷™ƒ}c‘ÄðÂ|y'ðO’TóÏÈÓ¶ ÇËOÖ‹Püé=oàšŒèŽdDw¬æö¤9¡®Çϱ)Þ¢J7«.Œc×xwO£S¼^L:¶%@ì/—Ùl{á¿… ÈÓÕt@»Ó7:[x–ž:ÈL9>aâþ[à·ñ,ƒ%£’9ØT9¸Áõ­|ÝÚÊ‹­‚®aí| ܳBï&^¹WLÄùB÷¨³¶Î Ä Þï’–MÞÅtófHæ›`3@fsÈ>fmÎ;9»SR8jZšù&™"nY$`ÓîØ&æeoå©»Rã‘nØG,oHœ0@èÞã—U4Òj£‰,û-¬£uLÁ:!ªñ}+ªù6 Óv¸]ɦ£¯+c”è{#;ö÷u`7v–9Í/ÑrJDÁÈÃï4ýü»& Úu{„÷Y+HÓͯž÷'pZt˜N(§Q·ˆ ‰í"ßÚ¢«Ë‚­qš^"EØlF_ÀtNB§ñ;ñŧwRòžíÌ»öC'ײ}?Ú„Êöm(àÝ¥–;æÃG•õ”@_Q¿^ÜG0Oï\ä°ù,L¼§„ï R~e0ø9ÐÁ;[¥&n+& <¹–Ö]ƒÍ½œÕ¶†­ñÂDOáCdW‚~, ~ëK¶ˆÕºÖ–ô©C{$ÿ޾tþדáe–«ë‹œV·Ó£‘uÔ1n¯cÚ(†.c}úï£WN¬Š´#IÒbG5z\õx'iYÿ—\r‚þDòì³sÖ]_ ÌEnLC)¾/2PíÜå*!x4K¼xyŠë2 ÆŠ—ÓÆ´ÛœIêX¡Óf>rhí4sÄôëãL?? ëùÂØ³º•UïÖôñ.*r#plÄ©8.œiK+ÁÁ•plã?º8dåÎ’ßwÀå^”$S±•ä'R~²1‚•ó&í±l/£»îD)€íEìO¬½dJ6V5>^½à0rÔÂhäW:xVšåAÆßj:¨N°e7nk&±î@l[²¨ÍŽä+ÃÄØ‡—£\^Ѹº‚T2ÝZ.Õ­5“ŽI‹Ê¥Âñþ™Ü+ê6roo·Yon·zõjQÔŒ<9B‡ušWÏËš’ðc™pï›Í³‡vÖɇíýäó}ìÐjf÷êH¥4H_ƒä­àv‘Ë1løÿ\òbO³|%Ùj^ É•ó2‚z]O¢psÝvs×*S2bíj]ò‚M·Èm}äùd6‹ÚÔdÙ칯b³[î®b¹Ò{Óíá<Yõç? Ƚzxø"Æ;ñ"6hòV€çí®¶¢Ñت«a¶TrÅ-,‰«6¯m¿ó¤å–“Å/¡!À ¥±Ð}?¼Òä•'¿ø`¬÷@q¿–cÜÍjŸÏØf _m¾ª¦1ˆ.½j\f æç.\Ñó<ÜP7>¾øÇ"²*ÝÀIÖg(ÒØÍ1 )ŸÐW˜Vãd‘î–W1¹F²¶KJò÷Ù0Þ*¿Bý®=Ì©q2†N‰ØTaÌòDî±õ,üyìOž;Q§—ôàßf/tßÛãîK^½Ï ¼p®‘‘.¿•sÓûxÈG4 ~¤Ñw‹÷I.íÒ¨:´ç†nu¡Ã½è¹7Ó¯T>ÂúxçÆHê£ØzqØéú¾”JQjþH þ Æãx”üBŠ¢–~¨¿yGù¨†ØüþÄÎün…Õ ÛMÆfõÀ¶âq„¶¢Ÿ.¦×¶òÓö§ÛZå:-dË/¹“Æ ‘»';YÖסÞÇÕèxͬ¸Êò(¨{—ˆ»f„0‘š«ðJÍÈ_ðò4—ü˜)þ¡Œù SüCïØ¼¯ôD¬p¤F¸ }¾}ä†ù áPŽ^´289=þË{–Bøë îªê”¯®¥ïö~dØÔL®@}WÎì-°···ƒ«¢¸±[-Z—K¹Ù\hï‡;¦t&ªuWÔ… õù®×³´Ì’Yö7¼pd5•wÞsŸ|Àm¢9Ò þc–æá]d¢x¤Q¼Ë«p-Ç ú_›xº²¿ÝO;ú¿`ÜšïŒ%r'j©P§g&á¯@ZQŽñ‚öZô»¢§›¸EF |2¤½¥íÀæüÝëêwæâ˜/÷Àýjç÷#¡´-n-7{«V©:ZPmÏbl È‹-” ®ìµXÖwt}…UXí]!FÅ`ßäk–gP—Îú=ÕšV·”_j¹ÿ?÷Ì£§_T©%ÙÅýR|êEÞo7b®¦Ð_I¿—gÜì¹üôÿPKDhŸê¾)…PKú>CjHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Paths.hxUX ‚IRÈ IRõuQKÃ0…Ÿ;è¸Ì‡)ÃôÝჶ¦µløT’ön‹Ii²Mÿ»éV×{îù‡Ô¬Ø°5‚ÕZR±O”‚Oü?($3æÌV¾ýg,³¢€k gY²ˆó”Ò îÁ]½+±‚ÏY-Zɸ7š ( å?A•nAF#z¶Bƒ`*½•%p¡¤PºYy«•üj—}Å,î°95ª·\vÅÂeäê(Üh²DNÖhÃ}y}ãóÊ“‹pô˜‡ôeš<¹ˆ6h Ã’Z­Äš¼­†½Ø4™Å'¨ûRòqÊžçy”¤'È~Ô=ùÎ:ûç•A;σ#fq"}M2š¾ ýüPK–š÷ÚöPKú>ClHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Rebuild.hxUX ‚IRÈ IRõ}RÑŠS1}n¡ÿ0.…Ü‹5úÜZ¥he_ÔÅ*+,‹¤IÚ†ÍM.ÉÜm‹ôßÍ䦻ć<äœ3““9Ó ù ¶Ð{ùN´5ëÙh8š¦õ!#ÿd¬^#êfvÏo‚—:Æ\!­ˆ¾éug¬‚ß£á ¢@#aÓ9‰Æ;«d£¦+ Æm'ð¾‰Ûr90–¶qºAßöÄ»:·˜ TDÂ|®³¶†þw÷3âE€6]ÞCqEoM²¬ž[´\ ~ðJW5¼˜Ã›ˆà.ø=°e>À˜|1x -¨tc>N¡¸º >MèëŠÃòÐj‰ZA)€u‡ 4öàØG–z:O„mîÒ`èý­Æ¥{¬®®?—7‹ï×WõÓì6)d a|.y]¶»¾' ž¢b¡OšÂ+Ò„Þå°WN?øt¥®(X¯`EüKZ£²'šæFüÅ.òÏ=JšûúÒ½‘ÅTµöÏVÈGŠƒRø¼Ç\i›†F@E‚ÿñ¬k•@Íw‡Æ²^H£lÓ M.~db'iç6]QRPð•ž~<:ÑY2ÿ»|…*íX^(]Ÿ OPK¯,í—PKú>CiHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Repo.hxUX ‚IRÈ IRõ½ksÛ¸ñs2“ÿón.T¬2¹ët¦uÎQ,ùÌ©,i$9~ÉÀ$$!¡H–eûrúïÝ]|èaßµf›\,öýøúÕ‹çì»Èò‡B.WšùŸÞ¼ùËŸ~zóãOìŠß v™•i̵ÌRD%ô‰(ÖR)1©ØJâö- žjwÙ¢‚e ­x±]¦3ÆÓ–‹BÁ†ìVs™ÊtÉ8ÑŠ€5bëRÙBßñBÀ†˜q¥²Hr Éâ,*×"Õ$[ÈD(æë•`ÞÌîð:]"ÌbÁ&S†ën™ÝI½ÊJÍ ¡t!#¤Ó¤()c”Å-'r-u¥,‘ »($\*Ðåí²uËþ¤b^Þ&R­º,–Hþ¶ÔTŒD »ˆèô:+˜I‚T$è@z×RvIoà”£µ5ñ¾[ekÄ%J•V`²EY¤ÀZо8ç/"ÒAò‹,I²;T3ÊÒX¢vê¬ræ0øm¶¤š‰‚4Ó ¹‘ý’×·KjÅA[amì¥1ohW $JC\HpIžÄzWë åjÀfãËù‡ÞtÀ›LÇïÃþ Ï¼Þ Þ½.ûίÆ7sÓÞhþ‰/Yoô‰ý#õ»lðq2Ìfl<%ráõdŽ.†7ýpô {{Gã9†×áÏÇÄÔ’ 3$x=˜^\Ákï]8 矌÷.Ãùi_ާ¬Ç&½é<¼¸ö¦lr3Œg£¤Gáèr œ׃Ñ<Îcƒ÷ðÂfW½áÙ½Þ h2EYÙÅxòiþr5gWãaÀw°÷n80ì@Á‹a/¼î²~ïº÷Ë€v’ÑQ¤ìÃÕÁÈ·?óp|¢óPVU%)n÷Óx·ÿ4Z;e(X%Ø>õº?bÕ–ÒŽÔïS/ÐëÜk °xcÛtñÀpþ…ƒŽÀ0òØG’]]”-/†Fî?€µAÛ©_D þ~çʸ*(¿ÊÜÒ§Á^ƒ)ï!J訰ï‡oD4ˆ’L ð§9Œ áÔÖGæ>4¶5©ÑD$o{šAªÅÈ‘Z­bÍÞþWÁÕýæ"ëÄDÖñ:O4³‚°0¼†È](1IT©¦ÚÓ±ç¦ÿ\üƒSC•ýé×ú¿ÙXW>UZÑÛ¶iq¨ÎÙ¯och4]pÅ0Ƨ@ÁaÒŸŠEbNkUÑ$ô{J¨!ìJPK=$óú53ǸªJÉ‘ˆE| ÚZsæ¶ZÞÎV¹kƒ-žn­1¼6|§"·îS·fßݲOݲ}wËv³æ@«š¶Pb[ ØqŠ˜h²ÚÔÌnzfzAMÕÄËò Öfµ­‚é2ýÝb©-K˜©+f4#c!àË ²ÏMâ¶­}‰íoÎð ÐÜ>VÁb³æôÅ*÷¥‚Ý8¥ðÄÚ¼n´†ð^v,®uwd°°X…n!ú¾6t¡¹Ðàµjç¬dxmy ¿škF#{³Ld6Ñœ\ÓŽpv#xüL|Édê{g^#¡ÊœNŒ¶™Q¸:Íê°§ ØJ (Žuœì¤YuIp²“´Šnpc. 4_a™T©„E§§ó•:´IfÎè¼VͧÉCe;“tOív]CP8ïÿ“ùÆÚÍzý˜%ªP<¿˜Î1LÃ5Á£¥ã‰Ú±_<V½òaëÇ¶ÒæiÇÙbƒ"šwºèƒº¬JGËÒºt°0íU¦¦"[7PAv$Yö• ¨F!Rín.éGàúôѸã9rsôøH¿©¦y@îB¦R¾f¹9P•Pòvf·>)UCI5e¶ ×ÃælÕÏ"œ¬êÙÈ¢œìtXœýÂ5\só©µ >®“ ®uÀå–}X3S­o¨Ûž?0÷Í~§‹¬êm4e¸WäVdÙÁ› ëˆ{Jš±ªHSw’†ÓûFDEx@ŸOÌe=뻟»Ÿ;gv¹ÚCΩ·™}Þ"ájåuÍ߿ ßð;Â__ø†»¥¿ÁšÁ¸†0âå9üÎWø›®ã½3Œ³ô¥vßÀœñËtý åˆÅ‚—‰>3†0—2÷U>ظ®Ñü0y2S“ü¶6´jºu& Óï¯ —*,!ƒ´\‡i,îÛ}“Ö.84ü]¸r„|’¿f(>UãvÑÆ·9X08Yœ5Îfè.v>¡B½I%KåŸÓw[¹LÑŒR‡¦›6x©gàÎŽ ýhÀNÈà7¥ bŽ ,ì]X·¸FðÀ´NdD¼î芾À3ó)&ÈÖȶE¦ï xŠl)L[W1vóÖƒ¶ÅÎÑ‚o[ÕóNQº°ð6v»ÇÙijÅy§Mpê18Ê~We| }ÈMSnÖcÇ„;exccÓ2±¼7{•µøK†Æ5V6¯nI¦­%|ut(èª%z­XˆÖõ¢´—Gåz`õÙý÷Ùx¾ºK“ŒÇˆ÷ÆÁ8Í#Œ"€3^ëR¾ÚvØÅ›fD@ã €í/;CËž?! Ž|¬À41î%ètè ­k_Óä™Òaª4O’ý¯C]V±¨®Ož¸¦ûŸ} ù[çÄ*ü*“íæl+[]¤îÏ$!‘ÜýJ÷[fÁFî¹ãfC¹^7áÛX'@µnc¸^7€zÝrÂvq(š÷ЊXµa7ö}åHŠó¶æ§§Ò Â|¡¥Ûƒ§×\V_§Ñ¢((á«1È|,‡”nƨGú²mêÑ‘Ë-Bs4¿Ñª°·YÛõ(<-óÆ•“ÙsÒ²ÕþÕ"¢VoûoPKð§Ù…š Ó$PKú>CkHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/SemVer.hxUX ‚IRÈ IRõTÛŽÓ0}N¥þìTmµM¹!Jµ,H UÝÕvá…‹ä¦nkHíÊvR»|;c;·v+ /ŽgΟ9gGÒïdMA ‘©hC~ÐŒ-’n§ÛÉãk˜ë¥ÝQžoáZÒ‚Ñ=üêv¼‹éõ» Ly¯ßÞÚõæ2ñº{îvÒŒ(sºýH¥…ïòEÆR(ˆ„-ù&düžëä(Îx÷;¢Ó͉‚“Ïò,{Yj{u3Ë·†,mÈ*ç©f‚§ûÀ 8wê&%Có†\¡íÉÓ¦"[c×VÒ„ ‹ ›µ [V Ûµ.W‚¤ðÔ&‹@³½½h1×?^ÆîÅ©5vHª‘ÅïY±QÏŠ‹zVŒod+*1gcàèYÙ¬gjûX<ô¡_ ‰ÖTÏÈ–a¤ÅT쩼$ w–«Mfä×|6YóE-¾²1Û™ä’ÍU³J]…T{ù=ú|z4|ñ¥~޾Àd» ¹[PMîdM.œ„“Þ(q&–ÔÇ^ŠUé¥*½DOÝT7 ë^ÕÙØ4ççNΨCoÂÊœ¹òŠ.൪è2xF6€3„ƒ“'ÿ†<=Q{fæðù¬úÒø¤(|kC}Ù[9c(¦ªëßÊÈãø;8ˆ`*`\Al—#L z#ÅüœKšŠ5g?鲚 Ðd ½Â¯jîÿÚÌóãfþS@Ñr«>É­¡]h†@(Åö0\h 8š[BA¥2Ó£ìÈøÉht{õæ*ÆÓ,_RPbKáÃÍVÂÜÉ•”§ÿžPK•^ØYPKú>CiHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Site.hxUX ‚IRÈ IRõÅY{oâVÿ;ù·^¥˜‰c2#­T‘f*È„-¤ÓÙnUs7ÆöÚ×$é(ß}ç>ü dšÕJ])3Ø÷ž÷9÷<®[oŽÙÖ“Ç4Xo³»Íwçç?{wþö»ö8»Šóhé‰ ŽIÀžnƒ,à 2¶á)_<²uêE‚/¶J9gñŠù/]s‡‰˜yÑ#Kxš!^/ˆ‚hÍ<"åƒ/‹ (eñJÜ{)ü’yYû’lûù–GBÊÀVAÈ3f‹ gÖLcXM‡¨Õ’{! "FÛf—Ýbç‚¥<ià@~˜/I³Û@E%i’ŒèæT!i¶—ÁŠ~¹Ô/Éam¶ ˆú"XÌhÑç°ˆjÅ)Ëx‘ H¥K©4%d\¡Í%Yßoâ-Á¡B%˜k•§s‰¶Œa>É÷wî Z!ê«8 ã{ÒÑ£e@ªemíÅ9ö½E¼ãR-åü(Z‰BIJOë­lãA‡׿ó@ZË«h–’™@<pF§’ï¾Æ®‘ãºÏfã«ù§Î´Ï36™Žôú=fufx·öi0¿ßÎ ¦Ñü3_±Îè3ûq0ê9¬ÿódÚŸÍØxJÔ7“á åÁ¨;¼í FÙ ŽÆs6Ü æ ;KžšÚ ?#z7ýi÷¯ƒá`þYzíj0å«ñ”uؤ3º·ÃΔMn§“ñ¬!z <Œ®¦`Ô¿éæ.cõ ›]w†CâFä:·PcJ‚²îxòy:øx=g×ãa¯Å}È×ù0ì+nЮ;ì nÖëÜt>ö%Ö„¤’©ÄdŸ®û´J\;øëÎãéÓæS¼:Pw:/°? f}‡u¦ƒ–:NÇ`BÖÒXÒꨯ‘åë½ßÎú5‰zýÎg„_…''·ŽÏ¿óÖQ‡™»AR ƒÅÅñq°¥à`´àÞó…Û ²ÄþæÂìDü.v‡[]øÄË…ì1s— ÷Mm!ˆÝ+d‰b­Æ×‚÷J ’{*Dàvç ¯¯ÿ‡ð2Ol2b|œgtÂjŒË%zŸ=f‚oÍêÐÛ.–ðüIŽ‘8ìËñQF©ÇÇ©Žd‚B²yb7Ù—§V+^dqÈ?~–æá/XÙì›:W—? /eöüfò[o0m²&àŽö`ü”#Óö‚¹#N à‹¯Óœöÿ šø¢.ŠDf79ÿ•]^2K*m1¥Ð‘6al’‘°­-#ãEü_‘¥vS,¥=>áßÎKe™`—,ÊÃðB/eÁroeñ(°.Ù¹ªÕšv&80³¶LUȼ ²A: Éq+d6 @”3žqž…Œï‚P*Ål”?p?Þ"ä%vÓ ¢%¯ìFßh’Âgo¥éÑn⥿ÉCàIØÆÁvâ*‘·åÚ*Òt‰4íÖ‚½¤‚3±TÄ0V{¡@´Y*ÁêÞ§ˆ@ãrvʬ–…ÿ‰ž]±M‚EšOŒ‡gŠœØ¤ñ=KN-ªÌó}ž b[òÉ)t@ûà9Iœ9ÆH«lzɰ¦(¯ i®à£´_ÇTdå”A"?@@+2ãš‹ ÞzÀÓ‘CN‘ß(çQú˜´_:iòcC+K¸¦p–Ѻ1ˆv^3ý3HØ™,{10œê`ÛÐæ.áØ¦Â0’å1µÏÅ_ó"0Rwª rü‚—%u7KÂ@Ø ãòK«Ñt“¨YÚ÷ó½9/$¦ .k±¹hµNÈ[Ç*=ã`†Â=ËÅê»=çÎÐ%EkéYíQ}luVbj_™Ø–Ø~güy: EØß¬SH841ÈÚÌ:•òbQÉMÜ?œ2м%¡÷(©ãýyžE\Íù0°Y·­ÔPòU\'Í ànŒvâÁ¶Cm\BÃOÃÝ ¡Lɳݳ‚¸±ËS!Qßz~“é‰Ý2¾ÂØ#‹#FÍ­–éì}ï¼Í©ÃvƆš™r1)y< ß}.\/×ÉÚ#kƒ¦4]Ü!ö®éŠxÆ·;žÚòQùREØ“©/Ô¨Â¸ì ¼,ó,¨ý;GmXÂ7²yZÿ Û²ôƒ¸ë0^x(¼ò¹·&#àÌz³ßž7‰§ôAže¸l]Á˜-w1[ò8¹ µ%ºH•™LâReŒc²Š—z[”*GVì¦ Ÿ`™ÍÛ¯Ÿ¦qªM=çãÞ¸ ÷=¢g¾§^;—l íöX„Ž:eœ0Mdz$Â’ ÈBÔ2Ñ9ZÑÖnÀ;G3®ÆGag…¸ÍÖµàL9T=¹Ûp”dò¥ÍÜ\56bö3ßK8‘ T÷¤ãPº‹ˆÐAQ¼… .¥±Éxî@o¢8'PDKä( ¢­C´YK§I¹5¹%ŸNe$ËD¡º[/rêbvÅ«ýEe±¶úy*:DÙ¨Œ]É5* ­Ûè.BÊ*ÄiX§„~j5¬j4Úi0£_ÒF£àˆÙÄ•NEwZÔNÝ$Æ ‹G­ò™Èm™HJ ½Ôß@C#&QE%|jîYu-}Ѥ·‡MšÃ¤·À{­=óרS ò'Æ$cɼÍr©|®U„z|ÇÃ8©I¦í ÉEûIÙ•.Û"”dšé² àgVƒÁ_4ÚÜÆ.U“‘ê™ ›F<¾˜µ4 íßRŃN&qÚL£j]Z ë‡÷½Áh‘áRJ³7¿¼ö(¡á´ŸÁΛºÞín°]MtüÛ€S…É´Áe²,võåp_5vyAIè”9%]Û¯ÞÔ0¿z½[aÿ -D·8r_—Ä1£ß3ÉøŸHö\úIW^2Òí‚9ñÅ £Y©RŒ#þ\³šº¼¦.ÿšºú²é¯Sö/Ò•Â!?¶|û^ˆ2Ä£ßng.¢ù»2‹å)“ß­SõºaAÌÁºFm©ôYvPi zpÊ$o¤Ku¢PûÞáH•W/Š81®xíÞSÀ‡cÓÖ0tÄʳN•é, Ù+à ºÔü’g~$²Ã’è ×CJV¯äºæ·=§Fä×JëEë“Ð̵+}C±åõÇóë‘2>M“[½1{àÛ=”,iSGà âDÅ/ ÍÔÕW¶£»Ñ]åî³ù&¥»Nu‰¬} u,_$pjý°»D}¤JTX‰7N+WJÁà[OØ´à®Òx«3>Úg¬4ÁãÄsØ g' vò™\·OnÚ'3vòÇ«Ì˜ä ¢ %¹W`x¹ØÈH2ªÈËœW[¤Ñ/•{Ôõ-î¬ù¬yÈ2]¯÷+Ý}@¥™R·²åçBõÕÍ3:tI´¸0–_`Ug,/ƒmFM”™O›•ûVVå&&Ð"ã)º~ȽÈ|ì¤ÖI!|S¶0££9’Ÿl¹írÝ|<ÿPKÛ±'h‚ Ç#PKú>ClHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/SiteApi.hxUX ‚IRÈ IRõ}TQoâ8~>~ŨO°Êµ½J÷Ò=ÀëB%¡½>šÄï†8²MÙjµÿýf ´PèIHÁãù¾o¾Û7_zðFº{5jU;èw··þ~wûÇLÅ ½i+á”n1“’SiÖÊZ €²PK#¯°2¢u² `i¤½„²f%pDû 4zá„jU»AT%êR²«‘Éê¥Û #1¿a­.•@J¨t¹YËÖù`©i¡ïj Wùq5ˆ ¥*)P-Ðöa¶ÊÕzãÀHëŒ*‰&À¤²ÙTTÉa»QkåF=ƒo‰%ÞE+Tmk]©%}¥÷×m²u•"öÅÆaÐR°”-¢ˆ ÝhV6 ‘(4àM¿×xÓ(ÔQsݾ]^z[ë5åÑ›%l×rcZ–VilŸ×ý&KGb_ê¦Ñ[òXê¶RdÍÞï§Xà¾Xèémí†ßj‡UïJ¡‰tï“ÞoÙZ ‡…Ü·Å•ï–8rf¨ ëð<(F§×ýèøúPÇ”AžLЧ0cÀsH³ä‘Ù®Â×W<ñbšÌ ÀŒ,Œ‹gH&ÆÏðǰӌå9$±ñYq†a¢ù˜Ç0Dhœñ/·H¼æž³œøf,MqyÄ‹g?µ /bbž$„†YÁGó(Ì gi’3,bŒÌ1' ±‹‹kưG\@> £ˆÔˆ.œ£Œ …Q’>güaZÀ4‰Æ ƒC†õ…ÈíÔÐÝ( ù,€q8 ˜G%HäMRæ®Lxš2Š’jˆ¿QÁ“˜üŒ’¸Èp Ý¬xC?ñœf<Ç‚½Ç,Aê.‚σИ툨ó§ÂZÏsvRј…2æ„?Χ!ßô:Q~+‰§R7öºÆG¥Q‹¯½žZÓá8 _…´‡¯‰Y –/²Ñ;óíHžœžÒCkHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/SiteDb.hxUX ‚IRÈ IRõ­WmoÛÈþ,ÿŠ©‘ƒ©TG§úEvŒÈe³•E¤ãEq È•µŠäqÉ(jÎÿ½Ïì’2å‹àPÀ€ÅÙ™gÞggOßÑ[çÅ®”늬qÿý»wÿùý»¿½§ëè« i^gITÉ<'3/D¹‘J@RÑZ”b¹£‡2Ê*‘ hU AùŠâuT>ˆU9EÙŽ Q*äË*’™Ì(b¨z™¹ZIå«j•ü EJ屌IIבUÚZÉT(²ªµ ã ‘8î ª¥$3âãö”¶²ZçuE¥PU)c†€)Në„-iS¹‘Uë¨FÐ!QŒ[+¸ÂÖh“'rÅÿ…ö¯¨—©Të%’Ñ—u¢bb,2H1:ÍKR"MDÂíô“í4ܪ —V½]çæe ½Kת.3(Z,É>­÷WWLaôUž¦ù–}Œó,‘ìš6Y q-ó/B»e’Ÿå¬6¦pFЧL7GjÁ‡¥hÂåRG+êxV²ªB=H$£ÈK­÷¹ÇvkǵC7 ïF¾Cn@ ßûäNœ |èÎ ¯½ÛÀáæá=ySÍïéŸî|2 ç_ ß ò|Fso3×Ùg·w~E—{!ÍÜ7nèi šëŒwãøãk|Ž.Ý™Þë¬MÝpÎÈSϧ-F~èŽog#Ÿ·þ 1òÜO}(rnœyhC1hä|Â×£ÙŒµ1Üènøl(½Å½ï^]‡tíÍ&ˆ—ì]Σ Þg#÷f@“ÑÍèÊÑR€´“Ìi̤»k‡©¬u„¿qèzsögìÍCŸ¸ë‡{é;7p4òÝk}J8ºò4DçŽâÈ&,ü}8MœÑ ˆËwù9ɧGEŽª2O•½ÆPIåòìèHn¸8Hí”,í·gÏá®jO<¶QµV,R+.o–¹=Ålè’ø;Ø©Jl -N1SèV‰’Ä×Jd‰"ÏtË·££žn㘾D%É„†¸ÉÙ5‹6‚éèñìáðhU§é+ÇbÉô…³‚mz::zlí\”¹¶íÿlj"T\ÊBOÒïslÅRÉê%ùfª½„žo³4vÉÍ*ú@ïÀðqXŠTÏU ç¢ìSGDSÀÎy9äý‚ˆÿÜ ÕÏôóOæû’G=ÅÃ;nÙWu¦'=¾æÎ±h›—ÉÐXN} Ì0³Ï¿!ŒÚÞŽ\ë=^ ܽë-;“‰­–°úÐ×c,O~zÿ~:aÚ ÃÏ*šÔáÚD ¿´•ˆÊxm½a|;•Ÿ…Å2}úýwzÓIIç¨ß\zí¢Vk‹Œ‘ ´-“ÖÖ–¢sþHÚ2Hán`£ñ…Šz)2Ú—»9­¾öôô4ô&Þk¯È‘ä`áMP¡U¼æ EÕ…nÄg>UeÛëÆ~"ÊËÝPÛeWù,ߊr)?´«¨3­„)leÎ c§™Iûú÷|ÌGº¼§™wçøƒ÷O°eD©}ãÞ¾gÂèáOõK¹NAwj°‰îA ¶é¶6¾V|U^À*eQÖ´D§ê ¶©E^-ê¬2MÙ5ÁŠ#UÑM±8ûj—â·{ŒuÜÄ (ÌìÛyh½ícm2P&ˆ+ß»]pÙË}4 ÓÄ Ææ^¤cú+e} «:E6ž‡¶i´ïŸbçxýš—&bÏdöýS¦íÁÇa†ñ-Sq¨T|‘èaØèdõæ<øe/ ùâ ¡ÎëÍ~ÚûBƒ«Ï² g×z<@FT¸¯¥}!àô—Ì´Z“Ù*‡~p[}t‹Ðaß[Ñ)¢–shLî%CµxbèÈ ô/•þ¥cc~§º¿á ¾L¾fyÔ½èô”Ôo)_ IŽ%ë ­#,§{"°À U¸´pâ|ÃË»ú±+ãùawóoÓ``^ù¨<î‘N×}ûãüyi€ýÌž Ìs㬙^¯ÌÑå®)b‹Š§Š~Ué›¶>| Bóç<©ÅßÇ¡L,¼AÊAÛLM_NPo©Žÿ:³wЄ,|ÐLøî½ûƒíú4TÅdÉ›øèÔ-Á<γLèAE{»è—5)¿<²•|¨K“ß%/n€8 K¼±”ÚéË'Úé×C*0_I<îùª¹Í`ÁâB—+²&—¿`¯ºW¶øŠé‹××g½›ÊÚŽ¡¯—ö?ðò²‹¨ÄÕõ$†þ…71àûú6ë \A$Ða#‹LÝ™cX`h¯3¼aP²<ëÐØ\<’ä…Ù)šu£)5•e´;o¸Ï';L_\çß ÏɳfÝÓMvh¸¾›Q~@Û—QKñ?û…fÓYeT¿ é_Bž¯ãR XÛ¨nÌÚÒëÅúŽÎؿǗ÷4ä6«‹}öì8ÍU—} [žƒqÕ>!¦›ÇÄS)R»ìdù––XP±c1ŠSপ~Ùó*È¥ïX÷ãÑÿPK™5 Y:PKú>CmHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Template.hxUX ‚IRÈ IRõ¥TMkÜ0=;ÿ0 …H:ôjwsI)ôÐ44!—REïšh-#É›]šýïÕ—åµréÅËÎ×›yóFãÏl…`¤:_³Šæ©<=9=i6Tœ)¯tþ£3lËì÷F5íê;ë|LkxÀM'˜AÀÁ¶Ò!8YÿœždÚ0ÓpØ2uƒ¢ºa|°€_ •$´Cë¾å®…ï¼fßaqã?Ù·lÓðkê‹g®¬5¸‚6(_¡ñq·ÖæÓ|ᬩœð9îm4q™4VÊŽÜ÷]¯Z* ÞM›0¾µ¶×–ãWçЈ†~aq Fõø; ÜG¡éU{4¿«Ð]‹ICµ÷U‰,⬗!±lÑ",(1Ú~ýÒ¾½ºÎdMä0dÆ™FxðN‹`ÌÒv´%2ÑÎÃYà/øêü? ¯¯0µ_ØÉ–¼íÂRó³{i÷ñkܸáï”ìP™=‘q:š°PhºÍ²[Ùâà9„ß kÖ Sõ6T^3ÉKea]ϼÐë0ߊmyVømÒÇí qâ}/[ZÀ¶<²:ÜÚ^ˆ=ËìGnQ©¦BèT³u•úÙ°g¼cfM°x”M¯!©EÐA9Û/Ù)èÞ²žÉ.¸¼º2ÒŠ»FÂÅwÕY-˘҆ gDœuá{u»ïòÎpžŸƒ'dPz Q䌧=*Ìí®d´eéæ:5k%_BTÞÕ©FÛäé±rìÔÒÌÆNkCêç’Þ ÄŠ| ¡q”DÖÀ=±+…èL²@BíÂi Oi”OÚ_Ú›B-ÅÉô¢'ëš+‰ËÖØçu¦§©œb;QU£¨Ò äŸ1nvî³O¦oªÖF¼¯Û)Ð iîø`¸µž/—¼W [³\΄‡+Sb´¿ÙÝtq+!Ÿ¬ªÿóÎõðPK¥!Ð0ÁPKv¹B,Haxe Toolkit Installer Template/haxelogo.pngUX ™IR/7 QõÝ»‡SSÛ6¯W±aCE@@ºtD•zïé¡#] DEA@@¡J ½÷^TšH B¤B/ $ï9¹¿™ï?øÞ™73 Ã9묶Ÿõ¬µwaZJ´/@ Z¨²¼òÏr vî,p+›Ìü:ï®lì ÜŸN=¿—â\¤ñ‚ª+ÐLŸa8-ų?ù&r•¦ç‡ÅOø™ pG}—ìÎú>g÷‹¹wþzgQ6g킼Ãð“I"tÜ8gÊžY"f¯ë[µÇ#hj°nTÚ¯ˆrRç2Žoјªwqî5¶­šv \Ñu™ãô¶2 ãB±+\çô»v9;Ñðy‡´Áú//ŠýÃ$±—´—ð/`®uéÒVZ0îs äÿùOÆKDLJ6[öÅDÛÇm´ñwñÓ† ¥²•é‚ûUôb›vägä¥Çébý§…çÑæ©y¦3ˆcÕwRHä-ñöF¡õu¢[²²…ÛJ¹’ úY/7³h›±NîWÖ …aC›$ÒººuÞ/&Fx[[@ðóÝÄ>7·Mú :™$24°™+*º¶D·B+㌜!Ã)eX9õ*ÓÓ»“ÉsÚ8\ëÿ~¥)â¹èȧ…9é´HkU. “©×W¤9V,~ð·ÍØRžÒåðànV)¾ì²H ß>è=iuë£Oûz¹#Ïär(æ(ê¯OÏÔ‹Ã 2ïWË)ˆ:«d{£ÆW²§_ëRžPÀW¯J\åVÌYYÆ6¥Åƒ_)*8›üª“CŠžÊ„-ÒÐŽ5ÁË6Xº¥™tµ÷Ö‹~ú««|ÂSoJóˆu×È‹YÕçíªøÕÚ?óîÇKäk©6«eà l0ÙÞ´âñög]<_ñ(3¯·,3ûXÑë´´;o£¸9&Oz2)qrtg gÈŽµøNy ÛTâj)ø¹A¬Èþ4™~é¯GÏÖ¸ ‹ð´ä±H±¯J\§æÒé‰8 Ë[ó®.|y¸ böðÞZçÀA¨†v½‚Žt äÆ.áÁ/Šoê°¿òF[&ÑHð%ÊÞíÆ”0qi›„¯Ê>³ný0Z+;¹ê²YO+ÃÕ8,ÚspÔBxe•‘å& Fò¹o¡ylC´j£ªŽ“ ΘYSñA™@·ö^ïïÐþÖšL bÎáN|*ÙÔ…Ìi¿8§¯QÛ’ò™:LáZpôûXŒ,'/‹¶|"YØãÉöúÆÜ7…•„¹ƒ'+ü2öVµ¾ÿ.ŸódªK@µûŒìRXl"Á ÷ï øsü#”t¤4Ï‘^éµ-g;¿—“ɦ±µk±‹xàØ±äy”>q‘œ˜mêäÚ©4f#P%q§7os$+(ñì xFÛfáNùcU¤ÊË\Pñ`ýL/)g¼Ë~¾š½M!·–±!Ï~¼M6‚ÕM¯N:'5z'kçýñCJ±žîÚ/ka%Ù†å|b²Iªåíh‰m¢OXŽ(bÖ¬§ˆRlÇ™Ç$ðëÒ_ùÓ7t8ý£Ëze&¸ÂØ`/çaBZØoiÓÓÀ7D«4Ö”GM{³3¤Ê ´MöŽëÒ{/{U ›p¥J¡ä„Ðl¿OA:FÖÚÍ[›æ ˆú…¼ÕíS©H1™ UG‹Ù€âAÄACÕÚ¯ššJ·ç—aa>Ü<•r=Cã36ªVÓ­Ëï\±zDœr7“EÎ$Í_†<1Ò½3䞤1ÜP³%ˆj† Ž8Í@ËØK:Œ%`¦”´wW~  }zWSîRX[(HA­Ì‹*ð<ô‰îcÑ Ø&7#¿» "šØ0ÛG¿ec½Ú²â‰J¼ã½[=¿_ˆúìçeáQô3û…Ùýý›Fç}!;…ÇyäñÅWÍ_ýÛmr c *qP˜YfË”“d€)AØ?͹·—Ÿmkd;“þ½ùàîÜü$SK"–ÏÁ©JZ½=±1e¡â:Pw}Ù\“¥ß#.Ä;}SJoüo~«-3°üÅmlˆFÎ8­á0š¿Rôò{_P‚¦sP¡\‚’û¹Ò…2óOßvÅýÚ·{Õ\ü’"Ö’4^¯Š"àߤ;¾âÐm|j•TnØð##g>ç#Òdã`íÅÊÅ}Môh§Ìnx%ß_B|h´ŠA Ç—Rít5ÂÇèE¹ÀGu=½cëAK¼¿ª¶î7N¾¢‚§ª¢Fw>¨ðý3³{ hxßdIiqܶ®¶êvx%:C¯²å¬ÿ{ ¥ÓäfœîÚîäýñ”þ&ÍBõMXÛçÇÀº3«Åú£b§8§»„|,rìü›Áö›0Âb1pÕ.æÚ’‘“;lO¦ó)Ê…Of+-NÕlrq˜r‘â²ôT®ÒåL@oÿö²v£KLÔ̵}Cbè1¹fE­C7K ÒÒAòÝ쥈ªÚròד2¸u'îœùpì§¾Ïgz^%ÔÅ£Ää þ_:ÀßP|ºãŠ2‘ÞdùÙ QÓ³¾,z’OârîOCèÉÖxî‚•Íy§<]¶´ *Ö Ë—óÓ#Öò݉ø~|²ý;•üûG1ò ÕqH¬2­¼tJtƒn…~~^ðe`öždºš§¢¢i¼œVyÕ)·[­þ4D$%M'ôrõýÐΗãwÙÊrÚâ3ó“jõ*¡ÃÉw럾se2EgGŠ4qã¯õ,‘ϧº’æc•¾ *‰&N/~5*‚õ»³ÖåèTê… îÚ™òqÜIÃóòWøäÖØ(\`ÞWc$|:Lî=¥XÇeNÙ¨qNPˆ†ú÷®Ó¿ÓÌE^gu ›Ç”LÉûŸfò ó¡ŸÐ;ZPæ^°¯Wþ)½#­Ï ápûÅéßOFLrŸÞ§5v%ÂãœQæûðÀ1 â/2þà¿¢âŸÝ÷1Auý©Gã‚û£d‚²†]¿Õ«ÚÑ'ö÷ƒÿ&šoˆ•€°ÍpóP/Xçñ¸dÕð­ol %sÔpOPo—Rnt.P[ÍÐ変’3ìØKŽjÞ>•N¨WÊÓîê®ì\Á¬N¨ÎõÉõ Ü›ù°û !ì\?Êì¸Æß¶£€é‰Æô:”Z;Pÿ¯ü]Ž#QãŽÚÀz­—A÷?d Òd1Ð4w×;1ÿ~¡­<¥¼,sw‡\Xá¾ã“ª0Ëb¯ýúã¡ÃQÒ¾Ùeç6™«·[3í†mŒj>*„aRÚŠ1(×»@о|ÌÚ˱¶ž…y =b$Ð_§ÓÓ_Z)üÀ‚pyÚB+á9ùŠ æ›z©}²MãòÂTlì¤àý2óÌ4œæ 0^'y'”½8÷ðgI¿j’©þÏYß·ÇW/lS&Ói) —Ñ­œÐFq ,=|æV:Û7tóC'2Ýe=pž™5Û5-ŽÛWžröËô·LB´HC0¸ËVxIJKȇƒÆ_ÙgdªA(Ì´I#ªLPt—²Ne¥ú•ѳÅòÏ^‚ëuV_¹Ù5xwH£y"¨FÝ“Ln&ùºÈ{0f+ÓQ>àÂÑeAuñÖ½gÃlÑ`xà‚“ïŽ†{u*h`V²¸©:⾘Q5¡†'ÿOXíýs`o|ojÊ'òîìGŸ¹–\Î3S‚a9Tåö©hZµÌg@73‡å9ðbĉ Ëv$>*—ë‘ýÔ¡PUÓ¬–ù¶˜\2Úož÷ᢆÿ)¯ÏBÙ_ eÁw¡!Þq¼`ºô”T=bÙÓm®þwýœõø× ï…\¬æÆØžÛÉw±a 3‹t*թϨ” $ä&>•'un Í÷÷¨ÚŽú@ˆR#(¬øYÍ+¦]ÎJ˜f“kŽÔºª:HÕg¾ÍØ÷“ †gþ&ÈüæÁD,²Ö‰…î“o7’C9SǶLŸÖ$¹ŸwÒ B!ƒï€t ÷ ‰«½³5êªã_À¨eÒ(b÷˜ª§\OtÜt¦óv² Çqƒ†Kÿ-'°l_rlnÎÛ×Ù%ªßÁwx«Á²k64_rD… ŤƮA)Ynù‚3ì=Ip:%Òû­4î™%a†JGÇ$v@ËSÌ…F%—1uÃN©è»X%’ÓVkšŸÅ¡û ˈYôON híip¥ë^ïÞ÷,7{ó•G8_Î.¿3“Z}X¿‚ÙßýbV«¸ë>þN†kd¦@®`ª˜¢ïWXŒÍE\ÉîDQkПFC+úS?—LË gÎÚ¨mÇóy‰Ü`>^LÜ»W“¸á½áº<ýÁü_Èë¯Õ5Ùî~›)f,Gú ÈòR‹'¬¢ä"rÁÅÂt/!Ëâàºñuvù¦A†XÐô« ÝZÓÒ30».ô$¨ ³Î L¨7E»P ãMÚ¿±.•]O¢Å@Óh‘ì‘‹Èa"¦D“ ­„2·W e4þSÓT’¢©ÍjLúPjôç¡… ¾‰ìÈ&Ú€ó@Ç^Þ¿L«Òˆü:a¡{Ç*• VWº¾•Kà³µ)urØLžo¸•¬º,Íæ`Éš?z³Ìþ5cþGu:›ÅÓ°A‡Söq÷OÊ­=)¬û7¾=8 yÍüEO;»é–×B.ßÌ —€}¹J¨Ú~Ëu±1mª¥Öúš'x†ŸÛÄTkCÆApƒû¬yÀç®v85qlw K¢døÐ¥ñÓûòi”ÊŽÐÁØÂ­,æ’€fo »!áI™Áý÷W$¦…¾Uù6þ§Ù”Ä…š1ìã–àMFn><èl¢wfSýAvYÒ¥±pmœ¶?xj Ÿ ™n»ÔVÇÂi¶‚’ÜYõ'ž”é|˜ƒ+én0>7µd<1;ºŸä¿¦b-/õá€á_VÃr—™±­ÝÖX*-‡’1ÙöKÞ©û?j@!Õ·x”XúÁÛuÂÏè‡x¡¯Uÿ@^7Üíõ®ãLïvî&ßaBmƒÝ3z Ë$ø¤K·T#ÄëÉùU\ÂîØ«“JsÓ'ÊÕÁ~mò4žmå­'‘'ÈáѦδw2µƒb<7"Ót¤†.Ïd-)hÓpáD–œ ëC‘þÈ—f£& e¢„gk`.û;ÏŸ«„%ôá‡~ûó“é^ˆù?Uêm7n>%¹û°ä·R\âúaäùu e{ß}&K~CV››$ç@DÎÜ×5nñl}îV0#û! ^Vã'!eV7Àj8Dç’>oËj±L3¹IåÆèhz(.iÄvj>2y`þÁ§ïÁœM¿l‹¥«Zµ´áÎKY˜cÿ“ïgA ä?oY“CñyÖÿ–ôî ~êÜûõY&±OYNŒÞÿXQ¶ñ[8<3Vp„~Ékrfî>¦¿±>cÅ 1°ÕÂ;‡râ¢`¡ïu`ÙÆ£_Ôñÿ˜–—J–ži)¶¾€}´¶Ó¹{-Àä<ØJ2ÑŠ6ÄÃbz5’mà;¸Òƒî€{pÊ4}JÍÚMkgèU«Ï‰T¸/~£¶±9€D7)ßÖ®AþŽÂ>›ø=ÃP"ºŸvOõû,&ÎXÝÅUomÜ è©…í7p’Tº'öñVÖà¶@À¼ÙwÕmÛ ãfuJú΃òÚÚ kUÍ-í5³ö4ò¹çµBï2 J÷ ¡©´Ò+;/Nþ–;¯Á6`ÈVcßµï%;Ò£Lü2W´—•ÀLÔ…"ppu@¡]øß¢¦ˆ{Õòiñ)†$*Ù{í•6qv&Ï n Eq‡dTº5ìŽÈ#ÇF[Û¬Oƒ&‹Íê|áyfH¿·Å؛«xxˆßtŠ£Ž_h«D§|—Pa ¶&ƒ´µy”†Åœ³‰>ìç•$6l…ÕÖ‡äýöº´u2qæ´ó 0Ê›öÓŒñNÝ\m¦wÔÖFï BOýžÙ\oÞsñß]àl“ÏœJDe§7ˬÎ}ð)vnæQe%<;£Z÷¶ðmBŽ!=úBd°S±!þáúæ€ñ˜=7usJ‚CðUs¨ö” /b(Á×›·©P ‘†?£J~>œÞ²A¿ÕXc‚S­ÆpÏM‡ZP¸«–­÷§ ]jé ÚÄ;‰j±ôòêš\šÕ˜Ìù–ìHzÄBÒÏ2 ™(IUÕ¥}öÆnÃÅÖxuWlÑÑ}‚¼Ô­›}é)5^,Áuí'IåÜWÙ¾j° -ò€õå•ERŸT˜Ï¨J³éÍyéK¤÷„Y÷“<}ä0å@-4¼ßþ],'×–a;®¡~ïð»2?4CÑÈÖoˆ>rúh´†4×JÙÀ{€ßJÕ˜Ù9i¸ÎM$^qo²ÖíŽL—hp•'\­TÞWU%7Ø.Ø$6(‹9òAƱ‰s!—rànŸsÌ ö-¤vµŠ,jíIi«}$Bñ`æÆjmm`’ùJ óàW8tÕâ@¿4Š” ’;=1Ò9?_)‘fÃáJ%]‰ÕN¹”æ”+ÇJÜPPcÛ³ÑÌg 䧨âN`¶˜ß óAsd1?d ÀjÛ=ö :›ËíµroxÁ"­ÓºS^ö-Sóä½êOòR«l3ùÂd9¥r•‰ÔÚ» bjU6D­‚}Z:nÊG‡‡¿ó;x[‰â‹¿ÐÖ= Þfä Áî}Ì–5 h†¢èðùk~¾è«).Ьd¶-4Œz¢ŸÑÄå]„©L€+Iw7EO %ýpíáIº.äü{­º}Uÿ'&†þèÿnÃ;þ¦¯’‰_Dt©]^K:ãg% zÉïŠB„ÔÜ8OâeꃊƒŽ‘¼ ”¯Ã2òÕ¡ù–,:–ã^`.·jpçiâüàõV…j Ëü´Ü.~£lÂKG½uÙ:Éèe>jØLS%rí0ƒ , îûYÈÅØÊãÕð`¥ Ä7,~ÐÐù Ïü~ŒT)’é¿g×tø |_q™Øæî”r*4cX²¤>è J UZD[p÷{m¨¹1498Z‰÷´G³ÍhÉŽY zÐPõAÇì ¬ÊÄ)!?9¾­(ÿp¨ŽL±GI‘ðË‹ë¿àå£ï-gGW;72uH­rc¹x1x»¯Ìc4ˆŠ!öü ‹Ø]ÙWlž/r{¯ò#à œº&¼S\;§+^JÑ»øÇs¶¶þf¨oO×lqƒJ͘EÌÉzkòNx¶×æ¦C.H¤ƒ·»¼²#QáAÅÞã˜Ø)Gi,ôÎÏ.t ÏÑ6yÀ¯ Zl•ƒ?_ãDÌ©ÝÈññ·rñl`ÙŠJŽòÞrHU#qò†¯["›tÔb@Ñ .-PÎ÷GaGfh¿îJ…€É³‹tø¥ý¡[R|P¡iÑøúXNBnó-ÛsìxZ܆¯¥\®Œâá²6+GŠMœ¯Æ¥~žÔ­ñu]·É‰uï¦\©rLZœ *ûÍ7yÇöç®~J‚€lNe«ùvºªà!¬KíHÂÿ<3·'ôÊr‚á®sÌ5·ð¨¿¹ÅJµk5ôÅ>›RÄRÛFªÖkòyc¼#rKHÁÇ£Ë\ÿIàż·û™÷Ñ‘ñxý„~”ávèeÁ°Gw”Rør„*$Ë<ðÝÉÏoRÄ™¾l*éH…+Ö@‡i„±6þ oELj €$°„Æ**’^ä„¿þ}­m§AÛW¯A—lwzºÇÈl€vtñ›9jÚà°¤µî¾7ˆPì%ÌÛ¾•ýˆ¶õÓ.)ñsK×ùï%_xBi<ÑÝÿÔæm¿BõÑàvC¥(‚ì;·_I™É!6tH<lkLqÝæ;h­(ý+ô)»0Œ”±‡pƾ4£UV„ø zû”ø¿ñRØ<ŽýŸ–¥”i ÿî\þÉë ¯5×”èLxºsZvëJ`Q¤¹{+¥œêÍÖ“¬d÷*T¦¤8Mƒ©TÎéÿT§{­ʃ¸×ä=ù\pHB ~UÙŽ{àÓÝ…w¾ F‡¦Í~;#°’n±2Ÿ$½½p"­ÖlÍ•eŽŠÛfR“ô#d‡jVÙRÐ'3îë'¥ê——tù=Ú>øf!0'fY¤7ªAÓ^¤ïnû'L?€ßö㪴®sZå6ܼbáT‡ÔP+ûö¸¨õ'Åýò6sÞZ†¾l+;xÿØÝüˆžêÔ^ ŸQšK…[¸>Æ ˆ¶“ýz æÎ‚Ô!=¤ÄU’º2eYîÍý6Ê›“„=¹ž÷>ÐYM£‰k¨ˆ-«ªüI¦X¡:j£aýýåZ˜ùƒƒPöÁ“2In¹Ò ‚J ˜Kü¨G’ŽÌ ILŽ|›Ô`ª§m uSÒí„å¦xAeP¬ºBoro…Õb_Tn’œÜLC¹$€QGÙw¼ˆÝŽ™:í¬z˜Áe¨˜;ÐïÓàþ(½l²ûió%Ȩ`.;±èÐ"Úk»!ÐŒ!ô;«S…ïâÐÕÞñ6I—ÊÝ W69fÖ¤±ÞÁÛ§=2&8å².;†žDbWA.s̯F7lÁ‰¼u•°Ç„w]síÄê?¸ ‚#¼V*œoÙJ±Ò ßp›62ŒŽó¤b·xõamÞcîl zÚ©Ûkã(Ô¦)]°miÝ`áØÒ¨>ÕËS´´{»ƒ©ÅzíìB•ecF¹¦ŒØjÚG»Ü½N¨©ùe”žÖÎÕ4«YÙIY4‚V2`2G±æÑàýΈ¯”ölÌ> èÚøUŸ*žà”‹<>iÍ.Zô[¹ÆÚ7†ð» (Ô·]ðl¶‘ô;3§–ä-½ÁH”Ì“¥Þèß^´ë‡nf:¼¾Õ+œ—]Brï{ïÿ`I=1¾ã¯¬Ók&ÌUrAÀZ™ÆûÒø£´ÇO*COð*`ã|ázJ°L…ȳS¯rît‰)“ëe …°È‰/IˇOöL»†°O|YŸýóãûîrsé)W4&-ä3 ˜ñß;™öA¤ÏÒ~ÄŸ‘©ý²à±GßXþ Li!â[™ÙŽ"¦Ç(Lýåë›glqÐÜYóKßµ‡¹c¢øDŠ\[C+ËÃ=]ìpm¬êe“ý!3bDÄ‹\IÄSƒ'ež¿CMÅ%ºý@ì¾Á§]DÝFp@ kà»5­ 8AöðC(G.«£‚f ïô7{ä>H^¨¡}ýs©F;yçñô@cÕfT«Hcjòݓإ[?á’zbÆÕFú#g—zØK+5¼¤ÅÁ^ XžO?ü»Ÿ—ÚW†—0U.ö •E«4:²Ò–-*¥È(‡LÚëÕÊõ³àQÙÅ8ΣŽ~´¸ó7€ß¥e$;Ê#D~™Wh¦JmÃÝýÌ AuV¼ý?Í 1x³Á;ÿÃ%U5ß°=×Â-¼ÖüÊÚmvÐKÌtÌì>J0£bÖz7w‹Pä„3Èú…«ºœ3aû¯Šˆ·`'ä´ )qWê@n¾‡­ ñ·•+Çã_ã?9À´§UA‚³ƒ/6ûƒ©ýÃX§‹©|*@ÒûÜg¡`¸öƇEjuÑÇv¸2brF‘«*Iä½,×ìDlAG¥Z,‰»yã ï]l®¦ÐÔIä8«Ùb¸°ó·¼GvMß]ÐÞKlVŠY²IG7•©ïÜ1œ'ò&‘:gÔnçûĨ‚;¢ ‚Ã¥xÃý?+R>Ô0­êÕžiªDÓ8 [ö¹hI”&ÑÃDà¶“¶u=_Kó.ïR·~Öõ†Y¬†ä5lº ¿Ð»çÕš“YTºÆŠ:Ä¡*柼‡ÓCî&0¤¥š[‡ï‹Ä{t®Ô¯á鑽Á>ï+à}Ý£E¼S?ìŒfSÿÄIçeHH˜ÖWé…¼~¬µtQÍò=Ìíõ„A­m.ãuÏ¡ÊFbÀ½§öÙ—ôËMÒÅ£Ç 8éFÃaÙTÿ9,åkëË•õ‹5Ÿüå ù•ÍQÙÏÐ{*·ÃØY«ð,£=&°ø,MqÜ–=ð†G¿üÊ•êò^ÊóéêÖ—qEx¸|ªöéú{¹q7Íz¬[ô­àŸ_fâE\¦Ä-C‹3“\ozólCÁÕHÿàÑ¢ŽëøË±â‰7Š ¦ØíÚu"¶WU¹S6Ï\La î¦>šÒa˜˜ý!1áöBG•G ûæplys7E¥NÙ1µ}LÑœ\U°M·ÚÏ9<ûÐE÷h¼ûÒAhí÷Iß¿¥ÛGù©8øMSß°ý¤Øqá µ^K#¾Ó§º!'Zµ×gaýI]â·4¦T{z¼Öc}RÍ&T“×’Ì®'‘Ùå|…\™ÐÂIu€¦š2±ïoB)¹kˆ‡ó¤Vˆôø‘OŽhí(‡‚tOfKéÇø|l­y`ˆÆ^­:–¦Ù Ñ¿›H}+ ¨CÎ¥DͲ"'h¦€1TW:í—´Nð]«-Ûï©­Ž/¥ ͤ‚´‡ÞpOÚ¯M7Ìwž áŸ³Ž¼šE5Gãz)½ær·¦XX«ñþâî4iªø`ÎgïR(6qS\ ’±rú‡ª­Z,Ú­$"Î( Ú¯[<ûWÞßðƒB¦„J£Çµº}”Âþ×*ÖŒêápMØÎÚ†¿š'…ÿkìýúTjîÌÚ¹XŸ*3ŸäWòÅN|2¢¼È07OIe$YèwDÁÿ@qš·ßö“Áùö¡K‘‡âíŒôVZ¥È±O<ëd¡ëáž»¯³¯ùý}˜Ä‰Sª4®ïGÐ7:ü0\ï¦ñ+m³£Ï¬Þîé3Hk`”Pµ…@ê?þ;¾¡›˜„^7²©¡ô0ºDdKè­äFp4[ÍŽ±È>Ê2–eu:ÃBŠJµ…FGÍ–墉ï SwÓ$¬@‰é]Üj’ŸEDl—?úK¤]\¡ájñd ñ nØ0nßß+„›þœZLVÖ01iüCK}%ÃøÛt÷0’ž¢Op‰Ü¹«¹½ á§”þ¼]É—<¿ÆcS;òlT÷e¼kÂe{ǰm2kY*ÛöÔW¨~â?@ç[’³nh¬v{V¯ø‚ï¹\}„e\m‹ð{õË¢‹/üeWT)ýœBĺsô¾ìHIýd©Ô"‘øía›en(§y] ì´ÿ|†…wz]µZꆋÈG£hMì>ÚͰF)>òl7‡û8LøüéïnÙ+â,Ø€ge&³MÞÏK5Gç€5²I6côÃÊúî¥kÖÈ$V¬‡+Ë4_©˜–ô×åbÍ6+í&vf¾HyRºÁä˜@¾©m”g5/ÌiYp (ÿ×5gaýÖª\lÛ¼«fKó“<ÇÏuY}2ô"k"¤º'{íÄ·œ&nâØV#s²µŒo¹°táâËÿ«þ¤dä´d>ª$•Œ¤¾-uƒM6±hRBÍ¿8Æ]Ë|öÛ oLü¡^äņ d$Ã7œN~“Û×Õ«œ2 ¹ZšvœX®ðRŠÏ4~óå• ›ÁšñŽ”'àmAî‚c¬L ƒ­ÅlÓùL¦¾“ÀÍÞ`eB\`}Άe€©_Qo+ðjЫ¿Š»#3º§x®+ì$ (_„ mÇÇݶ”£¡XSYGµ C[¿¿ÙJÚÊ•×|…¸P̾ˆ¥Ô± ÌcàÕþÈ–Äw9¢×¹¾_²´2ã\ŒA­!?)Ws¬Þ¸21:,(Af˜ì‡” |­£¾kd«÷øH(AúîÑ*ckKµfÈO4‹I¯ © Åö¹R<õ±HÿÊ]`ê?t¶!çnK!_¾"¼V±|Tó@&ñàåZ À+Ò·hVïU#z|ÖªxôqßéˌщT}×¾íÄM,zþÇ1÷–è|ªxT·3u¨øXl4¦~‹+Ô$aa€l9|¹£L14§×¨ÀPØuÎ…I"I%ÿ=g r@:Â…¨><£ÀV–Ÿù¶´ÄÊ’ÄïÑÖr+Çý7åÈäÂÔ'Qmô?°+Š2‚œJÀ4®NhæØÈùQ7Ñ©R\²*ËQ[ᎅ5.ëEîݾŒ»†¬ß¹Hca7`¤« #õr#;Ìeu}ªª”æ/jK~œT¿°šO¸7%Ä:$^Îg¯èì¶ÿ@šš¦rà–Ò _>›sÑGPrH<·&¥ñÑ,~!Òvï&˜ÃËÊ^录i”DÜ®xëÃc=ô)ºÊTBDàr¨.êþæÑïØ`äMØ*1G!û»»{ ÿçYZ•L\æ“ùǖÄš’UJ!^ë…[AæÉ~ïšißJ“±>{_)Æ£_ÛbÉþ-ÑEWkâ­ÛJ5b€ŽúöÌà—YØ‘+áYd^Y éfÉõ }û Gg¢^dŠ~7+òšÌÓ µ •Õ"0¶•:&ŠªÀÐŒˆC0ôë"Bl†gW:]‚Bh}«ÚЦ‹‡\¹¤ ÔðWò²>ÿÀ.’ýÑ,4¬zéÜ­~ýL˜Œ(1”vP£È*` çbP<Ó»ñå™\ ‡¹æn>•X”ÜÝžPÓËPD=ÍÍùÌшY¿B¿™• ‰åÛäN’Ö”5Mš}t¾¬ éðM¶ŸÌ«þ²¦5mhäõRÃϧ´¾ã”Óî[ïwçÛÂ…–#FçyIÚ®Öà E®5<0;üÿ:ßÊøYä! '"ã¥Ã!ò¤×íX£ pñµº={㬿_L^õ6°¨¦ÝA]ÞÝ- ¡ˆWÔ¯6@ew1¾œúï…²cwrá0¥n5º}¨ÏÝ[ªeÅ”ü7¦éÂ…ýÁÖ v -ñ…&ü ¦³«ñîë¿m£›WÆãÞU^† $‡‡:g­U}+iþoÿ§ÀÿO½!Ê•¶[Ÿu¬˜À¿¡ ò¥Ï_¼ý?PK1ÏÕ“.d2PKl¹B-Haxe Toolkit Installer Template/haxelogo3.pngUX ™IR7 QõÍšƒsœ]Æcll7¶Û¶í4¶µ±mÛlØØhÒ¨±667h’†Mòåý/¾3ó<ÏÌbν7~×uf6FUY@€€€@‘“•Tÿ|¾üw!À}Þ£ÁúBŸDY=÷Ï÷Wÿ» Åéò|>_„÷S’‚ß‚%€ÀUªX€ ƒ“ÓôY¿ìú‚ôŽ__W¶{ì²ÊkSäô·´£6³°P9¿Î†ì Z æÃˆ¯O„Ü *’ÙV‘`"„Xd»( OË-\yG¼R×+Cû¤ŽL˜b^•/›™’%(l¹u\·kjÕ^lÛœ$õÕQm´0O¥R7ò$}ë2jy0¾®zë]¿àúü,0Ùx“`t ·toÃ)-­D©fyvâ$/Ø®¯™ÂßL7“ ƒ•äc‡xbpñfˆ=:ÁB:dydÏšù™Aß”óœ»óþ|Ü·MsÑêÊþòä~o´?4=¡/`&,HÐBõZJ ¸4Ì¿q?H„µ–DmW/`~o$#…AEA›wÄÎçƒö[Ú±×Ü#b+iàh\A⇙Tº-#“ª çpø[i¤.Zï-6I¿;üÔ¤H5-R€š£À<¥ß§J ½4ß¼7]È¡;Ã{pÒÞ(ó­Õ@빞±"¯>ÎýŠC—î0”müK&ŠÚ>¯’DÎêPŸn]Hwµ zº˜:; ¾œw·±$ï®tc"ø¦’ŽÙ =)ûÎ÷{€òCß¾\ýËL3iì±9ùÑÌU EÖÇ|®ýw²óC/}ØVz2?m€­l¾•K:…¤Ø×ÓvÌC¸\(Tÿ™±FøwQT¯s¾ )ã%­Ómvò¾@(:ë ~¢ÒÔ)xíœç=ÁYe½HøÐ~¢­ŽTx¢ØšL5Õúlëå4Wz!-»i—(˜.ž0A#–8š IõLWÏÂÓ ‚ÇT-ÌØ–*E«Nk4f41ž»YnKQ_|˜ðã7W›_¬±Ð«vzQŸ®þô1“w6èû%ˆ# Ú 45À5à.ƒ»Ì' X«+[("DSÖ¬µc ï¬ñ]Pb0¾£ê9 ÷J²òÊþ”Ú†YéÍÕ9àvã¹VV@¬cžúŠÛSyˆÓbê*œŠfã+‚,³‰þ’Flj@þîñ‘Â*¡z»%}¡H p¼aw3ùvçàÖ”v‡ô&ß½üëà„òìñ„*éû—æ×c'¨ÖbÙµ¤ì7™kB¨›=f6u®Ù&MˆxµìáË!®æ!ÿ ïr$](²Õ:Ö[î"u4?q øÜó¯bs¯XhýKšUZ1¸¯x˹l Ä6Ç,w%žgêáݯÃÐ5á·öï»âÒ§ffl Ö5iI@¨€ùt]{Ò\é«I¸)x^s ódöïσ U3c¿>ù1ÒÅÃ,± ÂtsáµdóÄ窰 ‹ÓåSꌒWž*¨Àè?Ó~½zíMÛÓJ"V»B_>UiªAa FwL^ñÝýèzÀ$ünøY'Hç´°ÖÉ€‚Þ'œOà–†‰#ùiã€ÆÄ¦Ãf­ ýqžˆ |³ž9¢.üF¦¡«ÊǪqêH~8¨à,è=Ô`É)æú­WCðH*³5lÌPA2Q§¡“…ÛÙÜžÙ y:˜`ÍÓˆN'˜¹Ì9ãâäXInŠ9|µ05XzãáMšAÆëÐSýà7·¦Ɉjò‘_=oCëÕV-?¬° ˜K~Œ.Ã}2Â8â6íùÕ{âa¸ÑA%±¦¬jK´ÍÊÎú²Æg¸ž¥çè‘c ÏP7!ä 9ÙûÜÂéb Iד¾¤æçÙÞA"]‰¦&ȇJ_ÊŬ7_Ѥt±.7ý&¾‘6—Áf‡˜?!þÆ¥åéð«dÇîä$äú³% xßE—„«Š6#frq0Q©ªxäo”¦âR³¢N; ?p}8\XsJë?âëâlí8Ëäíô»‰áHt륌€ ÑB:œ¹²&vú™©F)¹Vv­{SŸ·C¸éT|K¥ç)Ý^é@Rê?€ãÃÑMtĽAœâ +T-‰ƒR’ 4c8FxeiYÕ÷éo_np¿=A$¥ˆô<>¢¨ðP$ª‚cW™½ß·Ã¨áôR”Ø>àÜŠÒå_Ý¿Ð^Ú²§®'lÀˆ²µA»É‰MþRüg3°X:®àx˜ª¯rÉcüX§XAAÑý^r'_Ш|Vá×âá^{§ðÒo¦Ù†IÆdo:!®³‘:î‰à([,•¾_ëØK‡vBòÚìøÃú¾§V°CûèùÎð8†Ñ©‰êÕLgGt’SE9êWNþq†øŠb I/úÅž?³ wßNm•w¬cï²'¸&Lè²mɆ]ÃNT µI38ÅÆ'q|0|…sÿ¤K£GÂÖÓi]„S=HÐÊH€Å¥L=—<ø7ÚAâÁÑ’é1˜FG ~ðâ£gfŒ2PÕkæÔ~é×·Q¾8¶Uä#Oîÿt»`w Ösšž?$ºÛ€^äµ,¬EŠð.üâ«<,`;zwE輕ªG=Ä%œ”¤f0¶›[#ñ%1h¢ìƒF/°ÐN>·î\hžgªJÃMÊÜ•(Cå?xkí._#Š)y?¬)5T1WXb#A_Úb¯eDKÁ»pø'Ì·¸:ØÃXÈ¢mg(íSÀ yÉ„©•p¸+ÚþBÃ$îF¶šrR¸«« Ò¨`¶¯¹ÅE­sH]ÎkR=Íé¿—HoлgD\ÂÙ¨ c~¥¸dI!Øž“R?ùgCÂÉ(HP,´WTãpral©jÆ¢w¦©+*¨+nDo§D=>B]Ïž€jÛtŸòR®òÒ3Ïó»°ÔÉmÀ§oOœä?4í¨Júµ׋ô+Ë á–éÊ<ªrÕ/…ˆ{Mp+Æ¥cò$>ƒ™qiÞ’kÃ/ßUÊ/Ôïñca ªªS åS |¨-¹/o~ÿ;Ý”ù;ÒD=ºtÉç*“=è׃ç.ÅŸíÂ?*üùÕ|«ÿÜýÀÁop9o¹â."‰6fwkrüÛøëjå×Á#¹?°Rºìâ|HÑ~6¡.·qü v?Ç*¼…̵ž|xÂ#GEH„,3>¿Á­:é3>xÿìu Õ ñÉæ&åØ3ö’7íxáúR;4”ÂL_.ø‡Ó0? rPýŠ˜ßzù<Ìñ i+(¤,;ßðŠd¢”ßÝ^¡€F¾¶ïÄÛA5O";Ïpã(‰?÷ú CÔ2ËK¢ë rt€}ID;SsøPûxÅÃñ ZòG„ \/ ß,(ŒÆGì“@y£„3‡4 hÿSml±ìþ‰ð­ì~m!‡-=_]YÃn^*×>)ÎÿòüVGnq×)UUëYðбYúÅLôñšÖdŸ[&en‹y~®n>r$ÏcƒÇ® +qi‘pŒ®*vN,¦ïÈ(ã¦N° -µa&$¤å_ca£‘YqêuD¢êyºl3’Zä­Ê_æb|y+CZÑ„Hð#‘mãnû4kqLMm\H{¨ª<7g·hõžÅj²»&h1‘×p{c +à"zƇ=3R×9ïBÑgN2s«BT@,G–Q\t4Ý(Øì¬4yç`ÒU=tÙk†ð¯äŽþüo—ä÷½Ü[a¦Ì_è‘GÞüÆÃk:ÑÍ0"û.@è‡'Bb©ì¡Þ½¹jDÄ‘n„j3yGZßH‡\É}­¾ ˜¤è¿#jx†#}¿o¹ë$ÎüRS©)Ã6ÏFÉ»)Km«à°¨•@(ÄRÙ8ä*Ì'Œ‹&øW%)¯6c&ÉÊ´›ÙËÚ(NrÚæê1;…ó [Nž{¼qø®“ÓÐÛP61)ƒ3¥ÙH:’]Ó½À0{5ÑÏï 2qýü*.ËŠ*„©®DÎòçØ'FN7íà›ÔåÄÜw³iM#W­™«æýù iYL#tbY.zLÛ]f­·áIõ[ún«Î@.˜øÏ@´µ„Ò—¸Ž †VKó—u óƒ¡bNîîóc–R?ÍC?Qž÷CÀâÈ\¤l)8ÁYé:¬?±€#ˆ9`.¶\¿Tf> ¢KŠ9V%9„V Q3Kþ± Xê\æ*¼%D®z ÷åóSGJŽ?2RúÉ^™‰;íeÎé(·n~Æ(¶C ÷cœ4ûÁ£lIχŸ§|;5ñyj³X5p(_^nŽï`£tãÔÐ$€ÉŽDÿpOt´˜º©úêyÊPØÊXð/='¡€~ 1gq8ÎF! È†N½'A¹-78_4‰£¬—Áä[º“. Â 5ÍÜt ˆí¨>{ x0ÓLó¼´—%¿ÖY¸¶‹\*^ÀˆmR`˜àÛèòrëìÇÝ86˜ÖeÉÚ Ù«&¬”»8מ®vå6\¸£®-2žh®Õ¾a;H<ì׿X'v•Õoý£YýÛw2—8ªŠa”õ•}Æww˜¿JÜ•ìµç7É…·ÂŸvþއ€ë…†Ë”j‰ Iûr±µÊ’1Iqmá©=È`¹ðÄ:x†ß¶Æ–h–-Q…’æÿãs«E˜x´öm™yÁoÒpÖMpÞF´œßgüÑ¢4Ióî$M܈ÈpÔë5Ò¤ðï.?q°-LX-Ëí»¡&x4þ´ã„ëªÍ-{¯an¸Oµl«¡ï^×q¸“~ß1ú®(B[¿%r)ñÈèãá\¸òuЬx¢üÐØCcÏZ!pxTÒ¯»0·<Žª6g)ÕÉÍ•¾uñäŸ;»fÛ¥Pø¼Tú²–Oû‚ƒª©.ÊÀñ‘ó½ù®í/¸¹ ütƺ6‘i£Cæ3q Œ‰XVÔ¥>^Ob |&8r㣊Ÿã¯MbQÍÓjF«n¹$¿rðDÚ‰7’îãíŽnö7"«NÙÛþO>!͸3çÄøü˜£ØõÖÏ[} Ââ²b(ûÝÈþðµÙ©R/Ë[ÂÙØØØM¬AW$7ÈÒ÷s}+7ŽzÉb­êÔ¥è óÈꪠ¥fÊH}íŽòè†vï¨ ã)ûãÜQk%»+J*­(ÆSÍDm‘WµòŒ +þLa…Ä/@L}Xº«þ/Óg‰ÝoÏÅëuèFø?z7«ÏšuâÌöKÖÅ7|Nrü¿9]œôä;ë¶ ]w|ˆ½h¢Ë6~¨=_&±¶,‘Ç/,0ãn*µ*HûZxæE½¨cIr‚›UnGŸtý5pœóœõʪ‹§®S ÃF\"*·Þ~îžVWœƒ‡ßL,ºø~.²M»„í}PÜ,úîLFt‰j=Üów¦˜Å™êŽn¬$x`{èåµ=¸]L«B¼?}@ØEµÔ·¾‘¾ÅÓ¾D¢¯´¼yîf…D䃯X8_S® ÎPûÌ,c;ô|ˆ6šÅÔÔçç°ëδú|ƒ*·µ r¶|Žîªg¦QÞêP¸æ-ÍU³)wœ^k´È¯×Ct†b4 Ïšgs„š•>H­Xñ×§iÞe¥Å‹à}ÉUsKën÷iÃhÐAȦõ&O>=ë$ñ¼É»pŽ9‹iýp>T V­\|ÆÞýÁÄ…D½Ï m T98±¾»¡ÓBLc/ë³}^Þà§¿ÝéÚÚ¤°CuHGÓòaßÝ> Gûl tU%œŒí¹ˆkÆXD¶i«UƒH=±,£˜ÍÚ!.e±@7«+4ÇF#Ê×HÒ¼GÉ3'Íö-Õš›×Áo:È{¢±^ñÍ­’÷8Îm)j½Ž£<Ó~èæÒ‰\õºþ›Ÿ+›S„–ëy>¿!C毄ç©V™uö7½hг-+Bf€tCŠeN’Ôs ÉŸöVf¡íȰÄz˜2Œ‘D·ÕÚ6O9šŽõñ»õåœ/ß]¹à=5øyïóg9bÖêý%²-Peð÷ËÐÉšºó`fOÁuÝwr»éoQ)¤ß“Qÿï2vE?äåüB"‚Û¨c+Ù?‡÷6ØlůìNÒgrŠ^ž™woØ7]ŒøêtX5ÔíSŒW§Ì­ ‰3Mt§0­Œ¥:Ûé—Pª Úœ$ÚÖÇ­^6„Ït…§yÂxG½_u¤Ú”éÒ8ƒ£tëÄ" Ç‚ÿpvÊí½Îhõ:öÃnûÃ{±Ý7¬YÜ#-çtEÙE]%¨¶ Ê‚ ’*ehY§—!¨—ùaknwƒäîS ~ðÌÊ€-þkÓ·cúS&%ÇEȱ•¦rì§fÿ7/üƒF‹õ¡ ó~ìO‹ Ç+Фs:9¾KL;÷ž¾æŸ ‡M&ØDrÇ®{y‹,ƒuÚZ÷ Õž nÕ‚œ¼©#©VÕmb! dZ~ú'«Á:GR©¦7V—Å{ï͆Å8¸ ÄË"Á9å¯!tRŒŸ*˜z"›uk7Ì à<ôr½Œýð½ê_ò` ¦†ƒŸ—Ì¡Õêã ŸoN¸ÈŠ«¸ƒ!Ò…;g¦B,´Í íÔþ88Îj 5'؂Թ¡ýµ6;3¹ñMÁÖ‹w@°`ÕVó°lcI™-V.W¿4oýÝ.´/¾‰¨ z&aÙ£DsrãÁ©–§£ßêÇ„Spz¤=~TYwÅ]æB­…ÞE 3B:ÖHwÊ]F]®ÄŸÞ ÖÜ‘ÞVppr±ja縎F66:S M— ñ†Ö«ih,ËÂä/ôí;¾º?43§Lñk-̨(® ^¾"ÜXC´½^W<Üž‘°Å[ÉôŽ:þ ~*‚ LüΦ Ú°Çr˜4Ò5þãuÇôW]-Á j¾¾T0k–]å]73ÍÌÚwû%NSDð$F˜Ó8ÙÆx©x¿#DeÑYÇE€Zgæà&¶#Oåa˜†þt‰Ù×]Í{ïñckµSdâ}Å4ÌeKyÈçËØ*FÍW•@'ü¯¼É}[DÇ8Î#!¿5æb¸-Jƒ”hAzw;ÿ*yD*>åýù”xËXŠV 3‹Ö‡ü N) ðg‚-*9GvÈ'u¨ƒxÊà (]Qä´Ùv%>§4úŠ–}>ÏÒgNø|H+4•yƒUì E߬¸b8)*÷¨Þô%u“q;2ÌS]¼ˆªõz+òi2Ž@þáœcz;ßEÂe!{ê{ŠŠµÖ+6¡@^æ÷ú‘P p{Q¸·Ã”! • ½5Eؽ{½løk…¹«:¶¼6‰HðÂÈ àÞ±}Pëwã_óŒ^ïõ³¾›g‹u^~9qt9x¡Ó¤M¿™ËH!&ßMó¥÷Ñ©ÜÓ,âá°„‹óŸx¬~S¹ì,Y÷-y]X“e˜†ˆ7Ïi¡Ðéƒ:Áq.;¬lP«BÏZÔ}€2Jö¾ÿÔ$-X 6ý…º óÙ£KSBó2œ¬x¢žÁÞÑÂ…Fí.¾+ ´¯ Ź_9f„C÷^ÄçFŒö²k…*¡ð%¿@ª¦4=ßžì­3«Ücü=Ö¿z"ЬÄà¿ò`›4@˜À™¶¤Ž„íÆÈoÆö0Uý ;úÿ­JYº¹y…€ ÿ÷_] ¯ä#Êß×*n>ŽU…ш4R#Ó3Žðßúò™`ð@uÆÒê;Ìžr½TÕ¢(hÃÏ@®¦ì˜0„<íŸ×™hâÕÀf?*þ#õ¼È\€ÒZí²µôIª}#”lŽL«ài|&môJ0ÉJe|w+³ úÅAîGS@R1~m¥C†*ïÍK9•o^dÀ ÝY1tÈ÷ à·Ë:KcÓ´™$m‘é\ùOãÄ ¼»1ÂKî&S¬†Ä”Éì5+Ï<ƒ ª!É…lÜÂ3«D·0šŠ úä­oÕ²WÊø¿'c¹ØÌ¾”ìí¢*¯þ˺ÄâðâjðºqhÑ¡_…Ü —=H·ô;ÕKÉ—Rš:D®p+ꚇôÓ¿._P>ÄiB8ž…E:p$¥h>öÓ”Ù:¾E ß[}½d…W úëM;†ÍÒìùÒ„ÝrÙuÝþ(P5ÔßfÄEU4Ü®¥9͵jZÏg í`œªlf4èŸï¶ÈZJ²ŽòúÅ•j.¤'WZo*Qø&Y½(&›Wø…qaU|åK‡šåºé{‰Ý²r³R&ŠBUÓ/<•8úò=N‘”Ú‚*šÐ/Nûë Íæ`Œ{u9bÞ²ƒÀŠv¯£(™¢£¤5yÈõRgÕóÖŠŠ–ȯ ‡f‚E®uFÊù÷È}2ú}ÎLÍ8æo£íjZ‘Ðó2Ž3-³³‡™úböFô2cñh‹C%&s±êS‡óxZ6ô,=bÐ}(¿¢êj†£o‚:Ã2~sö(ŠéÈa„ãw2]Þìb; T—Ì•ï!N!wbL >•¥¬[B_)Ap~•ÚÚùîïà#¤™$6f¦ýz˜|ÓÄñê#8æ j ÷û®aÒ¾cÙ:õÁb*=‘]1„÷¿:ŠG5—Á€²XK\s4.Lîé&•Q…ÌúJбüXðøÙ§Psw)óVøNS è6£ŠºÍþEâMéô‰ˆ‹£Üõ¬k¿Q î­—œ±J„¯—@‹cK ùëU.ü¡Aý]D½*""ª.­P=3aLyZ¢µÙ-ž˜-à`Ü¡Ý6÷m4úòµÖ>øQ‹4€K‹ô"Cè†ÝMrul·æg!êÖeËЂ;2r¥4x)~+\­>W>÷¥¾ã‚ìù˜~›;•E7fÉHüþ}è0HM€ó-HÓº¼ŒªýžôSg®WH³>¸QŸÆ ^/5Ôî{§ð[¦7ÔikÍðspsÙġЛÇ0±¡®!Tq§m2õe"OýÈÑ–e#4³j ácíû2¸G ¹‡i0¶OWä Ê|zœYÈÅe]",}Û$à-n›i5–™R¿“æ>Hî`Æåzý.ýѼk0Â-KöRí‹q>Åñ¸@\íÿÓžr#ô3ÕxK*™Tßoô¾á|Ú_ýSp8ÜOëLNcúÏÈÈá]ñáåfÅROÂoJC Ì]æL#ö+µwtù·tDïòSd"ÛFÀéɇOZÚ‘ö϶®ÒÁYIíw½ÏFƒ T(×ÇÄήòïWâj¢ÅuÆ++Íõ8¡ù ~²žEþ×à‘œ ÓÆäG>!Nsü±þúŽÒЫÿꚌˆhÓhkÀè#u9wß¡øÄ Wù²F܆A7 y*¬ûºG=ø‘©òs½jÞÒ¯rÜcTø¬­9·EüY8+šò`2{L#·FHUN£ú™é®urÒngùµ†®¯jD›Ðÿ~ÕE᪠Šë"ú|É|”ÎµÕæ¶$?3wëáêÑÑoqô†ÜYêSã›G¾YàÙ -[ÀvÞÇÎ:ª €ÍTç1ðß ê‹{r>1#XŠía^åùÏæ3ìË Òî^m‰ à/H,Œ‘çVÖ»»:œ²LcèΫ÷ÙÈVaÅpûÒµ_ØM.x› Æû1Yfâj¥}ñLð h#¬Ç‚ºî>¾ØØù]ºî§2¦Dm\ ÂUú\Ä™EZ#9ö õè?ÛmF»ñÜÏ|NDæUQ¥êí—€7*gT'q.õ!ÈÂ'î–Ò!­óe¤¤RuóV'¹ =@7“¡‰2^¤,²»Ð#1Àýíé;gÛ€Á Éä˜l"}[ðœR0Ë‘‡vé¿çB§) ¯.ý¹Œ™+áÆª!|IÁ— ³²b¦.?|»ÉŸ²}býÒQÒ/Š»Mš2ñ‡ŒšhèB¬'œf³\… ^+ûÆU’óšsBºùD I \ÉÓðØåâP½(>Nïù:Ô|² *¿ö".ud”ż›÷=äúÙ‘T5{U/¤ÐTf¦ùÂ]f§‰ã¢®þ|y«}X€RG†u…x‚oùq¼ Þ­Åœ,ˆl d…jåÇ®¶«‰uPDÖl`E–ìˆ8[XòÌLm{ú O¸?8*r@©×ið§B3âò±ì^ù± ¥Â¢Ó“Y]à’+Ü©´*böD$>E=›æºµ¨¼ÂϰÂÁC.~žÓ>8  rŠ÷=‘W©c%ä~ÆÁHâ:½0OÇ òàêfµnßf †îÕTçêé¶ç Än—5ñbÚšÇ;>¼M>ÙÐÉ~gá-ÒS:™Üý…&‰å;8 ¢Pþ»¼Z+N~©õdÓL#€?#xXéc¾ïöu4ÄNm•ÂÙŽ¤›±¦=ð4اÔĬºàqtÃ{Öˆ~ +€D¢Wx§"µ@DcC¬ÍÃZ£VŒK‰M¢i¶Ð3RNGkÕû8›1Ûöȹú⥰ä/ÎHwn«&_Ío—ÔK)1¥´<éœÑ ºX3îÈÒÜ‹òFŸRg¯wÂ`c†â}§ƒÂ¬Ôà†zBû¾ãªLl|‰GÊ|à*_ õmMê[ÆÃeÏV&ÔÖç YÚO°©#žÖÄl¯ÒÿQrç0‡ ïS­H\ ºÊÔî¡•<Œ ïØýKiCyµµ$üßÑ ÄPR*8Xß; nâ€sú¿Ùß´?ÏÍÍ¿6ÚÏÂéœÒG1¨»E®$ É2 ^S÷ƒcéà,v,R¯ÉF7"ñ´«ÍyE&÷^é0ûHù WõÉ¥©;+b¶uæ2˜ó*‹§†ÿ¾$jô: .h-{Q/¶[ž””Z`/a0ö¯iû«á·pOaZ)•^É|RÑÆ$c»¾®ï9/ îýK”fË·ÑYsŸ£ÐŸÞ~qæî1,ÿòúÊ}bÊY¡gÅU`éݯK±f°gùgf ÇC/©[ö¦da#-…bT eG&é² _W?„È g.‡è³Ó6írw&˜[ÿ~Å´jŽ<Ηʛ tèª:ÂßÝy¦¼º3 ”„&…kÙ`D§€÷—¾û ,¸â~byÝãýí¡ *'`m ¹þD1.^qþ2‚äøõE¿tsûÍ_ZLŠ{ ÿhÿ¡2Ñá¤Ç´5Ãþ܅¢7B‰ ´gV&Ìèµ×%&WÞX#BÛêÔÓ>û­©“ —zÈ8öJGêq”|¡^üò'w*([ù(*1§©—•ÓpŒn›…g8úWÈ6ªZ=²£*w‰XŠ"Ü“e–#iö+AF÷ÉëaèÒì†DÔZ–;ÏT >`[EO‘ÐÀj¦ƒãèÌ*ß1ØŽú£ãÆM.$Þ¢ó+@!TÕ^; `ų÷6›{ˆKE[ù½Ðû$l©I~=ÕW<Ó/ð…ö¡y^§g'}îörüÎЈp="qk|פËgèæ”£’Š\»ç”ŽÄ€:éʃ['®VÝCx®×ƒ =~s=]É a T|Ù-oSs[6ú<̺ œQê}£‡Ÿ{íëùÐÍò`óSúÚp c~éjHÄ~LHSñËQXH ‘¯DrŽ%,³ãPNåWҔߖwÃIêãª0Ëœ»8‘6Ÿse‚ÇzÿÞîô\;àßDôW…êësóxÛ‚Òy‰õpéÿÍ­E¡Ãß{­°Ž&Ÿ"ðÛx‹Dycc˜µù$tcÓ–cŒ |»vw9ê:1FÚ–S:ìjJ ïÎîµKþ¸ph¿)7Õn£uÁ:L£/(~Æ[‡'mVº£ë‡•HS^0ËpÄáÔ$Úïéz ÔìÉyß,~ÒœJ÷û.›êô/º.—ß4ưCÎn†íUû1°x»€¥9=à÷G!ŸÄtÅó’÷_ËpG·Ü–tȆc êC yÙǶ¹„úTèÀ7MFÚon÷œ²ˆ­¶¸FJâ@a[…bïÈö4égN gVÎÇWˆJx ⛃!èô$cÿÑ‹”ž¯c¼öõö¤y±òQxÂHþ ¯kKÞ"p½ à ×Ä-Bþõ”»n¦oëâgjÚŒô¸a˜(…´F՘ͲIÑàɯ*÷J„ëšY¥–éoÑ Gܸ¿‘LLE%ç%3Ûa/eg¹–suu8Jµd‹CÍÔc±Rˆ·R××Á&¬¤A*Ò7@€éÂí|W¹«Eî-p¥Ëìù Ò†4¯ÔÇܖ4]T÷³PÖÛ®'×éS{Id½a¯:Ss¸_X{MA^ÜhcßPƒ¢û^–j!fꉫaŒx«‚igh|œ·`žÌa¬€‰@œä¨gY»Áí k£šnaµ†[©–„¾3òÌFÃENʳ =Ø‚>®´ëZ`ûû†|oRæD…ÓØÛ[ÔôgN§NÀ£È¼ÏçQTC@„óÙx¸áùƨFO¤é¦hãW¥0T/œõ°;<–B0µäõ¼ª¶j_±c˜W¹ ^+Ò:NýE¶á°¬±}€Ú ¬jXrâ˜9÷?I¼AyÙŸ½˜¾–qòÉÂfË K–‹?¦Äª§BÛ©]”¨ÐË€l9ä!Váãï(ðº-y=ƒ¬¤ ¤÷dŠ<©™;Uõ<›£9«ÂE·Eza™¨¬ªÀGwz\èaRG!vj_ÞΛãϘw`a{ î ŒžïéCÇbpèÏxÅÓXlTæ8ÏLdÒYDÍš`;Å_æA=³‡M=¼*“TÈ ”ݵ§êf9’={h¬•íèLJWÙ?¼äÌësÛË¿ÑÛÉHÖcV‹‰º1 ù@mv_i¶ª1ä›÷ÛùgØj>t˜]šÄZ™«_‹ÜfïYÇÓù:g+ôIh}þÞäVÒL)ùFß—?*Bb;ҼȽœí,ªøªRßx”ÓûÒҹȩS`$(H¦Ú\9+ÂÐMXÎöØ{ïòm‘% ëD ”é”bÞ-‡‘¼š1™5óá’Y–ó,„™ŠÅF56±ä)PòÍE •õ×Ô|]qƒL7Úé"¬"‚;“}éI3‹2¨s‚nÁÊòÜìÏn  ¢®÷ïXß1ßκŸE/¿¯……÷/ p8GÜÕ ñ†0A xøäœLmÓ‹G—#üÔOvUJâÂ)ù%×Á„µžÊø ïÛgÈÙÎþ#ûÌ‹àëÇ{Hã:;ö'9â/*ššpÊižs«”­ÁÊ\Ér–l÷jÊkµ£¤‹_Qí_a`ãmá3œèÛÐ yªº0ce–Î"ÒŸ°_{C­;Rg!°ŽÞ<]y‘Ö9áíÀk£ ÈɩÔÍÊÃÉ»H@ø3ÞÖlÕ0õ%É™K¹Vrr#/r˜¬ä@ÝcÖñfR ”©Ã¦*’%HG¸Ù9o5üÚ&£uµKס´ïÎꫜiƒŽÏl©8!‡kp6k¯Ÿ|¡¯ñEøM.>,ßþ>ª&s •9Cûn¬ìŒù™BlÜÙ*ˆsTz‚YÆPI«îÿÞ =4Ÿ¼£fÁ÷Ä.¸ý–êuéâ–W÷„•2ô°óÖ)!¶’+9N\†Õ÷ìv°›Ö¾¼õvA 3|cŸ¦"ïîŽä;bÉNÀkå:šáB¾‘ÖœÃ}bÝýÂDà×àzXømþŽL;zçü°ñwC¼|Ün»ýÛLiW1‚„Öš¤Ô‡ç#r3ËccP!„Ù¤ÂÀÙBim¥´n%of‰S›bñp±ŒØT$Ê ˜ CèÌp íN«ðúÒ~Áý6ýÞø=ÓAíRvªu†º(aÆã£vMö¼{±àUs0£í:úž„zÓQÌÊò9¯ Câã!¦¡³•GewÝþ‡Ó;÷¶ôBs;Aq {°ÚëÂÜ8±“' Qxýˆ>7 ÞhŸ#ÀO¿,KEó€DÐõÌ㺛Ï`!à¡Ë]}A Š)çjÓéÎlãªg!5ÆÃ—‰Ó\÷nâ-±ÎQ3`PÐê<¥'FQ³×<“ýolÑpsR«¯æöZQ–Ð0×A³'Á2ŸÈÛÉ‹8Œ,ö÷ªÚ\§ ³yùE<5øý?ìâö"Zäù“qöGàÿ¿¦ÔðPöòŽ:¦ñ[U^»å¡tyÑ}­²ö…¯cבLê²åî»`Ãíôxf–!PSVürÇ7ž¾Á0ºÓÚ .¤ã‹w2^k¨ÛÏî§U¶µ—ÑìÁû¯Y+Ã…ö/çxj ‰Æó_Ênµ)©å-,V²9éåÛgc[6 -éQÓmR©Dry¬¬siŠóÁc)Ð%YºÖ6ýïNc¤¹ÖéªÏCXzïn°Q¿Ë¥½€1² ò&ðtê¿Jz7™&³ˆt÷³9K±ðÙªOyµR‡M$»iîBˆAôOEêZy®çqRï“P¡«Ð0¨)añÄÜÅWi‘Ͱ*7Ü¡ìø){(&,)—‘¥,9>O¶,½/|àn÷[ Äš_ýk ËŸ3†cÇ¢’·mz1ÄO¹HýžÍó·lƒìøØÙ ~E 9½4.ÛPBû[Ñá÷‡Ã%5ûÜyF@å^aNø'õëå¹9s{a«bL Ä÷C„Ë\– ƒ“ñ; Iª²›ß5¼rù_JøX(¹çÓ^ƒÀΆ‹jbàä_’Ó^ïX+¬‡^ÛOÌB3 5Í9’æzå3Œ(ÿ^]UC'Ng©ÅÑ0†m›gÂj-üd{b"¾·erƒÕsüÔwGù¼ù›´ŸgüqDO𖚉´ë—ʱ4Þ?™Ê–!©×5ÍôÇf"fcKaL¿¿^€@À2{}Ç%®AŽSc¬ö—@ù ´m‰#³ë!Úá¼óÇ,’ \ #5a½¥æ¤€Â´­©µ×¢{¬³½ÿ‹ÕŒóô)”'ójœ^ ñ¹ä¤”%ÄMCÿPKãæÇ¾U;Y<PK >C/Haxe Toolkit Installer Template/neko-2.0.0-osx/UX ‚IRkIRõPK>C8Haxe Toolkit Installer Template/neko-2.0.0-osx/.DS_StoreUX ‚IR’IRõí˜;Â0Dg K4.)Ýpn`EÉ ¸W ÷Ñ!Ú²RP%‚y’õVŠiOØð¸_€ Á3>’Ø„®6Î!„Bˆ}c®tÜvBˆ2Ÿ…®tsŸ:vc2]èJ7·±_ #èLºÒÍÍCË>Œ+Š1…X¡ëW¯,Äßppåùû?a5ÿ !~‹ãuð˯vëê†õK@🅧nl¡+Ýܺ±OPKjˆm²PK >C8__MACOSX/Haxe Toolkit Installer Template/neko-2.0.0-osx/UX ™IR™IRõPK>CC__MACOSX/Haxe Toolkit Installer Template/neko-2.0.0-osx/._.DS_StoreUX ‚IR’IRõc`cg`b`ðMLVðVˆP€'±ƒøA L…VPK¾CŠ *RPK>C9__MACOSX/Haxe Toolkit Installer Template/._neko-2.0.0-osxUX ‚IRkIRõc`cg`b`ðMLVðVˆP€'ñ ñï1CB‚ LŽ@솦„!.šœŸ«—XP“ªWXšX”˜W’™—ÊP¨o```hmj˜h``l”f힟Ÿž“SadàœQ”Ÿ›jíh`blbnéªkjääªkbaâªkélä¨ëâìldäèdâdädÌPK#"ü¿‘ÞPK >C$Haxe Toolkit Installer Template/out/UX ‚IR’IRõPK>C-Haxe Toolkit Installer Template/out/.DS_StoreUX ‚IR“IRõí˜;Â0Dg K4.)Ýpn`EÉ ¸W ÷Ñ!Ú²RP%‚y’õVŠiOØð¸_€ Á3>’Ø„®6Î!„Bˆ}c®tÜvBˆ2Ÿ…®tsŸ:vc2]èJ7·±_ #èLºÒÍÍCË>Œ+Š1…X¡ëW¯,Äßppåùû?a5ÿ !~‹ãuð˯vëê†õK@🅧nl¡+Ýܺ±OPKjˆm²PK >C-__MACOSX/Haxe Toolkit Installer Template/out/UX ™IR™IRõPK>C8__MACOSX/Haxe Toolkit Installer Template/out/._.DS_StoreUX ‚IR“IRõc`cg`b`ðMLVðVˆP€'±ƒøA L…VPK¾CŠ *RPK Ö>C(Haxe Toolkit Installer Template/scripts/UX ‚IR$IRõPKÖ>C;Haxe Toolkit Installer Template/scripts/haxe-postinstall.shUX ‚IR$IRõ}O» B1 ÝóÇë&”Žü WqðöA m/´Wñó uÒP—óÈIr<è5UÝ#µýèmÀxyA¸Í .§•r…êšá Gù‰›Ù8Vî™™ÈRÀÊaùös³àvÆ}% C1__MACOSX/Haxe Toolkit Installer Template/scripts/UX ™IR™IRõPKÖ>CF__MACOSX/Haxe Toolkit Installer Template/scripts/._haxe-postinstall.shUX ‚IR$IRõc`cg`b`ðMLVðVˆP€'q%ƒø«ˆŽ!!AP&HÇ æGSˆOÎÏÕK,(ÈIÕ I­(qÍKÎOÉÌKJ––¤éZX›š[Z˜PKpÀ]«PKq>C:Haxe Toolkit Installer Template/scripts/haxe-preinstall.shUX ‚IR†IRõSVÔOÊÌÓ/Îà*ÊUÐ-JSÐ/-.ÒÏÉLÒÏH¬HÕ/.IÁ.‘’Ÿ PK4’Žp);PKq>CE__MACOSX/Haxe Toolkit Installer Template/scripts/._haxe-preinstall.shUX ‚IR†IRõc`cg`b`ðMLVðVˆP€'q%ƒø«ˆŽ!!AP&HÇ æGSˆOÎÏÕK,(ÈIÕ I­(qÍKÎOÉÌKJ––¤éZX›š[Z˜PKpÀ]«PKܹB;Haxe Toolkit Installer Template/scripts/neko-postinstall.shUX ‚IR04 QõSVÔOÊÌÓ/Îà*ÊUÐ/-.sóR³ó1’1Drs0„JòósŠá¢9™I ’ÐK©²¸¸ròt‹² )0f9.eÉènÂ¥07í¸”‚ÝŒÍØ4 x‡/PK‹´ÓJ\UPKܹBF__MACOSX/Haxe Toolkit Installer Template/scripts/._neko-postinstall.shUX ‚IR04 Qõc`cg`b`ðMLVðVˆP€'q%ƒø«ˆŽ!!AP&HÇ æGSˆOÎÏÕK,(ÈIÕ I­(qÍKÎOÉÌKJ––¤éZX›š[Z˜PKpÀ]«PKì¸B:Haxe Toolkit Installer Template/scripts/neko-preinstall.shUX ‚IRí QõSVÔOÊÌÓ/Îà*ÊUÐ-JSÐ/-.ÒÏÉLÒÏKÍÎçPK%=p×!PK >C @íAHaxe Toolkit Installer Template/UX‚IRaIRPK>Cdè 0) @¤NHaxe Toolkit Installer Template/.DS_StoreUX‚IRaIRPK >C @ýAÕ__MACOSX/UX™IR™IRPK >C) @ýA __MACOSX/Haxe Toolkit Installer Template/UX™IR™IRPK>C¾CŠ *R4 @¤c__MACOSX/Haxe Toolkit Installer Template/._.DS_StoreUX‚IRaIRPK Y:C= @íAÿHaxe Toolkit Installer Template/Haxe Toolkit Installer.pmdoc/UX™IRYÉCRPKY:C8šŽš÷C'½P @¤jHaxe Toolkit Installer Template/Haxe Toolkit Installer.pmdoc/01haxe-contents.xmlUX‚IRYÉCRPKY:C õ;ÿì†G @¤ïHHaxe Toolkit Installer Template/Haxe Toolkit Installer.pmdoc/01haxe.xmlUX‚IRYÉCRPKY:CŠ/îP @¤`KHaxe Toolkit Installer Template/Haxe Toolkit Installer.pmdoc/02neko-contents.xmlUX‚IRYÉCRPKY:C™§Ò•ÛPG @¤MHaxe Toolkit Installer Template/Haxe Toolkit Installer.pmdoc/02neko.xmlUX‚IRYÉCRPKY:C"›gyñœ F @¤}OHaxe Toolkit Installer Template/Haxe Toolkit Installer.pmdoc/index.xmlUX‚IRYÉCRPKY:C%í!Ÿ(RG @¤òR__MACOSX/Haxe Toolkit Installer Template/._Haxe Toolkit Installer.pmdocUX™IRYÉCRPK >C/ @íAŸSHaxe Toolkit Installer Template/haxe-3.0.0-osx/UX‚IRgIRPK>C§N¼8 @¤üSHaxe Toolkit Installer Template/haxe-3.0.0-osx/.DS_StoreUX‚IRjIRPK >C8 @ýAŽU__MACOSX/Haxe Toolkit Installer Template/haxe-3.0.0-osx/UX™IR™IRPK>C¾CŠ *RC @¤ôU__MACOSX/Haxe Toolkit Installer Template/haxe-3.0.0-osx/._.DS_StoreUX‚IRjIRPK j>C: @íAŸVHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/UX‚IR˜ IRPK ú>CI @íAWHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/UX‚IRÈ IRPKú>C€Ãþ Q @¤~WHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/.currentUX‚IRÈ IRPK ú>CT @íAXHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/UX‚IRÈ IRPKú>CȈuÒéf` @¤›XHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/haxelib.jsonUX™IRÈ IRPK ú>CZ @íA"ZHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/UX‚IRÈ IRPK ú>Cb @íAªZHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/UX‚IRÈ IRPKú>C|ÑøÅéo @¤:[Haxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/ConvertXml.hxUX‚IRÈ IRPKú>C?ÖA% { i @¤¬^Haxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Data.hxUX‚IRÈ IRPKú>Cü‰{Fcw @¤xjHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/dbconfig.json.exampleUX‚IRÈ IRPKú>C¼šu˜Ð m @¤skHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/haxelib.cssUX‚IRÈ IRPKú>CDhŸê¾)…i @¤¶oHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Main.hxUX‚IRÈ IRPKú>C–š÷Úöj @¤šHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Paths.hxUX‚IRÈ IRPKú>C¯,í—l @¤Ñ›Haxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Rebuild.hxUX‚IRÈ IRPKú>Cð§Ù…š Ó$i @¤hžHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Repo.hxUX‚IRÈ IRPKú>C•^ØYk @¤©«Haxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/SemVer.hxUX‚IRÈ IRPKú>CÛ±'h‚ Ç#i @¤«®Haxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Site.hxUX‚IRÈ IRPKú>C#‡i‰‘\l @¤Ô¼Haxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/SiteApi.hxUX‚IRÈ IRPKú>C™5 Y:k @¤ÁHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/SiteDb.hxUX‚IRÈ IRPKú>C¥!Ð0Ám @¤ÉHaxe Toolkit Installer Template/haxe-3.0.0-osx/lib-client/haxelib_client/3,1,0-rc,3/tools/haxelib/Template.hxUX‚IRÈ IRPKv¹B1ÏÕ“.d2, @¤}ÌHaxe Toolkit Installer Template/haxelogo.pngUX™IR/7 QPKl¹BãæÇ¾U;Y<- @¤zûHaxe Toolkit Installer Template/haxelogo3.pngUX™IR7 QPK >C/ @íA:7Haxe Toolkit Installer Template/neko-2.0.0-osx/UX‚IRkIRPK>Cjˆm²8 @¤—7Haxe Toolkit Installer Template/neko-2.0.0-osx/.DS_StoreUX‚IR’IRPK >C8 @ýA¿8__MACOSX/Haxe Toolkit Installer Template/neko-2.0.0-osx/UX™IR™IRPK>C¾CŠ *RC @¤%9__MACOSX/Haxe Toolkit Installer Template/neko-2.0.0-osx/._.DS_StoreUX‚IR’IRPK>C#"ü¿‘Þ9 @¤Ð9__MACOSX/Haxe Toolkit Installer Template/._neko-2.0.0-osxUX‚IRkIRPK >C$ @íAØ:Haxe Toolkit Installer Template/out/UX‚IR’IRPK>Cjˆm²- @¤*;Haxe Toolkit Installer Template/out/.DS_StoreUX‚IR“IRPK >C- @ýAG<__MACOSX/Haxe Toolkit Installer Template/out/UX™IR™IRPK>C¾CŠ *R8 @¤¢<__MACOSX/Haxe Toolkit Installer Template/out/._.DS_StoreUX‚IR“IRPK Ö>C( @íAB=Haxe Toolkit Installer Template/scripts/UX‚IR$IRPKÖ>C¤*c‡”; @ÿ˜=Haxe Toolkit Installer Template/scripts/haxe-postinstall.shUX‚IR$IRPK >C1 @ýA˜>__MACOSX/Haxe Toolkit Installer Template/scripts/UX™IR™IRPKÖ>CpÀ]«F @¶÷>__MACOSX/Haxe Toolkit Installer Template/scripts/._haxe-postinstall.shUX‚IR$IRPKq>C4’Žp);: @ÿØ?Haxe Toolkit Installer Template/scripts/haxe-preinstall.shUX‚IR†IRPKq>CpÀ]«E @¶y@__MACOSX/Haxe Toolkit Installer Template/scripts/._haxe-preinstall.shUX‚IR†IRPKܹB‹´ÓJ\U; @ÿYAHaxe Toolkit Installer Template/scripts/neko-postinstall.shUX‚IR04 QPKܹBpÀ]«F @¶.B__MACOSX/Haxe Toolkit Installer Template/scripts/._neko-postinstall.shUX‚IR04 QPKì¸B%=p×!: @ÿCHaxe Toolkit Installer Template/scripts/neko-preinstall.shUX‚IRí QPK887¨Chaxe_3.4.4.orig/extra/release-checklist.txt0000664000175000017500000000245713166552354020677 0ustar andyandy00000000000000# Preparing related projects - Check that haxelib is working - Make sure to update the haxelib submodule - Check that the run-time haxelibs are ready for release: hxcpp, hxjava, hxcs # Building the binaries and installers - Make sure CHANGES.txt has a proper date set! - Make sure `version` in globals.ml has the correct value. - Update README.md: - Version compatibility: add/update the Haxe/Neko version - Merge development branch into master. - Wait for Travis to greenlight master. - Tag master as MAJOR.MINOR.PATCH. - Wait for builds.haxe.org to build master. - Get https://github.com/waneck/hxbuilds/tree/master/release-helper - Run it with the fileName corresponding to the latest master file name on builds.haxe.org. # Making the release - Regenerate API documentation (check --title and -D version values). - Make a GitHub release in https://github.com/HaxeFoundation/haxe/releases with - the generated binaries and installers - the API documentation - Update haxe.org - Copy relevant changelog part to downloads/$version/CHANGES.md. - Write announcement post in downloads/$version/RELEASE.md. - Update downloads/versions.json. - Push to staging, check https://staging.haxe.org/. - Merge staging to master, check https://haxe.org/. # Announcing the release - Post announcement post to haxelang. haxe_3.4.4.orig/extra/release.neko0000664000175000017500000000413413166552354017037 0ustar andyandy00000000000000version = $loader.args[0]; if( version == null ) $throw(" argument required"); sys = $loader.loadprim("std@sys_string",0)(); binext = ""; curdir = "./"; ext = switch( sys ) { "Windows" => { curdir = ".\\"; binext = ".exe"; "-win" } "Mac" => "-osx" "Linux" => "-linux" "BSD" => "-bsd" default => $throw("Unknown system") } rights = 493; // octal 755 _mkdir = $loader.loadprim("std@sys_create_dir",2); mkdir = function(d) { _mkdir(d,rights); } chdir = $loader.loadprim("std@set_cwd",1); _cmd = $loader.loadprim("std@sys_command",1); cmd = function(c) { if( _cmd(c) != 0 ) $throw("Command '"+c+"' failed"); } dir = "haxe-"+version+ext; cmd("rm -rf "+dir); mkdir(dir); mkdir(dir+"/doc"); if( sys == "Windows" ) { cmd("cp ../haxe.exe ../haxesetup.exe haxeserver.bat "+dir); // copy if available (means we build on recent OCaml/MSVC) try cmd("cp C:/Windows/System32/msvcr100.dll "+dir) catch e {}; } else cmd("cp ../haxe "+dir); cmd("cp -pR CHANGES.txt LICENSE.txt ../std "+dir); if( sys == "Windows" ) cmd("chmod -R 777 "+dir); cmd("haxe all.hxml"); chdir(dir+"/std/tools"); // BUILD TOOLS chdir("haxedoc"); cmd("haxe haxedoc.hxml"); cmd(curdir+"haxedoc -v \"../../../../neko.xml;neko\" \"../../../../js.xml;js\" \"../../../../flash9.xml;flash\" \"../../../../php.xml;php\" \"../../../../cpp.xml;cpp\""); cmd("mv index.html content ../../../doc"); cmd("mv haxedoc"+binext+" ../../.."); chdir(".."); chdir("haxelib"); cmd("haxe haxelib.hxml"); cmd("mv haxelib"+binext+" ../../.."); chdir(".."); // CLEANUP chdir(".."); cmd("rm -rf .svn */.svn */*/.svn */*/*/.svn */*/*/*/.svn"); cmd("rm -rf all.n all.js *.swf *.xml"); chdir("tools"); chdir("haxedoc"); cmd("rm -rf haxedoc.n index.html content haxedoc"+binext); chdir(".."); chdir("haxelib"); cmd("rm -rf *.bat *.zip *.db *.n tmp files"); chdir(".."); chdir("hxinst"); cmd("rm -rf *.n *.zip *.dmg *.app hxinst-win.exe hxinst-linux hxinst-osx"); chdir(".."); chdir(".."); cmd("rm -rf mt mtwin"); chdir("../.."); // PACKAGE if( sys == "Windows" ) cmd("7z a -tzip "+dir+".zip "+dir); else cmd("tar -czf "+dir+".tar.gz "+dir); cmd("rm -rf "+dir); haxe_3.4.4.orig/extra/setup.cpp0000664000175000017500000000501713166552354016406 0ustar andyandy00000000000000/* Haxe Setup Copyright (C) 2005-2016 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // this is a small program that do basic Haxe setup on Windows #include static void Set( HKEY k, const char *name, DWORD t, const char *data ) { RegSetValueEx(k,name,0,t,(const BYTE*)data,(DWORD)strlen(data)+1); } int WINAPI WinMain( HINSTANCE inst, HINSTANCE prev, LPSTR lpCmdLine, int nCmdShow ) { char path[MAX_PATH]; *path = '"'; GetModuleFileName(NULL,path+1,MAX_PATH); // register .hxml extension char *s = strrchr(path,'\\') + 1; strcpy(s,"haxe.exe\" -prompt \"%1\""); HKEY k; RegCreateKey(HKEY_CLASSES_ROOT,".hxml\\shell\\Compile\\command",&k); RegSetValueEx(k,NULL,0,REG_SZ,(const BYTE*)path,(DWORD)(strlen(path)+1)); *s = 0; // add %HAXEPATH% to PATH and set HAXEPATH to current path DWORD ktype; DWORD ksize = 16000; char *kdata = new char[16000]; memset(kdata,0,ksize); RegOpenKey(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",&k); RegQueryValueEx(k,"PATH",NULL,&ktype,(LPBYTE)kdata,&ksize); if( strstr(kdata,"%HAXEPATH%") == NULL ) { char *s = kdata + strlen(kdata); strcpy(s,";%HAXEPATH%"); Set(k,"PATH",REG_EXPAND_SZ,kdata); } if( strstr(kdata,"%NEKO_INSTPATH%") == NULL ) { char *s = kdata + strlen(kdata); strcpy(s,";%NEKO_INSTPATH%"); Set(k,"PATH",REG_EXPAND_SZ,kdata); } Set(k,"HAXEPATH",REG_SZ,path + 1); s[-1] = 0; strcpy(strrchr(path,'\\'),"\\neko"); Set(k,"NEKO_INSTPATH",REG_SZ,path+1); RegCloseKey(k); // inform running apps of env changes (W2K/NT systems only ?) DWORD unused; SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, &unused ); // delete kdata; // // register // if( strcmp(lpCmdLine,"-silent") != 0 ) // MessageBox(NULL,"Setup completed, you can start using Haxe now","haxesetup",MB_OK | MB_ICONINFORMATION); return 0; } haxe_3.4.4.orig/extra/setup.sln0000664000175000017500000000155613166552354016424 0ustar andyandy00000000000000Microsoft Visual Studio Solution File, Format Version 8.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "setup", "setup.vcproj", "{6E869222-35FF-4BC0-B5AA-E63BCB8803A6}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {6E869222-35FF-4BC0-B5AA-E63BCB8803A6}.Debug.ActiveCfg = Debug|Win32 {6E869222-35FF-4BC0-B5AA-E63BCB8803A6}.Debug.Build.0 = Debug|Win32 {6E869222-35FF-4BC0-B5AA-E63BCB8803A6}.Release.ActiveCfg = Release|Win32 {6E869222-35FF-4BC0-B5AA-E63BCB8803A6}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal haxe_3.4.4.orig/extra/setup.vcproj0000664000175000017500000000547613166552354017140 0ustar andyandy00000000000000 haxe_3.4.4.orig/haxe.hxproj0000664000175000017500000004266713166552354015614 0ustar andyandy00000000000000 make -j4 FD_OUTPUT=1 -f Makefile.win kill haxe haxe_3.4.4.orig/src/context/common.ml0000664000175000017500000010656713166552354017530 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Type open Globals type package_rule = | Forbidden | Directory of string | Remap of string type pos = Globals.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; } (** 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; (** 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; (** 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; } module DisplayMode = struct type t = | DMNone | DMField | DMUsage of bool (* true = also report definition *) | DMPosition | DMToplevel | DMResolve of string | DMPackage | DMType | DMModuleSymbols of string option | DMDiagnostics of bool (* true = global, false = only in display file *) | DMStatistics | DMSignature type error_policy = | EPIgnore | EPCollect | EPShow type display_file_policy = | DFPOnly | DFPAlso | DFPNo type settings = { dms_kind : t; dms_display : bool; dms_full_typing : bool; dms_force_macro_typing : bool; dms_error_policy : error_policy; dms_collect_data : bool; dms_check_core_api : bool; dms_inline : bool; dms_display_file_policy : display_file_policy; dms_exit_during_typing : bool; } let default_display_settings = { dms_kind = DMField; dms_display = true; dms_full_typing = false; dms_force_macro_typing = false; dms_error_policy = EPIgnore; dms_collect_data = false; dms_check_core_api = false; dms_inline = false; dms_display_file_policy = DFPOnly; dms_exit_during_typing = true; } let default_compilation_settings = { dms_kind = DMNone; dms_display = false; dms_full_typing = true; dms_force_macro_typing = true; dms_error_policy = EPShow; dms_collect_data = false; dms_check_core_api = true; dms_inline = true; dms_display_file_policy = DFPNo; dms_exit_during_typing = false; } let create dm = let settings = { default_display_settings with dms_kind = dm } in match dm with | DMNone -> default_compilation_settings | DMField | DMPosition | DMResolve _ | DMPackage | DMType | DMSignature -> settings | DMUsage _ -> { settings with dms_full_typing = true; dms_collect_data = true; dms_display_file_policy = DFPAlso; dms_exit_during_typing = false } | DMToplevel -> { settings with dms_full_typing = true; } | DMModuleSymbols filter -> { settings with dms_display_file_policy = if filter = None then DFPOnly else DFPNo; dms_exit_during_typing = false; dms_force_macro_typing = false; } | DMDiagnostics global -> { settings with dms_full_typing = true; dms_error_policy = EPCollect; dms_collect_data = true; dms_inline = true; dms_display_file_policy = if global then DFPNo else DFPAlso; dms_exit_during_typing = false; } | DMStatistics -> { settings with dms_full_typing = true; dms_collect_data = true; dms_inline = false; dms_display_file_policy = DFPAlso; dms_exit_during_typing = false } let to_string = function | DMNone -> "none" | DMField -> "field" | DMPosition -> "position" | DMResolve s -> "resolve " ^ s | DMPackage -> "package" | DMType -> "type" | DMUsage true -> "rename" | DMUsage false -> "references" | DMToplevel -> "toplevel" | DMModuleSymbols None -> "module-symbols" | DMModuleSymbols (Some s) -> "workspace-symbols " ^ s | DMDiagnostics b -> (if b then "global " else "") ^ "diagnostics" | DMStatistics -> "statistics" | DMSignature -> "signature" end type compiler_callback = { mutable after_typing : (module_type list -> unit) list; mutable before_dce : (unit -> unit) list; mutable after_generation : (unit -> unit) list; } module IdentifierType = struct type t = | ITLocal of tvar | ITMember of tclass * tclass_field | ITStatic of tclass * tclass_field | ITEnum of tenum * tenum_field | ITEnumAbstract of tabstract * tclass_field | ITGlobal of module_type * string * Type.t | ITType of module_type | ITPackage of string | ITLiteral of string | ITTimer of string let get_name = function | ITLocal v -> v.v_name | ITMember(_,cf) | ITStatic(_,cf) | ITEnumAbstract(_,cf) -> cf.cf_name | ITEnum(_,ef) -> ef.ef_name | ITGlobal(_,s,_) -> s | ITType mt -> snd (t_infos mt).mt_path | ITPackage s -> s | ITLiteral s -> s | ITTimer s -> s end type shared_display_information = { mutable import_positions : (pos,bool ref * placed_name list) PMap.t; mutable diagnostics_messages : (string * pos * DisplayTypes.DiagnosticsSeverity.t) list; mutable type_hints : (pos,Type.t) Hashtbl.t; mutable document_symbols : (string * DisplayTypes.SymbolInformation.t DynArray.t) list; mutable removable_code : (string * pos * pos) list; } type display_information = { mutable unresolved_identifiers : (string * pos * (string * IdentifierType.t) list) list; mutable interface_field_implementations : (tclass * tclass_field * tclass * tclass_field option) list; } (* This information is shared between normal and macro context. *) type shared_context = { shared_display_information : shared_display_information; } type context = { (* config *) version : int; args : string list; shared : shared_context; display_information : display_information; mutable sys_args : string list; mutable display : DisplayMode.settings; 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 *) callbacks : compiler_callback; 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; parser_cache : (string,(type_def * pos) list) Hashtbl.t; cached_macros : (path * string,((string * bool * t) list * t * tclass * Type.tclass_field)) 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 include_files : (string * 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 * pos let display_default = ref DisplayMode.DMNone let get_signature com = match com.defines_signature with | Some s -> s | None -> let defines = PMap.foldi (fun k v acc -> (* don't make much difference between these special compilation flags *) match String.concat "_" (ExtString.String.nsplit k "-") with (* If we add something here that might be used in conditional compilation it should be added to Parser.parse_macro_ident as well (issue #5682). *) | "display" | "use_rtti_doc" | "macro_times" | "display_details" | "no_copt" | "display_stdin" -> acc | _ -> (k ^ "=" ^ v) :: acc ) com.defines [] in let str = String.concat "@" (List.sort compare defines) in let s = Digest.string str in com.defines_signature <- Some s; s let is_php7 com = com.platform = Php && PMap.exists "php7" com.defines module CompilationServer = struct type cache = { c_haxelib : (string list, string list) Hashtbl.t; c_files : ((string * string), float * Ast.package) Hashtbl.t; c_modules : (path * string, module_def) Hashtbl.t; c_directories : (string, (string * float ref) list) Hashtbl.t; } type t = { cache : cache; mutable signs : (string * string) list; } type context_options = | NormalContext | MacroContext | NormalAndMacroContext let instance : t option ref = ref None let create_cache () = { c_haxelib = Hashtbl.create 0; c_files = Hashtbl.create 0; c_modules = Hashtbl.create 0; c_directories = Hashtbl.create 0; } let create () = let cs = { cache = create_cache(); signs = []; } in instance := Some cs; cs let get () = !instance let runs () = !instance <> None let get_context_files cs signs = Hashtbl.fold (fun (file,sign) (_,data) acc -> if (List.mem sign signs) then (file,data) :: acc else acc ) cs.cache.c_files [] (* signatures *) let get_sign cs sign = List.assoc sign cs.signs let add_sign cs sign = let i = string_of_int (List.length cs.signs) in cs.signs <- (sign,i) :: cs.signs; i (* modules *) let find_module cs key = Hashtbl.find cs.cache.c_modules key let cache_module cs key value = Hashtbl.replace cs.cache.c_modules key value let taint_modules cs file = Hashtbl.iter (fun _ m -> if m.m_extra.m_file = file then m.m_extra.m_dirty <- Some m) cs.cache.c_modules (* files *) let find_file cs key = Hashtbl.find cs.cache.c_files key let cache_file cs key value = Hashtbl.replace cs.cache.c_files key value let remove_file cs key = Hashtbl.remove cs.cache.c_files key let remove_files cs file = List.iter (fun (sign,_) -> remove_file cs (sign,file)) cs.signs (* haxelibs *) let find_haxelib cs key = Hashtbl.find cs.cache.c_haxelib key let cache_haxelib cs key value = Hashtbl.replace cs.cache.c_haxelib key value (* directories *) let find_directories cs key = Hashtbl.find cs.cache.c_directories key let add_directories cs key value = Hashtbl.replace cs.cache.c_directories key value let remove_directory cs key value = try let current = find_directories cs key in Hashtbl.replace cs.cache.c_directories key (List.filter (fun (s,_) -> s <> value) current); with Not_found -> () let has_directory cs key value = try List.mem_assoc value (find_directories cs key) with Not_found -> false let add_directory cs key value = try let current = find_directories cs key in add_directories cs key (value :: current) with Not_found -> add_directories cs key [value] let clear_directories cs key = Hashtbl.remove cs.cache.c_directories key end module Define = struct type strict_defined = | AbsolutePath | AdvancedTelemetry | AnnotateSource (* | Analyzer *) | As3 | CheckXmlProxy | CoreApi | CoreApiSerialize | Cppia | Dce | DceDebug | Debug | Display | DisplayStdin | DllExport | DllImport | DocGen | Dump | DumpDependencies | DumpIgnoreVarIds | DynamicInterfaceClosures | EraseGenerics | FastCast | Fdb | FileExtension | FlashStrict | FlashUseStage | ForceLibCheck | ForceNativeProperty | FormatWarning | GencommonDebug | HaxeBoot | HaxeVer | HxcppApiLevel | HxcppGcGenerational | HxcppDebugger | IncludePrefix | Interp | JavaVer | JqueryVer | JsClassic | JsEs | JsUnflatten | JsSourceMap | SourceMap | KeepOldOutput | LoopUnrollMaxCost | LuaVer | LuaJit | Macro | MacroDebug | MacroTimes | NekoSource | NekoV1 | NetworkSandbox | NetVer | NetTarget | NoCompilation | NoCOpt | NoDeprecationWarnings | NoFlashOverride | NoDebug | NoInline | NoOpt | NoPatternMatching | NoRoot | NoSwfCompress | NoTraces | Objc | PhpPrefix | RealPosition | ReplaceFiles | Scriptable | ShallowExpose | SourceHeader | 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") | AnnotateSource -> ("annotate_source","Add additional comments to generated source code") (* | 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","Mark some generated core api classes with the Serializable attribute on C#") | Cppia -> ("cppia", "Generate cpp instruction assembly") | Dce -> ("dce"," Set the dead code elimination mode (default std)") | DceDebug -> ("dce_debug","Show DCE log") | Debug -> ("debug","Activated when compiling with -debug") | Display -> ("display","Activated during completion") | DisplayStdin -> ("display_stdin","Read the contents of a file specified in --display from standard input") | 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 typed AST in dump subdirectory using specified mode or non-prettified default") | DumpDependencies -> ("dump_dependencies","Dump the classes dependencies in a dump subdirectory") | DumpIgnoreVarIds -> ("dump_ignore_var_ids","Remove variable IDs from non-pretty dumps (helps with diff)") | DynamicInterfaceClosures -> ("dynamic_interface_closures","Use slow path for interface closures to save space") | EraseGenerics -> ("erase_generics","Erase generic classes on C#") | FastCast -> ("fast_cast","Enables an experimental casts cleanup on C# and Java") | 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") | HxcppGcGenerational -> ("HXCPP_GC_GENERATIONAL","Experimental Garbage Collector") | HxcppDebugger -> ("HXCPP_DEBUGGER","Include additional information for HXCPP_DEBUGGER") | 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") | JqueryVer -> ("jquery_ver", "The jQuery version supported by js.jquery.*. The version is encoded as an interger. e.g. 1.11.3 is encoded as 11103") | JsClassic -> ("js_classic","Don't use a function wrapper and strict mode in JS output") | JsEs -> ("js_es","Generate JS compilant with given ES standard version (default 5)") | JsUnflatten -> ("js_unflatten","Generate nested objects for packages and types") | JsSourceMap -> ("js_source_map","Generate JavaScript source map even in non-debug mode") | SourceMap -> ("source_map","Generate source map for compiled files (Currently supported for php7 only)") | 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)") | LuaJit -> ("lua_jit","Enable the jit compiler for lua (version 5.2 only") | LuaVer -> ("lua_ver","The lua version to target") | Macro -> ("macro","Defined when code is compiled in the macro context") | MacroDebug -> ("macro_debug","Show warnings for potential macro problems (e.g. macro-in-macro calls)") | 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") | NoSwfCompress -> ("no_swf_compress","Disable SWF output compression") | NoTraces -> ("no_traces","Disable all trace calls") | Objc -> ("objc","Sets the hxcpp output to objective-c++ classes. Must be defined for interop") | PhpPrefix -> ("php_prefix","Compiled with --php-prefix") | RealPosition -> ("real_position","Disables Haxe source mapping when targetting C#, removes position comments in Java and Php7 output") | 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") | SourceHeader -> ("source-header","Print value as comment on top of generated files, use '' value to disable") | 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 let short_platform_name = function | Cross -> "x" | Js -> "js" | Lua -> "lua" | Neko -> "n" | Flash -> "swf" | Php -> "php" | Cpp -> "cpp" | Cs -> "cs" | Java -> "jav" | Python -> "py" | Hl -> "hl" 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_capture_policy = CPNone; pf_pad_nulls = false; pf_add_final_return = false; pf_overload = 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 -> { default_config with pf_static = false; pf_sys = false; pf_capture_policy = CPLoopVars; pf_reserved_type_paths = [([],"Object");([],"Error")]; } | Lua -> { default_config with pf_static = false; pf_capture_policy = CPLoopVars; } | Neko -> { default_config with pf_static = false; pf_pad_nulls = true; } | Flash when defined Define.As3 -> { default_config with pf_sys = false; pf_capture_policy = CPLoopVars; pf_add_final_return = true; pf_can_skip_non_nullable_argument = false; } | Flash -> { default_config with pf_sys = false; pf_capture_policy = CPLoopVars; pf_can_skip_non_nullable_argument = false; pf_reserved_type_paths = [([],"Object");([],"Error")]; } | Php -> if is_php7 com then { default_config with pf_static = false; } else { default_config with pf_static = false; pf_pad_nulls = true; } | Cpp -> { default_config with pf_capture_policy = CPWrapRef; pf_pad_nulls = true; pf_add_final_return = true; } | Cs -> { default_config with pf_capture_policy = CPWrapRef; pf_pad_nulls = true; pf_overload = true; } | Java -> { default_config with pf_capture_policy = CPWrapRef; pf_pad_nulls = true; pf_overload = true; } | Python -> { default_config with pf_static = false; pf_capture_policy = CPLoopVars; } | Hl -> { default_config with pf_capture_policy = CPWrapRef; pf_pad_nulls = true; pf_can_skip_non_nullable_argument = false; } let memory_marker = [|Unix.time()|] let create_callbacks () = { after_typing = []; before_dce = []; after_generation = []; } let create version s_version args = let m = Type.mk_mono() in let defines = PMap.add "true" "1" ( PMap.add "source-header" ("Generated by Haxe " ^ s_version) ( if !display_default <> DisplayMode.DMNone then PMap.add "display" "1" PMap.empty else PMap.empty)) in { version = version; args = args; shared = { shared_display_information = { import_positions = PMap.empty; diagnostics_messages = []; type_hints = Hashtbl.create 0; document_symbols = []; removable_code = []; } }; display_information = { unresolved_identifiers = []; interface_field_implementations = []; }; sys_args = args; debug = false; display = DisplayMode.create !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 = defines; package_rules = PMap.empty; file = ""; types = []; callbacks = create_callbacks(); 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 = []; include_files = []; 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; cached_macros = Hashtbl.create 0; memory_marker = memory_marker; parser_cache = Hashtbl.create 0; } 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; parser_cache = Hashtbl.create 0 ; callbacks = create_callbacks(); display_information = { unresolved_identifiers = []; interface_field_implementations = []; }; } let file_time file = Extc.filetime file let file_extension file = match List.rev (ExtString.String.nsplit file ".") with | e :: _ -> String.lowercase e | [] -> "" 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 | v when v >= 12.0 && float_of_int (int_of_float v) = v -> int_of_float v + 11 | v -> failwith ("Invalid SWF version " ^ string_of_float v) 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) || Meta.has 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 (Meta.has Meta.RealPath (t_infos t).mt_meta)) com.types with | t when meth = "*" -> (match t with TAbstractDecl a -> Meta.has Meta.ValueUsed a.a_meta | _ -> Meta.has 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 abort msg p = raise (Abort (msg,p)) let platform ctx p = ctx.platform = p let add_typing_filter ctx f = ctx.callbacks.after_typing <- f :: ctx.callbacks.after_typing let add_filter ctx f = ctx.callbacks.before_dce <- f :: ctx.callbacks.before_dce let add_final_filter ctx f = ctx.callbacks.after_generation <- f :: ctx.callbacks.after_generation 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 begin (try let ext = String.rindex file '.' in let file_pf = String.sub file 0 (ext + 1) ^ platform_name ctx.platform ^ String.sub file ext (String.length file - ext) in if not (defined ctx Define.CoreApi) && Sys.file_exists file_pf then file_pf else file with Not_found -> file) end 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 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 = { id : string list; mutable start : float list; mutable total : float; mutable calls : int; } let get_time = Extc.time let htimers = Hashtbl.create 0 let new_timer id = let key = String.concat "." id in try let t = Hashtbl.find htimers key in t.start <- get_time() :: t.start; t.calls <- t.calls + 1; t with Not_found -> let t = { id = id; start = [get_time()]; total = 0.; calls = 1; } in Hashtbl.add htimers key 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 " ^ (String.concat "." t.id) ^ " 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 id = let t = new_timer id in curtime := t :: !curtime; (function() -> close t) let rec close_times() = match !curtime with | [] -> () | t :: _ -> close t; close_times() ;; (* 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 let add_diagnostics_message com s p sev = let di = com.shared.shared_display_information in di.diagnostics_messages <- (s,p,sev) :: di.diagnostics_messages open Printer let dump_context com = s_record_fields "" [ "version",string_of_int com.version; "args",s_list ", " (fun s -> s) com.args; "debug",string_of_bool com.debug; "platform",platform_name com.platform; "std_path",s_list ", " (fun s -> s) com.std_path; "class_path",s_list ", " (fun s -> s) com.class_path; "defines",s_pmap (fun s -> s) (fun s -> s) com.defines; "defines_signature",s_opt (fun s -> Digest.to_hex s) com.defines_signature; ] haxe_3.4.4.orig/src/context/meta.ml0000664000175000017500000005767513166552354017173 0ustar andyandy00000000000000open Globals type strict_meta = | Abi | Abstract | Access | Accessor | Allow | Analyzer | Annotation | ArrayAccess | Ast | AstSource | AutoBuild | Bind | Bitmap | BridgeProperties | Build | BuildXml | Callable | Class | ClassCode | Commutative | CompilerGenerated | Const | CoreApi | CoreType | CppFileCode | CppInclude | CppNamespaceCode | CsNative | Dce | Debug | Decl | DefParam | Delegate | Depend | Deprecated | DirectlyUsed | DynamicObject | Eager | Enum | EnumConstructorParam | Event | Exhaustive | Expose | Extern | FakeEnum | File | FileXml | Final | Fixed | FlatEnum | Font | Forward | ForwardStatics | From | FunctionCode | FunctionTailCode | Generic | GenericBuild | GenericInstance | Getter | Hack | HasUntyped | HaxeGeneric | HeaderClassCode | HeaderCode | HeaderInclude | HeaderNamespaceCode | HxGen | IfFeature | Impl | PythonImport | ImplicitCast | Include | InitPackage | InlineConstructorVariable | Internal | IsVar | JavaCanonical | JavaNative | JsRequire | Keep | KeepInit | KeepSub | LibType | LuaRequire | Meta | Macro | MaybeUsed | MergeBlock | MultiReturn | MultiType | Native | NativeChildren | NativeGen | NativeGeneric | NativeProperty | NativeStaticExtension | NoCompletion | NoDebug | NoDoc | NoExpr | NoImportGlobal | NonVirtual | NoPackageRestrict | NoPrivateAccess | NoStack | NotNull | NoUsing | Ns | Objc | ObjcProtocol | Op | Optional | Overload | PhpConstants | PhpGlobal | PhpClassConst | PhpMagic | PhpNoConstructor | PrivateAccess | Property | Protected | Public | PublicFields | Pure | QuotedField | ReadOnly | RealPath | Remove | Require | RequiresAssign | Resolve | Rtti | Runtime | RuntimeValue | Scalar | SelfCall | Setter | SkipCtor | SkipReflection | Sound | SourceFile | StackOnly | StoredTypedExpr | Strict | Struct | StructAccess | StructInit | SuppressWarnings | This | Throws | To | ToString | Transient | TemplatedCall | ValueUsed | Volatile | Unbound | UnifyMinDynamic | Unreflective | Unsafe | Usage | Used | UserVariable | 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 type meta_usage = | TClass | TClassField | TAbstract | TAbstractField | TEnum | TTypedef | TAnyField | TExpr | TTypeParameter type meta_parameter = | HasParam of string | Platform of platform | Platforms of platform list | UsedOn of meta_usage | UsedOnEither of meta_usage list | UsedInternally let get_info = 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;UsedInternally]) | 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",[UsedInternally]) | AstSource -> ":astSource",("Filled by the compiler with the parsed expression of the field",[UsedOn TClassField]) | 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; UsedInternally]) | 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]]) | Const -> ":const",("Allows a type parameter to accept expression values",[UsedOn TTypeParameter]) | 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]; UsedInternally]) | 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",("Default function argument value loaded from the SWF and used for documentation in Genxml",[Platform Flash;UsedInternally]) | Delegate -> ":delegate",("Automatically added by -net-lib on delegates",[Platform Cs; UsedOn TAbstract]) | Depend -> ":depend",("",[Platform Cpp]) | Deprecated -> ":deprecated",("Mark a type or field as deprecated",[]) | DirectlyUsed -> ":directlyUsed",("Marks types that are directly referenced by non-extern code",[UsedInternally]) | DynamicObject -> ":dynamicObject",("Used internally to identify the Dynamic Object implementation",[Platforms [Java;Cs]; UsedOn TClass; UsedInternally]) | Eager -> ":eager",("Forces typedefs to be followed early",[UsedOn TTypedef]) | Enum -> ":enum",("Defines finite value sets to abstract definitions",[UsedOn TAbstract]) | EnumConstructorParam -> ":enumConstructorParam",("Used internally to annotate GADT type parameters",[UsedOn TClass; UsedInternally]) | Event -> ":event",("Automatically added by -net-lib on events. Has no effect on types compiled by Haxe",[Platform Cs; UsedOn TClassField]) | Exhaustive -> ":exhaustive",("",[UsedInternally]) | 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]) | FileXml -> ":fileXml",("Include xml attribute snippet in Build.xml entry for file",[UsedOn TClass;Platform Cpp]) | Final -> ":final",("Prevents a class from being extended",[UsedOn TClass]) | Fixed -> ":fixed",("Delcares an anonymous object to have fixed fields",[ (*UsedOn TObjectDecl(_)*)]) | FlatEnum -> ":flatEnum",("Internally used to mark an enum as being flat, i.e. having no function constructors",[UsedOn TEnum; UsedInternally]) | 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]) | ForwardStatics -> ":forwardStatics",("Forwards static 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",("Used to inject platform-native code into a function",[Platforms [Cpp;Java;Cs]]) | 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;UsedInternally]) | 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",[UsedInternally])) | HaxeGeneric -> ":haxeGeneric",("Used internally to annotate non-native generic classes",[Platform Cs; UsedOnEither[TClass;TEnum]; UsedInternally]) | 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; UsedInternally]) | 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",[UsedInternally; UsedOn TExpr]) | Include -> ":include",("",[Platform Cpp]) | InitPackage -> ":initPackage",("Some weird thing for Genjs we want to remove someday",[UsedInternally; Platform Js]) | InlineConstructorVariable -> ":inlineConstructorVariable",("Internally used to mark variables that come from inlined constructors",[UsedInternally]) | 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]; UsedInternally]) | JsRequire -> ":jsRequire",("Generate javascript module require expression for given extern",[Platform Js; UsedOn TClass]) | LuaRequire -> ":luaRequire",("Generate lua module require expression for given extern",[Platform Lua; 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",[UsedInternally; 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",[UsedInternally]) | MergeBlock -> ":mergeBlock",("Merge the annotated block into the current scope",[UsedOn TExpr]) | MultiReturn -> ":multiReturn",("Annotates an extern class as the result of multi-return function",[UsedOn TClass; Platform Lua]) | 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]; UsedInternally]) | NativeProperty -> ":nativeProperty",("Use native properties which will execute even with dynamic usage",[Platform Cpp]) | NativeStaticExtension -> ":nativeStaticExtension",("Converts static function syntax into member call",[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",[UsedInternally]) | 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",[UsedInternally]) | 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]) | Objc -> ":objc",("Declares a class or interface that is used to interoperate with Objective-C code",[Platform Cpp;UsedOn TClass]) | ObjcProtocol -> ":objcProtocol",("Associates an interface with, or describes a function in, a native Objective-C protocol.",[Platform Cpp;UsedOnEither [TClass;TClassField] ]) | 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]) | PhpConstants -> ":phpConstants",("Marks the static fields of a class as PHP constants, without $",[Platform Php;UsedOn TClass]) | PhpGlobal -> ":phpGlobal",("(php7) Puts the static fields of a class in the global PHP namespace",[Platforms [Php;Php];UsedOn TClass]) | PhpClassConst -> ":phpClassConst",("(php7) Generate static var of an extern class as a PHP class constant",[Platform Php;UsedOn TClass]) | PhpMagic -> ":phpMagic",("(php7) Treat annotated field as special PHP magic field",[Platform Php;UsedOn TClassField]) | PhpNoConstructor -> ":phpNoConstructor",("(php7) Special meta for extern classes which does not have native constructor in PHP, but need a constructor in Haxe extern",[Platform Php;UsedOn TClass]) | Public -> ":public",("Marks a class field as being public",[UsedOn TClassField;UsedInternally]) | 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",[UsedInternally]) | PrivateAccess -> ":privateAccess",("Allow private access to anything for the annotated expression",[UsedOn TExpr]) | Protected -> ":protected",("Marks a class field as being protected",[UsedOn TClassField;Platforms [Cs;Java;Flash]]) | Property -> ":property",("Marks a property field to be compiled as a native C# property",[UsedOn TClassField;Platform Cs]) | Pure -> ":pure",("Marks a class field, class or expression as pure (side-effect free)",[UsedOnEither [TClass;TClassField;TExpr]]) | 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",[UsedInternally]) | 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",[UsedInternally]) | Resolve -> ":resolve",("Abstract fields marked with this metadata can be used to resolve unknown fields",[UsedOn TClassField]) | Rtti -> ":rtti",("Adds runtime type informations",[UsedOn TClass]) | Runtime -> ":runtime",("?",[]) | RuntimeValue -> ":runtimeValue",("Marks an abstract as being a runtime value",[UsedOn TAbstract]) | Scalar -> ":scalar",("Used by hxcpp to mark a custom coreType abstract",[UsedOn TAbstract; Platform Cpp]) | 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]) | StackOnly -> ":stackOnly",("Instances of this type can only appear on the stack",[Platform Cpp]) | StoredTypedExpr -> ":storedTypedExpr",("Used internally to reference a typed expression returned from a macro",[UsedInternally]) | SkipCtor -> ":skipCtor",("Used internally to generate a constructor as if it were a native type (no __hx_ctor)",[Platforms [Java;Cs]; UsedInternally]) | SkipReflection -> ":skipReflection",("Used internally to annotate a field that shouldn't have its reflection data generated",[Platforms [Java;Cs]; UsedOn TClassField; UsedInternally]) | 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]) | StructInit -> ":structInit",("Allows to initialize the class with a structure that matches constructor parameters",[UsedOn TClass]) | SuppressWarnings -> ":suppressWarnings",("Adds a SuppressWarnings annotation for the generated Java class",[Platform Java; UsedOn TClass]) | TemplatedCall -> ":templatedCall",("Indicates that the first parameter of static call should be treated as a template arguement",[Platform Cpp; UsedOn TClassField]) | 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",[UsedInternally; 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",[UsedInternally]) | 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",[UsedInternally]) | Volatile -> ":volatile",("",[Platforms [Java;Cs]]) | Unbound -> ":unbound", ("Compiler internal to denote unbounded global variable",[UsedInternally]) | 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",("Internal metadata used to mark a symbol for which usage request was invoked",[UsedInternally]) | Used -> ":used",("Internally used by DCE to mark a class or field as used",[UsedInternally]) | UserVariable -> ":userVariable",("Internally used to mark variables that come from user code",[UsedInternally]) | 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 to_string m = fst (get_info m) 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 (get_info 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 let get_documentation d = let t, (doc,flags) = get_info d in if not (List.mem UsedInternally flags) then begin let params = ref [] and used = ref [] and pfs = ref [] in List.iter (function | HasParam s -> params := s :: !params | Platform f -> pfs := f :: !pfs | Platforms fl -> pfs := fl @ !pfs | UsedOn u -> used := u :: !used | UsedOnEither ul -> used := ul @ !used | UsedInternally -> assert false ) flags; let params = (match List.rev !params with | [] -> "" | l -> "(" ^ String.concat "," l ^ ")" ) in let pfs = (match List.rev !pfs with | [] -> "" | [p] -> " (" ^ platform_name p ^ " only)" | pl -> " (for " ^ String.concat "," (List.map platform_name pl) ^ ")" ) in let str = "@" ^ t in Some (str,params ^ doc ^ pfs) end else None let get_documentation_list () = let m = ref 0 in let rec loop i = let d = Obj.magic i in if d <> Last then begin match get_documentation d with | None -> loop (i + 1) | Some (str,desc) -> if String.length str > !m then m := String.length str; (str,desc) :: loop (i + 1) end else [] in let all = List.sort (fun (s1,_) (s2,_) -> String.compare s1 s2) (loop 0) in all,!mhaxe_3.4.4.orig/src/display/display.ml0000664000175000017500000006776613166552354017675 0ustar andyandy00000000000000open Ast open Common open Common.DisplayMode open Type open Typecore open Globals type display_field_kind = | FKVar of t | FKMethod of t | FKType of t | FKModule | FKPackage | FKMetadata | FKTimer of string let display_field_kind_index = function | FKVar _ -> 0 | FKMethod _ -> 1 | FKType _ -> 2 | FKModule -> 3 | FKPackage -> 4 | FKMetadata -> 5 | FKTimer _ -> 6 exception Diagnostics of string exception Statistics of string exception ModuleSymbols of string exception Metadata of string exception DisplaySignatures of (tsignature * documentation) list * int exception DisplayType of t * pos * string option exception DisplayPosition of pos list exception DisplayFields of (string * display_field_kind * documentation) list exception DisplayToplevel of IdentifierType.t list exception DisplayPackage of string list let is_display_file file = file <> "?" && Path.unique_full_path file = (!Parser.resume_display).pfile let encloses_position p_target p = p.pmin <= p_target.pmin && p.pmax >= p_target.pmax let is_display_position p = encloses_position !Parser.resume_display p module ExprPreprocessing = struct let find_enclosing com e = let display_pos = ref (!Parser.resume_display) in let mk_null p = (EDisplay(((EConst(Ident "null")),p),false),p) in let encloses_display_pos p = if encloses_position !display_pos p then begin let p = !display_pos in display_pos := { pfile = ""; pmin = -2; pmax = -2 }; Some p end else None in let rec loop e = match fst e with | EBlock el -> let p = pos e in (* We want to find the innermost block which contains the display position. *) let el = List.map loop el in let el = match encloses_display_pos p with | None -> el | Some p2 -> let b,el = List.fold_left (fun (b,el) e -> let p = pos e in if b || p.pmax <= p2.pmin then begin (b,e :: el) end else begin let e_d = (EDisplay(mk_null p,false)),p in (true,e :: e_d :: el) end ) (false,[]) el in let el = if b then el else begin mk_null p :: el end in List.rev el in (EBlock el),(pos e) | _ -> Ast.map_expr loop e in loop e let find_before_pos com e = let display_pos = ref (!Parser.resume_display) in let is_annotated p = if p.pmin <= !display_pos.pmin && p.pmax >= !display_pos.pmax then begin display_pos := { pfile = ""; pmin = -2; pmax = -2 }; true end else false in let loop e = if is_annotated (pos e) then (EDisplay(e,false),(pos e)) else e in let rec map e = loop (Ast.map_expr map e) in map e let find_display_call e = let found = ref false in let loop e = if !found then e else match fst e with | ECall _ | ENew _ when is_display_position (pos e) -> found := true; (EDisplay(e,true),(pos e)) | _ -> e in let rec map e = match fst e with | EDisplay(_,true) -> found := true; e | EDisplay(e1,false) -> map e1 | _ -> loop (Ast.map_expr map e) in map e let process_expr com e = match com.display.dms_kind with | DMToplevel -> find_enclosing com e | DMPosition | DMUsage _ | DMType -> find_before_pos com e | DMSignature -> find_display_call e | _ -> e end module DisplayEmitter = struct let display_module_type dm mt p = match dm.dms_kind with | DMPosition -> raise (DisplayPosition [(t_infos mt).mt_pos]); | DMUsage _ -> let ti = t_infos mt in ti.mt_meta <- (Meta.Usage,[],ti.mt_pos) :: ti.mt_meta | DMType -> raise (DisplayType (type_of_module_type mt,p,None)) | _ -> () let rec display_type dm t p = match dm.dms_kind with | DMType -> raise (DisplayType (t,p,None)) | _ -> try display_module_type dm (module_type_of_type t) p with Exit -> match follow t,follow !t_dynamic_def with | _,TDynamic _ -> () (* sanity check in case it's still t_dynamic *) | TDynamic _,_ -> display_type dm !t_dynamic_def p | _ -> () let check_display_type ctx t p = let add_type_hint () = Hashtbl.replace ctx.com.shared.shared_display_information.type_hints p t; in let maybe_display_type () = if ctx.is_display_file && is_display_position p then display_type ctx.com.display t p in match ctx.com.display.dms_kind with | DMStatistics -> add_type_hint() | DMUsage _ -> add_type_hint(); maybe_display_type() | _ -> maybe_display_type() let display_variable dm v p = match dm.dms_kind with | DMPosition -> raise (DisplayPosition [v.v_pos]) | DMUsage _ -> v.v_meta <- (Meta.Usage,[],v.v_pos) :: v.v_meta; | DMType -> raise (DisplayType (v.v_type,p,None)) | _ -> () let display_field dm cf p = match dm.dms_kind with | DMPosition -> raise (DisplayPosition [cf.cf_pos]); | DMUsage _ -> cf.cf_meta <- (Meta.Usage,[],cf.cf_pos) :: cf.cf_meta; | DMType -> raise (DisplayType (cf.cf_type,p,cf.cf_doc)) | _ -> () let maybe_display_field ctx p cf = if is_display_position p then display_field ctx.com.display cf p let display_enum_field dm ef p = match dm.dms_kind with | DMPosition -> raise (DisplayPosition [p]); | DMUsage _ -> ef.ef_meta <- (Meta.Usage,[],p) :: ef.ef_meta; | DMType -> raise (DisplayType (ef.ef_type,p,ef.ef_doc)) | _ -> () let display_meta dm meta = match dm.dms_kind with | DMType -> begin match meta with | Meta.Custom _ | Meta.Dollar _ -> () | _ -> match Meta.get_documentation meta with | None -> () | Some (_,s) -> (* TODO: hack until we support proper output for hover display mode *) raise (Metadata ("" ^ s ^ "")); end | DMField -> let all,_ = Meta.get_documentation_list() in let all = List.map (fun (s,doc) -> (s,FKMetadata,Some doc)) all in raise (DisplayFields all) | _ -> () let check_display_metadata ctx meta = List.iter (fun (meta,args,p) -> if is_display_position p then display_meta ctx.com.display meta; List.iter (fun e -> if is_display_position (pos e) then begin let e = ExprPreprocessing.process_expr ctx.com e in delay ctx PTypeField (fun _ -> ignore(type_expr ctx e Value)); end ) args ) meta end module DocumentSymbols = struct open DisplayTypes.SymbolKind let collect_module_symbols (pack,decls) = let l = DynArray.create() in let add name kind location parent = let si = DisplayTypes.SymbolInformation.make name kind location (if parent = "" then None else Some parent) in DynArray.add l si; in let rec expr parent (e,p) = let add name kind location = add name kind location parent in begin match e with | EVars vl -> List.iter (fun ((s,p),_,eo) -> add s Variable p; expr_opt parent eo ) vl | ETry(e1,catches) -> expr parent e1; List.iter (fun ((s,p),_,e,_) -> add s Variable p; expr parent e ) catches; | EFunction(Some s,f) -> add s Function p; func parent f | EIn((EConst(Ident s),p),e2) -> add s Variable p; expr parent e2; | _ -> iter_expr (expr parent) (e,p) end and expr_opt parent eo = match eo with | None -> () | Some e -> expr parent e and func parent f = List.iter (fun ((s,p),_,_,_,eo) -> add s Variable p parent; expr_opt parent eo ) f.f_args; expr_opt parent f.f_expr in let field parent cff = let field_parent = parent ^ "." ^ (fst cff.cff_name) in match cff.cff_kind with | FVar(_,eo) -> add (fst cff.cff_name) Field cff.cff_pos parent; expr_opt field_parent eo | FFun f -> add (fst cff.cff_name) (if fst cff.cff_name = "new" then Constructor else Method) cff.cff_pos parent; func field_parent f | FProp(_,_,_,eo) -> add (fst cff.cff_name) Property cff.cff_pos parent; expr_opt field_parent eo in List.iter (fun (td,p) -> match td with | EImport _ | EUsing _ -> () (* TODO: Can we do anything with these? *) | EClass d -> add (fst d.d_name) (if List.mem HInterface d.d_flags then Interface else Class) p ""; List.iter (field (fst d.d_name)) d.d_data | EEnum d -> add (fst d.d_name) Enum p ""; List.iter (fun ef -> add (fst ef.ec_name) Method ef.ec_pos (fst d.d_name) ) d.d_data | ETypedef d -> add (fst d.d_name) Typedef p ""; (match d.d_data with | CTAnonymous fields,_ -> List.iter (field (fst d.d_name)) fields | _ -> ()) | EAbstract d -> add (fst d.d_name) Abstract p ""; List.iter (field (fst d.d_name)) d.d_data ) decls; l 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_on_expr com e = 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 expr e let run_on_field com cf = match cf.cf_expr with None -> () | Some e -> run_on_expr com e let run com = List.iter (fun t -> match t with | TClassDecl c -> curclass := c; (match c.cl_constructor with None -> () | Some cf -> run_on_field com cf); (match c.cl_init with None -> () | Some e -> run_on_expr com e); List.iter (run_on_field com) c.cl_ordered_statics; List.iter (run_on_field com) c.cl_ordered_fields; | _ -> () ) com.types end module Diagnostics = struct module DiagnosticsKind = struct type t = | DKUnusedImport | DKUnresolvedIdentifier | DKCompilerError | DKRemovableCode let to_int = function | DKUnusedImport -> 0 | DKUnresolvedIdentifier -> 1 | DKCompilerError -> 2 | DKRemovableCode -> 3 end open DiagnosticsKind open DisplayTypes let add_removable_code com s p prange = let di = com.shared.shared_display_information in di.removable_code <- (s,p,prange) :: di.removable_code let find_unused_variables com e = let vars = Hashtbl.create 0 in let pmin_map = Hashtbl.create 0 in let rec loop e = match e.eexpr with | TVar(v,eo) when Meta.has Meta.UserVariable v.v_meta -> Hashtbl.add pmin_map e.epos.pmin v; let p = match eo with | None -> e.epos | Some e1 -> loop e1; { e.epos with pmax = e1.epos.pmin } in Hashtbl.replace vars v.v_id (v,p); | TLocal v when Meta.has Meta.UserVariable v.v_meta -> Hashtbl.remove vars v.v_id; | _ -> Type.iter loop e in loop e; Hashtbl.iter (fun _ (v,p) -> let p = match (Hashtbl.find_all pmin_map p.pmin) with [_] -> p | _ -> null_pos in add_removable_code com "Unused variable" v.v_pos p ) vars let check_other_things com e = let had_effect = ref false in let no_effect p = add_diagnostics_message com "This code has no effect" p DiagnosticsSeverity.Warning; in let pointless_compound s p = add_diagnostics_message com (Printf.sprintf "This %s has no effect, but some of its sub-expressions do" s) p DiagnosticsSeverity.Warning; in let rec compound s el p = let old = !had_effect in had_effect := false; List.iter (loop true) el; if not !had_effect then no_effect p else pointless_compound s p; had_effect := old; and loop in_value e = match e.eexpr with | TBlock el -> let rec loop2 el = match el with | [] -> () | [e] -> loop in_value e | e :: el -> loop false e; loop2 el in loop2 el | TMeta((Meta.Extern,_,_),_) -> (* This is so something like `[inlineFunc()]` is not reported. *) had_effect := true; | TLocal v when not (Meta.has Meta.UserVariable v.v_meta) -> () | TConst _ | TLocal _ | TTypeExpr _ | TFunction _ when not in_value -> no_effect e.epos; | TConst _ | TLocal _ | TTypeExpr _ | TEnumParameter _ | TVar _ -> () | TFunction tf -> loop false tf.tf_expr | TNew _ | TCall _ | TBinop ((Ast.OpAssignOp _ | Ast.OpAssign),_,_) | TUnop ((Ast.Increment | Ast.Decrement),_,_) | TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) | TIf _ | TTry _ | TSwitch _ | TWhile _ | TFor _ -> had_effect := true; Type.iter (loop true) e | TParenthesis e1 | TMeta(_,e1) -> loop in_value e1 | TArray _ | TCast (_,None) | TBinop _ | TUnop _ | TField _ | TArrayDecl _ | TObjectDecl _ when in_value -> Type.iter (loop true) e; | TArray(e1,e2) -> compound "array access" [e1;e2] e.epos | TCast(e1,None) -> compound "cast" [e1] e.epos | TBinop(op,e1,e2) -> compound (Printf.sprintf "'%s' operator" (s_binop op)) [e1;e2] e.epos | TUnop(op,_,e1) -> compound (Printf.sprintf "'%s' operator" (s_unop op)) [e1] e.epos | TField(e1,_) -> compound "field access" [e1] e.epos | TArrayDecl el -> compound "array declaration" el e.epos | TObjectDecl fl -> compound "object declaration" (List.map snd fl) e.epos in loop true e let prepare_field com cf = match cf.cf_expr with | None -> () | Some e -> find_unused_variables com e; check_other_things com e; DeprecationCheck.run_on_expr com e let prepare com global = List.iter (function | TClassDecl c when global || is_display_file c.cl_pos.pfile -> List.iter (prepare_field com) c.cl_ordered_fields; List.iter (prepare_field com) c.cl_ordered_statics; (match c.cl_constructor with None -> () | Some cf -> prepare_field com cf); | _ -> () ) com.types let is_diagnostics_run ctx = match ctx.com.display.dms_kind with | DMDiagnostics true -> true | DMDiagnostics false -> ctx.is_display_file | _ -> false let secure_generated_code ctx e = if is_diagnostics_run ctx then mk (TMeta((Meta.Extern,[],e.epos),e)) e.etype e.epos else e end module ImportHandling = struct type import_display_kind = | IDKPackage of string list | IDKModule of string list * string | IDKSubType of string list * string * string | IDKModuleField of string list * string * string | IDKSubTypeField of string list * string * string * string | IDK type import_display = import_display_kind * pos let convert_import_to_something_usable pt path = let rec loop pack m t = function | (s,p) :: l -> let is_lower = is_lower_ident s in let is_display_pos = encloses_position pt p in begin match is_lower,m,t with | _,None,Some _ -> assert false (* impossible, I think *) | true,Some m,None -> if is_display_pos then (IDKModuleField(List.rev pack,m,s),p) else (IDK,p) (* assume that we're done *) | _,Some m,Some t -> if is_display_pos then (IDKSubTypeField(List.rev pack,m,t,s),p) else (IDK,p) | true,None,None -> if is_display_pos then (IDKPackage (List.rev (s :: pack)),p) else loop (s :: pack) m t l | false,Some sm,None -> if is_display_pos then (IDKSubType (List.rev pack,sm,s),p) else loop pack m (Some s) l | false,None,None -> if is_display_pos then (IDKModule (List.rev pack,s),p) else loop pack (Some s) None l end | [] -> (IDK,null_pos) in loop [] None None path let add_import_position com p path = com.shared.shared_display_information.import_positions <- PMap.add p (ref false,path) com.shared.shared_display_information.import_positions let mark_import_position com p = try let r = fst (PMap.find p com.shared.shared_display_information.import_positions) in r := true with Not_found -> () let maybe_mark_import_position ctx p = if Diagnostics.is_diagnostics_run ctx then mark_import_position ctx.com p end module Statistics = struct open ImportHandling type relation = | Implemented | Extended | Overridden | Referenced type symbol = | SKClass of tclass | SKInterface of tclass | SKEnum of tenum | SKField of tclass_field | SKEnumField of tenum_field | SKVariable of tvar let is_usage_symbol symbol = let meta = match symbol with | SKClass c | SKInterface c -> c.cl_meta | SKEnum en -> en.e_meta | SKField cf -> cf.cf_meta | SKEnumField ef -> ef.ef_meta | SKVariable v -> v.v_meta in Meta.has Meta.Usage meta let collect_statistics ctx = let relations = Hashtbl.create 0 in let symbols = Hashtbl.create 0 in let add_relation pos r = if is_display_file pos.pfile then try Hashtbl.replace relations pos (r :: Hashtbl.find relations pos) with Not_found -> Hashtbl.add relations pos [r] in let declare kind p = if is_display_file p.pfile then begin if not (Hashtbl.mem relations p) then Hashtbl.add relations p []; Hashtbl.replace symbols p kind; end in let collect_overrides c = List.iter (fun cf -> let rec loop c = match c.cl_super with | Some (c,_) -> begin try let cf' = PMap.find cf.cf_name c.cl_fields in add_relation cf'.cf_name_pos (Overridden,cf.cf_pos) with Not_found -> loop c end | _ -> () in loop c ) c.cl_overrides in let rec find_real_constructor c = match c.cl_constructor,c.cl_super with (* The pos comparison might be a bit weak, not sure... *) | Some cf,_ when not (Meta.has Meta.CompilerGenerated cf.cf_meta) && c.cl_pos <> cf.cf_pos -> cf | _,Some(c,_) -> find_real_constructor c | _,None -> raise Not_found in let var_decl v = declare (SKVariable v) v.v_pos in let patch_string_pos p s = { p with pmin = p.pmax - String.length s } in let patch_string_pos_front p s = { p with pmax = p.pmin + String.length s } in let field_reference cf p = add_relation cf.cf_name_pos (Referenced,patch_string_pos p cf.cf_name) in let collect_references c e = let rec loop e = match e.eexpr with | TField(e1,fa) -> (* Check if the sub-expression is actually shorter than the whole one. This should detect cases where it was automatically generated. *) if e1.epos.pmin = e.epos.pmin && e1.epos.pmax <> e.epos.pmax then loop e1; begin match fa with | FStatic(_,cf) | FInstance(_,_,cf) | FClosure(_,cf) -> field_reference cf e.epos | FAnon cf -> declare (SKField cf) cf.cf_name_pos; field_reference cf e.epos | FEnum(_,ef) -> add_relation ef.ef_name_pos (Referenced,patch_string_pos e.epos ef.ef_name) | FDynamic _ -> () end | TTypeExpr mt -> let tinfos = t_infos mt in add_relation tinfos.mt_name_pos (Referenced,patch_string_pos e.epos (snd tinfos.mt_path)) | TNew(c,_,el) -> List.iter loop el; (try add_relation (find_real_constructor c).cf_name_pos (Referenced,e.epos) with Not_found -> ()); | TCall({eexpr = TConst TSuper},el) -> List.iter loop el; begin match c.cl_super with | Some(c,_) -> (try add_relation (find_real_constructor c).cf_name_pos (Referenced,e.epos) with Not_found -> ()) | None -> () end | TVar(v,eo) -> Option.may loop eo; var_decl v; | TFor(v,e1,e2) -> var_decl v; loop e1; loop e2; | TFunction tf -> List.iter (fun (v,_) -> var_decl v) tf.tf_args; loop tf.tf_expr; | TLocal v when e.epos.pmax - e.epos.pmin = String.length v.v_name -> add_relation v.v_pos (Referenced,e.epos) | _ -> Type.iter loop e in loop e in List.iter (function | TClassDecl c -> declare (if c.cl_interface then (SKInterface c) else (SKClass c)) c.cl_name_pos; List.iter (fun (c',_) -> add_relation c'.cl_name_pos ((if c.cl_interface then Extended else Implemented),c.cl_name_pos)) c.cl_implements; begin match c.cl_super with | None -> () | Some (c',_) -> add_relation c'.cl_name_pos (Extended,c.cl_name_pos); end; collect_overrides c; let field cf = if cf.cf_pos.pmin > c.cl_name_pos.pmin then declare (SKField cf) cf.cf_name_pos; let _ = follow cf.cf_type in match cf.cf_expr with None -> () | Some e -> collect_references c e in Option.may field c.cl_constructor; List.iter field c.cl_ordered_fields; List.iter field c.cl_ordered_statics; | TEnumDecl en -> declare (SKEnum en) en.e_name_pos; PMap.iter (fun _ ef -> declare (SKEnumField ef) ef.ef_name_pos) en.e_constrs | _ -> () ) ctx.com.types; let explore_type_hint p t = match follow t with | TInst(c,_) -> add_relation c.cl_name_pos (Referenced,(patch_string_pos_front p (snd c.cl_path))) | _ -> () in Hashtbl.iter (fun p t -> explore_type_hint p t ) ctx.com.shared.shared_display_information.type_hints; let l = List.fold_left (fun acc (_,cfi,_,cfo) -> match cfo with | Some cf -> if List.mem_assoc cf.cf_name_pos acc then acc else (cf.cf_name_pos,cfi.cf_name_pos) :: acc | None -> acc ) [] ctx.com.display_information.interface_field_implementations in List.iter (fun (p,p') -> add_relation p' (Implemented,p)) l; let deal_with_imports paths = let check_subtype m s p = try let mt = List.find (fun mt -> snd (t_infos mt).mt_path = s) m.m_types in add_relation (t_infos mt).mt_name_pos (Referenced,p); Some mt with Not_found -> None in let check_module path p = let m = ctx.g.do_load_module ctx path p in m in let check_field c s p = let cf = PMap.find s c.cl_statics in add_relation cf.cf_name_pos (Referenced,p) in let check_subtype_field m ssub psub sfield pfield = match check_subtype m ssub psub with | Some (TClassDecl c) -> check_field c sfield pfield | _ -> () in PMap.iter (fun p (_,path) -> match ImportHandling.convert_import_to_something_usable { p with pmin = p.pmax - 1; pmax = p.pmax - 1 } path,List.rev path with | (IDKSubType(sl,s1,s2),_),(_,psubtype) :: (_,pmodule) :: _ -> let m = check_module (sl,s1) pmodule in (*ignore(check_subtype m s1 pmodule);*) ignore(check_subtype m s2 psubtype) | (IDKModuleField(sl,s1,s2),_),(_,pfield) :: (_,pmodule) :: _ -> let m = check_module (sl,s1) pmodule in check_subtype_field m s1 pmodule s2 pfield | (IDKSubTypeField(sl,s1,s2,s3),_),(_,pfield) :: (_,psubtype) :: (_,pmodule) :: _ -> let m = check_module (sl,s1) pmodule in check_subtype_field m s2 psubtype s3 pfield | (IDKModule(sl,s),_),(_,pmodule) :: _ -> let m = check_module (sl,s) pmodule in ignore(check_subtype m s pmodule); | _ -> () ) paths in if false then deal_with_imports ctx.com.shared.shared_display_information.import_positions; symbols,relations end let explore_class_paths ctx class_paths recusive f_pack f_module f_type = let rec loop dir pack = try let entries = Sys.readdir dir in Array.iter (fun file -> match file with | "." | ".." -> () | _ when Sys.is_directory (dir ^ file) && file.[0] >= 'a' && file.[0] <= 'z' -> f_pack file; if recusive then loop (dir ^ file ^ "/") (file :: pack) | _ -> let l = String.length file in if l > 3 && String.sub file (l - 3) 3 = ".hx" then begin try let name = String.sub file 0 (l - 3) in let path = (List.rev pack,name) in let md = ctx.g.do_load_module ctx path null_pos in f_module md; List.iter (fun mt -> f_type mt) md.m_types with _ -> () end ) entries; with Sys_error _ -> () in List.iter (fun dir -> loop dir []) class_paths module ToplevelCollector = struct open IdentifierType let run ctx only_types = let acc = DynArray.create () in if not only_types then begin (* locals *) PMap.iter (fun _ v -> if not (is_gen_local v) then DynArray.add acc (ITLocal v) ) ctx.locals; (* member vars *) if ctx.curfun <> FunStatic then begin let rec loop c = List.iter (fun cf -> DynArray.add acc (ITMember(ctx.curclass,cf)) ) c.cl_ordered_fields; match c.cl_super with | None -> () | Some (csup,tl) -> loop csup; (* TODO: type parameters *) in loop ctx.curclass; (* TODO: local using? *) end; (* statics *) List.iter (fun cf -> DynArray.add acc (ITStatic(ctx.curclass,cf)) ) ctx.curclass.cl_ordered_statics; (* enum constructors *) let rec enum_ctors t = match t with | TAbstractDecl ({a_impl = Some c} as a) when Meta.has Meta.Enum a.a_meta -> List.iter (fun cf -> if (Meta.has Meta.Enum cf.cf_meta) then DynArray.add acc (ITEnumAbstract(a,cf)); ) c.cl_ordered_statics | TClassDecl _ | TAbstractDecl _ -> () | TTypeDecl t -> begin match follow t.t_type with | TEnum (e,_) -> enum_ctors (TEnumDecl e) | _ -> () end | TEnumDecl e -> PMap.iter (fun _ ef -> DynArray.add acc (ITEnum(e,ef)) ) e.e_constrs; in List.iter enum_ctors ctx.m.curmod.m_types; List.iter enum_ctors (List.map fst ctx.m.module_types); (* imported globals *) PMap.iter (fun _ (mt,s,_) -> try let t = match resolve_typedef mt with | TClassDecl c -> (PMap.find s c.cl_statics).cf_type | TEnumDecl en -> (PMap.find s en.e_constrs).ef_type | TAbstractDecl {a_impl = Some c} -> (PMap.find s c.cl_statics).cf_type | _ -> raise Not_found in DynArray.add acc (ITGlobal(mt,s,t)) with Not_found -> () ) ctx.m.module_globals; (* literals *) DynArray.add acc (ITLiteral "null"); DynArray.add acc (ITLiteral "true"); DynArray.add acc (ITLiteral "false"); end; let module_types = ref [] in let add_type mt = match mt with | TClassDecl {cl_kind = KAbstractImpl _} -> () | _ -> let path = (t_infos mt).mt_path in if not (List.exists (fun mt2 -> (t_infos mt2).mt_path = path) !module_types) then begin (match mt with | TClassDecl c | TAbstractDecl { a_impl = Some c } when Meta.has Meta.CoreApi c.cl_meta -> !merge_core_doc_ref ctx c | _ -> ()); module_types := mt :: !module_types end in (* module types *) List.iter add_type ctx.m.curmod.m_types; (* module imports *) List.iter add_type (List.map fst ctx.m.module_types); (* module using *) List.iter (fun (c,_) -> add_type (TClassDecl c) ) ctx.m.module_using; (* TODO: wildcard packages. How? *) (* packages and toplevel types *) let class_paths = ctx.com.class_path in let class_paths = List.filter (fun s -> s <> "") class_paths in let packages = ref [] in let add_package pack = try begin match PMap.find pack ctx.com.package_rules with | Forbidden -> () | _ -> raise Not_found end with Not_found -> if not (List.mem pack !packages) then packages := pack :: !packages in explore_class_paths ctx class_paths false add_package (fun _ -> ()) add_type; List.iter (fun pack -> DynArray.add acc (ITPackage pack) ) !packages; List.iter (fun mt -> DynArray.add acc (ITType mt) ) !module_types; DynArray.to_list acc let handle_unresolved_identifier ctx i p only_types = let l = run ctx only_types in let cl = List.map (fun it -> let s = IdentifierType.get_name it in (s,it),StringError.levenshtein i s ) l in let cl = List.sort (fun (_,c1) (_,c2) -> compare c1 c2) cl in let cl = StringError.filter_similar (fun (s,_) r -> r > 0 && r <= (min (String.length s) (String.length i)) / 3) cl in ctx.com.display_information.unresolved_identifiers <- (i,p,cl) :: ctx.com.display_information.unresolved_identifiers endhaxe_3.4.4.orig/src/display/displayOutput.ml0000664000175000017500000006375213166552354021105 0ustar andyandy00000000000000open Globals open Common open Common.DisplayMode open Type open Display open Typecore (* Old XML stuff *) let htmlescape s = let s = String.concat "&" (ExtString.String.nsplit s "&") in let s = String.concat "<" (ExtString.String.nsplit s "<") in let s = String.concat ">" (ExtString.String.nsplit s ">") in let s = String.concat """ (ExtString.String.nsplit s "\"") in s let get_timer_fields start_time = let tot = ref 0. in Hashtbl.iter (fun _ t -> tot := !tot +. t.total) Common.htimers; let fields = [("@TOTAL", Printf.sprintf "%.3fs" (get_time() -. start_time))] in if !tot > 0. then Hashtbl.fold (fun _ t acc -> ((String.concat "." t.id),(Printf.sprintf "%.3fs (%.0f%%)" t.total (t.total *. 100. /. !tot))) :: acc ) Common.htimers fields else fields let print_keywords () = let b = Buffer.create 0 in Buffer.add_string b "\n"; Hashtbl.iter (fun k _ -> Buffer.add_string b (Printf.sprintf "\n" k) ) Lexer.keywords; Buffer.add_string b "\n"; Buffer.contents b let print_fields fields = let b = Buffer.create 0 in Buffer.add_string b "\n"; List.iter (fun (n,k,d) -> let s_kind, t = match k with | FKVar t -> "var", s_type (print_context()) t | FKMethod t -> "method", s_type (print_context()) t | FKType t -> "type", s_type (print_context()) t | FKPackage -> "package", "" | FKModule -> "type", "" | FKMetadata -> "metadata", "" | FKTimer s -> "timer", s in Buffer.add_string b (Printf.sprintf "%s%s\n" n s_kind (htmlescape t) (htmlescape d)) ) (List.sort (fun (a,ak,_) (b,bk,_) -> compare (display_field_kind_index ak,a) (display_field_kind_index bk,b)) fields); Buffer.add_string b "\n"; Buffer.contents b let maybe_print_doc d = Option.map_default (fun s -> Printf.sprintf " d=\"%s\"" (htmlescape s)) "" d let print_toplevel il = let b = Buffer.create 0 in Buffer.add_string b "\n"; let s_type t = htmlescape (s_type (print_context()) t) in let s_doc d = maybe_print_doc d in List.iter (fun id -> match id with | IdentifierType.ITLocal v -> Buffer.add_string b (Printf.sprintf "%s\n" (s_type v.v_type) v.v_name); | IdentifierType.ITMember(c,cf) -> Buffer.add_string b (Printf.sprintf "%s\n" (s_type cf.cf_type) (s_doc cf.cf_doc) cf.cf_name); | IdentifierType.ITStatic(c,cf) -> Buffer.add_string b (Printf.sprintf "%s\n" (s_type cf.cf_type) (s_doc cf.cf_doc) cf.cf_name); | IdentifierType.ITEnum(en,ef) -> Buffer.add_string b (Printf.sprintf "%s\n" (s_type ef.ef_type) (s_doc ef.ef_doc) ef.ef_name); | IdentifierType.ITEnumAbstract(a,cf) -> Buffer.add_string b (Printf.sprintf "%s\n" (s_type cf.cf_type) (s_doc cf.cf_doc) cf.cf_name); | IdentifierType.ITGlobal(mt,s,t) -> Buffer.add_string b (Printf.sprintf "%s\n" (s_type_path (t_infos mt).mt_path) (s_type t) s); | IdentifierType.ITType(mt) -> let infos = t_infos mt in Buffer.add_string b (Printf.sprintf "%s\n" (s_type_path infos.mt_path) (s_doc infos.mt_doc) (snd infos.mt_path)); | IdentifierType.ITPackage s -> Buffer.add_string b (Printf.sprintf "%s\n" s) | IdentifierType.ITLiteral s -> Buffer.add_string b (Printf.sprintf "%s\n" s) | IdentifierType.ITTimer s -> Buffer.add_string b (Printf.sprintf "%s\n" s) ) il; Buffer.add_string b ""; Buffer.contents b let print_type t p doc = let b = Buffer.create 0 in if p = null_pos then Buffer.add_string b "\n"; Buffer.add_string b (htmlescape (s_type (print_context()) t)); Buffer.add_string b "\n\n"; Buffer.contents b let print_signatures tl = let b = Buffer.create 0 in List.iter (fun ((args,ret),doc) -> Buffer.add_string b " Buffer.add_string b (Printf.sprintf " d=\"%s\"" (htmlescape s))) doc; Buffer.add_string b ">\n"; Buffer.add_string b (htmlescape (s_type (print_context()) (TFun(args,ret)))); Buffer.add_string b "\n\n"; ) tl; Buffer.contents b let print_positions pl = let b = Buffer.create 0 in let error_printer file line = Printf.sprintf "%s:%d:" (Path.get_real_path file) line in Buffer.add_string b "\n"; List.iter (fun p -> let epos = Lexer.get_error_pos error_printer p in Buffer.add_string b ""; Buffer.add_string b epos; Buffer.add_string b "\n"; ) pl; Buffer.add_string b ""; Buffer.contents b let display_memory com = let verbose = com.verbose in let print = print_endline in let fmt_size sz = if sz < 1024 then string_of_int sz ^ " B" else if sz < 1024*1024 then string_of_int (sz asr 10) ^ " KB" else Printf.sprintf "%.1f MB" ((float_of_int sz) /. (1024.*.1024.)) in let size v = fmt_size (mem_size v) in Gc.full_major(); Gc.compact(); let mem = Gc.stat() in print ("Total Allocated Memory " ^ fmt_size (mem.Gc.heap_words * (Sys.word_size asr 8))); print ("Free Memory " ^ fmt_size (mem.Gc.free_words * (Sys.word_size asr 8))); (match CompilationServer.get() with | None -> print "No cache found"; | Some {CompilationServer.cache = c} -> print ("Total cache size " ^ size c); print (" haxelib " ^ size c.CompilationServer.c_haxelib); print (" parsed ast " ^ size c.CompilationServer.c_files ^ " (" ^ string_of_int (Hashtbl.length c.CompilationServer.c_files) ^ " files stored)"); print (" typed modules " ^ size c.CompilationServer.c_modules ^ " (" ^ string_of_int (Hashtbl.length c.CompilationServer.c_modules) ^ " modules stored)"); let rec scan_module_deps m h = if Hashtbl.mem h m.m_id then () else begin Hashtbl.add h m.m_id m; PMap.iter (fun _ m -> scan_module_deps m h) m.m_extra.m_deps end in let all_modules = Hashtbl.fold (fun _ m acc -> PMap.add m.m_id m acc) c.CompilationServer.c_modules PMap.empty in let modules = Hashtbl.fold (fun (path,key) m acc -> let mdeps = Hashtbl.create 0 in scan_module_deps m mdeps; let deps = ref [] in let out = ref all_modules in Hashtbl.iter (fun _ md -> out := PMap.remove md.m_id !out; if m == md then () else begin deps := Obj.repr md :: !deps; List.iter (fun t -> match t with | TClassDecl c -> deps := Obj.repr c :: !deps; List.iter (fun f -> deps := Obj.repr f :: !deps) c.cl_ordered_statics; List.iter (fun f -> deps := Obj.repr f :: !deps) c.cl_ordered_fields; | TEnumDecl e -> deps := Obj.repr e :: !deps; List.iter (fun n -> deps := Obj.repr (PMap.find n e.e_constrs) :: !deps) e.e_names; | TTypeDecl t -> deps := Obj.repr t :: !deps; | TAbstractDecl a -> deps := Obj.repr a :: !deps; ) md.m_types; end ) mdeps; let chk = Obj.repr Common.memory_marker :: PMap.fold (fun m acc -> Obj.repr m :: acc) !out [] in let inf = Objsize.objsize m !deps chk in (m,Objsize.size_with_headers inf, (inf.Objsize.reached,!deps,!out)) :: acc ) c.CompilationServer.c_modules [] in let cur_key = ref "" and tcount = ref 0 and mcount = ref 0 in List.iter (fun (m,size,(reached,deps,out)) -> let key = m.m_extra.m_sign in if key <> !cur_key then begin print (Printf.sprintf (" --- CONFIG %s ----------------------------") (Digest.to_hex key)); cur_key := key; end; let sign md = if md.m_extra.m_sign = key then "" else "(" ^ (try Digest.to_hex md.m_extra.m_sign with _ -> "???" ^ md.m_extra.m_sign) ^ ")" in print (Printf.sprintf " %s : %s" (s_type_path m.m_path) (fmt_size size)); (if reached then try incr mcount; let lcount = ref 0 in let leak l = incr lcount; incr tcount; print (Printf.sprintf " LEAK %s" l); if !lcount >= 3 && !tcount >= 100 && not verbose then begin print (Printf.sprintf " ..."); raise Exit; end; in if (Objsize.objsize m deps [Obj.repr Common.memory_marker]).Objsize.reached then leak "common"; PMap.iter (fun _ md -> if (Objsize.objsize m deps [Obj.repr md]).Objsize.reached then leak (s_type_path md.m_path ^ sign md); ) out; with Exit -> ()); if verbose then begin print (Printf.sprintf " %d total deps" (List.length deps)); PMap.iter (fun _ md -> print (Printf.sprintf " dep %s%s" (s_type_path md.m_path) (sign md)); ) m.m_extra.m_deps; end; flush stdout ) (List.sort (fun (m1,s1,_) (m2,s2,_) -> let k1 = m1.m_extra.m_sign and k2 = m2.m_extra.m_sign in if k1 = k2 then s1 - s2 else if k1 > k2 then 1 else -1 ) modules); if !mcount > 0 then print ("*** " ^ string_of_int !mcount ^ " modules have leaks !"); print "Cache dump complete") module TypePathHandler = struct let unique l = let rec _unique = function | [] -> [] | x1 :: x2 :: l when x1 = x2 -> _unique (x2 :: l) | x :: l -> x :: _unique l in _unique (List.sort compare l) let rec read_type_path com p = let classes = ref [] in let packages = ref [] in let p = (match p with | x :: l -> (try match PMap.find x com.package_rules with | Directory d -> d :: l | Remap s -> s :: l | _ -> p with Not_found -> p) | _ -> p ) in List.iter (fun path -> let dir = path ^ String.concat "/" p in let r = (try Sys.readdir dir with _ -> [||]) in Array.iter (fun f -> if (try (Unix.stat (dir ^ "/" ^ f)).Unix.st_kind = Unix.S_DIR with _ -> false) then begin if f.[0] >= 'a' && f.[0] <= 'z' then begin if p = ["."] then match read_type_path com [f] with | [] , [] -> () | _ -> try match PMap.find f com.package_rules with | Forbidden -> () | Remap f -> packages := f :: !packages | Directory _ -> raise Not_found with Not_found -> packages := f :: !packages else packages := f :: !packages end; end else if file_extension f = "hx" then begin let c = Filename.chop_extension f in if String.length c < 2 || String.sub c (String.length c - 2) 2 <> "__" then classes := c :: !classes; end; ) r; ) com.class_path; List.iter (fun (_,_,extract) -> Hashtbl.iter (fun (path,name) _ -> if path = p then classes := name :: !classes else let rec loop p1 p2 = match p1, p2 with | [], _ -> () | x :: _, [] -> packages := x :: !packages | a :: p1, b :: p2 -> if a = b then loop p1 p2 in loop path p ) (extract()); ) com.swf_libs; List.iter (fun (path,std,close,all_files,lookup) -> List.iter (fun (path, name) -> if path = p then classes := name :: !classes else let rec loop p1 p2 = match p1, p2 with | [], _ -> () | x :: _, [] -> packages := x :: !packages | a :: p1, b :: p2 -> if a = b then loop p1 p2 in loop path p ) (all_files()) ) com.java_libs; List.iter (fun (path,std,all_files,lookup) -> List.iter (fun (path, name) -> if path = p then classes := name :: !classes else let rec loop p1 p2 = match p1, p2 with | [], _ -> () | x :: _, [] -> packages := x :: !packages | a :: p1, b :: p2 -> if a = b then loop p1 p2 in loop path p ) (all_files()) ) com.net_libs; unique !packages, unique !classes (** raise field completion listing packages and modules in a given package *) let complete_type_path com p = let packs, modules = read_type_path com p in if packs = [] && modules = [] then (abort ("No classes found in " ^ String.concat "." p) null_pos) else let packs = List.map (fun n -> n,Display.FKPackage,"") packs in let modules = List.map (fun n -> n,Display.FKModule,"") modules in Some (packs @ modules) (** raise field completion listing module sub-types and static fields *) let complete_type_path_inner com p c cur_package is_import = try let sl_pack,s_module = match List.rev p with | s :: sl when s.[0] >= 'A' && s.[0] <= 'Z' -> List.rev sl,s | _ -> p,c in let ctx = Typer.create com in let rec lookup p = try Typeload.load_module ctx (p,s_module) null_pos with e -> if cur_package then match List.rev p with | [] -> raise e | _ :: p -> lookup (List.rev p) else raise e in let m = lookup sl_pack in let statics = ref None in let public_types = List.filter (fun t -> let tinfos = t_infos t in let is_module_type = snd tinfos.mt_path = c in if is_import && is_module_type then begin match t with | TClassDecl c -> ignore(c.cl_build()); statics := Some c.cl_ordered_statics | _ -> () end; not tinfos.mt_private ) m.m_types in let types = if c <> s_module then [] else List.map (fun t -> let infos = t_infos t in (snd infos.mt_path), Display.FKModule, (Option.default "" infos.mt_doc) ) public_types in let make_field_doc cf = cf.cf_name, (match cf.cf_kind with Method _ -> Display.FKMethod cf.cf_type | Var _ -> Display.FKVar cf.cf_type), (match cf.cf_doc with Some s -> s | None -> "") in let fields = match !statics with | None -> types | Some cfl -> types @ (List.map make_field_doc (List.filter (fun cf -> cf.cf_public) cfl)) in Some fields with _ -> abort ("Could not load module " ^ (s_type_path (p,c))) null_pos end (* New JSON stuff *) open Json (** return a range JSON structure for given position positions are 0-based and the result object looks like this: { start: {line: 0, character: 0}, end: {line: 3, character: 42}, } *) let pos_to_json_range p = if p.pmin = -1 then JNull else let l1, p1, l2, p2 = Lexer.get_pos_coords p in let to_json l c = JObject [("line", JInt (l - 1)); ("character", JInt c)] in JObject [ ("start", to_json l1 p1); ("end", to_json l2 p2); ] let print_signature tl display_arg = let st = s_type (print_context()) in let s_arg (n,o,t) = Printf.sprintf "%s%s:%s" (if o then "?" else "") n (st t) in let s_fun args ret = Printf.sprintf "(%s):%s" (String.concat ", " (List.map s_arg args)) (st ret) in let siginf = List.map (fun ((args,ret),doc) -> let label = s_fun args ret in let parameters = List.map (fun arg -> let label = s_arg arg in JObject [ "label",JString label ] ) args in let js = [ "label",JString label; "parameters",JArray parameters; ] in JObject (match doc with None -> js | Some s -> ("documentation",JString s) :: js) ) tl in let jo = JObject [ "signatures",JArray siginf; "activeParameter",JInt display_arg; "activeSignature",JInt 0; ] in let b = Buffer.create 0 in write_json (Buffer.add_string b) jo; Buffer.contents b module StatisticsPrinter = struct open Statistics let relation_to_string = function | Implemented -> "implementers" | Extended -> "subclasses" | Overridden -> "overrides" | Referenced -> "references" let symbol_to_string = function | SKClass _ -> "class type" | SKInterface _ -> "interface type" | SKEnum _ -> "enum type" | SKField _ -> "class field" | SKEnumField _ -> "enum field" | SKVariable _ -> "variable" let print_statistics (kinds,relations) = let files = Hashtbl.create 0 in Hashtbl.iter (fun p rl -> let file = Path.get_real_path p.pfile in try Hashtbl.replace files file ((p,rl) :: Hashtbl.find files file) with Not_found -> Hashtbl.add files file [p,rl] ) relations; let ja = Hashtbl.fold (fun file relations acc -> let l = List.map (fun (p,rl) -> let h = Hashtbl.create 0 in List.iter (fun (r,p) -> let s = relation_to_string r in let jo = JObject [ "range",pos_to_json_range p; "file",JString (Path.get_real_path p.pfile); ] in try Hashtbl.replace h s (jo :: Hashtbl.find h s) with Not_found -> Hashtbl.add h s [jo] ) rl; let l = Hashtbl.fold (fun s js acc -> (s,JArray js) :: acc) h [] in let l = ("range",pos_to_json_range p) :: l in let l = try ("kind",JString (symbol_to_string (Hashtbl.find kinds p))) :: l with Not_found -> l in JObject l ) relations in (JObject [ "file",JString file; "statistics",JArray l ]) :: acc ) files [] in let b = Buffer.create 0 in write_json (Buffer.add_string b) (JArray ja); Buffer.contents b end module DiagnosticsPrinter = struct open Diagnostics open Diagnostics.DiagnosticsKind open DisplayTypes type t = DiagnosticsKind.t * pos module UnresolvedIdentifierSuggestion = struct type t = | UISImport | UISTypo let to_int = function | UISImport -> 0 | UISTypo -> 1 end let print_diagnostics ctx global = let com = ctx.com in let diag = Hashtbl.create 0 in let add dk p sev args = let file = Path.get_real_path p.pfile in let diag = try Hashtbl.find diag file with Not_found -> let d = DynArray.create() in Hashtbl.add diag file d; d in DynArray.add diag (dk,p,sev,args) in let add dk p sev args = if global || is_display_file p.pfile then add dk p sev args in let find_type i = let types = ref [] in Hashtbl.iter (fun _ m -> List.iter (fun mt -> let s_full_type_path (p,s) n = s_type_path (p,s) ^ if (s <> n) then "." ^ n else "" in let tinfos = t_infos mt in if snd tinfos.mt_path = i then types := JObject [ "kind",JInt (UnresolvedIdentifierSuggestion.to_int UnresolvedIdentifierSuggestion.UISImport); "name",JString (s_full_type_path m.m_path i) ] :: !types ) m.m_types; ) ctx.g.modules; !types in List.iter (fun (s,p,suggestions) -> let suggestions = List.map (fun (s,_) -> JObject [ "kind",JInt (UnresolvedIdentifierSuggestion.to_int UnresolvedIdentifierSuggestion.UISTypo); "name",JString s ] ) suggestions in add DKUnresolvedIdentifier p DiagnosticsSeverity.Error (JArray (suggestions @ (find_type s))); ) com.display_information.unresolved_identifiers; PMap.iter (fun p (r,_) -> if not !r then add DKUnusedImport p DiagnosticsSeverity.Warning (JArray []) ) com.shared.shared_display_information.import_positions; List.iter (fun (s,p,sev) -> add DKCompilerError p sev (JString s) ) com.shared.shared_display_information.diagnostics_messages; List.iter (fun (s,p,prange) -> add DKRemovableCode p DiagnosticsSeverity.Warning (JObject ["description",JString s;"range",if prange = null_pos then JNull else pos_to_json_range prange]) ) com.shared.shared_display_information.removable_code; let jl = Hashtbl.fold (fun file diag acc -> let jl = DynArray.fold_left (fun acc (dk,p,sev,jargs) -> (JObject [ "kind",JInt (to_int dk); "severity",JInt (DiagnosticsSeverity.to_int sev); "range",pos_to_json_range p; "args",jargs ]) :: acc ) [] diag in (JObject [ "file",JString file; "diagnostics",JArray jl ]) :: acc ) diag [] in let js = JArray jl in let b = Buffer.create 0 in write_json (Buffer.add_string b) js; Buffer.contents b end module ModuleSymbolsPrinter = struct open DisplayTypes.SymbolKind open DisplayTypes.SymbolInformation let print_module_symbols com symbols filter = let regex = Option.map Str.regexp_case_fold filter in let reported = Hashtbl.create 0 in let add si = if Hashtbl.mem reported si.pos then false else begin let b = match regex with | None -> true | Some regex -> (try ignore(Str.search_forward regex si.name 0); true with Not_found -> false) in Hashtbl.replace reported si.pos true; b end in let ja = List.fold_left (fun acc (file,l) -> let jl = ExtList.List.filter_map (fun si -> if not (add si) then None else begin let l = ("name",JString si.name) :: ("kind",JInt (to_int si.kind)) :: ("range", pos_to_json_range si.pos) :: (match si.container_name with None -> [] | Some s -> ["containerName",JString s]) in Some (JObject l) end ) (DynArray.to_list l) in if jl = [] then acc else (JObject [ "file",JString file; "symbols",JArray jl ]) :: acc ) [] symbols in let js = JArray ja in let b = Buffer.create 0 in write_json (Buffer.add_string b) js; Buffer.contents b end (* Mode processing *) exception Completion of string let unquote v = let len = String.length v in if len > 0 && v.[0] = '"' && v.[len - 1] = '"' then String.sub v 1 (len - 2) else v let handle_display_argument com file_pos pre_compilation did_something = match file_pos with | "classes" -> pre_compilation := (fun() -> raise (Parser.TypePath (["."],None,true))) :: !pre_compilation; | "keywords" -> raise (Completion (print_keywords ())) | "memory" -> did_something := true; (try display_memory com with e -> prerr_endline (Printexc.get_backtrace ())); | "diagnostics" -> Common.define com Define.NoCOpt; com.display <- DisplayMode.create (DMDiagnostics true); Common.display_default := DMDiagnostics true; | _ -> let file, pos = try ExtString.String.split file_pos "@" with _ -> failwith ("Invalid format: " ^ file_pos) in let file = unquote file in let pos, smode = try ExtString.String.split pos "@" with _ -> pos,"" in let mode = match smode with | "position" -> Common.define com Define.NoCOpt; DMPosition | "usage" -> Common.define com Define.NoCOpt; DMUsage false (*| "rename" -> Common.define com Define.NoCOpt; DMUsage true*) | "package" -> DMPackage | "type" -> Common.define com Define.NoCOpt; DMType | "toplevel" -> Common.define com Define.NoCOpt; DMToplevel | "module-symbols" -> Common.define com Define.NoCOpt; DMModuleSymbols None; | "diagnostics" -> Common.define com Define.NoCOpt; DMDiagnostics false; | "statistics" -> Common.define com Define.NoCOpt; DMStatistics | "signature" -> DMSignature | "" -> DMField | _ -> let smode,arg = try ExtString.String.split smode "@" with _ -> pos,"" in match smode with | "resolve" -> DMResolve arg | "workspace-symbols" -> Common.define com Define.NoCOpt; DMModuleSymbols (Some arg) | _ -> DMField in let pos = try int_of_string pos with _ -> failwith ("Invalid format: " ^ pos) in com.display <- DisplayMode.create mode; Common.display_default := mode; Common.define_value com Define.Display (if smode <> "" then smode else "1"); Parser.use_doc := true; Parser.resume_display := { pfile = Path.unique_full_path file; pmin = pos; pmax = pos; } let process_display_file com classes = let get_module_path_from_file_path com spath = let rec loop = function | [] -> None | cp :: l -> let cp = (if cp = "" then "./" else cp) in let c = Path.add_trailing_slash (Path.get_real_path cp) in let clen = String.length c in if clen < String.length spath && String.sub spath 0 clen = c then begin let path = String.sub spath clen (String.length spath - clen) in (try let path = Path.parse_type_path path in (match loop l with | Some x as r when String.length (s_type_path x) < String.length (s_type_path path) -> r | _ -> Some path) with _ -> loop l) end else loop l in loop com.class_path in match com.display.dms_display_file_policy with | DFPNo -> () | dfp -> if dfp = DFPOnly then begin classes := []; com.main_class <- None; end; let real = Path.get_real_path (!Parser.resume_display).pfile in (match get_module_path_from_file_path com real with | Some path -> if com.display.dms_kind = DMPackage then raise (DisplayPackage (fst path)); classes := path :: !classes | None -> if not (Sys.file_exists real) then failwith "Display file does not exist"; (match List.rev (ExtString.String.nsplit real Path.path_sep) with | file :: _ when file.[0] >= 'a' && file.[1] <= 'z' -> failwith ("Display file '" ^ file ^ "' should not start with a lowercase letter") | _ -> ()); failwith "Display file was not found in class path" ); Common.log com ("Display file : " ^ real); Common.log com ("Classes found : [" ^ (String.concat "," (List.map s_type_path !classes)) ^ "]") let process_global_display_mode com tctx = match com.display.dms_kind with | DMUsage with_definition -> let symbols,relations = Statistics.collect_statistics tctx in let rec loop acc relations = match relations with | (Statistics.Referenced,p) :: relations -> loop (p :: acc) relations | _ :: relations -> loop acc relations | [] -> acc in let usages = Hashtbl.fold (fun p sym acc -> if Statistics.is_usage_symbol sym then begin let acc = if with_definition then p :: acc else acc in (try loop acc (Hashtbl.find relations p) with Not_found -> acc) end else acc ) symbols [] in let usages = List.sort (fun p1 p2 -> let c = compare p1.pfile p2.pfile in if c <> 0 then c else compare p1.pmin p2.pmin ) usages in raise (DisplayPosition usages) | DMDiagnostics global -> Diagnostics.prepare com global; raise (Diagnostics (DiagnosticsPrinter.print_diagnostics tctx global)) | DMStatistics -> let stats = Statistics.collect_statistics tctx in raise (Statistics (StatisticsPrinter.print_statistics stats)) | DMModuleSymbols filter -> let symbols = com.shared.shared_display_information.document_symbols in let symbols = match CompilationServer.get() with | None -> symbols | Some cs -> let l = CompilationServer.get_context_files cs ((get_signature com) :: (match com.get_macros() with None -> [] | Some com -> [get_signature com])) in List.fold_left (fun acc (file,data) -> print_endline (Printf.sprintf "%s %b" file (is_display_file file)); if (filter <> None || is_display_file file) then (file,DocumentSymbols.collect_module_symbols data) :: acc else acc ) symbols l in raise (ModuleSymbols(ModuleSymbolsPrinter.print_module_symbols com symbols filter)) | _ -> () let find_doc t = let doc = match follow t with | TAnon an -> begin match !(an.a_status) with | Statics c -> c.cl_doc | EnumStatics en -> en.e_doc | AbstractStatics a -> a.a_doc | _ -> None end | _ -> None in dochaxe_3.4.4.orig/src/display/displayTypes.ml0000664000175000017500000000153613166552354020701 0ustar andyandy00000000000000open Ast module SymbolKind = struct type t = | Class | Interface | Enum | Typedef | Abstract | Field | Property | Method | Constructor | Function | Variable let to_int = function | Class -> 1 | Interface -> 2 | Enum -> 3 | Typedef -> 4 | Abstract -> 5 | Field -> 6 | Property -> 7 | Method -> 8 | Constructor -> 9 | Function -> 10 | Variable -> 11 end module SymbolInformation = struct type t = { name : string; kind : SymbolKind.t; pos : Globals.pos; container_name : string option; } let make name kind pos container_name = { name = name; kind = kind; pos = pos; container_name = container_name; } end module DiagnosticsSeverity = struct type t = | Error | Warning | Information | Hint let to_int = function | Error -> 1 | Warning -> 2 | Information -> 3 | Hint -> 4 endhaxe_3.4.4.orig/src/generators/codegen.ml0000664000175000017500000007300713166552354020321 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Type open Common open Error open Globals (* -------------------------------------------------------------------------- *) (* TOOLS *) (* Collection of functions that return expressions *) module ExprBuilder = struct let make_static_this c p = let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in mk (TTypeExpr (TClassDecl c)) ta p let make_static_field c cf p = let e_this = make_static_this c p in mk (TField(e_this,FStatic(c,cf))) cf.cf_type p let make_int com i p = mk (TConst (TInt (Int32.of_int i))) com.basic.tint p let make_float com f p = mk (TConst (TFloat f)) com.basic.tfloat p let make_bool com b p = mk (TConst(TBool b)) com.basic.tbool p let make_string com s p = mk (TConst (TString s)) com.basic.tstring p let make_null t p = mk (TConst TNull) t p let make_local v p = mk (TLocal v) v.v_type p let make_const_texpr com ct p = match ct with | TString s -> mk (TConst (TString s)) com.basic.tstring p | TInt i -> mk (TConst (TInt i)) com.basic.tint p | TFloat f -> mk (TConst (TFloat f)) com.basic.tfloat p | TBool b -> mk (TConst (TBool b)) com.basic.tbool p | TNull -> mk (TConst TNull) (com.basic.tnull (mk_mono())) p | _ -> error "Unsupported constant" p end 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 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 null_pos in PMap.add n cf fields,(n, ExprBuilder.make_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 null_pos 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 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 (* -------------------------------------------------------------------------- *) (* 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) let update_cache_dependencies t = 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 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); | _ -> () (* -------------------------------------------------------------------------- *) (* 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 p in let exc_var = alloc_var exc_var st p in let pos_var = alloc_var pos_var t.tint p 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 (ExprBuilder.make_string com (s_type_path c.cl_path ^ "::") p) (ExprBuilder.make_string com m p) t.tstring p else ExprBuilder.make_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 e.epos 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 || com.platform = Hl then (* 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 v.v_pos 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 module Dump = struct let make_valid_filename s = let r = Str.regexp "[^A-Za-z0-9_\\-\\.,]" in Str.global_substitute r (fun s -> "_") s let rec create_file ext acc = function | [] -> assert false | d :: [] -> let d = make_valid_filename d in let maxlen = 200 - String.length ext in let d = if String.length d > maxlen then String.sub d 0 maxlen else d in let ch = open_out (String.concat "/" (List.rev (d :: acc)) ^ ext) in ch | d :: l -> let dir = String.concat "/" (List.rev (d :: acc)) in if not (Sys.file_exists dir) then Unix.mkdir dir 0o755; create_file ext (d :: acc) l (* Make a dump of the full typed AST of all types *) let create_dumpfile acc l = let ch = create_file ".dump" acc l in let buf = Buffer.create 0 in buf, (fun () -> output_string ch (Buffer.contents buf); close_out ch) let create_dumpfile_from_path com path = let buf,close = create_dumpfile [] ("dump" :: (platform_name com.platform) :: fst path @ [snd path]) in buf,close let dump_types com s_expr = let s_type = s_type (Type.print_context()) in let params tl = match tl with [] -> "" | l -> Printf.sprintf "<%s>" (String.concat "," (List.map (fun (n,t) -> n ^ " : " ^ s_type t) l)) in List.iter (fun mt -> let path = Type.t_path mt in let buf,close = create_dumpfile_from_path com path in let print fmt = Printf.kprintf (fun s -> Buffer.add_string buf s) fmt in let s_metas ml tabs = let args el = match el with | [] -> "" | el -> Printf.sprintf "(%s)" (String.concat ", " (List.map (fun e -> Ast.s_expr e) el)) in match ml with | [] -> "" | ml -> String.concat " " (List.map (fun me -> match me with (m,el,_) -> "@" ^ Meta.to_string m ^ args el) ml) ^ "\n" ^ tabs in (match mt with | Type.TClassDecl c -> let s_cf_expr f = match f.cf_expr with | None -> "" | Some e -> Printf.sprintf "%s" (s_expr s_type e) in let is_inline_var v : bool = v = Var { v_read = AccInline; v_write = AccNever } in let rec print_field stat f = print "\n\t%s%s%s%s%s %s%s" (s_metas f.cf_meta "\t") (if (f.cf_public && not (c.cl_extern || c.cl_interface)) then "public " else "") (if stat then "static " else "") (match f.cf_kind with | Var v when (is_inline_var f.cf_kind) -> "inline " | Var v -> "" | Method m -> match m with | MethNormal -> "" | MethDynamic -> "dynamic " | MethInline -> "inline " | MethMacro -> "macro ") (match f.cf_kind with Var v -> "var" | Method m -> "function") (f.cf_name ^ match f.cf_kind with | Var { v_read = AccNormal; v_write = AccNormal } -> "" | Var v when (is_inline_var f.cf_kind) -> "" | Var v -> "(" ^ s_access true v.v_read ^ "," ^ s_access false v.v_write ^ ")" | _ -> "") (params f.cf_params); (match f.cf_kind with | Var v -> print ":%s%s;" (s_type f.cf_type) (match f.cf_expr with | None -> "" | Some e -> " = " ^ (s_cf_expr f)); | Method m -> if (c.cl_extern || c.cl_interface) then ( match f.cf_type with | TFun(al,t) -> print "(%s):%s;" (String.concat ", " ( List.map (fun (n,o,t) -> n ^ ":" ^ (s_type t)) al)) (s_type t) | _ -> () ) else print "%s" (s_cf_expr f)); print "\n"; List.iter (fun f -> print_field stat f) f.cf_overloads in print "%s%s%s%s %s%s" (s_metas c.cl_meta "") (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\tstatic function __init__() "; print "%s" (s_expr s_type e); print "\n"); print "}"; | Type.TEnumDecl e -> print "%s%s%senum %s%s {\n" (s_metas e.e_meta "") (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 ( match f.ef_type with | TFun (al,t) -> Printf.sprintf "(%s)" (String.concat ", " (List.map (fun (n,o,t) -> (if o then "?" else "") ^ n ^ ":" ^ (s_type t)) al)) | _ -> "") ) e.e_names; print "}" | Type.TTypeDecl t -> print "%s%stypedef %s%s = %s" (s_metas t.t_meta "") (if t.t_private then "private " else "") (s_type_path path) (params t.t_params) (s_type t.t_type); | Type.TAbstractDecl a -> print "%s%sabstract %s%s%s%s {}" (s_metas a.a_meta "") (if a.a_private then "private " else "") (s_type_path path) (params a.a_params) (String.concat " " (List.map (fun t -> " from " ^ s_type t) a.a_from)) (String.concat " " (List.map (fun t -> " to " ^ s_type t) a.a_to)); ); close(); ) com.types let dump_record com = List.iter (fun mt -> let buf,close = create_dumpfile_from_path com (t_path mt) in let s = match mt with | TClassDecl c -> Printer.s_tclass "" c | TEnumDecl en -> Printer.s_tenum "" en | TTypeDecl t -> Printer.s_tdef "" t | TAbstractDecl a -> Printer.s_tabstract "" a in Buffer.add_string buf s; close(); ) com.types let dump_types com = match Common.defined_value_safe com Define.Dump with | "pretty" -> dump_types com (Type.s_expr_pretty false "\t" true) | "legacy" -> dump_types com Type.s_expr | "record" -> dump_record com | _ -> dump_types com (Type.s_expr_ast (not (Common.defined com Define.DumpIgnoreVarIds)) "\t") let dump_dependencies ?(target_override=None) com = let target_name = match target_override with | None -> platform_name com.platform | Some s -> s in let buf,close = create_dumpfile [] ["dump";target_name;".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";target_name;".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() end (* 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 e.epos 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 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 ff e = let f e t = if not (type_iseq e.etype t) then ff e t else e in let check e = match e.eexpr with | TBinop((OpAssign | OpAssignOp _),e1,e2) -> assert false; (* this trigger #4347, to be fixed before enabling 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 ff) e) 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 -> begin try let expr = Array.get exprs (int_of_string n) in f_expr expr; with | Failure "int_of_string" -> f_string ("{" ^ n ^ "}"); | Invalid_argument _ -> err ("Out-of-bounds special parameter: " ^ n) end; i := !i + 2 + String.length n; loop tl | Str.Delim x :: tl -> f_string x; incr i; loop tl in loop (Str.full_split regex code) let map_source_header com f = match Common.defined_value_safe com Define.SourceHeader with | "" -> () | s -> f s (* Static extensions for classes *) module ExtClass = struct let add_cl_init c e = match c.cl_init with | None -> c.cl_init <- Some e | Some e' -> c.cl_init <- Some (concat e' e) let add_static_init c cf e p = let ethis = ExprBuilder.make_static_this c p in let ef1 = mk (TField(ethis,FStatic(c,cf))) cf.cf_type p in let e_assign = mk (TBinop(OpAssign,ef1,e)) e.etype p in add_cl_init c e_assign end let for_remap com v e1 e2 p = let v' = alloc_var v.v_name e1.etype e1.epos in let ev' = mk (TLocal v') e1.etype e1.epos in let t1 = (Abstract.follow_with_abstracts e1.etype) in let ehasnext = mk (TField(ev',quick_field t1 "hasNext")) (tfun [] com.basic.tbool) e1.epos in let ehasnext = mk (TCall(ehasnext,[])) com.basic.tbool ehasnext.epos in let enext = mk (TField(ev',quick_field t1 "next")) (tfun [] v.v_type) e1.epos in let enext = mk (TCall(enext,[])) v.v_type e1.epos in let eassign = mk (TVar(v,Some enext)) com.basic.tvoid p in let ebody = Type.concat eassign e2 in mk (TBlock [ mk (TVar (v',Some e1)) com.basic.tvoid e1.epos; mk (TWhile((mk (TParenthesis ehasnext) ehasnext.etype ehasnext.epos),ebody,NormalWhile)) com.basic.tvoid e1.epos; ]) com.basic.tvoid phaxe_3.4.4.orig/src/generators/genas3.ml0000664000175000017500000010752413166552354020077 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Type open Common type context_infos = { com : Common.context; } type context = { inf : context_infos; ch : out_channel; buf : Buffer.t; path : path; mutable get_sets : (string * bool,string) Hashtbl.t; mutable curclass : tclass; mutable tabs : string; mutable in_value : tvar option; mutable in_static : bool; mutable handle_break : bool; mutable imports : (string,string list list) Hashtbl.t; mutable gen_uid : int; mutable local_types : t list; mutable constructor_block : bool; mutable block_inits : (unit -> unit) option; } let follow = Abstract.follow_with_abstracts let is_var_field f = match f with | FStatic (_,f) | FInstance (_,_,f) -> (match f.cf_kind with Var _ | Method MethDynamic -> true | _ -> false) | _ -> false let is_special_compare e1 e2 = match e1.eexpr, e2.eexpr with | TConst TNull, _ | _ , TConst TNull -> None | _ -> match follow e1.etype, follow e2.etype with | TInst ({ cl_path = ["flash"],"NativeXml" } as c,_) , _ | _ , TInst ({ cl_path = ["flash"],"NativeXml" } as c,_) -> Some c | _ -> None let is_fixed_override cf t = let is_type_parameter c = match c.cl_kind with | KTypeParameter _ -> true | _ -> false in match follow cf.cf_type,follow t with | TFun(_,r1),TFun(_,r2) -> begin match follow r1,follow r2 with | TInst(c1,_),TInst(c2,_) when c1 != c2 && not (is_type_parameter c1) && not (is_type_parameter c2) -> true | _ -> false end | _ -> false let protect name = match name with | "Error" | "Namespace" -> "_" ^ name | _ -> name let s_path ctx stat path p = match path with | ([],name) -> (match name with | "Int" -> "int" | "Float" -> "Number" | "Dynamic" -> "Object" | "Bool" -> "Boolean" | "Enum" -> "Class" | "EnumValue" -> "enum" | _ -> name) | (["flash"],"FlashXml__") -> "Xml" | (["flash";"errors"],"Error") -> "Error" | (["flash"],"Vector") -> "Vector" | (["flash";"xml"],"XML") -> "XML" | (["flash";"xml"],"XMLList") -> "XMLList" | ["flash";"utils"],"QName" -> "QName" | ["flash";"utils"],"Namespace" -> "Namespace" | (["haxe"],"Int32") when not stat -> "int" | (pack,name) -> let name = protect name in let packs = (try Hashtbl.find ctx.imports name with Not_found -> []) in if not (List.mem pack packs) then Hashtbl.replace ctx.imports name (pack :: packs); Globals.s_type_path (pack,name) let reserved = let h = Hashtbl.create 0 in List.iter (fun l -> Hashtbl.add h l ()) (* these ones are defined in order to prevent recursion in some Std functions *) ["is";"as";"int";"uint";"const";"getTimer";"typeof";"parseInt";"parseFloat"; (* AS3 keywords which are not Haxe ones *) "finally";"with";"final";"internal";"native";"namespace";"include";"delete"; (* some globals give some errors with Flex SDK as well *) "print";"trace"; (* we don't include get+set since they are not 'real' keywords, but they can't be used as method names *) "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";"interface"; "override";"package";"null";"true";"false";"void" ]; h (* "each", "label" : removed (actually allowed in locals and fields accesses) *) let s_ident n = if Hashtbl.mem reserved n then "_" ^ n else n let valid_as3_ident s = try for i = 0 to String.length s - 1 do match String.unsafe_get s i with | 'a'..'z' | 'A'..'Z' | '$' | '_' -> () | '0'..'9' when i > 0 -> () | _ -> raise Exit done; true with Exit -> false let anon_field s = let s = s_ident s in if not (valid_as3_ident s) then "\"" ^ (Ast.s_escape s) ^ "\"" else s let rec create_dir acc = function | [] -> () | d :: l -> let dir = String.concat "/" (List.rev (d :: acc)) in if not (Sys.file_exists dir) then Unix.mkdir dir 0o755; create_dir (d :: acc) l let init infos path = let dir = infos.com.file :: fst path in create_dir [] dir; let ch = open_out (String.concat "/" dir ^ "/" ^ snd path ^ ".as") in let imports = Hashtbl.create 0 in Hashtbl.add imports (snd path) [fst path]; { inf = infos; tabs = ""; ch = ch; path = path; buf = Buffer.create (1 lsl 14); in_value = None; in_static = false; handle_break = false; imports = imports; curclass = null_class; gen_uid = 0; local_types = []; get_sets = Hashtbl.create 0; constructor_block = false; block_inits = None; } let close ctx = begin match ctx.inf.com.main_class with | Some tp when tp = ctx.curclass.cl_path -> output_string ctx.ch "// Compile __main__.as instead\n"; | _ -> () end; output_string ctx.ch (Printf.sprintf "package %s {\n" (String.concat "." (fst ctx.path))); Hashtbl.iter (fun name paths -> List.iter (fun pack -> let path = pack, name in if path <> ctx.path then output_string ctx.ch ("\timport " ^ Globals.s_type_path path ^ ";\n"); ) paths ) ctx.imports; output_string ctx.ch (Buffer.contents ctx.buf); close_out ctx.ch let gen_local ctx l = ctx.gen_uid <- ctx.gen_uid + 1; if ctx.gen_uid = 1 then l else l ^ string_of_int ctx.gen_uid let spr ctx s = Buffer.add_string ctx.buf s let print ctx = Printf.kprintf (fun s -> Buffer.add_string ctx.buf s) let unsupported p = abort "This expression cannot be generated to AS3" p let newline ctx = let rec loop p = match Buffer.nth ctx.buf p with | '}' | '{' | ':' | ';' -> print ctx "\n%s" ctx.tabs | '\n' | '\t' -> loop (p - 1) | _ -> print ctx ";\n%s" ctx.tabs in loop (Buffer.length ctx.buf - 1) let block_newline ctx = match Buffer.nth ctx.buf (Buffer.length ctx.buf - 1) with | '}' -> print ctx ";\n%s" ctx.tabs | _ -> newline ctx let rec concat ctx s f = function | [] -> () | [x] -> f x | x :: l -> f x; spr ctx s; concat ctx s f l let open_block ctx = let oldt = ctx.tabs in ctx.tabs <- "\t" ^ ctx.tabs; (fun() -> ctx.tabs <- oldt) let parent e = match e.eexpr with | TParenthesis _ -> e | _ -> mk (TParenthesis e) e.etype e.epos let default_value tstr = match tstr with | "int" | "uint" -> "0" | "Number" -> "NaN" | "Boolean" -> "false" | _ -> "null" let rec type_str ctx t p = match t with | TEnum _ | TInst _ when List.memq t ctx.local_types -> "*" | TAbstract (a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> type_str ctx (Abstract.get_underlying_type a pl) p | TAbstract (a,_) -> (match a.a_path with | [], "Void" -> "void" | [], "UInt" -> "uint" | [], "Int" -> "int" | [], "Float" -> "Number" | [], "Bool" -> "Boolean" | _ -> s_path ctx true a.a_path p) | TEnum (e,_) -> if e.e_extern then (match e.e_path with | [], "Void" -> "void" | [], "Bool" -> "Boolean" | _ -> let rec loop = function | [] -> "Object" | (Meta.FakeEnum,[Ast.EConst (Ast.Ident n),_],_) :: _ -> (match n with | "Int" -> "int" | "UInt" -> "uint" | _ -> n) | _ :: l -> loop l in loop e.e_meta ) else s_path ctx true e.e_path p | TInst ({ cl_path = ["flash"],"Vector" },[pt]) -> (match pt with | TInst({cl_kind = KTypeParameter _},_) -> "*" | _ -> "Vector.<" ^ type_str ctx pt p ^ ">") | TInst (c,_) -> (match c.cl_kind with | KNormal | KGeneric | KGenericInstance _ | KAbstractImpl _ -> s_path ctx false c.cl_path p | KTypeParameter _ | KExpr _ | KMacroType | KGenericBuild _ -> "*") | TFun _ -> "Function" | TMono r -> (match !r with None -> "*" | Some t -> type_str ctx t p) | TAnon _ | TDynamic _ -> "*" | TType (t,args) -> (match t.t_path with | [], "UInt" -> "uint" | [] , "Null" -> (match args with | [t] -> (match follow t with | TAbstract ({ a_path = [],"UInt" },_) | TAbstract ({ a_path = [],"Int" },_) | TAbstract ({ a_path = [],"Float" },_) | TAbstract ({ a_path = [],"Bool" },_) -> "*" | _ -> type_str ctx t p) | _ -> assert false); | _ -> type_str ctx (apply_params t.t_params args t.t_type) p) | TLazy f -> type_str ctx ((!f)()) p let rec iter_switch_break in_switch e = match e.eexpr with | TFunction _ | TWhile _ | TFor _ -> () | TSwitch _ when not in_switch -> iter_switch_break true e | TBreak when in_switch -> raise Exit | _ -> iter (iter_switch_break in_switch) e let handle_break ctx e = let old_handle = ctx.handle_break in try iter_switch_break false e; ctx.handle_break <- false; (fun() -> ctx.handle_break <- old_handle) with Exit -> spr ctx "try {"; let b = open_block ctx in newline ctx; ctx.handle_break <- true; (fun() -> b(); ctx.handle_break <- old_handle; newline ctx; spr ctx "} catch( e : * ) { if( e != \"__break__\" ) throw e; }"; ) let this ctx = if ctx.in_value <> None then "$this" else "this" let generate_resources infos = if Hashtbl.length infos.com.resources <> 0 then begin let dir = (infos.com.file :: ["__res"]) in create_dir [] dir; let add_resource name data = let name = Base64.str_encode name in let ch = open_out_bin (String.concat "/" (dir @ [name])) in output_string ch data; close_out ch in Hashtbl.iter (fun name data -> add_resource name data) infos.com.resources; let ctx = init infos ([],"__resources__") in spr ctx "\timport flash.utils.Dictionary;\n"; spr ctx "\tpublic class __resources__ {\n"; spr ctx "\t\tpublic static var list:Dictionary;\n"; let inits = ref [] in let k = ref 0 in Hashtbl.iter (fun name _ -> let varname = ("v" ^ (string_of_int !k)) in k := !k + 1; print ctx "\t\t[Embed(source = \"__res/%s\", mimeType = \"application/octet-stream\")]\n" (Base64.str_encode name); print ctx "\t\tpublic static var %s:Class;\n" varname; inits := ("list[\"" ^ Ast.s_escape name ^ "\"] = " ^ varname ^ ";") :: !inits; ) infos.com.resources; spr ctx "\t\tstatic public function __init__():void {\n"; spr ctx "\t\t\tlist = new Dictionary();\n"; List.iter (fun init -> print ctx "\t\t\t%s\n" init ) !inits; spr ctx "\t\t}\n"; spr ctx "\t}\n"; spr ctx "}"; close ctx; end let gen_constant ctx p = function | TInt i -> print ctx "%ld" i | TFloat s -> spr ctx s | TString s -> print ctx "\"%s\"" (Ast.s_escape s) | TBool b -> spr ctx (if b then "true" else "false") | TNull -> spr ctx "null" | TThis -> spr ctx (this ctx) | TSuper -> spr ctx "super" let gen_function_header ctx name f params p = let old = ctx.in_value in let old_t = ctx.local_types in let old_bi = ctx.block_inits in ctx.in_value <- None; ctx.local_types <- List.map snd params @ ctx.local_types; let init () = List.iter (fun (v,o) -> match o with | Some c when is_nullable v.v_type && c <> TNull -> newline ctx; print ctx "if(%s==null) %s=" v.v_name v.v_name; gen_constant ctx p c; | _ -> () ) f.tf_args; ctx.block_inits <- None; in ctx.block_inits <- Some init; print ctx "function%s(" (match name with None -> "" | Some (n,meta) -> let rec loop = function | [] -> n | (Meta.Getter,[Ast.EConst (Ast.Ident i),_],_) :: _ -> "get " ^ i | (Meta.Setter,[Ast.EConst (Ast.Ident i),_],_) :: _ -> "set " ^ i | _ :: l -> loop l in " " ^ loop meta ); concat ctx "," (fun (v,c) -> match v.v_name with | "__arguments__" -> print ctx "...__arguments__" | _ -> let tstr = type_str ctx v.v_type p in print ctx "%s : %s" (s_ident v.v_name) tstr; match c with | None -> if ctx.constructor_block then print ctx " = %s" (default_value tstr); | Some c -> spr ctx " = "; gen_constant ctx p c ) f.tf_args; print ctx ") : %s " (type_str ctx f.tf_type p); (fun () -> ctx.in_value <- old; ctx.local_types <- old_t; ctx.block_inits <- old_bi; ) let rec gen_call ctx e el r = match e.eexpr , el with | TCall (x,_) , el -> spr ctx "("; gen_value ctx e; spr ctx ")"; spr ctx "("; concat ctx "," (gen_value ctx) el; spr ctx ")"; | TLocal { v_name = "__is__" } , [e1;e2] -> gen_value ctx e1; spr ctx " is "; gen_value ctx e2; | TLocal { v_name = "__in__" } , [e1;e2] -> spr ctx "("; gen_value ctx e1; spr ctx " in "; gen_value ctx e2; spr ctx ")" | TLocal { v_name = "__as__" }, [e1;e2] -> gen_value ctx e1; spr ctx " as "; gen_value ctx e2; | TLocal { v_name = "__int__" }, [e] -> spr ctx "int("; gen_value ctx e; spr ctx ")"; | TLocal { v_name = "__float__" }, [e] -> spr ctx "Number("; gen_value ctx e; spr ctx ")"; | TLocal { v_name = "__typeof__" }, [e] -> spr ctx "typeof "; gen_value ctx e; | TLocal { v_name = "__keys__" }, [e] -> let ret = (match ctx.in_value with None -> assert false | Some r -> r) in print ctx "%s = new Array()" ret.v_name; newline ctx; let tmp = gen_local ctx "$k" in print ctx "for(var %s : String in " tmp; gen_value ctx e; print ctx ") %s.push(%s)" ret.v_name tmp; | TLocal { v_name = "__hkeys__" }, [e] -> let ret = (match ctx.in_value with None -> assert false | Some r -> r) in print ctx "%s = new Array()" ret.v_name; newline ctx; let tmp = gen_local ctx "$k" in print ctx "for(var %s : String in " tmp; gen_value ctx e; print ctx ") %s.push(%s.substr(1))" ret.v_name tmp; | TLocal { v_name = "__foreach__" }, [e] -> let ret = (match ctx.in_value with None -> assert false | Some r -> r) in print ctx "%s = new Array()" ret.v_name; newline ctx; let tmp = gen_local ctx "$k" in print ctx "for each(var %s : * in " tmp; gen_value ctx e; print ctx ") %s.push(%s)" ret.v_name tmp; | TLocal { v_name = "__new__" }, e :: args -> spr ctx "new "; gen_value ctx e; spr ctx "("; concat ctx "," (gen_value ctx) args; spr ctx ")"; | TLocal { v_name = "__delete__" }, [e;f] -> spr ctx "delete("; gen_value ctx e; spr ctx "["; gen_value ctx f; spr ctx "]"; spr ctx ")"; | TLocal { v_name = "__unprotect__" }, [e] -> gen_value ctx e | TLocal { v_name = "__vector__" }, [e] -> spr ctx (type_str ctx r e.epos); spr ctx "("; gen_value ctx e; spr ctx ")" | TField (_, FStatic( { cl_path = (["flash"],"Lib") }, { cf_name = "as" })), [e1;e2] -> gen_value ctx e1; spr ctx " as "; gen_value ctx e2 | TField (_, FStatic ({ cl_path = (["flash"],"Vector") }, cf)), args -> (match cf.cf_name, args with | "ofArray", [e] | "convert", [e] -> (match follow r with | TInst ({ cl_path = (["flash"],"Vector") },[t]) -> print ctx "Vector.<%s>(" (type_str ctx t e.epos); gen_value ctx e; print ctx ")"; | _ -> assert false) | _ -> assert false) | TField(e1, (FAnon {cf_name = s} | FDynamic s)),[ef] when s = "map" || s = "filter" -> spr ctx (s_path ctx true (["flash";],"Boot") e.epos); gen_field_access ctx t_dynamic (s ^ "Dynamic"); spr ctx "("; concat ctx "," (gen_value ctx) [e1;ef]; spr ctx ")" | TField (ee,f), args when is_var_field f -> spr ctx "("; gen_value ctx e; spr ctx ")"; spr ctx "("; concat ctx "," (gen_value ctx) el; spr ctx ")" | TField (e1,FInstance(_,_,cf)),el when is_fixed_override cf e.etype -> let s = type_str ctx r e.epos in spr ctx "(("; gen_value ctx e; spr ctx "("; concat ctx "," (gen_value ctx) el; spr ctx ")"; print ctx ") as %s)" s | _ -> gen_value ctx e; spr ctx "("; concat ctx "," (gen_value ctx) el; spr ctx ")" and gen_value_op ctx e = match e.eexpr with | TBinop (op,_,_) when op = Ast.OpAnd || op = Ast.OpOr || op = Ast.OpXor -> spr ctx "("; gen_value ctx e; spr ctx ")"; | _ -> gen_value ctx e and gen_field_access ctx t s = let field c = match fst c.cl_path, snd c.cl_path, s with | [], "Math", "NaN" | [], "Math", "NEGATIVE_INFINITY" | [], "Math", "POSITIVE_INFINITY" | [], "Math", "isFinite" | [], "Math", "isNaN" | [], "Date", "now" | [], "Date", "fromTime" | [], "Date", "fromString" -> print ctx "[\"%s\"]" s | [], "String", "charCodeAt" -> spr ctx "[\"charCodeAtHX\"]" | [], "Array", "map" -> spr ctx "[\"mapHX\"]" | [], "Array", "filter" -> spr ctx "[\"filterHX\"]" | [], "Date", "toString" -> print ctx "[\"toStringHX\"]" | [], "String", "cca" -> print ctx ".charCodeAt" | ["flash";"xml"], "XML", "namespace" -> print ctx ".namespace" | _ -> print ctx ".%s" (s_ident s) in match follow t with | TInst (c,_) -> field c | TAnon a -> (match !(a.a_status) with | Statics c -> field c | _ -> print ctx ".%s" (s_ident s)) | _ -> print ctx ".%s" (s_ident s) and gen_expr ctx e = match e.eexpr with | TConst c -> gen_constant ctx e.epos c | TLocal v -> spr ctx (s_ident v.v_name) | TArray ({ eexpr = TLocal { v_name = "__global__" } },{ eexpr = TConst (TString s) }) -> let path = Ast.parse_path s in spr ctx (s_path ctx false path e.epos) | TArray (e1,e2) -> gen_value ctx e1; spr ctx "["; gen_value ctx e2; spr ctx "]"; | TBinop (Ast.OpEq,e1,e2) when (match is_special_compare e1 e2 with Some c -> true | None -> false) -> let c = match is_special_compare e1 e2 with Some c -> c | None -> assert false in gen_expr ctx (mk (TCall (mk (TField (mk (TTypeExpr (TClassDecl c)) t_dynamic e.epos,FDynamic "compare")) t_dynamic e.epos,[e1;e2])) ctx.inf.com.basic.tbool e.epos); (* what is this used for? *) (* | TBinop (op,{ eexpr = TField (e1,s) },e2) -> gen_value_op ctx e1; gen_field_access ctx e1.etype s; print ctx " %s " (Ast.s_binop op); gen_value_op ctx e2; *) (* assignments to variable or dynamic methods fields on interfaces are generated as class["field"] = value *) | TBinop (op,{eexpr = TField (ei, FInstance({cl_interface = true},_,{cf_kind = (Method MethDynamic | Var _); cf_name = s}))},e2) -> gen_value ctx ei; print ctx "[\"%s\"]" s; print ctx " %s " (Ast.s_binop op); gen_value_op ctx e2; | TBinop (op,e1,e2) -> gen_value_op ctx e1; print ctx " %s " (Ast.s_binop op); gen_value_op ctx e2; (* variable fields and dynamic methods on interfaces are generated as (class["field"] as class) *) | TField (ei, FInstance({cl_interface = true},_,{cf_kind = (Method MethDynamic | Var _); cf_name = s})) -> spr ctx "("; gen_value ctx ei; print ctx "[\"%s\"]" s; print ctx " as %s)" (type_str ctx e.etype e.epos); | TField({eexpr = TArrayDecl _} as e1,s) -> spr ctx "("; gen_expr ctx e1; spr ctx ")"; gen_field_access ctx e1.etype (field_name s) | TEnumParameter (e,_,i) -> gen_value ctx e; print ctx ".params[%i]" i; | TField (e,s) -> gen_value ctx e; gen_field_access ctx e.etype (field_name s) | TTypeExpr t -> spr ctx (s_path ctx true (t_path t) e.epos) | TParenthesis e -> spr ctx "("; gen_value ctx e; spr ctx ")"; | TMeta (_,e) -> gen_expr ctx e | TReturn eo -> if ctx.in_value <> None then unsupported e.epos; (match eo with | None -> spr ctx "return" | Some e when (match follow e.etype with TEnum({ e_path = [],"Void" },[]) | TAbstract ({ a_path = [],"Void" },[]) -> true | _ -> false) -> print ctx "{"; let bend = open_block ctx in newline ctx; gen_value ctx e; newline ctx; spr ctx "return"; bend(); newline ctx; print ctx "}"; | Some e -> spr ctx "return "; gen_value ctx e); | TBreak -> if ctx.in_value <> None then unsupported e.epos; if ctx.handle_break then spr ctx "throw \"__break__\"" else spr ctx "break" | TContinue -> if ctx.in_value <> None then unsupported e.epos; spr ctx "continue" | TBlock el -> print ctx "{"; let bend = open_block ctx in let cb = (if not ctx.constructor_block then (fun () -> ()) else if not (Codegen.constructor_side_effects e) then begin ctx.constructor_block <- false; (fun () -> ()) end else begin ctx.constructor_block <- false; print ctx " if( !%s.skip_constructor ) {" (s_path ctx true (["flash"],"Boot") e.epos); (fun() -> print ctx "}") end) in (match ctx.block_inits with None -> () | Some i -> i()); List.iter (fun e -> gen_block_element ctx e) el; bend(); newline ctx; cb(); print ctx "}"; | TFunction f -> let h = gen_function_header ctx None f [] e.epos in let old = ctx.in_static in ctx.in_static <- true; gen_expr ctx f.tf_expr; ctx.in_static <- old; h(); | TCall (v,el) -> gen_call ctx v el e.etype | TArrayDecl el -> spr ctx "["; concat ctx "," (gen_value ctx) el; spr ctx "]" | TThrow e -> spr ctx "throw "; gen_value ctx e; | TVar (v,eo) -> spr ctx "var "; print ctx "%s : %s" (s_ident v.v_name) (type_str ctx v.v_type e.epos); begin match eo with | None -> () | Some e -> spr ctx " = "; gen_value ctx e end | TNew (c,params,el) -> (match c.cl_path, params with | (["flash"],"Vector"), [pt] -> print ctx "new Vector.<%s>(" (type_str ctx pt e.epos) | _ -> print ctx "new %s(" (s_path ctx true c.cl_path e.epos)); concat ctx "," (gen_value ctx) el; spr ctx ")" | TIf (cond,e,eelse) -> spr ctx "if"; gen_value ctx (parent cond); spr ctx " "; gen_expr ctx e; (match eelse with | None -> () | Some e -> newline ctx; spr ctx "else "; gen_expr ctx e); | TUnop (op,Ast.Prefix,e) -> spr ctx (Ast.s_unop op); gen_value ctx e | TUnop (op,Ast.Postfix,e) -> gen_value ctx e; spr ctx (Ast.s_unop op) | TWhile (cond,e,Ast.NormalWhile) -> let handle_break = handle_break ctx e in spr ctx "while"; gen_value ctx (parent cond); spr ctx " "; gen_expr ctx e; handle_break(); | TWhile (cond,e,Ast.DoWhile) -> let handle_break = handle_break ctx e in spr ctx "do "; gen_expr ctx e; spr ctx " while"; gen_value ctx (parent cond); handle_break(); | TObjectDecl fields -> spr ctx "{ "; concat ctx ", " (fun (f,e) -> print ctx "%s : " (anon_field f); gen_value ctx e) fields; spr ctx "}" | TFor (v,it,e) -> let handle_break = handle_break ctx e in let tmp = gen_local ctx "$it" in print ctx "{ var %s : * = " tmp; gen_value ctx it; newline ctx; print ctx "while( %s.hasNext() ) { var %s : %s = %s.next()" tmp (s_ident v.v_name) (type_str ctx v.v_type e.epos) tmp; newline ctx; gen_expr ctx e; newline ctx; spr ctx "}}"; handle_break(); | TTry (e,catchs) -> spr ctx "try "; gen_expr ctx e; List.iter (fun (v,e) -> newline ctx; print ctx "catch( %s : %s )" (s_ident v.v_name) (type_str ctx v.v_type e.epos); gen_expr ctx e; ) catchs; | TSwitch (e,cases,def) -> spr ctx "switch"; gen_value ctx (parent e); spr ctx " {"; newline ctx; List.iter (fun (el,e2) -> List.iter (fun e -> spr ctx "case "; gen_value ctx e; spr ctx ":"; ) el; gen_block ctx e2; print ctx "break"; newline ctx; ) cases; (match def with | None -> () | Some e -> spr ctx "default:"; gen_block ctx e; print ctx "break"; newline ctx; ); spr ctx "}" | TCast (e1,None) -> let s = type_str ctx e.etype e.epos in if s = "*" then gen_expr ctx e1 else begin spr ctx "(("; gen_value ctx e1; print ctx ") as %s)" s end | TCast (e1,Some t) -> gen_expr ctx (Codegen.default_cast ctx.inf.com e1 t e.etype e.epos) and gen_block_element ctx e = match e.eexpr with | TObjectDecl fl -> List.iter (fun (_,e) -> gen_block_element ctx e) fl | _ -> block_newline ctx; gen_expr ctx e and gen_block ctx e = newline ctx; match e.eexpr with | TBlock [] -> () | _ -> gen_expr ctx e; newline ctx and gen_value ctx e = let assign e = mk (TBinop (Ast.OpAssign, mk (TLocal (match ctx.in_value with None -> assert false | Some r -> r)) t_dynamic e.epos, e )) e.etype e.epos in let block e = mk (TBlock [e]) e.etype e.epos in let value block = let old = ctx.in_value in let t = type_str ctx e.etype e.epos in let r = alloc_var (gen_local ctx "$r") e.etype e.epos in ctx.in_value <- Some r; if ctx.in_static then print ctx "function() : %s " t else print ctx "(function($this:%s) : %s " (snd ctx.path) t; let b = if block then begin spr ctx "{"; let b = open_block ctx in newline ctx; print ctx "var %s : %s" r.v_name t; newline ctx; b end else (fun() -> ()) in (fun() -> if block then begin newline ctx; print ctx "return %s" r.v_name; b(); newline ctx; spr ctx "}"; end; ctx.in_value <- old; if ctx.in_static then print ctx "()" else print ctx "(%s))" (this ctx) ) in match e.eexpr with | TCall ({ eexpr = TLocal { v_name = "__keys__" } },_) | TCall ({ eexpr = TLocal { v_name = "__hkeys__" } },_) -> let v = value true in gen_expr ctx e; v() | TConst _ | TLocal _ | TArray _ | TBinop _ | TField _ | TEnumParameter _ | TTypeExpr _ | TParenthesis _ | TObjectDecl _ | TArrayDecl _ | TCall _ | TNew _ | TUnop _ | TFunction _ -> gen_expr ctx e | TMeta (_,e1) -> gen_value ctx e1 | TCast (e1,None) -> let s = type_str ctx e.etype e1.epos in begin match s with | "*" -> gen_value ctx e1 | "Function" | "Array" | "String" -> spr ctx "(("; gen_value ctx e1; print ctx ") as %s)" s; | _ -> print ctx "%s(" s; gen_value ctx e1; spr ctx ")"; end | TCast (e1,Some t) -> gen_value ctx (Codegen.default_cast ctx.inf.com e1 t e.etype e.epos) | TReturn _ | TBreak | TContinue -> unsupported e.epos | TVar _ | TFor _ | TWhile _ | TThrow _ -> (* value is discarded anyway *) let v = value true in gen_expr ctx e; v() | TBlock [] -> spr ctx "null" | TBlock [e] -> gen_value ctx e | TBlock el -> let v = value true in let rec loop = function | [] -> spr ctx "return null"; | [e] -> gen_expr ctx (assign e); | e :: l -> gen_expr ctx e; newline ctx; loop l in loop el; v(); | TIf (cond,e,eo) -> spr ctx "("; gen_value ctx cond; spr ctx "?"; gen_value ctx e; spr ctx ":"; (match eo with | None -> spr ctx "null" | Some e -> gen_value ctx e); spr ctx ")" | TSwitch (cond,cases,def) -> let v = value true in gen_expr ctx (mk (TSwitch (cond, List.map (fun (e1,e2) -> (e1,assign e2)) cases, match def with None -> None | Some e -> Some (assign e) )) e.etype e.epos); v() | TTry (b,catchs) -> let v = value true in gen_expr ctx (mk (TTry (block (assign b), List.map (fun (v,e) -> v, block (assign e)) catchs )) e.etype e.epos); v() let final m = if Meta.has Meta.Final m then " final " else "" let generate_field ctx static f = newline ctx; ctx.in_static <- static; ctx.gen_uid <- 0; List.iter (fun(m,pl,_) -> match m,pl with | Meta.Meta, [Ast.ECall ((Ast.EConst (Ast.Ident n),_),args),_] -> let mk_arg (a,p) = match a with | Ast.EConst (Ast.String s) -> (None, s) | Ast.EBinop (Ast.OpAssign,(Ast.EConst (Ast.Ident n),_),(Ast.EConst (Ast.String s),_)) -> (Some n, s) | _ -> abort "Invalid meta definition" p in print ctx "[%s" n; (match args with | [] -> () | _ -> print ctx "("; concat ctx "," (fun a -> match mk_arg a with | None, s -> gen_constant ctx (snd a) (TString s) | Some s, e -> print ctx "%s=" s; gen_constant ctx (snd a) (TString e) ) args; print ctx ")"); print ctx "]"; | _ -> () ) f.cf_meta; let public = f.cf_public || Hashtbl.mem ctx.get_sets (f.cf_name,static) || (f.cf_name = "main" && static) || f.cf_name = "resolve" || Meta.has Meta.Public f.cf_meta (* consider all abstract methods public to avoid issues with inlined private access *) || (match ctx.curclass.cl_kind with KAbstractImpl _ -> true | _ -> false) in let rights = (if static then "static " else "") ^ (if public then "public" else "protected") in let p = ctx.curclass.cl_pos in match f.cf_expr, f.cf_kind with | Some { eexpr = TFunction fd }, Method (MethNormal | MethInline) -> print ctx "%s%s " rights (if static then "" else final f.cf_meta); let rec loop c = match c.cl_super with | None -> () | Some (c,_) -> if PMap.mem f.cf_name c.cl_fields then spr ctx "override " else loop c in if not static then loop ctx.curclass; let h = gen_function_header ctx (Some (s_ident f.cf_name, f.cf_meta)) fd f.cf_params p in gen_expr ctx fd.tf_expr; h(); newline ctx | _ -> let is_getset = (match f.cf_kind with Var { v_read = AccCall } | Var { v_write = AccCall } -> true | _ -> false) in if ctx.curclass.cl_interface then match follow f.cf_type with | TFun (args,r) when (match f.cf_kind with Method MethDynamic | Var _ -> false | _ -> true) -> let rec loop = function | [] -> f.cf_name | (Meta.Getter,[Ast.EConst (Ast.String name),_],_) :: _ -> "get " ^ name | (Meta.Setter,[Ast.EConst (Ast.String name),_],_) :: _ -> "set " ^ name | _ :: l -> loop l in print ctx "function %s(" (loop f.cf_meta); concat ctx "," (fun (arg,o,t) -> let tstr = type_str ctx t p in print ctx "%s : %s" arg tstr; if o then print ctx " = %s" (default_value tstr); ) args; print ctx ") : %s " (type_str ctx r p); | _ -> () else let gen_init () = match f.cf_expr with | None -> () | Some e -> if not static || (match e.eexpr with | TConst _ | TFunction _ | TTypeExpr _ -> true | _ -> false) then begin print ctx " = "; gen_value ctx e end else Codegen.ExtClass.add_static_init ctx.curclass f e e.epos in if is_getset then begin let t = type_str ctx f.cf_type p in let id = s_ident f.cf_name in let v = (match f.cf_kind with Var v -> v | _ -> assert false) in (match v.v_read with | AccNormal | AccNo | AccNever -> print ctx "%s function get %s() : %s { return $%s; }" rights id t id; newline ctx | AccCall -> print ctx "%s function get %s() : %s { return %s(); }" rights id t ("get_" ^ f.cf_name); newline ctx | _ -> ()); (match v.v_write with | AccNormal | AccNo | AccNever -> print ctx "%s function set %s( __v : %s ) : void { $%s = __v; }" rights id t id; newline ctx | AccCall -> print ctx "%s function set %s( __v : %s ) : void { %s(__v); }" rights id t ("set_" ^ f.cf_name); newline ctx | _ -> ()); print ctx "%sprotected var $%s : %s" (if static then "static " else "") (s_ident f.cf_name) (type_str ctx f.cf_type p); gen_init() end else begin print ctx "%s var %s : %s" rights (s_ident f.cf_name) (type_str ctx f.cf_type p); gen_init() end let rec define_getset ctx stat c = let def f name = Hashtbl.add ctx.get_sets (name,stat) f.cf_name in let field f = match f.cf_kind with | Method _ -> () | Var v -> (match v.v_read with AccCall -> def f ("get_" ^ f.cf_name) | _ -> ()); (match v.v_write with AccCall -> def f ("set_" ^ f.cf_name) | _ -> ()) in List.iter field (if stat then c.cl_ordered_statics else c.cl_ordered_fields); match c.cl_super with | Some (c,_) when not stat -> define_getset ctx stat c | _ -> () let generate_class ctx c = ctx.curclass <- c; define_getset ctx true c; define_getset ctx false c; ctx.local_types <- List.map snd c.cl_params; let pack = open_block ctx in print ctx "\tpublic %s%s%s %s " (final c.cl_meta) (match c.cl_dynamic with None -> "" | Some _ -> if c.cl_interface then "" else "dynamic ") (if c.cl_interface then "interface" else "class") (snd c.cl_path); (match c.cl_super with | None -> () | Some (csup,_) -> print ctx "extends %s " (s_path ctx true csup.cl_path c.cl_pos)); (match c.cl_implements with | [] -> () | l -> spr ctx (if c.cl_interface then "extends " else "implements "); concat ctx ", " (fun (i,_) -> print ctx "%s" (s_path ctx true i.cl_path c.cl_pos)) l); spr ctx "{"; let cl = open_block ctx in (match c.cl_constructor with | None -> () | Some f -> let f = { f with cf_name = snd c.cl_path; cf_public = true; cf_kind = Method MethNormal; } in ctx.constructor_block <- true; generate_field ctx false f; ); List.iter (generate_field ctx false) c.cl_ordered_fields; List.iter (generate_field ctx true) c.cl_ordered_statics; let has_init = match c.cl_init with | None -> false | Some e -> newline ctx; spr ctx "static static_init function init() : void"; gen_expr ctx (mk_block e); true; in cl(); newline ctx; print ctx "}"; pack(); newline ctx; print ctx "}"; if has_init then begin newline ctx; spr ctx "namespace static_init"; newline ctx; print ctx "%s.static_init::init()" (s_path ctx true ctx.curclass.cl_path Globals.null_pos); end; newline ctx; if c.cl_interface && Meta.has (Meta.Custom ":hasMetadata") c.cl_meta then begin (* we have to reference the metadata class in order for it to be compiled *) let path = fst c.cl_path,snd c.cl_path ^ "_HxMeta" in spr ctx (Globals.s_type_path path); newline ctx end let generate_main ctx inits = ctx.curclass <- { null_class with cl_path = [],"__main__" }; let pack = open_block ctx in print ctx "\timport flash.Lib"; newline ctx; print ctx "public class __main__ extends %s {" (s_path ctx true (["flash"],"Boot") Globals.null_pos); let cl = open_block ctx in newline ctx; spr ctx "public function __main__() {"; let fl = open_block ctx in newline ctx; spr ctx "super()"; newline ctx; spr ctx "flash.Lib.current = this"; List.iter (fun e -> newline ctx; gen_expr ctx e) inits; fl(); newline ctx; print ctx "}"; cl(); newline ctx; print ctx "}"; pack(); newline ctx; print ctx "}"; newline ctx let generate_enum ctx e = ctx.local_types <- List.map snd e.e_params; let pack = open_block ctx in let ename = snd e.e_path in print ctx "\tpublic final class %s extends enum {" ename; let cl = open_block ctx in newline ctx; print ctx "public static const __isenum : Boolean = true"; newline ctx; print ctx "public function %s( t : String, index : int, p : Array = null ) : void { this.tag = t; this.index = index; this.params = p; }" ename; PMap.iter (fun _ c -> newline ctx; match c.ef_type with | TFun (args,_) -> print ctx "public static function %s(" c.ef_name; concat ctx ", " (fun (a,o,t) -> print ctx "%s : %s" (s_ident a) (type_str ctx t c.ef_pos); if o then spr ctx " = null"; ) args; print ctx ") : %s {" ename; print ctx " return new %s(\"%s\",%d,[" ename c.ef_name c.ef_index; concat ctx "," (fun (a,_,_) -> spr ctx (s_ident a)) args; print ctx "]); }"; | _ -> print ctx "public static var %s : %s = new %s(\"%s\",%d)" c.ef_name ename ename c.ef_name c.ef_index; ) e.e_constrs; newline ctx; (match Codegen.build_metadata ctx.inf.com (TEnumDecl e) with | None -> () | Some e -> print ctx "public static var __meta__ : * = "; gen_expr ctx e; newline ctx); print ctx "public static var __constructs__ : Array = [%s];" (String.concat "," (List.map (fun s -> "\"" ^ Ast.s_escape s ^ "\"") e.e_names)); cl(); newline ctx; print ctx "}"; pack(); newline ctx; print ctx "}"; newline ctx let generate_base_enum ctx = let pack = open_block ctx in spr ctx "\timport flash.Boot"; newline ctx; spr ctx "public class enum {"; let cl = open_block ctx in newline ctx; spr ctx "public var tag : String"; newline ctx; spr ctx "public var index : int"; newline ctx; spr ctx "public var params : Array"; newline ctx; spr ctx "public function toString() : String { return flash.Boot.enum_to_string(this); }"; cl(); newline ctx; print ctx "}"; pack(); newline ctx; print ctx "}"; newline ctx let generate com = let infos = { com = com; } in generate_resources infos; let ctx = init infos ([],"enum") in generate_base_enum ctx; close ctx; let inits = ref [] in List.iter (fun t -> match t with | TClassDecl c -> let c = (match c.cl_path with | ["flash"],"FlashXml__" -> { c with cl_path = [],"Xml" } | (pack,name) -> { c with cl_path = (pack,protect name) } ) in if c.cl_extern then (match c.cl_init with | None -> () | Some e -> inits := e :: !inits) else let ctx = init infos c.cl_path in generate_class ctx c; close ctx | TEnumDecl e -> let pack,name = e.e_path in let e = { e with e_path = (pack,protect name) } in if e.e_extern then () else let ctx = init infos e.e_path in generate_enum ctx e; close ctx | TTypeDecl _ | TAbstractDecl _ -> () ) com.types; (match com.main with | None -> () | Some e -> inits := e :: !inits); let ctx = init infos ([],"__main__") in generate_main ctx (List.rev !inits); close ctx haxe_3.4.4.orig/src/generators/gencommon.ml0000664000175000017500000135771013166552354020706 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) (* Gen Common API This is the key module for generation of Java and C# sources In order for both modules to share as much code as possible, some rules were devised: - every feature has its own submodule, and may contain the following methods: - configure sets all the configuration variables for the module to run. If a module has this method, it *should* be called once before running any filter - run_filter -> runs the filter immediately on the context - add_filter -> adds the filter to an expr->expr list. Most filter modules will provide this option so the filter function can only run once. - most submodules will have side-effects so the order of operations will matter. When running configure / add_filter this might be taken care of with the rule-based dispatch system working underneath, but still there might be some incompatibilities. There will be an effort to document it. The modules can hint on the order by suffixing their functions with _first or _last. - any of those methods might have different parameters, that configure how the filter will run. For example, a simple filter that maps switch() expressions to if () .. else if... might receive a function that filters what content should be mapped - Other targets can use those filters on their own code. In order to do that, a simple configuration step is needed: you need to initialize a generator_ctx type with Gencommon.new_gen (context:Common.context) with a generator_ctx context you will be able to add filters to your code, and execute them with Gencommon.run_filters (gen_context:Gencommon.generator_ctx) After running the filters, you can run your own generator normally. (* , or you can run Gencommon.generate_modules (gen_context:Gencommon.generator_ctx) (extension:string) (module_gen:module_type list->bool) where module_gen will take a whole module (can be *) *) open Unix open Ast open Type open Common open Globals open Option open Printf open ExtString open Codegen open Overloads let alloc_var n t = alloc_var n t null_pos let debug_type_ctor = function | TMono _ -> "TMono" | TEnum _ -> "TEnum" | TInst _ -> "TInst" | TType _ -> "TType" | TFun _ -> "TFun" | TAnon _ -> "TAnon" | TDynamic _ -> "TDynamic" | TLazy _ -> "TLazy" | TAbstract _ -> "TAbstract" let debug_type = (s_type (print_context())) let debug_expr = s_expr debug_type let rec like_float t = match follow t with | TAbstract({ a_path = ([], "Float") },[]) | TAbstract({ a_path = ([], "Int") },[]) -> true | TAbstract({ a_path = (["cs"], "Pointer") },_) -> false | TAbstract(a, _) -> List.exists (fun t -> like_float t) a.a_from || List.exists (fun t -> like_float t) a.a_to | _ -> false let rec like_int t = match follow t with | TAbstract({ a_path = ([], "Int") },[]) -> true | TAbstract({ a_path = (["cs"], "Pointer") },_) -> false | TAbstract(a, _) -> List.exists (fun t -> like_int t) a.a_from || List.exists (fun t -> like_int t) a.a_to | _ -> false let rec like_i64 t = match follow t with | TAbstract({ a_path = (["cs"], "Int64") },[]) | TAbstract({ a_path = (["cs"], "UInt64") },[]) | TAbstract({ a_path = (["java"], "Int64") },[]) | TAbstract({ a_path = (["haxe"], "Int64") },[]) -> true | TAbstract(a, _) -> List.exists (fun t -> like_i64 t) a.a_from || List.exists (fun t -> like_i64 t) a.a_to | _ -> false let follow_once t = match t with | TMono r -> (match !r with | Some t -> t | _ -> t_dynamic (* avoid infinite loop / should be the same in this context *)) | TLazy f -> !f() | TType (t,tl) -> apply_params t.t_params tl t.t_type | _ -> t let t_empty = TAnon({ a_fields = PMap.empty; a_status = ref (Closed) }) let tmp_count = ref 0 let reset_temps () = tmp_count := 0 (* the undefined is a special var that works like null, but can have special meaning *) let v_undefined = alloc_var "__undefined__" t_dynamic let undefined pos = ExprBuilder.make_local v_undefined pos let path_of_md_def md_def = match md_def.m_types with | [TClassDecl c] -> c.cl_path | _ -> md_def.m_path (* ******************************************* *) (* common helpers *) (* ******************************************* *) let assertions = false (* when assertions == true, many assertions will be made to guarantee the quality of the data input *) let debug_mode = ref false let trace s = if !debug_mode then print_endline s else () let timer name = if !debug_mode then Common.timer name else fun () -> () let is_string t = match follow t with | TInst({ cl_path = ([], "String") }, []) -> true | _ -> false (* helper function for creating Anon types of class / enum modules *) let anon_of_classtype cl = TAnon { a_fields = cl.cl_statics; a_status = ref (Statics cl) } let anon_of_enum e = TAnon { a_fields = PMap.empty; a_status = ref (EnumStatics e) } let anon_of_abstract a = TAnon { a_fields = PMap.empty; a_status = ref (AbstractStatics a) } let anon_of_mt mt = match mt with | TClassDecl cl -> anon_of_classtype cl | TEnumDecl e -> anon_of_enum e | TAbstractDecl a -> anon_of_abstract a | _ -> assert false let anon_class t = match follow t with | TAnon anon -> (match !(anon.a_status) with | Statics cl -> Some(TClassDecl cl) | EnumStatics e -> Some(TEnumDecl e) | AbstractStatics a -> Some(TAbstractDecl a) | _ -> None) | _ -> None let rec t_to_md t = match t with | TInst (cl,_) -> TClassDecl cl | TEnum (e,_) -> TEnumDecl e | TType (t,_) -> TTypeDecl t | TAbstract (a,_) -> TAbstractDecl a | TAnon anon -> (match !(anon.a_status) with | EnumStatics e -> TEnumDecl e | Statics cl -> TClassDecl cl | AbstractStatics a -> TAbstractDecl a | _ -> assert false) | TLazy f -> t_to_md (!f()) | TMono r -> (match !r with | Some t -> t_to_md t | None -> assert false) | _ -> assert false let get_cl mt = match mt with | TClassDecl cl -> cl | _ -> failwith (Printf.sprintf "Unexpected module type (class expected) for %s: %s" (s_type_path (t_path mt)) (s_module_type_kind mt)) let get_abstract mt = match mt with | TAbstractDecl a -> a | _ -> failwith (Printf.sprintf "Unexpected module type (abstract expected) for %s: %s" (s_type_path (t_path mt)) (s_module_type_kind mt)) let get_tdef mt = match mt with | TTypeDecl t -> t | _ -> assert false let mk_mt_access mt pos = { eexpr = TTypeExpr(mt); etype = anon_of_mt mt; epos = pos } let mk_local = ExprBuilder.make_local (* this function is used by CastDetection module *) let get_fun t = match follow t with | TFun(r1,r2) -> (r1,r2) | t -> (trace (debug_type t)); assert false let mk_cast t e = Type.mk_cast e t e.epos (** TODO: when adding new AST, make a new cast type for those fast casts. For now, we're using this hack * of using null_class to tell a fast cast from a normal one. Also note that this only works since both * C# and Java do not use the second part of TCast for anything *) let mk_castfast t e = { e with eexpr = TCast(e, Some (TClassDecl null_class)); etype = t } let mk_static_field_access_infer cl field pos params = try let cf = (PMap.find field cl.cl_statics) in { eexpr = TField(ExprBuilder.make_static_this cl pos, FStatic(cl, cf)); etype = (if params = [] then cf.cf_type else apply_params cf.cf_params params cf.cf_type); epos = pos } with | Not_found -> failwith ("Cannot find field " ^ field ^ " in type " ^ (s_type_path cl.cl_path)) let mk_static_field_access cl field fieldt pos = { (mk_static_field_access_infer cl field pos []) with etype = fieldt } (* stolen from Hugh's sources ;-) *) (* this used to be a class, but there was something in there that crashed ocaml native compiler in windows *) module SourceWriter = struct type source_writer = { sw_buf : Buffer.t; mutable sw_has_content : bool; mutable sw_indent : string; mutable sw_indents : string list; } let new_source_writer () = { sw_buf = Buffer.create 0; sw_has_content = false; sw_indent = ""; sw_indents = []; } let add_writer w_write w_read = Buffer.add_buffer w_read.sw_buf w_write.sw_buf let contents w = Buffer.contents w.sw_buf let len w = Buffer.length w.sw_buf let write w x = (if not w.sw_has_content then begin w.sw_has_content <- true; Buffer.add_string w.sw_buf w.sw_indent; Buffer.add_string w.sw_buf x; end else Buffer.add_string w.sw_buf x); let len = (String.length x)-1 in if len >= 0 && String.get x len = '\n' then begin w.sw_has_content <- false end else w.sw_has_content <- true let push_indent w = w.sw_indents <- "\t"::w.sw_indents; w.sw_indent <- String.concat "" w.sw_indents let pop_indent w = match w.sw_indents with | h::tail -> w.sw_indents <- tail; w.sw_indent <- String.concat "" w.sw_indents | [] -> w.sw_indent <- "/*?*/" let newline w = write w "\n" let begin_block w = (if w.sw_has_content then newline w); write w "{"; push_indent w; newline w let end_block w = pop_indent w; (if w.sw_has_content then newline w); write w "}"; newline w let print w = (if not w.sw_has_content then begin w.sw_has_content <- true; Buffer.add_string w.sw_buf w.sw_indent end); bprintf w.sw_buf; end;; (* rule_dispatcher's priority *) type priority = | PFirst | PLast | PZero | PCustom of float exception DuplicateName of string exception NoRulesApplied let indent = ref [] (* the rule dispatcher is the primary way to deal with distributed "plugins" *) (* we will define rules that will form a distributed / extensible match system *) class ['tp, 'ret] rule_dispatcher name ignore_not_found = object(self) val tbl = Hashtbl.create 16 val mutable keys = [] val names = Hashtbl.create 16 val mutable temp = 0 method add ?(name : string option) (* name helps debugging *) ?(priority : priority = PZero) (rule : 'tp->'ret option) = let p = match priority with | PFirst -> infinity | PLast -> neg_infinity | PZero -> 0.0 | PCustom i -> i in let q = if not( Hashtbl.mem tbl p ) then begin let q = Stack.create() in Hashtbl.add tbl p q; keys <- p :: keys; keys <- List.sort (fun x y -> - (compare x y)) keys; q end else Hashtbl.find tbl p in let name = match name with | None -> temp <- temp + 1; "$_" ^ (string_of_int temp) | Some s -> s in (if Hashtbl.mem names name then raise (DuplicateName(name))); Hashtbl.add names name q; Stack.push (name, rule) q method describe = Hashtbl.iter (fun s _ -> (trace s)) names; method remove (name : string) = if Hashtbl.mem names name then begin let q = Hashtbl.find names name in let q_temp = Stack.create () in Stack.iter (function | (n, _) when n = name -> () | _ as r -> Stack.push r q_temp ) q; Stack.clear q; Stack.iter (fun r -> Stack.push r q) q_temp; Hashtbl.remove names name; true end else false method run_f tp = get (self#run tp) method did_run tp = is_some (self#run tp) method get_list = let ret = ref [] in List.iter (fun key -> let q = Hashtbl.find tbl key in Stack.iter (fun (_, rule) -> ret := rule :: !ret) q ) keys; List.rev !ret method run_from (priority:float) (tp:'tp) : 'ret option = let ok = ref ignore_not_found in let ret = ref None in indent := "\t" :: !indent; (try begin List.iter (fun key -> if key < priority then begin let q = Hashtbl.find tbl key in Stack.iter (fun (n, rule) -> let t = if !debug_mode then Common.timer [("rule dispatcher rule: " ^ n)] else fun () -> () in let r = rule(tp) in t(); if is_some r then begin ret := r; raise Exit end ) q end ) keys end with Exit -> ok := true); (match !indent with | [] -> () | h::t -> indent := t); (if not (!ok) then raise NoRulesApplied); !ret method run (tp:'tp) : 'ret option = self#run_from infinity tp end;; (* this is a special case where tp = tret and you stack their output as the next's input *) class ['tp] rule_map_dispatcher name = object(self) inherit ['tp, 'tp] rule_dispatcher name true as super method run_f tp = get (self#run tp) method run_from (priority:float) (tp:'tp) : 'ret option = let cur = ref tp in (try begin List.iter (fun key -> if key < priority then begin let q = Hashtbl.find tbl key in Stack.iter (fun (n, rule) -> trace ("running rule " ^ n); let t = if !debug_mode then Common.timer [("rule map dispatcher rule: " ^ n)] else fun () -> () in let r = rule(!cur) in t(); if is_some r then begin cur := get r end ) q end ) keys end with Exit -> ()); Some (!cur) end;; type generator_ctx = { (* these are the basic context fields. If another target is using this context, *) (* this is all you need to care about *) gcon : Common.context; gclasses : gen_classes; gtools : gen_tools; (* configurable function that receives a desired name and makes it "internal", doing the best to ensure that it will not be called from outside. To avoid name clashes between internal names, user must specify two strings: a "namespace" and the name itself *) gmk_internal_name : string->string->string; (* module filters run before module filters and they should generate valid haxe syntax as a result. Module filters shouldn't go through the expressions as it adds an unnecessary burden to the GC, and it can all be done in a single step with gexpr_filters and proper priority selection. As a convention, Module filters should end their name with Modf, so they aren't mistaken with expression filters *) gmodule_filters : (module_type) rule_map_dispatcher; (* expression filters are the most common filters to be applied. They should also generate only valid haxe expressions, so e.g. calls to non-existant methods should be avoided, although there are some ways around them (like gspecial_methods) *) gexpr_filters : (texpr) rule_map_dispatcher; (* syntax filters are also expression filters but they no longer require that the resulting expressions be valid haxe expressions. They then have no guarantee that either the input expressions or the output one follow the same rules as normal haxe code. *) gsyntax_filters : (texpr) rule_map_dispatcher; (* these are more advanced features, but they would require a rewrite of targets *) (* they are just helpers to ditribute functions like "follow" or "type to string" *) (* so adding a module will already take care of correctly following a certain type of *) (* variable, for example *) (* follows the type through typedefs, lazy typing, etc. *) (* it's the place to put specific rules to handle typedefs, like *) (* other basic types like UInt *) gfollow : (t, t) rule_dispatcher; gtypes : (path, module_type) Hashtbl.t; mutable gtypes_list : module_type list; mutable gmodules : Type.module_def list; (* cast detection helpers / settings *) (* this is a cache for all field access types *) greal_field_types : (path * string, (tclass_field (* does the cf exist *) * t (*cf's type in relation to current class type params *) * t * tclass (* declared class *) ) option) Hashtbl.t; (* this function allows any code to handle casts as if it were inside the cast_detect module *) mutable ghandle_cast : t->t->texpr->texpr; (* when an unsafe cast is made, we can warn the user *) mutable gon_unsafe_cast : t->t->pos->unit; (* does this type needs to be boxed? Normally always false, unless special type handling must be made *) mutable gneeds_box : t->bool; (* does this 'special type' needs cast to this other type? *) (* this is here so we can implement custom behavior for "opaque" typedefs *) mutable gspecial_needs_cast : t->t->bool; (* sometimes we may want to support unrelated conversions on cast detection *) (* for example, haxe.lang.Null -> T on C# *) (* every time an unrelated conversion is found, each to/from path is searched on this hashtbl *) (* if found, the function will be executed with from_type, to_type. If returns true, it means that *) (* it is a supported conversion, and the unsafe cast routine changes to a simple cast *) gsupported_conversions : (path, t->t->bool) Hashtbl.t; (* API for filters *) (* add type can be called at any time, and will add a new module_def that may or may not be filtered *) (* module_type -> should_filter *) mutable gadd_type : module_type -> bool -> unit; (* during expr filters, add_to_module will be available so module_types can be added to current module_def. we must pass the priority argument so the filters can be resumed *) mutable gadd_to_module : module_type -> float -> unit; (* during expr filters, shows the current class path *) mutable gcurrent_path : path; (* current class *) mutable gcurrent_class : tclass option; (* current class field, if any *) mutable gcurrent_classfield : tclass_field option; (* events *) (* is executed once every new classfield *) mutable gon_classfield_start : (unit -> unit) list; (* is executed once every new module type *) mutable gon_new_module_type : (unit -> unit) list; (* after module filters ended *) mutable gafter_mod_filters_ended : (unit -> unit) list; (* after expression filters ended *) mutable gafter_expr_filters_ended : (unit -> unit) list; (* after all filters are run *) mutable gafter_filters_ended : (unit -> unit) list; mutable gbase_class_fields : (string, tclass_field) PMap.t; (* real type is the type as it is read by the target. *) (* This function is here because most targets don't have *) (* a 1:1 translation between haxe types and its native types *) (* But types aren't changed to this representation as we might lose *) (* some valuable type information in the process *) mutable greal_type : t -> t; (* the same as greal_type but for type parameters. *) mutable greal_type_param : module_type -> tparams -> tparams; (* is the type a value type? This may be used in some optimizations where reference types and value types are handled differently. At first the default is very good to use, and if tweaks are needed, it's best to be done by adding @:struct meta to the value types * mutable gis_value_type : t -> bool;*) (* misc configuration *) (* Should the target allow type parameter dynamic conversion, or should we add a cast to those cases as well? *) mutable gallow_tp_dynamic_conversion : bool; (* internal apis *) (* param_func_call : used by TypeParams and CastDetection *) mutable gparam_func_call : texpr->texpr->tparams->texpr list->texpr; (* does it already have a type parameter cast handler? This is used by CastDetect to know if it should handle type parameter casts *) mutable ghas_tparam_cast_handler : bool; (* type parameter casts - special cases *) (* function cast_from, cast_to -> texpr *) gtparam_cast : (path, (texpr->t->texpr)) Hashtbl.t; (* special vars are used for adding special behavior to *) gspecial_vars : (string, bool) Hashtbl.t; } and gen_classes = { cl_reflect : tclass; cl_type : tclass; cl_dyn : tclass; mutable nativearray_len : texpr -> pos -> texpr; mutable nativearray_type : Type.t -> Type.t; mutable nativearray : Type.t -> Type.t; } (* add here all reflection transformation additions *) and gen_tools = { (* Reflect.fields(). The bool is if we are iterating in a read-only manner. If it is read-only we might not need to allocate a new array *) r_fields : bool->texpr->texpr; (* (first argument = return type. should be void in most cases) Reflect.setField(obj, field, val) *) r_set_field : t->texpr->texpr->texpr->texpr; (* Reflect.field. bool indicates if is safe (no error throwing) or unsafe; t is the expected return type true = safe *) r_field : bool->t->texpr->texpr->texpr; (* return an expression that creates an unitialized instance of a class, used for the generic cast helper method. *) mutable r_create_empty : tclass->tparams->pos->texpr; } let get_type types path = List.find (fun md -> match md with | TClassDecl cl when cl.cl_path = path -> true | TEnumDecl e when e.e_path = path -> true | TTypeDecl t when t.t_path = path -> true | TAbstractDecl a when a.a_path = path -> true | _ -> false ) types let new_ctx con = let types = Hashtbl.create (List.length con.types) in List.iter (fun mt -> match mt with | TClassDecl cl -> Hashtbl.add types cl.cl_path mt | TEnumDecl e -> Hashtbl.add types e.e_path mt | TTypeDecl t -> Hashtbl.add types t.t_path mt | TAbstractDecl a -> Hashtbl.add types a.a_path mt ) con.types; let cl_dyn = match get_type con.types ([], "Dynamic") with | TClassDecl c -> c | TAbstractDecl a -> mk_class a.a_module ([], "Dynamic") a.a_pos null_pos | _ -> assert false in let rec gen = { gcon = con; gclasses = { cl_reflect = get_cl (get_type con.types ([], "Reflect")); cl_type = get_cl (get_type con.types ([], "Type")); cl_dyn = cl_dyn; nativearray = (fun _ -> assert false); nativearray_type = (fun _ -> assert false); nativearray_len = (fun _ -> assert false); }; gtools = { r_fields = (fun is_used_only_by_iteration expr -> let fieldcall = mk_static_field_access_infer gen.gclasses.cl_reflect "fields" expr.epos [] in { eexpr = TCall(fieldcall, [expr]); etype = gen.gcon.basic.tarray gen.gcon.basic.tstring; epos = expr.epos } ); (* Reflect.setField(obj, field, val). t by now is ignored. FIXME : fix this implementation *) r_set_field = (fun t obj field v -> let fieldcall = mk_static_field_access_infer gen.gclasses.cl_reflect "setField" v.epos [] in { eexpr = TCall(fieldcall, [obj; field; v]); etype = t_dynamic; epos = v.epos } ); (* Reflect.field. bool indicates if is safe (no error throwing) or unsafe. true = safe *) r_field = (fun is_safe t obj field -> let fieldcall = mk_static_field_access_infer gen.gclasses.cl_reflect "field" obj.epos [] in (* FIXME: should we see if needs to cast? *) mk_cast t { eexpr = TCall(fieldcall, [obj; field]); etype = t_dynamic; epos = obj.epos } ); r_create_empty = (fun _ _ pos -> gen.gcon.error "r_create_empty implementation is not provided" pos; assert false); }; gmk_internal_name = (fun ns s -> sprintf "__%s_%s" ns s); gexpr_filters = new rule_map_dispatcher "gexpr_filters"; gmodule_filters = new rule_map_dispatcher "gmodule_filters"; gsyntax_filters = new rule_map_dispatcher "gsyntax_filters"; gfollow = new rule_dispatcher "gfollow" false; gtypes = types; gtypes_list = con.types; gmodules = con.modules; greal_field_types = Hashtbl.create 0; ghandle_cast = (fun to_t from_t e -> mk_cast to_t e); gon_unsafe_cast = (fun t t2 pos -> (gen.gcon.warning ("Type " ^ (debug_type t2) ^ " is being cast to the unrelated type " ^ (s_type (print_context()) t)) pos)); gneeds_box = (fun t -> false); gspecial_needs_cast = (fun to_t from_t -> true); gsupported_conversions = Hashtbl.create 0; gadd_type = (fun md should_filter -> if should_filter then begin gen.gtypes_list <- md :: gen.gtypes_list; gen.gmodules <- { m_id = alloc_mid(); m_path = (t_path md); m_types = [md]; m_extra = module_extra "" "" 0. MFake [] } :: gen.gmodules; Hashtbl.add gen.gtypes (t_path md) md; end else gen.gafter_filters_ended <- (fun () -> gen.gtypes_list <- md :: gen.gtypes_list; gen.gmodules <- { m_id = alloc_mid(); m_path = (t_path md); m_types = [md]; m_extra = module_extra "" "" 0. MFake [] } :: gen.gmodules; Hashtbl.add gen.gtypes (t_path md) md; ) :: gen.gafter_filters_ended; ); gadd_to_module = (fun md pr -> failwith "module added outside expr filters"); gcurrent_path = ([],""); gcurrent_class = None; gcurrent_classfield = None; gon_classfield_start = []; gon_new_module_type = []; gafter_mod_filters_ended = []; gafter_expr_filters_ended = []; gafter_filters_ended = []; gbase_class_fields = PMap.empty; greal_type = (fun t -> t); greal_type_param = (fun _ t -> t); gallow_tp_dynamic_conversion = false; (* as a default, ignore the params *) gparam_func_call = (fun ecall efield params elist -> { ecall with eexpr = TCall(efield, elist) }); ghas_tparam_cast_handler = false; gtparam_cast = Hashtbl.create 0; gspecial_vars = Hashtbl.create 0; } in gen let init_ctx gen = (* ultimately add a follow once handler as the last follow handler *) let follow_f = gen.gfollow#run in let follow t = match t with | TMono r -> (match !r with | Some t -> follow_f t | _ -> Some t) | TLazy f -> follow_f (!f()) | TType (t,tl) -> follow_f (apply_params t.t_params tl t.t_type) | _ -> Some t in gen.gfollow#add ~name:"final" ~priority:PLast follow (* run_follow (gen:generator_ctx) (t:t) *) let run_follow gen = gen.gfollow#run_f let reorder_modules gen = let modules = Hashtbl.create 20 in List.iter (fun md -> Hashtbl.add modules ( (t_infos md).mt_module ).m_path md ) gen.gtypes_list; gen.gmodules <- []; let processed = Hashtbl.create 20 in Hashtbl.iter (fun md_path md -> if not (Hashtbl.mem processed md_path) then begin Hashtbl.add processed md_path true; gen.gmodules <- { m_id = alloc_mid(); m_path = md_path; m_types = List.rev ( Hashtbl.find_all modules md_path ); m_extra = (t_infos md).mt_module.m_extra } :: gen.gmodules end ) modules let run_filters_from gen t filters = match t with | TClassDecl c -> trace (snd c.cl_path); gen.gcurrent_path <- c.cl_path; gen.gcurrent_class <- Some(c); List.iter (fun fn -> fn()) gen.gon_new_module_type; gen.gcurrent_classfield <- None; let rec process_field f = reset_temps(); gen.gcurrent_classfield <- Some(f); List.iter (fun fn -> fn()) gen.gon_classfield_start; trace f.cf_name; (match f.cf_expr with | None -> () | Some e -> f.cf_expr <- Some (List.fold_left (fun e f -> f e) e filters)); List.iter process_field f.cf_overloads; 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); gen.gcurrent_classfield <- None; (match c.cl_init with | None -> () | Some e -> c.cl_init <- Some (List.fold_left (fun e f -> f e) e filters)); | TEnumDecl _ | TTypeDecl _ | TAbstractDecl _ -> () let run_filters gen = let last_error = gen.gcon.error in let has_errors = ref false in gen.gcon.error <- (fun msg pos -> has_errors := true; last_error msg pos); (* first of all, we have to make sure that the filters won't trigger a major Gc collection *) let t = Common.timer ["gencommon_filters"] in (if Common.defined gen.gcon Define.GencommonDebug then debug_mode := true else debug_mode := false); let run_filters filter = let rec loop acc mds = match mds with | [] -> acc | md :: tl -> let filters = [ filter#run_f ] in let added_types = ref [] in gen.gadd_to_module <- (fun md_type priority -> gen.gtypes_list <- md_type :: gen.gtypes_list; added_types := (md_type, priority) :: !added_types ); run_filters_from gen md filters; let added_types = List.map (fun (t,p) -> run_filters_from gen t [ fun e -> get (filter#run_from p e) ]; if Hashtbl.mem gen.gtypes (t_path t) then begin let rec loop i = let p = t_path t in let new_p = (fst p, snd p ^ "_" ^ (string_of_int i)) in if Hashtbl.mem gen.gtypes new_p then loop (i+1) else match t with | TClassDecl cl -> cl.cl_path <- new_p | TEnumDecl e -> e.e_path <- new_p | TTypeDecl _ | TAbstractDecl _ -> () in loop 0 end; Hashtbl.add gen.gtypes (t_path t) t; t ) !added_types in loop (added_types @ (md :: acc)) tl in List.rev (loop [] gen.gtypes_list) in let run_mod_filter filter = let last_add_to_module = gen.gadd_to_module in let added_types = ref [] in gen.gadd_to_module <- (fun md_type priority -> Hashtbl.add gen.gtypes (t_path md_type) md_type; added_types := (md_type, priority) :: !added_types ); let rec loop processed not_processed = match not_processed with | hd :: tl -> (match hd with | TClassDecl c -> gen.gcurrent_class <- Some c | _ -> gen.gcurrent_class <- None); let new_hd = filter#run_f hd in let added_types_new = !added_types in added_types := []; let added_types = List.map (fun (t,p) -> get (filter#run_from p t) ) added_types_new in loop ( added_types @ (new_hd :: processed) ) tl | [] -> processed in let filtered = loop [] gen.gtypes_list in gen.gadd_to_module <- last_add_to_module; gen.gtypes_list <- List.rev (filtered) in run_mod_filter gen.gmodule_filters; List.iter (fun fn -> fn()) gen.gafter_mod_filters_ended; let last_add_to_module = gen.gadd_to_module in gen.gtypes_list <- run_filters gen.gexpr_filters; gen.gadd_to_module <- last_add_to_module; List.iter (fun fn -> fn()) gen.gafter_expr_filters_ended; (* Codegen.post_process gen.gtypes_list [gen.gexpr_filters#run_f]; *) gen.gtypes_list <- run_filters gen.gsyntax_filters; List.iter (fun fn -> fn()) gen.gafter_filters_ended; reorder_modules gen; t(); if !has_errors then raise (Abort("Compilation aborted with errors",null_pos)) (* ******************************************* *) (* basic generation module that source code compilation implementations can use *) (* ******************************************* *) let write_file gen w source_dir path extension out_files = let t = timer ["write";"file"] in let s_path = source_dir ^ "/" ^ (snd path) ^ "." ^ (extension) in (* create the folders if they don't exist *) mkdir_from_path s_path; let contents = SourceWriter.contents w in let should_write = if not (Common.defined gen.gcon Define.ReplaceFiles) && Sys.file_exists s_path then begin let in_file = open_in s_path in let old_contents = Std.input_all in_file in close_in in_file; contents <> old_contents end else true in if should_write then begin let f = open_out_bin s_path in output_string f contents; close_out f end; out_files := (Path.unique_full_path s_path) :: !out_files; t() let clean_files path excludes verbose = let rec iter_files pack dir path = try let file = Unix.readdir dir in if file <> "." && file <> ".." then begin let filepath = path ^ "/" ^ file in if (Unix.stat filepath).st_kind = S_DIR then let pack = pack @ [file] in iter_files (pack) (Unix.opendir filepath) filepath; try Unix.rmdir filepath with Unix.Unix_error (ENOTEMPTY,_,_) -> (); else if not (String.ends_with filepath ".meta") && not (List.mem (Path.unique_full_path filepath) excludes) then begin if verbose then print_endline ("Removing " ^ filepath); Sys.remove filepath end end; iter_files pack dir path with | End_of_file | Unix.Unix_error _ -> Unix.closedir dir in iter_files [] (Unix.opendir path) path let dump_descriptor gen name path_s module_s = let w = SourceWriter.new_source_writer () in (* dump called path *) SourceWriter.write w (Sys.getcwd()); SourceWriter.newline w; (* dump all defines. deprecated *) SourceWriter.write w "begin defines"; SourceWriter.newline w; PMap.iter (fun name _ -> SourceWriter.write w name; SourceWriter.newline w ) gen.gcon.defines; SourceWriter.write w "end defines"; SourceWriter.newline w; (* dump all defines with their values; keeping the old defines for compatibility *) SourceWriter.write w "begin defines_data"; SourceWriter.newline w; PMap.iter (fun name v -> SourceWriter.write w name; SourceWriter.write w "="; SourceWriter.write w v; SourceWriter.newline w ) gen.gcon.defines; SourceWriter.write w "end defines_data"; SourceWriter.newline w; (* dump all generated types *) SourceWriter.write w "begin modules"; SourceWriter.newline w; let main_paths = Hashtbl.create 0 in List.iter (fun md_def -> SourceWriter.write w "M "; SourceWriter.write w (path_s (path_of_md_def md_def)); SourceWriter.newline w; List.iter (fun m -> match m with | TClassDecl cl when not cl.cl_extern -> SourceWriter.write w "C "; let s = module_s m in Hashtbl.add main_paths cl.cl_path s; SourceWriter.write w (s); SourceWriter.newline w | TEnumDecl e when not e.e_extern -> SourceWriter.write w "E "; SourceWriter.write w (module_s m); SourceWriter.newline w | _ -> () (* still no typedef or abstract is generated *) ) md_def.m_types ) gen.gmodules; SourceWriter.write w "end modules"; SourceWriter.newline w; (* dump all resources *) (match gen.gcon.main_class with | Some path -> SourceWriter.write w "begin main"; SourceWriter.newline w; (try SourceWriter.write w (Hashtbl.find main_paths path) with | Not_found -> SourceWriter.write w (path_s path)); SourceWriter.newline w; SourceWriter.write w "end main"; SourceWriter.newline w | _ -> () ); SourceWriter.write w "begin resources"; SourceWriter.newline w; Hashtbl.iter (fun name _ -> SourceWriter.write w name; SourceWriter.newline w ) gen.gcon.resources; SourceWriter.write w "end resources"; SourceWriter.newline w; SourceWriter.write w "begin libs"; SourceWriter.newline w; let path file ext = if Sys.file_exists file then file else try Common.find_file gen.gcon file with | Not_found -> try Common.find_file gen.gcon (file ^ ext) with | Not_found -> file in if Common.platform gen.gcon Java then List.iter (fun (s,std,_,_,_) -> if not std then begin SourceWriter.write w (path s ".jar"); SourceWriter.newline w; end ) gen.gcon.java_libs else if Common.platform gen.gcon Cs then List.iter (fun (s,std,_,_) -> if not std then begin SourceWriter.write w (path s ".dll"); SourceWriter.newline w; end ) gen.gcon.net_libs; SourceWriter.write w "end libs"; SourceWriter.newline w; let args = gen.gcon.c_args in if args <> [] then begin SourceWriter.write w "begin opts"; SourceWriter.newline w; List.iter (fun opt -> SourceWriter.write w opt; SourceWriter.newline w) (List.rev args); SourceWriter.write w "end opts"; SourceWriter.newline w; end; let contents = SourceWriter.contents w in let f = open_out (gen.gcon.file ^ "/" ^ name) in output_string f contents; close_out f (* various helper functions *) let mk_paren e = match e.eexpr with | TParenthesis _ -> e | _ -> { e with eexpr=TParenthesis(e) } (* private *) let get_real_fun gen t = match follow t with | TFun(args,t) -> TFun(List.map (fun (n,o,t) -> n,o,gen.greal_type t) args, gen.greal_type t) | _ -> t let mk_return e = { eexpr = TReturn (Some e); etype = e.etype; epos = e.epos } let mk_temp gen name t = incr tmp_count; let name = gen.gmk_internal_name "temp" (name ^ (string_of_int !tmp_count)) in alloc_var name t let v_nativearray = alloc_var "__array__" t_dynamic let mk_nativearray_decl gen t el pos = { eexpr = TCall(mk_local v_nativearray pos, el); etype = gen.gclasses.nativearray t; epos = pos; } let ensure_local gen block name e = match e.eexpr with | TLocal _ -> e | _ -> let var = mk_temp gen name e.etype in block := { e with eexpr = TVar(var, Some e); etype = gen.gcon.basic.tvoid; } :: !block; { e with eexpr = TLocal var } let follow_module follow_func md = match md with | TClassDecl _ | TEnumDecl _ | TAbstractDecl _ -> md | TTypeDecl tdecl -> match (follow_func (TType(tdecl, List.map snd tdecl.t_params))) with | TInst(cl,_) -> TClassDecl cl | TEnum(e,_) -> TEnumDecl e | TType(t,_) -> TTypeDecl t | TAbstract(a,_) -> TAbstractDecl a | _ -> assert false (* hxgen means if the type was generated by haxe. If a type was generated by haxe, it means it will contain special constructs for speedy reflection, for example @see SetHXGen module *) let rec is_hxgen md = match md with | TClassDecl cl -> Meta.has Meta.HxGen cl.cl_meta | TEnumDecl e -> Meta.has Meta.HxGen e.e_meta | TTypeDecl t -> Meta.has Meta.HxGen t.t_meta || ( match follow t.t_type with | TInst(cl,_) -> is_hxgen (TClassDecl cl) | TEnum(e,_) -> is_hxgen (TEnumDecl e) | _ -> false ) | TAbstractDecl a -> Meta.has Meta.HxGen a.a_meta let is_hxgen_t t = match t with | TInst (cl, _) -> Meta.has Meta.HxGen cl.cl_meta | TEnum (e, _) -> Meta.has Meta.HxGen e.e_meta | TAbstract (a, _) -> Meta.has Meta.HxGen a.a_meta | TType (t, _) -> Meta.has Meta.HxGen t.t_meta | _ -> false let mt_to_t_dyn md = match md with | TClassDecl cl -> TInst(cl, List.map (fun _ -> t_dynamic) cl.cl_params) | TEnumDecl e -> TEnum(e, List.map (fun _ -> t_dynamic) e.e_params) | TAbstractDecl a -> TAbstract(a, List.map (fun _ -> t_dynamic) a.a_params) | TTypeDecl t -> TType(t, List.map (fun _ -> t_dynamic) t.t_params) let mt_to_t mt params = match mt with | TClassDecl (cl) -> TInst(cl, params) | TEnumDecl (e) -> TEnum(e, params) | TAbstractDecl a -> TAbstract(a, params) | _ -> assert false let t_to_mt t = match follow t with | TInst(cl, _) -> TClassDecl(cl) | TEnum(e, _) -> TEnumDecl(e) | TAbstract(a, _) -> TAbstractDecl a | _ -> assert false let rec get_last_ctor cl = Option.map_default (fun (super,_) -> if is_some super.cl_constructor then Some(get super.cl_constructor) else get_last_ctor super) None cl.cl_super let add_constructor cl cf = match cl.cl_constructor with | None -> cl.cl_constructor <- Some cf | Some ctor -> if ctor != cf && not (List.memq cf ctor.cf_overloads) then ctor.cf_overloads <- cf :: ctor.cf_overloads (* replace open TMonos with TDynamic *) let rec replace_mono t = match t with | TMono t -> (match !t with | None -> t := Some t_dynamic | Some _ -> ()) | TEnum (_,p) | TInst (_,p) | TType (_,p) | TAbstract (_,p) -> List.iter replace_mono p | TFun (args,ret) -> List.iter (fun (_,_,t) -> replace_mono t) args; replace_mono ret | TAnon _ | TDynamic _ -> () | TLazy f -> replace_mono (!f()) (* helper *) let mk_class_field name t public pos kind params = { cf_name = name; cf_type = t; cf_public = public; cf_pos = pos; cf_name_pos = null_pos; cf_doc = None; cf_meta = [ Meta.CompilerGenerated, [], null_pos ]; (* annotate that this class field was generated by the compiler *) cf_kind = kind; cf_params = params; cf_expr = None; cf_expr_unoptimized = None; cf_overloads = []; } (* this helper just duplicates the type parameter class, which is assumed that cl is. *) (* This is so we can use class parameters on function parameters, without running the risk of name clash *) (* between both *) let map_param cl = let ret = mk_class cl.cl_module (fst cl.cl_path, snd cl.cl_path ^ "_c") cl.cl_pos null_pos in ret.cl_implements <- cl.cl_implements; ret.cl_kind <- cl.cl_kind; ret let get_cl_t t = match follow t with | TInst (cl,_) -> cl | _ -> assert false let mk_class m path pos = let cl = Type.mk_class m path pos null_pos in cl.cl_meta <- [ Meta.CompilerGenerated, [], null_pos ]; cl type tfield_access = | FClassField of tclass * tparams * tclass (* declared class *) * tclass_field * bool (* is static? *) * t (* the actual cf type, in relation to the class type params *) * t (* declared type *) | FEnumField of tenum * tenum_field * bool (* is parameterized enum ? *) | FAnonField of tclass_field | FDynamicField of t | FNotFound let is_var f = match f.cf_kind with | Var _ -> true | _ -> false let find_first_declared_field gen orig_cl ?get_vmtype ?exact_field field = let get_vmtype = match get_vmtype with None -> (fun t -> t) | Some f -> f in let chosen = ref None in let is_overload = ref false in let rec loop_cl depth c tl tlch = (try let ret = PMap.find field c.cl_fields in if Meta.has Meta.Overload ret.cf_meta then is_overload := true; match !chosen, exact_field with | Some(d,f,_,_,_), _ when depth <= d || (is_var ret && not (is_var f)) -> () | _, None -> chosen := Some(depth,ret,c,tl,tlch) | _, Some f2 -> List.iter (fun f -> let declared_t = apply_params c.cl_params tl f.cf_type in if same_overload_args ~get_vmtype declared_t f2.cf_type f f2 then chosen := Some(depth,f,c,tl,tlch) ) (ret :: ret.cf_overloads) with | Not_found -> ()); (match c.cl_super with | Some (sup,stl) -> let tl = List.map (apply_params c.cl_params tl) stl in let stl = gen.greal_type_param (TClassDecl sup) stl in let tlch = List.map (apply_params c.cl_params tlch) stl in loop_cl (depth+1) sup tl tlch | None -> ()); if c.cl_interface then List.iter (fun (sup,stl) -> let tl = List.map (apply_params c.cl_params tl) stl in let stl = gen.greal_type_param (TClassDecl sup) stl in let tlch = List.map (apply_params c.cl_params tlch) stl in loop_cl (depth+1) sup tl tlch ) c.cl_implements in loop_cl 0 orig_cl (List.map snd orig_cl.cl_params) (List.map snd orig_cl.cl_params); match !chosen with | None -> None | Some(_,f,c,tl,tlch) -> if !is_overload && not (Meta.has Meta.Overload f.cf_meta) then f.cf_meta <- (Meta.Overload,[],f.cf_pos) :: f.cf_meta; let declared_t = apply_params c.cl_params tl f.cf_type in let params_t = apply_params c.cl_params tlch f.cf_type in let actual_t = match follow params_t with | TFun(args,ret) -> TFun(List.map (fun (n,o,t) -> (n,o,gen.greal_type t)) args, gen.greal_type ret) | _ -> gen.greal_type params_t in Some(f,actual_t,declared_t,params_t,c,tl,tlch) let field_access gen (t:t) (field:string) : (tfield_access) = (* t can be either an haxe-type as a real-type; 'follow' should be applied here since we can generalize that a TType will be accessible as its underlying type. *) (* let pointers to values be accessed as the underlying values *) let t = match gen.greal_type t with | TAbstract({ a_path = ["cs"],"Pointer" },[t]) -> gen.greal_type t | _ -> t in match follow t with | TInst(cl, params) -> let orig_cl = cl in let orig_params = params in let rec not_found cl params = match cl.cl_dynamic with | Some t -> let t = apply_params cl.cl_params params t in FDynamicField t | None -> match cl.cl_super with | None -> FNotFound | Some (super,p) -> not_found super p in let not_found () = try let cf = PMap.find field gen.gbase_class_fields in FClassField (orig_cl, orig_params, gen.gclasses.cl_dyn, cf, false, cf.cf_type, cf.cf_type) with | Not_found -> not_found cl params in (* this is a hack for C#'s different generic types with same path *) let hashtbl_field = (String.concat "" (List.map (fun _ -> "]") cl.cl_params)) ^ field in let types = try Hashtbl.find gen.greal_field_types (orig_cl.cl_path, hashtbl_field) with | Not_found -> let ret = find_first_declared_field gen cl field in let ret = match ret with | None -> None | Some(cf,t,dt,_,cl,_,_) -> Some(cf,t,dt,cl) in if ret <> None then Hashtbl.add gen.greal_field_types (orig_cl.cl_path, hashtbl_field) ret; ret in (match types with | None -> not_found() | Some (cf, actual_t, declared_t, declared_cl) -> FClassField(orig_cl, orig_params, declared_cl, cf, false, actual_t, declared_t)) | TEnum _ | TAbstract _ -> (* enums have no field *) FNotFound | TAnon anon -> (try match !(anon.a_status) with | Statics cl -> let cf = PMap.find field cl.cl_statics in FClassField(cl, List.map (fun _ -> t_dynamic) cl.cl_params, cl, cf, true, cf.cf_type, cf.cf_type) | EnumStatics e -> let f = PMap.find field e.e_constrs in let is_param = match follow f.ef_type with | TFun _ -> true | _ -> false in FEnumField(e, f, is_param) | _ when PMap.mem field gen.gbase_class_fields -> let cf = PMap.find field gen.gbase_class_fields in FClassField(gen.gclasses.cl_dyn, [t_dynamic], gen.gclasses.cl_dyn, cf, false, cf.cf_type, cf.cf_type) | _ -> FAnonField(PMap.find field anon.a_fields) with | Not_found -> FNotFound) | _ when PMap.mem field gen.gbase_class_fields -> let cf = PMap.find field gen.gbase_class_fields in FClassField(gen.gclasses.cl_dyn, [t_dynamic], gen.gclasses.cl_dyn, cf, false, cf.cf_type, cf.cf_type) | TDynamic t -> FDynamicField t | TMono _ -> FDynamicField t_dynamic | _ -> FNotFound let field_access_esp gen t field = match field with | FStatic(cl,cf) | FInstance(cl,_,cf) when Meta.has Meta.Extern cf.cf_meta -> let static = match field with | FStatic _ -> true | _ -> false in let p = match follow (run_follow gen t) with | TInst(_,p) -> p | _ -> List.map snd cl.cl_params in FClassField(cl,p,cl,cf,static,cf.cf_type,cf.cf_type) | _ -> field_access gen t (field_name field) let mk_field_access gen expr field pos = match field_access gen expr.etype field with | FClassField(c,p,dc,cf,false,at,_) -> { eexpr = TField(expr, FInstance(dc,p,cf)); etype = apply_params c.cl_params p at; epos = pos } | FClassField(c,p,dc,cf,true,at,_) -> { eexpr = TField(expr, FStatic(dc,cf)); etype = at; epos = pos } | FAnonField cf -> { eexpr = TField(expr, FAnon cf); etype = cf.cf_type; epos = pos } | FDynamicField t -> { eexpr = TField(expr, FDynamic field); etype = t; epos = pos } | FNotFound -> { eexpr = TField(expr, FDynamic field); etype = t_dynamic; epos = pos } | FEnumField _ -> assert false (* ******************************************* *) (* Module dependency resolution *) (* ******************************************* *) type t_dependency = | DAfter of float | DBefore of float exception ImpossibleDependency of string let max_dep = 10000.0 let min_dep = - (10000.0) let solve_deps name (deps:t_dependency list) = let vmin = min_dep -. 1.0 in let vmax = max_dep +. 1.0 in let rec loop dep vmin vmax = match dep with | [] -> (if vmin >= vmax then raise (ImpossibleDependency name)); (vmin +. vmax) /. 2.0 | head :: tail -> match head with | DBefore f -> loop tail (max vmin f) vmax | DAfter f -> loop tail vmin (min vmax f) in loop deps vmin vmax (* type resolution *) exception TypeNotFound of path let get_type gen path = try Hashtbl.find gen.gtypes path with | Not_found -> raise (TypeNotFound path) (* ******************************************* *) (* set hxgen module *) (* ******************************************* *) (* Goes through all module types and adds the @:hxGen or @:nativeGen meta to them. Basically, everything that is extern is assumed to not be hxgen, unless meta :hxGen is set, and everything that is not extern is assumed to be hxgen, unless meta :nativeGgen is set. *) module SetHXGen = struct (* The only option is to run this filter eagerly, because it must be one of the first filters to run, since many others depend of it. *) let run_filter gen = let rec is_hxgen md = match md with | TClassDecl { cl_kind = KAbstractImpl a } -> is_hxgen (TAbstractDecl a) | TClassDecl cl -> let rec is_hxgen_class (c,_) = if c.cl_extern then begin if Meta.has Meta.HxGen c.cl_meta then true else Option.map_default (is_hxgen_class) false c.cl_super || List.exists is_hxgen_class c.cl_implements end else begin if Meta.has Meta.NativeChildren c.cl_meta || Meta.has Meta.NativeGen c.cl_meta then Option.map_default is_hxgen_class false c.cl_super || List.exists is_hxgen_class c.cl_implements else let rec has_nativec (c,p) = if is_hxgen_class (c,p) then false else (Meta.has Meta.NativeChildren c.cl_meta && not (Option.map_default is_hxgen_class false c.cl_super || List.exists is_hxgen_class c.cl_implements)) || Option.map_default has_nativec false c.cl_super in if Option.map_default has_nativec false c.cl_super && not (List.exists is_hxgen_class c.cl_implements) then false else true end in is_hxgen_class (cl,[]) | TEnumDecl e -> if e.e_extern then Meta.has Meta.HxGen e.e_meta else if Meta.has Meta.NativeGen e.e_meta then if Meta.has Meta.FlatEnum e.e_meta then false else begin gen.gcon.error "Only flat enums may be @:nativeGen" e.e_pos; true end else true | TAbstractDecl a when Meta.has Meta.CoreType a.a_meta -> not (Meta.has Meta.NativeGen a.a_meta) | TAbstractDecl a -> (match follow a.a_this with | TInst _ | TEnum _ | TAbstract _ -> is_hxgen (t_to_md (follow a.a_this)) | _ -> not (Meta.has Meta.NativeGen a.a_meta)) | TTypeDecl t -> (* TODO see when would we use this *) false in let filter md = let meta = if is_hxgen md then Meta.HxGen else Meta.NativeGen in match md with | TClassDecl cl -> cl.cl_meta <- (meta, [], cl.cl_pos) :: cl.cl_meta | TEnumDecl e -> e.e_meta <- (meta, [], e.e_pos) :: e.e_meta | TTypeDecl t -> t.t_meta <- (meta, [], t.t_pos) :: t.t_meta | TAbstractDecl a -> a.a_meta <- (meta, [], a.a_pos) :: a.a_meta in List.iter filter gen.gtypes_list end;; (* ******************************************* *) (* overloading reflection constructors *) (* ******************************************* *) (* this module works on languages that support function overloading and enable function hiding via static functions. it takes the constructor body out of the constructor and adds it to a special ctor static function. The static function will receive the same parameters as the constructor, plus the special "me" var, which will replace "this" Then it always adds two constructors to the class: one that receives a special marker class, indicating that the object should be constructed without executing constructor body, and one that executes its normal constructor. Both will only include a super() call to the superclasses' emtpy constructor. This enables two things: empty construction without the need of incompatibility with the platform's native construction method the ability to call super() constructor in any place in the constructor This will insert itself in the default reflection-related module filter *) module OverloadingConstructor = struct let priority = 0.0 let name = "overloading_constructor" let rec cur_ctor c tl = match c.cl_constructor with | Some ctor -> ctor, c, tl | None -> match c.cl_super with | None -> raise Not_found | Some (sup,stl) -> cur_ctor sup (List.map (apply_params c.cl_params tl) stl) let rec prev_ctor c tl = match c.cl_super with | None -> raise Not_found | Some (sup,stl) -> let stl = List.map (apply_params c.cl_params tl) stl in match sup.cl_constructor with | None -> prev_ctor sup stl | Some ctor -> ctor, sup, stl let make_static_ctor_name gen cl = let name = gen.gmk_internal_name "hx" "ctor" in name ^ "_" ^ (String.concat "_" (fst cl.cl_path)) ^ "_" ^ (snd cl.cl_path) (* replaces super() call with last static constructor call *) let replace_super_call gen c tl with_params me p = let rec loop_super c tl = match c.cl_super with | None -> raise Not_found | Some(sup,stl) -> let stl = List.map (apply_params c.cl_params tl) stl in try let static_ctor_name = make_static_ctor_name gen sup in sup, stl, PMap.find static_ctor_name sup.cl_statics with Not_found -> loop_super sup stl in let sup, stl, cf = loop_super c tl in let with_params = (mk (TLocal me) me.v_type p) :: with_params in let cf = try (* choose best super function *) List.iter (fun e -> replace_mono e.etype) with_params; List.find (fun cf -> replace_mono cf.cf_type; let args, _ = get_fun (apply_params cf.cf_params stl cf.cf_type) in try List.for_all2 (fun (_,_,t) e -> try let e_etype = run_follow gen e.etype in let t = run_follow gen t in unify e_etype t; true with Unify_error _ -> false ) args with_params with Invalid_argument("List.for_all2") -> false ) (cf :: cf.cf_overloads) with Not_found -> gen.gcon.error "No suitable overload for the super call arguments was found" p; cf in { eexpr = TCall( { eexpr = TField(ExprBuilder.make_static_this sup p, FStatic(sup,cf)); etype = apply_params cf.cf_params stl cf.cf_type; epos = p }, with_params ); etype = gen.gcon.basic.tvoid; epos = p; } (* will create a static counterpart of 'ctor', and replace its contents to a call to the static version*) let create_static_ctor gen ~empty_ctor_expr cl ctor = match Meta.has Meta.SkipCtor ctor.cf_meta with | true -> () | false when is_none ctor.cf_expr -> () | false -> let static_ctor_name = make_static_ctor_name gen cl in (* create the static constructor *) let basic = gen.gcon.basic in let ctor_types = List.map (fun (s,t) -> (s, TInst(map_param (get_cl_t t), []))) cl.cl_params in let me = alloc_var "__hx_this" (TInst(cl, List.map snd ctor_types)) in me.v_capture <- true; let fn_args, _ = get_fun ctor.cf_type in let ctor_params = List.map snd ctor_types in let fn_type = TFun((me.v_name,false, me.v_type) :: List.map (fun (n,o,t) -> (n,o,apply_params cl.cl_params ctor_params t)) fn_args, basic.tvoid) in let cur_tf_args = match ctor.cf_expr with | Some { eexpr = TFunction(tf) } -> tf.tf_args | _ -> assert false in let changed_tf_args = List.map (fun (v,_) -> (v,None)) cur_tf_args in let local_map = Hashtbl.create (List.length cur_tf_args) in let static_tf_args = (me, None) :: List.map (fun (v,b) -> let new_v = alloc_var v.v_name (apply_params cl.cl_params ctor_params v.v_type) in new_v.v_capture <- v.v_capture; Hashtbl.add local_map v.v_id new_v; (new_v, b) ) cur_tf_args in let static_ctor = mk_class_field static_ctor_name fn_type false ctor.cf_pos (Method MethNormal) ctor_types in (* change ctor contents to reference the 'me' var instead of 'this' *) let actual_super_call = ref None in let rec map_expr ~is_first e = match e.eexpr with | TCall (({ eexpr = TConst TSuper } as tsuper), params) -> (try let params = List.map (fun e -> map_expr ~is_first:false e) params in actual_super_call := Some { e with eexpr = TCall(tsuper, [empty_ctor_expr]) }; replace_super_call gen cl ctor_params params me e.epos with | Not_found -> (* last static function was not found *) actual_super_call := Some e; if not is_first then gen.gcon.error "Super call must be the first call when extending native types" e.epos; { e with eexpr = TBlock([]) }) | TFunction tf when is_first -> do_map ~is_first:true e | TConst TThis -> mk_local me e.epos | TBlock (fst :: bl) -> let fst = map_expr ~is_first:is_first fst in { e with eexpr = TBlock(fst :: List.map (fun e -> map_expr ~is_first:false e) bl); etype = apply_params cl.cl_params ctor_params e.etype } | _ -> do_map e and do_map ?(is_first=false) e = let do_t = apply_params cl.cl_params ctor_params in let do_v v = try Hashtbl.find local_map v.v_id with | Not_found -> v.v_type <- do_t v.v_type; v in Type.map_expr_type (map_expr ~is_first:is_first) do_t do_v e in let expr = do_map ~is_first:true (get ctor.cf_expr) in let expr = match expr.eexpr with | TFunction(tf) -> { expr with etype = fn_type; eexpr = TFunction({ tf with tf_args = static_tf_args }) } | _ -> assert false in static_ctor.cf_expr <- Some expr; (* add to the statics *) (try let stat = PMap.find static_ctor_name cl.cl_statics in stat.cf_overloads <- static_ctor :: stat.cf_overloads with | Not_found -> cl.cl_ordered_statics <- static_ctor :: cl.cl_ordered_statics; cl.cl_statics <- PMap.add static_ctor_name static_ctor cl.cl_statics); (* change current super call *) match ctor.cf_expr with | Some({ eexpr = TFunction(tf) } as e) -> let block_contents, p = match !actual_super_call with | None -> [], ctor.cf_pos | Some super -> [super], super.epos in let block_contents = block_contents @ [{ eexpr = TCall( { eexpr = TField( ExprBuilder.make_static_this cl p, FStatic(cl, static_ctor)); etype = apply_params static_ctor.cf_params (List.map snd cl.cl_params) static_ctor.cf_type; epos = p }, [{ eexpr = TConst TThis; etype = TInst(cl, List.map snd cl.cl_params); epos = p }] @ List.map (fun (v,_) -> mk_local v p) cur_tf_args ); etype = basic.tvoid; epos = p }] in ctor.cf_expr <- Some { e with eexpr = TFunction({ tf with tf_expr = { tf.tf_expr with eexpr = TBlock block_contents }; tf_args = changed_tf_args }) } | _ -> assert false (* makes constructors that only call super() for the 'ctor' argument *) let clone_ctors gen ctor sup stl cl = let basic = gen.gcon.basic in let rec clone cf = let ncf = mk_class_field "new" (apply_params sup.cl_params stl cf.cf_type) cf.cf_public cf.cf_pos cf.cf_kind cf.cf_params in let args, ret = get_fun ncf.cf_type in (* single expression: call to super() *) let tf_args = List.map (fun (name,_,t) -> (* the constructor will have no optional arguments, as presumably this will be handled by the underlying expr *) alloc_var name t, None ) args in let super_call = { eexpr = TCall( { eexpr = TConst TSuper; etype = TInst(cl, List.map snd cl.cl_params); epos = ctor.cf_pos }, List.map (fun (v,_) -> mk_local v ctor.cf_pos) tf_args); etype = basic.tvoid; epos = ctor.cf_pos; } in ncf.cf_expr <- Some { eexpr = TFunction { tf_args = tf_args; tf_type = basic.tvoid; tf_expr = mk_block super_call; }; etype = ncf.cf_type; epos = ctor.cf_pos; }; ncf in (* take off createEmpty *) let all = List.filter (fun cf -> replace_mono cf.cf_type; not (Meta.has Meta.SkipCtor cf.cf_meta)) (ctor :: ctor.cf_overloads) in let clones = List.map clone all in match clones with | [] -> (* raise Not_found *) assert false (* should never happen *) | cf :: [] -> cf | cf :: overl -> cf.cf_meta <- (Meta.Overload,[],cf.cf_pos) :: cf.cf_meta; cf.cf_overloads <- overl; cf let rec descends_from_native_or_skipctor cl = not (is_hxgen (TClassDecl cl)) || Meta.has Meta.SkipCtor cl.cl_meta || match cl.cl_super with | None -> false | Some(c,_) -> descends_from_native_or_skipctor c let ensure_super_is_first gen cf = let rec loop e = match e.eexpr with | TBlock (b :: block) -> loop b | TBlock [] | TCall({ eexpr = TConst TSuper },_) -> () | _ -> gen.gcon.error "Types that derive from a native class must have its super() call as the first statement in the constructor" cf.cf_pos in match cf.cf_expr with | None -> () | Some e -> Type.iter loop e let configure ~(empty_ctor_type : t) ~(empty_ctor_expr : texpr) gen = gen.gtools.r_create_empty <- (fun cl params pos -> mk (TNew(cl,params,[empty_ctor_expr])) (TInst(cl,params)) pos); let basic = gen.gcon.basic in let should_change cl = not cl.cl_interface && (not cl.cl_extern || is_hxgen (TClassDecl cl)) && (match cl.cl_kind with KAbstractImpl _ -> false | _ -> true) in let msize = List.length gen.gtypes_list in let processed, empty_ctors = Hashtbl.create msize, Hashtbl.create msize in let rec get_last_empty cl = try Hashtbl.find empty_ctors cl.cl_path with | Not_found -> match cl.cl_super with | None -> raise Not_found | Some (sup,_) -> get_last_empty sup in let rec change cl = if not (Hashtbl.mem processed cl.cl_path) then begin Hashtbl.add processed cl.cl_path true; (* make sure we've processed the super types *) Option.may (fun (super,_) -> if should_change super then change super) cl.cl_super; (* implement static hx_ctor and reimplement constructors *) (try let ctor = match cl.cl_constructor with | Some ctor -> ctor | None -> try let sctor, sup, stl = prev_ctor cl (List.map snd cl.cl_params) in (* we'll make constructors that will only call super() *) let ctor = clone_ctors gen sctor sup stl cl in cl.cl_constructor <- Some ctor; ctor with Not_found -> (* create default constructor *) let ctor = mk_class_field "new" (TFun ([], basic.tvoid)) false cl.cl_pos (Method MethNormal) [] in ctor.cf_expr <- Some { eexpr = TFunction { tf_args = []; tf_type = basic.tvoid; tf_expr = mk (TBlock []) basic.tvoid cl.cl_pos; }; etype = ctor.cf_type; epos = ctor.cf_pos; }; cl.cl_constructor <- Some ctor; ctor in (* now that we made sure we have a constructor, exit if native gen *) if not (is_hxgen (TClassDecl cl)) || Meta.has Meta.SkipCtor cl.cl_meta then begin if descends_from_native_or_skipctor cl && is_some cl.cl_super then List.iter (fun cf -> ensure_super_is_first gen cf) (ctor :: ctor.cf_overloads); raise Exit end; (* if cl descends from a native class, we cannot use the static constructor strategy *) if descends_from_native_or_skipctor cl && is_some cl.cl_super then List.iter (fun cf -> ensure_super_is_first gen cf) (ctor :: ctor.cf_overloads) else (* now that we have a current ctor, create the static counterparts *) List.iter (fun cf -> create_static_ctor gen ~empty_ctor_expr:empty_ctor_expr cl cf) (ctor :: ctor.cf_overloads) with Exit -> ()); (* implement empty ctor *) (try (* now that we made sure we have a constructor, exit if native gen *) if not (is_hxgen (TClassDecl cl)) then raise Exit; (* get first *) let empty_type = TFun (["empty",false,empty_ctor_type],basic.tvoid) in let super = match cl.cl_super with | None -> (* implement empty *) [] | Some (sup,_) -> try ignore (get_last_empty sup); let esuper = mk (TConst TSuper) (TInst (cl, List.map snd cl.cl_params)) cl.cl_pos in [mk (TCall (esuper, [empty_ctor_expr])) basic.tvoid cl.cl_pos] with Not_found -> try (* super type is native: find super constructor with least arguments *) let sctor, sup, stl = prev_ctor cl (List.map snd cl.cl_params) in let rec loop remaining (best,n) = match remaining with | [] -> best | cf :: r -> let args,_ = get_fun cf.cf_type in if (List.length args) < n then loop r (cf,List.length args) else loop r (best,n) in let args,_ = get_fun sctor.cf_type in let best = loop sctor.cf_overloads (sctor, List.length args) in let args,_ = get_fun (apply_params sup.cl_params stl best.cf_type) in let esuper = mk (TConst TSuper) (TInst (sup, stl)) cl.cl_pos in [mk (TCall (esuper, List.map (fun (n,o,t) -> null t cl.cl_pos) args)) basic.tvoid cl.cl_pos] with Not_found -> (* extends native type, but no ctor found *) [] in let ctor = mk_class_field "new" empty_type false cl.cl_pos (Method MethNormal) [] in ctor.cf_expr <- Some { eexpr = TFunction { tf_type = basic.tvoid; tf_args = [alloc_var "empty" empty_ctor_type, None]; tf_expr = mk (TBlock super) basic.tvoid cl.cl_pos }; etype = empty_type; epos = cl.cl_pos; }; ctor.cf_meta <- [Meta.SkipCtor, [], ctor.cf_pos]; Hashtbl.add empty_ctors cl.cl_path ctor; match cl.cl_constructor with | None -> cl.cl_constructor <- Some ctor | Some c -> c.cf_overloads <- ctor :: c.cf_overloads with Exit -> ()); end in let module_filter md = (match md with | TClassDecl cl when should_change cl -> change cl; | _ -> ()); None in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) module_filter end;; (* ******************************************* *) (* init function module *) (* ******************************************* *) (* This module will take proper care of the init function, by taking off all expressions from static vars and putting them in order in the init function. It will also initialize dynamic functions, both by putting them in the constructor and in the init function depends on: (syntax) must run before ExprStatement module (ok) must run before OverloadingConstructor module so the constructor can be in the correct place (syntax) must run before FunctionToClass module *) module InitFunction = struct let name = "init_funcs" let priority = solve_deps name [DBefore OverloadingConstructor.priority] let ensure_simple_expr gen e = let rec iter e = match e.eexpr with | TConst _ | TLocal _ | TArray _ | TBinop _ | TField _ | TTypeExpr _ | TParenthesis _ | TCast _ | TMeta _ | TCall _ | TNew _ | TUnop _ -> Type.iter iter e | _ -> print_endline (debug_expr e); gen.gcon.error "Expression is too complex for a readonly variable initialization" e.epos in iter e let configure gen = let handle_override_dynfun acc e this field = let add_expr = ref None in let v = mk_temp gen ("super_" ^ field) e.etype in v.v_capture <- true; let rec loop e = match e.eexpr with | TField({ eexpr = TConst(TSuper) }, f) -> let n = field_name f in (if n <> field then assert false); let local = mk_local v e.epos in (match !add_expr with | None -> add_expr := Some { e with eexpr = TVar(v, Some this) } | Some _ -> ()); local | TConst TSuper -> assert false | _ -> Type.map_expr loop e in let e = loop e in match !add_expr with | None -> e :: acc | Some add_expr -> add_expr :: e :: acc in let handle_class cl = let init = match cl.cl_init with | None -> [] | Some i -> [i] in let init = List.fold_left (fun acc cf -> match cf.cf_kind with | Var v when Meta.has Meta.ReadOnly cf.cf_meta -> if v.v_write <> AccNever && not (Meta.has Meta.CoreApi cl.cl_meta) then gen.gcon.warning "@:readOnly variable declared without `never` setter modifier" cf.cf_pos; (match cf.cf_expr with | None -> gen.gcon.warning "Uninitialized readonly variable" cf.cf_pos; acc | Some e -> ensure_simple_expr gen e; acc) | Var _ | Method MethDynamic when not (Type.is_extern_field cf) -> (match cf.cf_expr with | Some e -> (match cf.cf_params with | [] -> let var = { eexpr = TField(ExprBuilder.make_static_this cl cf.cf_pos, FStatic(cl,cf)); etype = cf.cf_type; epos = cf.cf_pos } in let ret = ({ eexpr = TBinop(Ast.OpAssign, var, e); etype = cf.cf_type; epos = cf.cf_pos; }) in cf.cf_expr <- None; ret :: acc | _ -> let params = List.map (fun _ -> t_dynamic) cf.cf_params in let fn = apply_params cf.cf_params params in let var = { eexpr = TField(ExprBuilder.make_static_this cl cf.cf_pos, FStatic(cl,cf)); etype = fn cf.cf_type; epos = cf.cf_pos } in let rec change_expr e = Type.map_expr_type (change_expr) fn (fun v -> v.v_type <- fn v.v_type; v) e in let ret = ({ eexpr = TBinop(Ast.OpAssign, var, change_expr e); etype = fn cf.cf_type; epos = cf.cf_pos; }) in cf.cf_expr <- None; ret :: acc ) | None -> acc) | _ -> acc ) init cl.cl_ordered_statics in let init = List.rev init in (match init with | [] -> cl.cl_init <- None | _ -> cl.cl_init <- Some { eexpr = TBlock(init); epos = cl.cl_pos; etype = gen.gcon.basic.tvoid; }); (* FIXME: find a way to tell OverloadingConstructor to execute this code even with empty constructors *) let vars, funs = List.fold_left (fun (acc_vars,acc_funs) cf -> match cf.cf_kind with | Var v when Meta.has Meta.ReadOnly cf.cf_meta -> if v.v_write <> AccNever && not (Meta.has Meta.CoreApi cl.cl_meta) then gen.gcon.warning "@:readOnly variable declared without `never` setter modifier" cf.cf_pos; (match cf.cf_expr with | None -> (acc_vars,acc_funs) | Some e -> ensure_simple_expr gen e; (acc_vars,acc_funs)) | Var _ | Method MethDynamic -> let is_var = match cf.cf_kind with | Var _ -> true | _ -> false in (match cf.cf_expr, cf.cf_params with | Some e, [] -> let var = { eexpr = TField({ eexpr = TConst(TThis); epos = cf.cf_pos; etype = TInst(cl, List.map snd cl.cl_params); }, FInstance(cl, List.map snd cl.cl_params, cf)); etype = cf.cf_type; epos = cf.cf_pos } in let ret = ({ eexpr = TBinop(Ast.OpAssign, var, e); etype = cf.cf_type; epos = cf.cf_pos; }) in cf.cf_expr <- None; let is_override = List.memq cf cl.cl_overrides in if is_override then begin cl.cl_ordered_fields <- List.filter (fun f -> f.cf_name <> cf.cf_name) cl.cl_ordered_fields; cl.cl_fields <- PMap.remove cf.cf_name cl.cl_fields; acc_vars, handle_override_dynfun acc_funs ret var cf.cf_name end else if is_var then ret :: acc_vars, acc_funs else acc_vars, ret :: acc_funs | Some e, _ -> let params = List.map (fun _ -> t_dynamic) cf.cf_params in let fn = apply_params cf.cf_params params in let var = { eexpr = TField({ eexpr = TConst(TThis); epos = cf.cf_pos; etype = TInst(cl, List.map snd cl.cl_params); }, FInstance(cl, List.map snd cl.cl_params, cf)); etype = cf.cf_type; epos = cf.cf_pos } in let rec change_expr e = Type.map_expr_type (change_expr) fn (fun v -> v.v_type <- fn v.v_type; v) e in let ret = ({ eexpr = TBinop(Ast.OpAssign, var, change_expr e); etype = fn cf.cf_type; epos = cf.cf_pos; }) in cf.cf_expr <- None; let is_override = List.memq cf cl.cl_overrides in if is_override then begin cl.cl_ordered_fields <- List.filter (fun f -> f.cf_name <> cf.cf_name) cl.cl_ordered_fields; cl.cl_fields <- PMap.remove cf.cf_name cl.cl_fields; acc_vars, handle_override_dynfun acc_funs ret var cf.cf_name end else if is_var then ret :: acc_vars, acc_funs else acc_vars, ret :: acc_funs | None, _ -> acc_vars,acc_funs) | _ -> acc_vars,acc_funs ) ([],[]) cl.cl_ordered_fields in (* let vars = List.rev vars in *) (* let funs = List.rev funs in *) (* see if there is any *) (match vars, funs with | [], [] -> () | _ -> (* if there is, we need to find the constructor *) let ctors = match cl.cl_constructor with | Some ctor -> ctor | None -> try let sctor, sup, stl = OverloadingConstructor.prev_ctor cl (List.map snd cl.cl_params) in let ctor = OverloadingConstructor.clone_ctors gen sctor sup stl cl in cl.cl_constructor <- Some ctor; ctor with | Not_found -> let basic = gen.gcon.basic in let ctor = mk_class_field "new" (TFun([], basic.tvoid)) false cl.cl_pos (Method MethNormal) [] in ctor.cf_expr <- Some { eexpr = TFunction { tf_args = []; tf_type = basic.tvoid; tf_expr = { eexpr = TBlock[]; etype = basic.tvoid; epos = cl.cl_pos }; }; etype = ctor.cf_type; epos = ctor.cf_pos; }; cl.cl_constructor <- Some ctor; ctor in let process ctor = let func = match ctor.cf_expr with | Some({eexpr = TFunction(tf)} as e) -> let rec add_fn e = match e.eexpr with | TBlock(hd :: tl) -> (match hd.eexpr with | TCall({ eexpr = TConst TSuper }, _) -> if not (OverloadingConstructor.descends_from_native_or_skipctor cl) then { e with eexpr = TBlock(vars @ (hd :: (funs @ tl))) } else { e with eexpr = TBlock(hd :: (vars @ funs @ tl)) } | TBlock(_) -> { e with eexpr = TBlock( (add_fn hd) :: tl ) } | _ -> { e with eexpr = TBlock( vars @ funs @ (hd :: tl) ) }) | _ -> Type.concat { e with eexpr = TBlock(vars @ funs) } e in let tf_expr = add_fn (mk_block tf.tf_expr) in { e with eexpr = TFunction({ tf with tf_expr = tf_expr }) } | _ -> assert false in ctor.cf_expr <- Some(func) in List.iter process (ctors :: ctors.cf_overloads) ) in let mod_filter = function | TClassDecl cl -> (if not cl.cl_extern then handle_class cl); None | _ -> None in gen.gmodule_filters#add ~name:"init_funcs" ~priority:(PCustom priority) mod_filter end;; (* ******************************************* *) (* Dynamic Binop/Unop handler *) (* ******************************************* *) (* On some languages there is limited support for operations on dynamic variables, so those operations must be changed. There are 5 types of binary operators: 1 - can take any variable and returns a bool (== and !=) 2 - can take either a string, or a number and returns either a bool or the underlying type ( >, < for bool and + for returning its type) 3 - take numbers and return a number ( *, /, ...) 4 - take ints and return an int (bit manipulation) 5 - take a bool and returns a bool ( &&, || ...) On the default implementation, type 1 and the plus function will be handled with a function call; Type 2 will be handled with the parameter "compare_handler", which will do something like Reflect.compare(x1, x2); Types 3, 4 and 5 will perform a cast to double, int and bool, which will then be handled normally by the platform Unary operators are the most difficult to handle correctly. With unary operators, there are 2 types: 1 - can take a number, changes and returns the result (++, --, ~) 2 - can take a number (-) or bool (!), and returns the result The first case is much trickier, because it doesn't seem a good idea to change any variable to double just because it is dynamic, but this is how we will handle right now. something like that: var x:Dynamic = 10; x++; will be: object x = 10; x = ((IConvertible)x).ToDouble(null) + 1; depends on: (syntax) must run before expression/statment normalization because it may generate complex expressions must run before OverloadingConstructor due to later priority conflicts. Since ExpressionUnwrap is only defined afterwards, we will set this value with absolute values *) module DynamicOperators = struct let name = "dyn_ops" let priority = 0.0 let configure gen ?(handle_strings = true) (should_change:texpr->bool) (equals_handler:texpr->texpr->texpr) (dyn_plus_handler:texpr->texpr->texpr->texpr) (compare_handler:texpr->texpr->texpr) = let get_etype_one e = if like_int e.etype then ExprBuilder.make_int gen.gcon 1 e.epos else ExprBuilder.make_float gen.gcon "1.0" e.epos in let basic = gen.gcon.basic in let rec run e = match e.eexpr with | TBinop (OpAssignOp op, e1, e2) when should_change e -> (* e1 will never contain another TBinop *) (match e1.eexpr with | TLocal _ -> mk_paren { e with eexpr = TBinop(OpAssign, e1, run { e with eexpr = TBinop(op, e1, e2) }) } | TField _ | TArray _ -> let eleft, rest = match e1.eexpr with | TField(ef, f) -> let v = mk_temp gen "dynop" ef.etype in { e1 with eexpr = TField(mk_local v ef.epos, f) }, [ { eexpr = TVar(v,Some (run ef)); etype = basic.tvoid; epos = ef.epos } ] | TArray(e1a, e2a) -> let v = mk_temp gen "dynop" e1a.etype in let v2 = mk_temp gen "dynopi" e2a.etype in { e1 with eexpr = TArray(mk_local v e1a.epos, mk_local v2 e2a.epos) }, [ { eexpr = TVar(v,Some (run e1a)); etype = basic.tvoid; epos = e1.epos }; { eexpr = TVar(v2, Some (run e2a)); etype = basic.tvoid; epos = e1.epos } ] | _ -> assert false in { e with eexpr = TBlock (rest @ [ { e with eexpr = TBinop(OpAssign, eleft, run { e with eexpr = TBinop(op, eleft, e2) }) } ]); } | _ -> assert false ) | TBinop (OpAssign, e1, e2) | TBinop (OpInterval, e1, e2) -> Type.map_expr run e | TBinop (op, e1, e2) when should_change e-> (match op with | OpEq -> (* type 1 *) equals_handler (run e1) (run e2) | OpNotEq -> (* != -> !equals() *) mk_paren { eexpr = TUnop(Ast.Not, Prefix, (equals_handler (run e1) (run e2))); etype = gen.gcon.basic.tbool; epos = e.epos } | OpAdd -> if handle_strings && (is_string e.etype || is_string e1.etype || is_string e2.etype) then { e with eexpr = TBinop(op, mk_cast gen.gcon.basic.tstring (run e1), mk_cast gen.gcon.basic.tstring (run e2)) } else dyn_plus_handler e (run e1) (run e2) | OpGt | OpGte | OpLt | OpLte -> (* type 2 *) { eexpr = TBinop(op, compare_handler (run e1) (run e2), { eexpr = TConst(TInt(Int32.zero)); etype = gen.gcon.basic.tint; epos = e.epos} ); etype = gen.gcon.basic.tbool; epos = e.epos } | OpMult | OpDiv | OpSub | OpMod -> (* always cast everything to double *) let etype = (get_etype_one e).etype in { e with eexpr = TBinop(op, mk_cast etype (run e1), mk_cast etype (run e2)) } | OpBoolAnd | OpBoolOr -> { e with eexpr = TBinop(op, mk_cast gen.gcon.basic.tbool (run e1), mk_cast gen.gcon.basic.tbool (run e2)) } | OpAnd | OpOr | OpXor | OpShl | OpShr | OpUShr -> { e with eexpr = TBinop(op, mk_cast gen.gcon.basic.tint (run e1), mk_cast gen.gcon.basic.tint (run e2)) } | OpAssign | OpAssignOp _ | OpInterval | OpArrow -> assert false) | TUnop (Increment as op, flag, e1) | TUnop (Decrement as op, flag, e1) when should_change e -> (* some naming definitions: * ret => the returning variable * _g => the get body * getvar => the get variable expr This will work like this: - if e1 is a TField, set _g = get body, getvar = (get body).varname - if Prefix, return getvar = getvar + 1.0 - if Postfix, set ret = getvar; getvar = getvar + 1.0; ret; *) let one = get_etype_one e in let etype = one.etype in let op = (match op with Increment -> OpAdd | Decrement -> OpSub | _ -> assert false) in let var, getvar = match e1.eexpr with | TField(fexpr, field) -> let tmp = mk_temp gen "getvar" fexpr.etype in let var = { eexpr = TVar(tmp, Some(run fexpr)); etype = gen.gcon.basic.tvoid; epos = e.epos } in (Some var, { eexpr = TField( { fexpr with eexpr = TLocal(tmp) }, field); etype = etype; epos = e1.epos }) | _ -> (None, e1) in (match flag with | Prefix -> let block = (match var with | Some e -> [e] | None -> []) @ [ mk_cast etype { e with eexpr = TBinop(OpAssign, getvar,{ eexpr = TBinop(op, mk_cast etype getvar, one); etype = etype; epos = e.epos }); etype = getvar.etype; } ] in { eexpr = TBlock(block); etype = etype; epos = e.epos } | Postfix -> let ret = mk_temp gen "ret" etype in let vars = (match var with Some e -> [e] | None -> []) @ [{ eexpr = TVar(ret, Some (mk_cast etype getvar)); etype = gen.gcon.basic.tvoid; epos = e.epos }] in let retlocal = { eexpr = TLocal(ret); etype = etype; epos = e.epos } in let block = vars @ [ { e with eexpr = TBinop(OpAssign, getvar, { eexpr = TBinop(op, retlocal, one); etype = getvar.etype; epos = e.epos }) }; retlocal ] in { eexpr = TBlock(block); etype = etype; epos = e.epos } ) | TUnop (op, flag, e1) when should_change e -> let etype = match op with | Not -> gen.gcon.basic.tbool | _ -> gen.gcon.basic.tint in mk_paren { eexpr = TUnop(op, flag, mk_cast etype (run e1)); etype = etype; epos = e.epos } | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gexpr_filters#add ~name:"dyn_ops" ~priority:(PCustom priority) map end;; (* ******************************************* *) (* Dynamic Field Access *) (* ******************************************* *) (* This module will filter every dynamic field access in haxe. On platforms that do not support dynamic access, it is with this that you should replace dynamic calls with x.field / Reflect.setField calls, and guess what - this is the default implemenation! Actually there is a problem with Reflect.setField because it returns void, which is a bad thing for us, so even in the default implementation, the function call should be specified to a Reflect.setField version that returns the value that was set (TODO: should it be separated?) As a plus, the default implementation adds something that doesn't hurt anybody, it looks for TAnon with Statics / EnumStatics field accesses and transforms them into real static calls. This means it will take this var m = Math; for (i in 0...1000) m.cos(10); which is an optimization in dynamic platforms, but performs horribly on strongly typed platforms and transform into: var m = Math; for (i in 0...1000) Math.cos(10); depends on: (ok) must run AFTER Binop/Unop handler - so Unops / Binops are already unrolled *) module DynamicFieldAccess = struct let name = "dynamic_field_access" let priority = solve_deps name [DAfter DynamicOperators.priority] (* is_dynamic (expr) (field_access_expr) (field) : a function that indicates if the field access should be changed change_expr (expr) (field_access_expr) (field) (setting expr) (is_unsafe) : changes the expression call_expr (expr) (field_access_expr) (field) (call_params) : changes a call expression *) let configure gen (is_dynamic:texpr->texpr->Type.tfield_access->bool) (change_expr:texpr->texpr->string->texpr option->bool->texpr) (call_expr:texpr->texpr->string->texpr list->texpr) = let rec run e = match e.eexpr with (* class types *) | TField(fexpr, f) when is_some (anon_class fexpr.etype) -> let decl = get (anon_class fexpr.etype) in let name = field_name f in (try match decl with | TClassDecl cl -> let cf = PMap.find name cl.cl_statics in { e with eexpr = TField({ fexpr with eexpr = TTypeExpr decl }, FStatic(cl, cf)) } | TEnumDecl en -> let ef = PMap.find name en.e_constrs in { e with eexpr = TField({ fexpr with eexpr = TTypeExpr decl }, FEnum(en, ef)) } | TAbstractDecl _ -> (* abstracts don't have TFields *) assert false | TTypeDecl _ -> (* anon_class doesn't return TTypeDecl *) assert false with | Not_found -> match f with | FStatic(cl,cf) when Meta.has Meta.Extern cf.cf_meta -> { e with eexpr = TField({ fexpr with eexpr = TTypeExpr decl }, FStatic(cl, cf)) } | _ -> change_expr e { fexpr with eexpr = TTypeExpr decl } (field_name f) None true ) | TField(fexpr, f) when is_dynamic e fexpr (f) -> change_expr e (run fexpr) (field_name f) None true | TCall( { eexpr = TField(_, FStatic({ cl_path = ([], "Reflect") }, { cf_name = "field" })) } , [obj; { eexpr = TConst(TString(field)) }] ) -> let t = match gen.greal_type obj.etype with | TDynamic _ | TAnon _ | TMono _ -> t_dynamic | t -> t in change_expr (mk_field_access gen { obj with etype = t } field obj.epos) (run obj) field None false | TCall( { eexpr = TField(_, FStatic({ cl_path = ([], "Reflect") }, { cf_name = "setField" } )) }, [obj; { eexpr = TConst(TString(field)) }; evalue] ) -> change_expr (mk_field_access gen obj field obj.epos) (run obj) field (Some (run evalue)) false | TBinop(OpAssign, ({eexpr = TField(fexpr, f)}), evalue) when is_dynamic e fexpr (f) -> change_expr e (run fexpr) (field_name f) (Some (run evalue)) true | TBinop(OpAssign, { eexpr = TField(fexpr, f) }, evalue) -> (match field_access_esp gen fexpr.etype (f) with | FClassField(_,_,_,cf,false,t,_) when (try PMap.find cf.cf_name gen.gbase_class_fields == cf with Not_found -> false) -> change_expr e (run fexpr) (field_name f) (Some (run evalue)) true | _ -> Type.map_expr run e ) (* #if debug *) | TBinop(OpAssignOp op, ({eexpr = TField(fexpr, f)}), evalue) when is_dynamic e fexpr (f) -> assert false (* this case shouldn't happen *) | TUnop(Increment, _, ({eexpr = TField( ( { eexpr=TLocal(local) } as fexpr ), f)})) | TUnop(Decrement, _, ({eexpr = TField( ( { eexpr=TLocal(local) } as fexpr ), f)})) when is_dynamic e fexpr (f) -> assert false (* this case shouldn't happen *) (* #end *) | TCall( ({ eexpr = TField(fexpr, f) }), params ) when is_dynamic e fexpr (f) -> call_expr e (run fexpr) (field_name f) (List.map run params) | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gexpr_filters#add ~name:"dynamic_field_access" ~priority:(PCustom(priority)) map end;; (* ******************************************* *) (* Closure Detection *) (* ******************************************* *) (* Just a small utility filter that detects when a closure must be created. On the default implementation, this means when a function field is being accessed not via reflection and not to be called instantly dependencies: must run after DynamicFieldAccess, so any TAnon { Statics / EnumStatics } will be changed to the corresponding TTypeExpr *) module FilterClosures = struct let name = "filter_closures" let priority = solve_deps name [DAfter DynamicFieldAccess.priority] let configure gen (should_change:texpr->string->bool) (filter:texpr->texpr->string->bool->texpr) = let rec run e = match e.eexpr with (*(* this is precisely the only case where we won't even ask if we should change, because it is a direct use of TClosure *) | TCall ( {eexpr = TClosure(e1,s)} as clos, args ) -> { e with eexpr = TCall({ clos with eexpr = TClosure(run e1, s) }, List.map run args ) } | TCall ( clos, args ) -> let rec loop clos = match clos.eexpr with | TClosure(e1,s) -> Some (clos, e1, s) | TParenthesis p -> loop p | _ -> None in let clos = loop clos in (match clos with | Some (clos, e1, s) -> { e with eexpr = TCall({ clos with eexpr = TClosure(run e1, s) }, List.map run args ) } | None -> Type.map_expr run e)*) | TCall({ eexpr = TLocal{ v_name = "__delegate__" } } as local, [del]) -> { e with eexpr = TCall(local, [Type.map_expr run del]) } | TCall(({ eexpr = TField(_, _) } as ef), params) -> { e with eexpr = TCall(Type.map_expr run ef, List.map run params) } | TField(ef, FEnum(en, field)) -> (* FIXME replace t_dynamic with actual enum Anon field *) let ef = run ef in (match follow field.ef_type with | TFun _ when should_change ef field.ef_name -> filter e ef field.ef_name true | _ -> { e with eexpr = TField(ef, FEnum(en,field)) } ) | TField(({ eexpr = TTypeExpr _ } as tf), f) -> (match field_access_esp gen tf.etype (f) with | FClassField(_,_,_,cf,_,_,_) -> (match cf.cf_kind with | Method(MethDynamic) | Var _ -> e | _ when should_change tf cf.cf_name -> filter e tf cf.cf_name true | _ -> e ) | _ -> e) | TField(e1, FClosure (Some _, cf)) when should_change e1 cf.cf_name -> (match cf.cf_kind with | Method MethDynamic | Var _ -> Type.map_expr run e | _ -> filter e (run e1) cf.cf_name false) | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gexpr_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* Dynamic TArray Handling *) (* ******************************************* *) (* In some languages you cannot overload the [] operator, so we need to decide what is kept as TArray and what gets mapped. depends on: (syntax) must run before expression/statment normalization because it may generate complex expressions (ok) must run before binop transformations because it may generate some untreated binop ops (ok) must run before dynamic field access is transformed into reflection *) module TArrayTransform = struct let name = "dyn_tarray" let priority = solve_deps name [DBefore DynamicOperators.priority; DBefore DynamicFieldAccess.priority] (* should change signature: tarray expr -> binop operation -> should change? *) let configure gen (should_change:texpr->Ast.binop option->bool) (get_fun:string) (set_fun:string) = let basic = gen.gcon.basic in let mk_get e e1 e2 = let efield = mk_field_access gen e1 get_fun e.epos in { e with eexpr = TCall(efield, [e2]) } in let mk_set e e1 e2 evalue = let efield = mk_field_access gen e1 set_fun e.epos in { e with eexpr = TCall(efield, [e2; evalue]) } in let rec run e = match e.eexpr with | TArray(e1, e2) -> (* e1 should always be a var; no need to map there *) if should_change e None then mk_get e (run e1) (run e2) else Type.map_expr run e | TBinop (Ast.OpAssign, ({ eexpr = TArray(e1a,e2a) } as earray), evalue) when should_change earray (Some Ast.OpAssign) -> mk_set e (run e1a) (run e2a) (run evalue) | TBinop (Ast.OpAssignOp op,({ eexpr = TArray(e1a,e2a) } as earray) , evalue) when should_change earray (Some (Ast.OpAssignOp op)) -> (* cache all arguments in vars so they don't get executed twice *) (* let ensure_local gen block name e = *) let block = ref [] in let arr_local = ensure_local gen block "array" (run e1a) in let idx_local = ensure_local gen block "index" (run e2a) in block := (mk_set e arr_local idx_local ( { e with eexpr=TBinop(op, mk_get earray arr_local idx_local, run evalue) } )) :: !block; { e with eexpr = TBlock (List.rev !block) } | TUnop(op, flag, ({ eexpr = TArray(e1a, e2a) } as earray)) -> if should_change earray None && match op with | Not | Neg -> false | _ -> true then begin let block = ref [] in let actual_t = match op with | Ast.Increment | Ast.Decrement -> (match follow earray.etype with | TInst _ | TAbstract _ | TEnum _ -> earray.etype | _ -> basic.tfloat) | Ast.Not -> basic.tbool | _ -> basic.tint in let val_v = mk_temp gen "arrVal" actual_t in let ret_v = mk_temp gen "arrRet" actual_t in let arr_local = ensure_local gen block "arr" (run e1a) in let idx_local = ensure_local gen block "arrIndex" (run e2a) in let val_local = { earray with eexpr = TLocal(val_v) } in let ret_local = { earray with eexpr = TLocal(ret_v) } in (* var idx = 1; var val = x._get(idx); var ret = val++; x._set(idx, val); ret; *) block := { eexpr = TVar(val_v, Some(mk_get earray arr_local idx_local)); (* var val = x._get(idx) *) etype = gen.gcon.basic.tvoid; epos = e2a.epos } :: !block; block := { eexpr = TVar(ret_v, Some { e with eexpr = TUnop(op, flag, val_local) }); (* var ret = val++ *) etype = gen.gcon.basic.tvoid; epos = e2a.epos } :: !block; block := (mk_set e arr_local idx_local val_local) (*x._set(idx,val)*) :: !block; block := ret_local :: !block; { e with eexpr = TBlock (List.rev !block) } end else Type.map_expr run e | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gexpr_filters#add ~name:"dyn_tarray" ~priority:(PCustom priority) map end;; (* ******************************************* *) (* Try / Catch + throw native types handling *) (* ******************************************* *) (* Some languages/vm's do not support throwing any kind of value. For them, only special kinds of objects can be thrown. Because of this, we must wrap some throw statements with an expression, and also we must unwrap it on the catch() phase, and maybe manually test with Std.is() dependencies: must run before dynamic field access (?) TODO review It's a syntax filter, as it alters types (throw wrapper) *) module TryCatchWrapper = struct let priority = solve_deps "try_catch" [DBefore DynamicFieldAccess.priority] (* should_wrap : does the type should be wrapped? This of course works on the reverse way, so it tells us if the type should be unwrapped as well wrap_throw : the wrapper for throw (throw expr->expr inside throw->returning wrapped expression) unwrap_expr : the other way around : given the catch var (maybe will need casting to wrapper_type) , return the unwrap expr rethrow_expr : how to rethrow ane exception in the platform catchall_type : the class used for catchall (e:Dynamic) wrapper_type : the wrapper type, so we can test if exception is of type 'wrapper' catch_map : maps the catch expression to include some intialization code (e.g. setting up Stack.exceptionStack) *) let configure gen (should_wrap:t->bool) (wrap_throw:texpr->texpr->texpr) (unwrap_expr:tvar->pos->texpr) (rethrow_expr:texpr->texpr) (catchall_type:t) (wrapper_type:t) (catch_map:tvar->texpr->texpr) = let rec run e = match e.eexpr with | TThrow texpr when should_wrap texpr.etype -> wrap_throw e (run texpr) | TTry (ttry, catches) -> let nowrap_catches, must_wrap_catches, catchall = List.fold_left (fun (nowrap_catches, must_wrap_catches, catchall) (v, catch) -> (* first we'll see if the type is Dynamic (catchall) *) match follow v.v_type with | TDynamic _ -> assert (is_none catchall); (nowrap_catches, must_wrap_catches, Some(v,run catch)) (* see if we should unwrap it *) | _ when should_wrap (follow v.v_type) -> (nowrap_catches, (v,run catch) :: must_wrap_catches, catchall) | _ -> ( (v,catch_map v (run catch)) :: nowrap_catches, must_wrap_catches, catchall ) ) ([], [], None) catches in (* temp (?) fix for https://github.com/HaxeFoundation/haxe/issues/4134 *) let must_wrap_catches = List.rev must_wrap_catches in (* 1st catch all nowrap "the easy way" 2nd see if there are any must_wrap or catchall. If there is, do a catchall first with a temp var. then get catchall var (as dynamic) (or create one), and declare it = catchall exception then test if it is of type wrapper_type. If it is, unwrap it then start doing Std.is() tests for each catch type if there is a catchall in the end, end with it. If there isn't, rethrow *) let dyn_catch = match (catchall, must_wrap_catches) with | Some (v,c), _ | _, (v, c) :: _ -> let pos = c.epos in let temp_var = mk_temp gen "catchallException" catchall_type in let temp_local = { eexpr=TLocal(temp_var); etype = temp_var.v_type; epos = pos } in let catchall_var = (*match catchall with | None -> *) mk_temp gen "catchall" t_dynamic (*| Some (v,_) -> v*) in let catchall_decl = { eexpr = TVar(catchall_var, Some(temp_local)); etype=gen.gcon.basic.tvoid; epos = pos } in let catchall_local = { eexpr = TLocal(catchall_var); etype = t_dynamic; epos = pos } in (* if it is of type wrapper_type, unwrap it *) let std_is = mk_static_field_access (get_cl (get_type gen ([],"Std"))) "is" (TFun(["v",false,t_dynamic;"cl",false,mt_to_t (get_type gen ([], "Class")) [t_dynamic]],gen.gcon.basic.tbool)) pos in let mk_std_is t pos = { eexpr = TCall(std_is, [catchall_local; mk_mt_access (t_to_mt t) pos]); etype = gen.gcon.basic.tbool; epos = pos } in let if_is_wrapper_expr = { eexpr = TIf(mk_std_is wrapper_type pos, { eexpr = TBinop(OpAssign, catchall_local, unwrap_expr temp_var pos); etype = t_dynamic; epos = pos } , None); etype = gen.gcon.basic.tvoid; epos = pos } in let rec loop must_wrap_catches = match must_wrap_catches with | (vcatch,catch) :: tl -> { eexpr = TIf(mk_std_is vcatch.v_type catch.epos, { eexpr = TBlock({ eexpr=TVar(vcatch, Some(mk_cast vcatch.v_type catchall_local)); etype=gen.gcon.basic.tvoid; epos=catch.epos } :: [catch] ); etype = catch.etype; epos = catch.epos }, Some (loop tl)); etype = catch.etype; epos = catch.epos } | [] -> match catchall with | Some (v,s) -> Type.concat { eexpr = TVar(v, Some(catchall_local)); etype = gen.gcon.basic.tvoid; epos = pos } s | None -> mk_block (rethrow_expr temp_local) in [ ( temp_var, catch_map temp_var { e with eexpr = TBlock([ catchall_decl; if_is_wrapper_expr; loop must_wrap_catches ]) } ) ] | _ -> [] in { e with eexpr = TTry(run ttry, (List.rev nowrap_catches) @ dyn_catch) } | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:"try_catch" ~priority:(PCustom priority) map end;; let fun_args = List.map (function | (v,s) -> (v.v_name, (match s with | None -> false | Some _ -> true), v.v_type)) (* ******************************************* *) (* Closures To Class *) (* ******************************************* *) (* This is a very important filter. It will take all anonymous functions from the AST, will search for all captured variables, and will create a class that implements an abstract interface for calling functions. This is very important for targets that don't support anonymous functions to work correctly. Also it is possible to implement some strategies to avoid value type boxing, such as NaN tagging or double/object arguments. All this will be abstracted away from this interface. dependencies: must run after dynamic field access, because of conflicting ways to deal with invokeField (module filter) must run after OverloadingConstructor so we can also change the dynamic function expressions uses TArray expressions for array. TODO see interaction uses TThrow expressions. *) module ClosuresToClass = struct let name = "closures_to_class" let priority = solve_deps name [ DAfter DynamicFieldAccess.priority ] type closures_ctx = { func_class : tclass; (* this is what will actually turn the function into class field. The standard implementation by default will already take care of creating the class, and setting the captured variables. It will also return the super arguments to be called *) closure_to_classfield : tfunc->t->pos->tclass_field * (texpr list); (* when a dynamic function call is made, we need to convert it as if it were calling the dynamic function interface. TCall expr -> new TCall expr *) dynamic_fun_call : texpr->texpr; (* Provide a toolchain so we can easily create classes that extend Function and add more functionality on top of it. arguments: tclass -> subject (so we know the type of this) ( int -> (int->t->tconstant option->texpr) -> ( (tvar * tconstant option) list * texpr) ) int -> current arity of the function whose member will be mapped; -1 for dynamic function. It is guaranteed that dynamic function will be called last t -> the return type of the function (int->t->tconstant option->texpr) -> api to get exprs that unwrap arguments correctly int -> argument wanted to unwrap t -> solicited type tconstant option -> map to this default value if null returns a texpr that tells how the default should return a list with additional arguments (only works if is_function_base = true) and the underlying function expression *) map_base_classfields : tclass->( int -> t -> (tvar list) -> (int->t->tconstant option->texpr) -> texpr )->tclass_field list; } type map_info = { in_unsafe : bool; in_unused : bool; } let null_map_info = { in_unsafe = false; in_unused = false; } (* the default implementation will take 3 transformation functions: * one that will transform closures that are not called immediately (instance.myFunc). normally on this case it's best to have a runtime handler that will take the instance, the function and call its invokeField when invoked * one that will actually handle the anonymous functions themselves. * one that will transform calling a dynamic function. So for example, dynFunc(arg1, arg2) might turn into dynFunc.apply2(arg1, arg2); ( suspended ) * an option to match papplied functions * handling parameterized anonymous function declaration (optional - tparam_anon_decl and tparam_anon_acc) *) let rec cleanup_delegate e = match e.eexpr with | TParenthesis e | TMeta(_,e) | TCast(e,_) -> cleanup_delegate e | _ -> e let funct gen t = match follow (run_follow gen t) with | TFun(args,ret) -> args,ret | _ -> raise Not_found let mk_conversion_fun gen e = let args, ret = funct gen e.etype in let tf_args = List.map (fun (n,o,t) -> alloc_var n t,None) args in let block, local = match e.eexpr with | TLocal v -> v.v_capture <- true; [],e | _ -> let tmp = mk_temp gen "delegate_conv" e.etype in tmp.v_capture <- true; [{ eexpr = TVar(tmp,Some e); etype = gen.gcon.basic.tvoid; epos = e.epos }], mk_local tmp e.epos in let body = { eexpr = TCall(local, List.map (fun (v,_) -> mk_local v e.epos) tf_args); etype = ret; epos = e.epos; } in let body = if not (ExtType.is_void ret) then { body with eexpr = TReturn( Some body ) } else body in let body = { eexpr = TBlock([body]); etype = body.etype; epos = body.epos; } in block, { tf_args = tf_args; tf_expr = body; tf_type = ret; } let traverse gen ?tparam_anon_decl ?tparam_anon_acc (handle_anon_func:texpr->tfunc->map_info->t option->texpr) (dynamic_func_call:texpr->texpr) e = let info = ref null_map_info in let rec run e = match e.eexpr with | TCast({ eexpr = TCall({ eexpr = TLocal{ v_name = "__delegate__" } } as local, [del] ) } as e2, _) -> let e2 = { e2 with etype = e.etype } in let replace_delegate ex = { e with eexpr = TCast({ e2 with eexpr = TCall(local, [ex]) }, None) } in (* found a delegate; let's see if it's a closure or not *) let clean = cleanup_delegate del in (match clean.eexpr with | TField( ef, (FClosure _ as f)) | TField( ef, (FStatic _ as f)) -> (* a closure; let's leave this unchanged for FilterClosures to handle it *) replace_delegate { clean with eexpr = TField( run ef, f ) } | TFunction tf -> (* handle like we'd handle a normal function, but create an unchanged closure field for it *) let ret = handle_anon_func clean { tf with tf_expr = run tf.tf_expr } !info (Some e.etype) in replace_delegate ret | _ -> try let block, tf = mk_conversion_fun gen del in let block = List.map run block in let tf = { tf with tf_expr = run tf.tf_expr } in let ret = handle_anon_func { clean with eexpr = TFunction(tf) } { tf with tf_expr = run tf.tf_expr } !info (Some e.etype) in let ret = replace_delegate ret in if block = [] then ret else { ret with eexpr = TBlock(block @ [ret]) } with Not_found -> gen.gcon.error "This delegate construct is unsupported" e.epos; replace_delegate (run clean)) | TCall(({ eexpr = TLocal{ v_name = "__unsafe__" } } as local), [arg]) -> let old = !info in info := { !info with in_unsafe = true }; let arg2 = run arg in info := old; { e with eexpr = TCall(local,[arg2]) } (* parameterized functions handling *) | TVar(vv, ve) -> (match tparam_anon_decl with | None -> Type.map_expr run e | Some tparam_anon_decl -> (match (vv, ve) with | ({ v_extra = Some( _ :: _, _) } as v), Some ({ eexpr = TFunction tf } as f) | ({ v_extra = Some( _ :: _, _) } as v), Some { eexpr = TArrayDecl([{ eexpr = TFunction tf } as f]) | TCall({ eexpr = TLocal { v_name = "__array__" } }, [{ eexpr = TFunction tf } as f]) } -> (* captured transformation *) ignore(tparam_anon_decl v f { tf with tf_expr = run tf.tf_expr }); { e with eexpr = TBlock([]) } | _ -> Type.map_expr run { e with eexpr = TVar(vv, ve) }) ) | TLocal ({ v_extra = Some( _ :: _, _) } as v) | TArray ({ eexpr = TLocal ({ v_extra = Some( _ :: _, _) } as v) }, _) -> (* captured transformation *) (match tparam_anon_acc with | None -> Type.map_expr run e | Some tparam_anon_acc -> tparam_anon_acc v e) | TCall( { eexpr = TField(_, FEnum _) }, _ ) -> Type.map_expr run e (* if a TClosure is being call immediately, there's no need to convert it to a TClosure *) | TCall(( { eexpr = TField(ecl,f) } as e1), params) -> (* check to see if called field is known and if it is a MethNormal (only MethNormal fields can be called directly) *) (* let name = field_name f in *) (match field_access_esp gen (gen.greal_type ecl.etype) f with | FClassField(_,_,_,cf,_,_,_) -> (match cf.cf_kind with | Method MethNormal | Method MethInline -> { e with eexpr = TCall({ e1 with eexpr = TField(run ecl, f) }, List.map run params) } | _ -> match gen.gfollow#run_f e1.etype with | TFun _ -> dynamic_func_call { e with eexpr = TCall(run e1, List.map run params) } | _ -> let i = ref 0 in let t = TFun(List.map (fun e -> incr i; "arg" ^ (string_of_int !i), false, e.etype) params, e.etype) in dynamic_func_call { e with eexpr = TCall( mk_castfast t (run e1), List.map run params ) } ) (* | FNotFound -> { e with eexpr = TCall({ e1 with eexpr = TField(run ecl, f) }, List.map run params) } (* expressions by now may have generated invalid expressions *) *) | _ -> match gen.gfollow#run_f e1.etype with | TFun _ -> dynamic_func_call { e with eexpr = TCall(run e1, List.map run params) } | _ -> let i = ref 0 in let t = TFun(List.map (fun e -> incr i; "arg" ^ (string_of_int !i), false, e.etype) params, e.etype) in dynamic_func_call { e with eexpr = TCall( mk_castfast t (run e1), List.map run params ) } ) | TFunction tf -> handle_anon_func e { tf with tf_expr = run tf.tf_expr } !info None | TCall({ eexpr = TConst(TSuper) }, _) -> Type.map_expr run e | TCall({ eexpr = TLocal(v) }, args) when String.get v.v_name 0 = '_' && Hashtbl.mem gen.gspecial_vars v.v_name -> Type.map_expr run e | TCall(tc,params) -> let i = ref 0 in let may_cast = match gen.gfollow#run_f tc.etype with | TFun _ -> fun e -> e | _ -> let t = TFun(List.map (fun e -> incr i; ("p" ^ (string_of_int !i), false, e.etype) ) params, e.etype) in fun e -> mk_castfast t e in dynamic_func_call { e with eexpr = TCall(run (may_cast tc), List.map run params) } | _ -> Type.map_expr run e in (match e.eexpr with | TFunction(tf) -> Type.map_expr run e | _ -> run e) let rec get_type_params acc t = match t with | TInst(( { cl_kind = KTypeParameter _ } as cl), []) -> if List.memq cl acc then acc else cl :: acc | TFun (params,tret) -> List.fold_left get_type_params acc ( tret :: List.map (fun (_,_,t) -> t) params ) | TDynamic t -> (match t with | TDynamic _ -> acc | _ -> get_type_params acc t) | TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) -> get_type_params acc ( Abstract.get_underlying_type a pl) | TAnon a -> PMap.fold (fun cf acc -> let params = List.map (fun (_,t) -> match follow t with | TInst(c,_) -> c | _ -> assert false) cf.cf_params in List.filter (fun t -> not (List.memq t params)) (get_type_params acc cf.cf_type) ) a.a_fields acc | TType(_, []) | TAbstract (_, []) | TInst(_, []) | TEnum(_, []) -> acc | TType(_, params) | TAbstract(_, params) | TEnum(_, params) | TInst(_, params) -> List.fold_left get_type_params acc params | TMono r -> (match !r with | Some t -> get_type_params acc t | None -> acc) | _ -> get_type_params acc (follow_once t) let get_captured expr = let ret = Hashtbl.create 1 in let ignored = Hashtbl.create 0 in let params = ref [] in let check_params t = params := get_type_params !params t in let rec traverse expr = match expr.eexpr with | TFor (v, _, _) -> Hashtbl.add ignored v.v_id v; check_params v.v_type; Type.iter traverse expr | TFunction(tf) -> List.iter (fun (v,_) -> Hashtbl.add ignored v.v_id v) tf.tf_args; (match follow expr.etype with | TFun(args,ret) -> List.iter (fun (_,_,t) -> check_params t ) args; check_params ret | _ -> ()); Type.iter traverse expr | TVar (v, opt) -> (match v.v_extra with | Some(_ :: _, _) -> () | _ -> check_params v.v_type); Hashtbl.add ignored v.v_id v; ignore(Option.map traverse opt) | TLocal { v_extra = Some( (_ :: _ ),_) } -> () | TLocal(( { v_capture = true } ) as v) -> (if not (Hashtbl.mem ignored v.v_id || Hashtbl.mem ret v.v_id) then begin check_params v.v_type; Hashtbl.replace ret v.v_id expr end); | _ -> Type.iter traverse expr in traverse expr; ret, !params (* OPTIMIZEME: Take off from Codegen the code that wraps captured variables, traverse through all variables, looking for their use (just like local_usage) three possible outcomes for captured variables: - become a function member variable <- best performance. Will not work on functions that can be created more than once (functions inside a loop or functions inside functions) The function will have to be created on top of the block, so its variables can be filled in instead of being declared - single-element array - the most compatible way, though also creates a slight overhead. - we'll have some labels for captured variables: - used in loop *) (* The default implementation will impose a naming convention: invoke(arity)_(o for returning object/d for returning double) when arity < max_arity invoke_dynamic_(o/d) when arity > max_arity This means that it also imposes that the dynamic function return types may only be Dynamic or Float, and all other basic types must be converted to/from it. *) let configure gen ft = let handle_anon_func fexpr tfunc mapinfo delegate_type : texpr * (tclass * texpr list) = let in_unsafe = mapinfo.in_unsafe || match gen.gcurrent_class, gen.gcurrent_classfield with | Some c, _ when Meta.has Meta.Unsafe c.cl_meta -> true | _, Some cf when Meta.has Meta.Unsafe cf.cf_meta -> true | _ -> false in (* get all captured variables it uses *) let captured_ht, tparams = get_captured fexpr in let captured = Hashtbl.fold (fun _ e acc -> e :: acc) captured_ht [] in let captured = List.sort (fun e1 e2 -> match e1, e2 with | { eexpr = TLocal v1 }, { eexpr = TLocal v2 } -> compare v1.v_name v2.v_name | _ -> assert false) captured in (*let cltypes = List.map (fun cl -> (snd cl.cl_path, TInst(map_param cl, []) )) tparams in*) let cltypes = List.map (fun cl -> (snd cl.cl_path, TInst(cl, []) )) tparams in (* create a new class that extends abstract function class, with a ctor implementation that will setup all captured variables *) let cfield = match gen.gcurrent_classfield with | None -> "Anon" | Some cf -> cf.cf_name in let cur_line = Lexer.get_error_line fexpr.epos in let path = (fst gen.gcurrent_path, Printf.sprintf "%s_%s_%d__Fun" (snd gen.gcurrent_path) cfield cur_line) in let cls = mk_class (get gen.gcurrent_class).cl_module path tfunc.tf_expr.epos in if in_unsafe then cls.cl_meta <- (Meta.Unsafe,[],null_pos) :: cls.cl_meta; if Common.defined gen.gcon Define.EraseGenerics then begin cls.cl_meta <- (Meta.HaxeGeneric,[],null_pos) :: cls.cl_meta end; cls.cl_module <- (get gen.gcurrent_class).cl_module; cls.cl_params <- cltypes; let mk_this v pos = { (mk_field_access gen { eexpr = TConst TThis; etype = TInst(cls, List.map snd cls.cl_params); epos = pos } v.v_name pos) with etype = v.v_type } in let mk_this_assign v pos = { eexpr = TBinop(OpAssign, mk_this v pos, { eexpr = TLocal(v); etype = v.v_type; epos = pos }); etype = v.v_type; epos = pos } in (* mk_class_field name t public pos kind params *) let ctor_args, ctor_sig, ctor_exprs = List.fold_left (fun (ctor_args, ctor_sig, ctor_exprs) lexpr -> match lexpr.eexpr with | TLocal(v) -> let cf = mk_class_field v.v_name v.v_type false lexpr.epos (Var({ v_read = AccNormal; v_write = AccNormal; })) [] in cls.cl_fields <- PMap.add v.v_name cf cls.cl_fields; cls.cl_ordered_fields <- cf :: cls.cl_ordered_fields; let ctor_v = alloc_var v.v_name v.v_type in ((ctor_v, None) :: ctor_args, (v.v_name, false, v.v_type) :: ctor_sig, (mk_this_assign v cls.cl_pos) :: ctor_exprs) | _ -> assert false ) ([],[],[]) captured in (* change all captured variables to this.capturedVariable *) let rec change_captured e = match e.eexpr with | TLocal( ({ v_capture = true }) as v ) when Hashtbl.mem captured_ht v.v_id -> mk_this v e.epos | _ -> Type.map_expr change_captured e in let func_expr = change_captured tfunc.tf_expr in let invokecf, invoke_field, super_args = match delegate_type with | None -> (* no delegate *) let ifield, sa = ft.closure_to_classfield { tfunc with tf_expr = func_expr } fexpr.etype fexpr.epos in ifield,ifield,sa | Some _ -> let pos = cls.cl_pos in let cf = mk_class_field "Delegate" (TFun(fun_args tfunc.tf_args, tfunc.tf_type)) true pos (Method MethNormal) [] in cf.cf_expr <- Some { fexpr with eexpr = TFunction { tfunc with tf_expr = func_expr }; }; cf.cf_meta <- (Meta.Final,[],pos) :: cf.cf_meta; cls.cl_ordered_fields <- cf :: cls.cl_ordered_fields; cls.cl_fields <- PMap.add cf.cf_name cf cls.cl_fields; (* invoke function body: call Delegate function *) let ibody = { eexpr = TCall({ eexpr = TField({ eexpr = TConst TThis; etype = TInst(cls, List.map snd cls.cl_params); epos = pos; }, FInstance(cls, List.map snd cls.cl_params, cf)); etype = cf.cf_type; epos = pos; }, List.map (fun (v,_) -> mk_local v pos) tfunc.tf_args); etype = tfunc.tf_type; epos = pos } in let ibody = if not (ExtType.is_void tfunc.tf_type) then { ibody with eexpr = TReturn( Some ibody ) } else ibody in let ifield, sa = ft.closure_to_classfield { tfunc with tf_expr = ibody } fexpr.etype fexpr.epos in cf,ifield,sa in (* create the constructor *) (* todo properly abstract how type var is set *) cls.cl_super <- Some(ft.func_class, []); let pos = cls.cl_pos in let super_call = { eexpr = TCall({ eexpr = TConst(TSuper); etype = TInst(ft.func_class,[]); epos = pos }, super_args); etype = gen.gcon.basic.tvoid; epos = pos; } in let ctor_type = (TFun(ctor_sig, gen.gcon.basic.tvoid)) in let ctor = mk_class_field "new" ctor_type true cls.cl_pos (Method(MethNormal)) [] in ctor.cf_expr <- Some( { eexpr = TFunction( { tf_args = ctor_args; tf_type = gen.gcon.basic.tvoid; tf_expr = { eexpr = TBlock(super_call :: ctor_exprs); etype = gen.gcon.basic.tvoid; epos = cls.cl_pos } }); etype = ctor_type; epos = cls.cl_pos; }); cls.cl_constructor <- Some(ctor); (* add invoke function to the class *) cls.cl_ordered_fields <- invoke_field :: cls.cl_ordered_fields; cls.cl_fields <- PMap.add invoke_field.cf_name invoke_field cls.cl_fields; cls.cl_overrides <- invoke_field :: cls.cl_overrides; gen.gadd_to_module (TClassDecl cls) priority; (* if there are no captured variables, we can create a cache so subsequent calls don't need to create a new function *) let expr, clscapt = match captured, tparams with | [], [] -> let cache_var = gen.gmk_internal_name "hx" "current" in let cache_cf = mk_class_field cache_var (TInst(cls,[])) false func_expr.epos (Var({ v_read = AccNormal; v_write = AccNormal })) [] in cls.cl_ordered_statics <- cache_cf :: cls.cl_ordered_statics; cls.cl_statics <- PMap.add cache_var cache_cf cls.cl_statics; (* if (FuncClass.hx_current != null) FuncClass.hx_current; else (FuncClass.hx_current = new FuncClass()); *) (* let mk_static_field_access cl field fieldt pos = *) let hx_current = mk_static_field_access cls cache_var (TInst(cls,[])) func_expr.epos in let pos = func_expr.epos in { fexpr with etype = hx_current.etype; eexpr = TIf( { eexpr = TBinop(OpNotEq, hx_current, null (TInst(cls,[])) pos); etype = gen.gcon.basic.tbool; epos = pos; }, hx_current, Some( { eexpr = TBinop(OpAssign, hx_current, { fexpr with eexpr = TNew(cls, [], captured) }); etype = (TInst(cls,[])); epos = pos; })) }, (cls,captured) | _ -> (* change the expression so it will be a new "added class" ( captured variables arguments ) *) { fexpr with eexpr = TNew(cls, List.map (fun cl -> TInst(cl,[])) tparams, List.rev captured) }, (cls,captured) in match delegate_type with | None -> expr,clscapt | Some _ -> { eexpr = TField(expr, FClosure(Some (cls,[]),invokecf)); (* TODO: FClosure change *) etype = invokecf.cf_type; epos = cls.cl_pos }, clscapt in let tvar_to_cdecl = Hashtbl.create 0 in let run = traverse gen ~tparam_anon_decl:(fun v e fn -> let _, info = handle_anon_func e fn null_map_info None in Hashtbl.add tvar_to_cdecl v.v_id info ) ~tparam_anon_acc:(fun v e -> try let cls, captured = Hashtbl.find tvar_to_cdecl v.v_id in let captured = List.sort (fun e1 e2 -> match e1, e2 with | { eexpr = TLocal v1 }, { eexpr = TLocal v2 } -> compare v1.v_name v2.v_name | _ -> assert false) captured in let types = match v.v_extra with | Some(t,_) -> t | _ -> assert false in let monos = List.map (fun _ -> mk_mono()) types in let vt = match follow v.v_type with | TInst(_, [v]) -> v | v -> v in let et = match follow e.etype with | TInst(_, [v]) -> v | v -> v in let original = apply_params types monos vt in unify et original; let monos = List.map (fun t -> apply_params types (List.map (fun _ -> t_dynamic) types) t) monos in let same_cl t1 t2 = match follow t1, follow t2 with | TInst(c,_), TInst(c2,_) -> c == c2 | _ -> false in let passoc = List.map2 (fun (_,t) m -> t,m) types monos in let cltparams = List.map (fun (_,t) -> try snd (List.find (fun (t2,_) -> same_cl t t2) passoc) with | Not_found -> t) cls.cl_params in { e with eexpr = TNew(cls, cltparams, List.rev captured) } with | Not_found -> gen.gcon.warning "This expression may be invalid" e.epos; e | Unify_error el -> List.iter (fun el -> gen.gcon.warning (Error.unify_error_msg (print_context()) el) e.epos) el; gen.gcon.warning "This expression may be invalid" e.epos; e ) (* (handle_anon_func:texpr->tfunc->texpr) (dynamic_func_call:texpr->texpr->texpr list->texpr) *) (fun e f info delegate_type -> fst (handle_anon_func e f info delegate_type)) ft.dynamic_fun_call (* (dynamic_func_call:texpr->texpr->texpr list->texpr) *) in let map e = Some(run e) in gen.gexpr_filters#add ~name:name ~priority:(PCustom priority) map (* this submodule will provide the default implementation for the C# and Java targets. it will have two return types: double and dynamic, and *) module DoubleAndDynamicClosureImpl = struct let get_ctx gen parent_func_class max_arity (* e.g. new haxe.lang.ClassClosure *) = let basic = gen.gcon.basic in let func_args_i i = let rec loop i (acc) = if i = 0 then (acc) else begin let vfloat = alloc_var (gen.gmk_internal_name "fn" ("float" ^ string_of_int i)) basic.tfloat in let vdyn = alloc_var (gen.gmk_internal_name "fn" ("dyn" ^ string_of_int i)) t_dynamic in loop (i - 1) ((vfloat, None) :: (vdyn, None) :: acc) end in loop i [] in let args_real_to_func args = let arity = List.length args in if arity >= max_arity then [ alloc_var (gen.gmk_internal_name "fn" "dynargs") (basic.tarray t_dynamic), None ] else func_args_i arity in let func_sig_i i = let rec loop i acc = if i = 0 then acc else begin let vfloat = gen.gmk_internal_name "fn" ("float" ^ string_of_int i) in let vdyn = gen.gmk_internal_name "fn" ("dyn" ^ string_of_int i) in loop (i - 1) ( (vfloat,false,basic.tfloat) :: (vdyn,false,t_dynamic) :: acc ) end in loop i [] in let args_real_to_func_sig args = let arity = List.length args in if arity >= max_arity then [gen.gmk_internal_name "fn" "dynargs", false, basic.tarray t_dynamic] else begin func_sig_i arity end in let rettype_real_to_func t = match run_follow gen t with | TType({ t_path = [],"Null" }, _) -> 0,t_dynamic | _ when like_float t && not (like_i64 t) -> (1, basic.tfloat) | _ -> (0, t_dynamic) in let args_real_to_func_call el (pos:pos) = if List.length el >= max_arity then [{ eexpr = TArrayDecl el; etype = basic.tarray t_dynamic; epos = pos }] else begin List.fold_left (fun acc e -> if like_float (gen.greal_type e.etype) && not (like_i64 (gen.greal_type e.etype)) then ( e :: undefined e.epos :: acc ) else ( null basic.tfloat e.epos :: e :: acc ) ) ([]) (List.rev el) end in let const_type c def = match c with | TString _ -> basic.tstring | TInt _ -> basic.tint | TFloat _ -> basic.tfloat | TBool _ -> basic.tbool | _ -> def in let get_args_func args changed_args pos = let arity = List.length args in let mk_const const elocal t = match const with | None -> mk_cast t elocal | Some const -> { eexpr = TIf( { elocal with eexpr = TBinop(Ast.OpEq, elocal, null elocal.etype elocal.epos); etype = basic.tbool }, { elocal with eexpr = TConst(const); etype = const_type const t }, Some ( mk_cast t elocal ) ); etype = t; epos = elocal.epos } in if arity >= max_arity then begin let varray = match changed_args with | [v,_] -> v | _ -> assert false in let varray_local = mk_local varray pos in let mk_varray i = { eexpr = TArray(varray_local, { eexpr = TConst(TInt(Int32.of_int i)); etype = basic.tint; epos = pos }); etype = t_dynamic; epos = pos } in snd (List.fold_left (fun (count,acc) (v,const) -> (count + 1, (mk (TVar(v, Some(mk_const const (mk_varray count) v.v_type))) basic.tvoid pos) :: acc) ) (0,[]) args) end else begin let _, dyn_args, float_args = List.fold_left (fun (count,fargs, dargs) arg -> if count land 1 = 0 then (count + 1, fargs, arg :: dargs) else (count + 1, arg :: fargs, dargs) ) (1,[],[]) (List.rev changed_args) in let rec loop acc args fargs dargs = match args, fargs, dargs with | [], [], [] -> acc | (v,const) :: args, (vf,_) :: fargs, (vd,_) :: dargs -> let acc = { eexpr = TVar(v, Some( { eexpr = TIf( { eexpr = TBinop(Ast.OpEq, mk_local vd pos, undefined pos); etype = basic.tbool; epos = pos }, mk_cast v.v_type (mk_local vf pos), Some ( mk_const const (mk_local vd pos) v.v_type ) ); etype = v.v_type; epos = pos } )); etype = basic.tvoid; epos = pos } :: acc in loop acc args fargs dargs | _ -> assert false in loop [] args float_args dyn_args end in let closure_to_classfield tfunc old_sig pos = (* change function signature *) let old_args = tfunc.tf_args in let changed_args = args_real_to_func old_args in (* FIXME properly handle int64 cases, which will break here (because of inference to int) UPDATE: the fix will be that Int64 won't be a typedef to Float/Int *) let changed_sig, arity, type_number, changed_sig_ret, is_void, is_dynamic_func = match follow old_sig with | TFun(_sig, ret) -> let type_n, ret_t = rettype_real_to_func ret in let arity = List.length _sig in let is_dynamic_func = arity >= max_arity in let ret_t = if is_dynamic_func then t_dynamic else ret_t in (TFun(args_real_to_func_sig _sig, ret_t), arity, type_n, ret_t, ExtType.is_void ret, is_dynamic_func) | _ -> (print_endline (s_type (print_context()) (follow old_sig) )); assert false in let tf_expr = if is_void then begin let rec map e = match e.eexpr with | TReturn None -> { e with eexpr = TReturn (Some (null t_dynamic e.epos)) } | _ -> Type.map_expr map e in let e = mk_block (map tfunc.tf_expr) in match e.eexpr with | TBlock(bl) -> { e with eexpr = TBlock(bl @ [{ eexpr = TReturn (Some (null t_dynamic e.epos)); etype = t_dynamic; epos = e.epos }]) } | _ -> assert false end else tfunc.tf_expr in let changed_sig_ret = if is_dynamic_func then t_dynamic else changed_sig_ret in (* get real arguments on top of function body *) let get_args = get_args_func tfunc.tf_args changed_args pos in (* FIXME HACK: in order to be able to run the filters that have already ran for this piece of code, we will cheat and run it as if it was the whole code We could just make ClosuresToClass run before TArrayTransform, but we cannot because of the dependency between ClosuresToClass (after DynamicFieldAccess, and before TArrayTransform) maybe a way to solve this would be to add an "until" field to run_from *) let real_get_args = gen.gexpr_filters#run_f { eexpr = TBlock(get_args); etype = basic.tvoid; epos = pos } in let func_expr = Type.concat real_get_args tf_expr in (* set invoke function *) (* todo properly abstract how naming for invoke is made *) let invoke_name = if is_dynamic_func then "invokeDynamic" else ("invoke" ^ (string_of_int arity) ^ (if type_number = 0 then "_o" else "_f")) in let invoke_name = gen.gmk_internal_name "hx" invoke_name in let invoke_field = mk_class_field invoke_name changed_sig false func_expr.epos (Method(MethNormal)) [] in let invoke_fun = { eexpr = TFunction { tf_args = changed_args; tf_type = changed_sig_ret; tf_expr = func_expr; }; etype = changed_sig; epos = func_expr.epos; } in invoke_field.cf_expr <- Some invoke_fun; invoke_field, [ ExprBuilder.make_int gen.gcon arity pos; ExprBuilder.make_int gen.gcon type_number pos; ] in let dynamic_fun_call call_expr = let tc, params = match call_expr.eexpr with | TCall(tc, params) -> tc, params | _ -> assert false in let ct = gen.greal_type call_expr.etype in let postfix, ret_t = if like_float ct && not (like_i64 ct) then "_f", gen.gcon.basic.tfloat else "_o", t_dynamic in let params_len = List.length params in let ret_t = if params_len >= max_arity then t_dynamic else ret_t in let invoke_fun = if params_len >= max_arity then "invokeDynamic" else "invoke" ^ (string_of_int params_len) ^ postfix in let invoke_fun = gen.gmk_internal_name "hx" invoke_fun in let fun_t = match follow tc.etype with | TFun(_sig, _) -> TFun(args_real_to_func_sig _sig, ret_t) | _ -> let i = ref 0 in let _sig = List.map (fun p -> let name = "arg" ^ (string_of_int !i) in incr i; (name,false,p.etype) ) params in TFun(args_real_to_func_sig _sig, ret_t) in let may_cast = match follow call_expr.etype with | TAbstract ({ a_path = ([], "Void") },[]) -> (fun e -> e) | _ -> mk_cast call_expr.etype in may_cast { eexpr = TCall( { (mk_field_access gen { tc with etype = gen.greal_type tc.etype } invoke_fun tc.epos) with etype = fun_t }, args_real_to_func_call params call_expr.epos ); etype = ret_t; epos = call_expr.epos } in let iname i is_float = let postfix = if is_float then "_f" else "_o" in gen.gmk_internal_name "hx" ("invoke" ^ string_of_int i) ^ postfix in let map_base_classfields cl map_fn = let pos = cl.cl_pos in let this_t = TInst(cl,List.map snd cl.cl_params) in let this = { eexpr = TConst(TThis); etype = this_t; epos = pos } in let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in let mk_invoke_i i is_float = let cf = mk_class_field (iname i is_float) (TFun(func_sig_i i, if is_float then basic.tfloat else t_dynamic)) false pos (Method MethNormal) [] in cf in let type_name = gen.gmk_internal_name "fn" "type" in let dynamic_arg = alloc_var (gen.gmk_internal_name "fn" "dynargs") (basic.tarray t_dynamic) in let mk_invoke_complete_i i is_float = (* let arity = i in *) let args = func_args_i i in (* api fn *) (* only cast if needed *) let mk_cast tto efrom = gen.ghandle_cast (gen.greal_type tto) (gen.greal_type efrom.etype) efrom in let api i t const = let vf, _ = List.nth args (i * 2) in let vo, _ = List.nth args (i * 2 + 1) in let needs_cast, is_float = match t, like_float t && not (like_i64 t) with | TAbstract({ a_path = ([], "Float") },[]), _ -> false, true | _, true -> true, true | _ -> false,false in let olocal = mk_local vo pos in let flocal = mk_local vf pos in let get_from_obj e = match const with | None -> mk_cast t e | Some tc -> { eexpr = TIf( { eexpr = TBinop(Ast.OpEq, olocal, null t_dynamic pos); etype = basic.tbool; epos = pos } , { eexpr = TConst(tc); etype = t; epos = pos }, Some (mk_cast t e) ); etype = t; epos = pos; } in { eexpr = TIf( { eexpr = TBinop(Ast.OpEq, olocal, undefined pos); etype = basic.tbool; epos = pos }, (if needs_cast then mk_cast t flocal else flocal), Some ( get_from_obj olocal ) ); etype = t; epos = pos } in (* end of api fn *) let ret = if is_float then basic.tfloat else t_dynamic in let fn_expr = map_fn i ret (List.map fst args) api in let t = TFun(fun_args args, ret) in let tfunction = { eexpr = TFunction({ tf_args = args; tf_type = ret; tf_expr = mk_block fn_expr }); etype = t; epos = pos; } in let cf = mk_invoke_i i is_float in cf.cf_expr <- Some tfunction; cf in let rec loop i cfs = if i < 0 then cfs else begin (*let mk_invoke_complete_i i is_float =*) (mk_invoke_complete_i i false) :: (mk_invoke_complete_i i true) :: (loop (i-1) cfs) end in let cfs = loop max_arity [] in let switch = let api i t const = match i with | -1 -> mk_local dynamic_arg pos | _ -> mk_cast t { eexpr = TArray( mk_local dynamic_arg pos, { eexpr = TConst(TInt(Int32.of_int i)); etype = basic.tint; epos = pos }); etype = t; epos = pos; } in map_fn (-1) t_dynamic [dynamic_arg] api in let args = [dynamic_arg, None] in let dyn_t = TFun(fun_args args, t_dynamic) in let dyn_cf = mk_class_field (gen.gmk_internal_name "hx" "invokeDynamic") dyn_t false pos (Method MethNormal) [] in dyn_cf.cf_expr <- Some { eexpr = TFunction { tf_args = args; tf_type = t_dynamic; tf_expr = mk_block switch }; etype = dyn_t; epos = pos; }; let additional_cfs = begin let new_t = TFun(["arity", false, basic.tint; "type", false, basic.tint],basic.tvoid) in let new_cf = mk_class_field "new" (new_t) true pos (Method MethNormal) [] in let v_arity, v_type = alloc_var "arity" basic.tint, alloc_var "type" basic.tint in let mk_assign v field = mk (TBinop (OpAssign, mk_this field v.v_type, mk_local v pos)) v.v_type pos in let arity_name = gen.gmk_internal_name "hx" "arity" in new_cf.cf_expr <- Some { eexpr = TFunction({ tf_args = [v_arity, None; v_type, None]; tf_type = basic.tvoid; tf_expr = { eexpr = TBlock([ mk_assign v_type type_name; mk_assign v_arity arity_name ]); etype = basic.tvoid; epos = pos; } }); etype = new_t; epos = pos; }; [ new_cf; mk_class_field type_name basic.tint true pos (Var { v_read = AccNormal; v_write = AccNormal }) []; mk_class_field arity_name basic.tint true pos (Var { v_read = AccNormal; v_write = AccNormal }) []; ] end in dyn_cf :: (additional_cfs @ cfs) in begin (* setup fields for the abstract implementation of the Function class new(arity, type) { this.arity = arity; this.type = type; } hx::invokeX_f|o (where X is from 0 to max_arity) (args) { if (this.type == 0|1) return invokeX_o|f(args); else throw "Invalid number of arguments." } hx::invokeDynamic, which will work in the same way *) let cl = parent_func_class in let pos = cl.cl_pos in let rec mk_dyn_call arity api = let zero = ExprBuilder.make_float gen.gcon "0.0" pos in let rec loop i acc = if i = 0 then acc else begin let arr = api (i - 1) t_dynamic None in loop (i - 1) (zero :: arr :: acc) end in loop arity [] in let this = mk (TConst TThis) (TInst (cl, List.map snd cl.cl_params)) pos in let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in let mk_invoke_switch i api = let t = TFun (func_sig_i i, t_dynamic) in (* case i: return this.invokeX_o(0, 0, 0, 0, 0, ... arg[0], args[1]....); *) [ExprBuilder.make_int gen.gcon i pos], mk_return (mk (TCall(mk_this (iname i false) t, mk_dyn_call i api)) t_dynamic pos) in let rec loop_cases api arity acc = if arity < 0 then acc else loop_cases api (arity - 1) (mk_invoke_switch arity api :: acc) in let type_name = gen.gmk_internal_name "fn" "type" in let mk_expr i is_float vars = let call_expr = let call_t = TFun(List.map (fun v -> (v.v_name, false, v.v_type)) vars, if is_float then t_dynamic else basic.tfloat) in { eexpr = TCall(mk_this (iname i (not is_float)) call_t, List.map (fun v -> mk_local v pos) vars); etype = if is_float then t_dynamic else basic.tfloat; epos = pos } in { eexpr = TIf( mk (TBinop (Ast.OpNotEq, mk_this type_name basic.tint, (ExprBuilder.make_int gen.gcon (if is_float then 0 else 1) pos))) basic.tbool pos, mk (TThrow (ExprBuilder.make_string gen.gcon "Wrong number of arguments" pos)) t_dynamic pos, Some (mk_return call_expr) ); etype = t_dynamic; epos = pos; } in let arities_processed = Hashtbl.create 10 in let max_arity = ref 0 in let map_fn cur_arity fun_ret_type vars (api:int->t->tconstant option->texpr) = let is_float = like_float fun_ret_type && not (like_i64 fun_ret_type) in match cur_arity with | -1 -> let dynargs = api (-1) t_dynamic None in (* (dynargs == null) ? 0 : dynargs.length *) let switch_cond = { eexpr = TIf( mk (TBinop (OpEq, dynargs, null dynargs.etype pos)) basic.tbool pos, mk (TConst (TInt Int32.zero)) basic.tint pos, Some (mk_field_access gen dynargs "length" pos)); etype = basic.tint; epos = pos; } in { eexpr = TSwitch( switch_cond, loop_cases api !max_arity [], Some(mk (TThrow (ExprBuilder.make_string gen.gcon "Too many arguments" pos)) basic.tvoid pos)); etype = basic.tvoid; epos = pos; } | _ -> if not (Hashtbl.mem arities_processed cur_arity) then begin Hashtbl.add arities_processed cur_arity true; if cur_arity > !max_arity then max_arity := cur_arity end; mk_expr cur_arity is_float vars in let cfs = map_base_classfields cl map_fn in List.iter (fun cf -> if cf.cf_name = "new" then parent_func_class.cl_constructor <- Some cf else parent_func_class.cl_fields <- PMap.add cf.cf_name cf parent_func_class.cl_fields ) cfs; parent_func_class.cl_ordered_fields <- (List.filter (fun cf -> cf.cf_name <> "new") cfs) @ parent_func_class.cl_ordered_fields end; { func_class = parent_func_class; closure_to_classfield = closure_to_classfield; dynamic_fun_call = dynamic_fun_call; map_base_classfields = map_base_classfields; } end;; end;; (* ******************************************* *) (* Type Parameters *) (* ******************************************* *) (* This module will handle type parameters. There are lots of changes we need to do to correctly support type parameters: traverse will: V Detect when parameterized function calls are made * Detect when a parameterized class instance is being cast to another parameter * Change new<> parameterized function calls * extras: * On languages that support "real" type parameters, a Cast function is provided that will convert from a to the requested type. This cast will call createEmpty with the correct type, and then set each variable to the new form. Some types will be handled specially, namely the Native Array. Other implementations may be delegated to the runtime. * parameterized classes will implement a new interface (with only a Cast<> function added to it), so we can access the type parameter for them. Also any reference to will be replaced by a reference to this interface. (also on TTypeExpr - Std.is()) * Type parameter renaming to avoid name clash * Detect type parameter casting and call Cast<> instead for java: * for specially assigned classes, parameters will be replaced by _d and _i versions of parameterized functions. This will only work for parameterized classes, not functions. dependencies: must run after casts are detected. This will be ensured at CastDetect module. *) module TypeParams = struct let name = "type_params" let priority = max_dep -. 20. (* this function will receive the original function argument, the applied function argument and the original function parameters. *) (* from this info, it will infer the applied tparams for the function *) (* this function is used by CastDetection module *) let infer_params gen pos (original_args:((string * bool * t) list * t)) (applied_args:((string * bool * t) list * t)) (params:(string * t) list) calls_parameters_explicitly : tparams = match params with | [] -> [] | _ -> let args_list args = (if not calls_parameters_explicitly then t_dynamic else snd args) :: (List.map (fun (n,o,t) -> t) (fst args)) in let monos = List.map (fun _ -> mk_mono()) params in let original = args_list (get_fun (apply_params params monos (TFun(fst original_args,snd original_args)))) in let applied = args_list applied_args in (try List.iter2 (fun a o -> unify a o (* type_eq EqStrict a o *) ) applied original (* unify applied original *) with | Unify_error el -> (* List.iter (fun el -> gen.gcon.warning (Typecore.unify_error_msg (print_context()) el) pos) el; *) gen.gcon.warning ("This expression may be invalid") pos | Invalid_argument("List.map2") -> gen.gcon.warning ("This expression may be invalid") pos ); List.map (fun t -> match follow t with | TMono _ -> t_empty | t -> t ) monos (* ******************************************* *) (* Real Type Parameters Module *) (* ******************************************* *) (* This submodule is by now specially made for the .NET platform. There might be other targets that will make use of this, but it IS very specific. On the .NET platform, generics are real specialized classes that are JIT compiled. For this reason, we cannot cast from one type parameter to another. Also there is no common type for the type parameters, so for example an instance of type Array will return false for instance is Array . So we need to: 1. create a common interface (without type parameters) (e.g. "Array") which will only contain a __Cast<> function, which will cast from one type into another 2. Implement the __Cast function. This part is a little hard, as we must identify all type parameter-dependent fields contained in the class and convert them. In most cases the conversion will just be to call .__Cast<>() on the instances, or just a simple cast. But when the instance is a @:nativegen type, there will be no .__Cast function, and we will need to deal with this case either at compile-time (added handlers - specially for NativeArray), or at runtime (adding new runtime handlers) 3. traverse the AST looking for casts involving type parameters, and replace them with .__Cast<>() calls. If type is @:nativegen, throw a warning. If really casting from one type parameter to another on a @:nativegen context, throw an error. special literals: it will use the special literal __typehandle__ that the target must implement in order to run this. This literal is a way to get the typehandle of e.g. the type parameters, so we can compare them. In C# it's the equivalent of typeof(T).TypeHandle (TypeHandle compare is faster than System.Type.Equals()) dependencies: (module filter) Interface creation must run AFTER enums are converted into classes, otherwise there is no way to tell parameterized enums to implement an interface Must run AFTER CastDetect. This will be ensured per CastDetect *) module RealTypeParams = struct let name = "real_type_params" let priority = priority let rec has_type_params t = match follow t with | TInst( { cl_kind = KTypeParameter _ }, _) -> true | TAbstract(_, params) | TEnum(_, params) | TInst(_, params) -> List.exists (fun t -> has_type_params t) params | TFun(args,ret) -> List.exists (fun (n,o,t) -> has_type_params t) args || has_type_params ret | _ -> false let rec follow_all_md md = let t = match md with | TClassDecl { cl_kind = KAbstractImpl a } -> TAbstract(a, List.map snd a.a_params) | TClassDecl c -> TInst(c, List.map snd c.cl_params) | TEnumDecl e -> TEnum(e, List.map snd e.e_params) | TTypeDecl t -> TType(t, List.map snd t.t_params) | TAbstractDecl a -> TAbstract(a, List.map snd a.a_params) in Abstract.follow_with_abstracts t let rec is_hxgeneric md = match md with | TClassDecl { cl_kind = KAbstractImpl a } -> is_hxgeneric (TAbstractDecl a) | TClassDecl(cl) -> not (Meta.has Meta.NativeGeneric cl.cl_meta) | TEnumDecl(e) -> not (Meta.has Meta.NativeGeneric e.e_meta) | TAbstractDecl(a) when Meta.has Meta.NativeGeneric a.a_meta -> not (Meta.has Meta.NativeGeneric a.a_meta) | md -> match follow_all_md md with | TInst(cl,_) -> is_hxgeneric (TClassDecl cl) | TEnum(e,_) -> is_hxgeneric (TEnumDecl e) | TAbstract(a,_) -> not (Meta.has Meta.NativeGeneric a.a_meta) | _ -> true let rec set_hxgeneric gen mds isfirst md = let path = t_path md in if List.exists (fun m -> path = t_path m) mds then begin if isfirst then None (* we still can't determine *) else Some true (* if we're in second pass and still can't determine, it's because it can be hxgeneric *) end else begin let has_unresolved = ref false in let is_false v = match v with | Some false -> true | None -> has_unresolved := true; false | Some true -> false in let mds = md :: mds in match md with | TClassDecl(cl) -> (* first see if any meta is present (already processed) *) if Meta.has Meta.NativeGeneric cl.cl_meta then Some false else if Meta.has Meta.HaxeGeneric cl.cl_meta then Some true else if cl.cl_params = [] && is_hxgen md then (cl.cl_meta <- (Meta.HaxeGeneric,[],cl.cl_pos) :: cl.cl_meta; Some true) else if cl.cl_params = [] then (cl.cl_meta <- (Meta.NativeGeneric, [], cl.cl_pos) :: cl.cl_meta; Some false) else if not (is_hxgen md) then (cl.cl_meta <- (Meta.NativeGeneric, [], cl.cl_pos) :: cl.cl_meta; Some false) else begin (* if it's not present, see if any superclass is nativegeneric. nativegeneric is inherited, while hxgeneric can be later changed to nativegeneric *) (* on the first pass, our job is to find any evidence that makes it not be hxgeneric. Otherwise it will be hxgeneric *) match cl.cl_super with | Some (c,_) when is_false (set_hxgeneric gen mds isfirst (TClassDecl c)) -> cl.cl_meta <- (Meta.NativeGeneric, [], cl.cl_pos) :: cl.cl_meta; Some false | _ -> (* see if it's a generic class *) match cl.cl_params with | [] -> (* if it's not, then it will follow hxgen *) if is_hxgen (TClassDecl cl) then cl.cl_meta <- (Meta.HaxeGeneric, [], cl.cl_pos) :: cl.cl_meta else cl.cl_meta <- (Meta.NativeGeneric, [], cl.cl_pos) :: cl.cl_meta; Some true | _ -> (* if it is, loop through all fields + statics and look for non-hxgeneric generic classes that have KTypeParameter as params *) let rec loop cfs = match cfs with | [] -> false | cf :: cfs -> let t = follow (gen.greal_type cf.cf_type) in match t with | TInst( { cl_kind = KTypeParameter _ }, _ ) -> loop cfs | TInst(cl,p) when has_type_params t && is_false (set_hxgeneric gen mds isfirst (TClassDecl cl)) -> if not (Hashtbl.mem gen.gtparam_cast cl.cl_path) then true else loop cfs | TEnum(e,p) when has_type_params t && is_false (set_hxgeneric gen mds isfirst (TEnumDecl e)) -> if not (Hashtbl.mem gen.gtparam_cast e.e_path) then true else loop cfs | _ -> loop cfs (* TAbstracts / Dynamics can't be generic *) in if loop cl.cl_ordered_fields then begin cl.cl_meta <- (Meta.NativeGeneric, [], cl.cl_pos) :: cl.cl_meta; Some false end else if isfirst && !has_unresolved then None else begin cl.cl_meta <- (Meta.HaxeGeneric, [], cl.cl_pos) :: cl.cl_meta; Some true end end | TEnumDecl e -> if Meta.has Meta.NativeGeneric e.e_meta then Some false else if Meta.has Meta.HaxeGeneric e.e_meta then Some true else if not (is_hxgen (TEnumDecl e)) then begin e.e_meta <- (Meta.NativeGeneric, [], e.e_pos) :: e.e_meta; Some false end else begin (* if enum is not generic, then it's hxgeneric *) match e.e_params with | [] -> e.e_meta <- (Meta.HaxeGeneric, [], e.e_pos) :: e.e_meta; Some true | _ -> let rec loop efs = match efs with | [] -> false | ef :: efs -> let t = follow (gen.greal_type ef.ef_type) in match t with | TFun(args, _) -> if List.exists (fun (n,o,t) -> let t = follow t in match t with | TInst( { cl_kind = KTypeParameter _ }, _ ) -> false | TInst(cl,p) when has_type_params t && is_false (set_hxgeneric gen mds isfirst (TClassDecl cl)) -> not (Hashtbl.mem gen.gtparam_cast cl.cl_path) | TEnum(e,p) when has_type_params t && is_false (set_hxgeneric gen mds isfirst (TEnumDecl e)) -> not (Hashtbl.mem gen.gtparam_cast e.e_path) | _ -> false ) args then true else loop efs | _ -> loop efs in let efs = PMap.fold (fun ef acc -> ef :: acc) e.e_constrs [] in if loop efs then begin e.e_meta <- (Meta.NativeGeneric, [], e.e_pos) :: e.e_meta; Some false end else if isfirst && !has_unresolved then None else begin e.e_meta <- (Meta.HaxeGeneric, [], e.e_pos) :: e.e_meta; Some true end end | _ -> assert false end let set_hxgeneric gen md = let ret = match md with | TClassDecl { cl_kind = KAbstractImpl a } -> (match follow_all_md md with | (TInst _ | TEnum _ as t) -> ( let md = match t with | TInst(cl,_) -> TClassDecl cl | TEnum(e,_) -> TEnumDecl e | _ -> assert false in let ret = set_hxgeneric gen [] true md in if ret = None then get (set_hxgeneric gen [] false md) else get ret) | TAbstract(a,_) -> true | _ -> true) | _ -> match set_hxgeneric gen [] true md with | None -> get (set_hxgeneric gen [] false md) | Some v -> v in if not ret then begin match md with | TClassDecl c -> let set_hxgeneric (_,param) = match follow param with | TInst(c,_) -> c.cl_meta <- (Meta.NativeGeneric, [], c.cl_pos) :: c.cl_meta | _ -> () in List.iter set_hxgeneric c.cl_params; let rec handle_field cf = List.iter set_hxgeneric cf.cf_params; List.iter handle_field cf.cf_overloads in (match c.cl_kind with | KAbstractImpl a -> List.iter set_hxgeneric a.a_params; | _ -> ()); List.iter handle_field c.cl_ordered_fields; List.iter handle_field c.cl_ordered_statics | _ -> () end; ret let params_has_tparams params = List.fold_left (fun acc t -> acc || has_type_params t) false params (* ******************************************* *) (* RealTypeParamsModf *) (* ******************************************* *) (* This is the module filter of Real Type Parameters. It will traverse through all types and look for hxgeneric classes (only classes). When found, a parameterless interface will be created and associated via the "ifaces" Hashtbl to the original class. Also a "cast" function will be automatically generated which will handle unsafe downcasts to more specific type parameters (necessary for serialization) dependencies: Anything that may create hxgeneric classes must run before it. Should run before ReflectionCFs (this dependency will be added to ReflectionCFs), so the added interfaces also get to be real IHxObject's *) module RealTypeParamsModf = struct let set_only_hxgeneric gen = let rec run md = match md with | TTypeDecl _ | TAbstractDecl _ -> md | _ -> ignore (set_hxgeneric gen md); md in run let name = "real_type_params_modf" let priority = solve_deps name [] let rec get_fields gen cl params_cl params_cf acc = let fields = List.fold_left (fun acc cf -> match follow (gen.greal_type (gen.gfollow#run_f (cf.cf_type))) with | TInst(cli, ((_ :: _) as p)) when (not (is_hxgeneric (TClassDecl cli))) && params_has_tparams p -> (cf, apply_params cl.cl_params params_cl cf.cf_type, apply_params cl.cl_params params_cf cf.cf_type) :: acc | TEnum(e, ((_ :: _) as p)) when not (is_hxgeneric (TEnumDecl e)) && params_has_tparams p -> (cf, apply_params cl.cl_params params_cl cf.cf_type, apply_params cl.cl_params params_cf cf.cf_type) :: acc | _ -> acc ) [] cl.cl_ordered_fields in match cl.cl_super with | Some(cs, tls) -> get_fields gen cs (List.map (apply_params cl.cl_params params_cl) tls) (List.map (apply_params cl.cl_params params_cf) tls) (fields @ acc) | None -> (fields @ acc) let get_cast_name cl = String.concat "_" ((fst cl.cl_path) @ [snd cl.cl_path; "cast"]) (* explicitly define it *) (* overrides all needed cast functions from super classes / interfaces to call the new cast function *) let create_stub_casts gen cl cast_cfield = (* go through superclasses and interfaces *) let p = cl.cl_pos in let this = { eexpr = TConst TThis; etype = (TInst(cl, List.map snd cl.cl_params)); epos = p } in let rec loop cls tls level reverse_params = if (level <> 0 || cls.cl_interface) && tls <> [] && is_hxgeneric (TClassDecl cls) then begin let cparams = List.map (fun (s,t) -> (s, TInst (map_param (get_cl_t t), []))) cls.cl_params in let name = get_cast_name cls in if not (PMap.mem name cl.cl_fields) then begin let reverse_params = List.map (apply_params cls.cl_params (List.map snd cparams)) reverse_params in let cfield = mk_class_field name (TFun([], t_dynamic)) false cl.cl_pos (Method MethNormal) cparams in let field = { eexpr = TField(this, FInstance(cl,List.map snd cl.cl_params, cast_cfield)); etype = apply_params cast_cfield.cf_params reverse_params cast_cfield.cf_type; epos = p } in let call = { eexpr = TCall(field, []); etype = t_dynamic; epos = p; } in let call = gen.gparam_func_call call field reverse_params [] in let delay () = cfield.cf_expr <- Some { eexpr = TFunction( { tf_args = []; tf_type = t_dynamic; tf_expr = { eexpr = TReturn( Some call ); etype = t_dynamic; epos = p; } }); etype = cfield.cf_type; epos = p; } in gen.gafter_filters_ended <- delay :: gen.gafter_filters_ended; (* do not let filters alter this expression content *) cl.cl_ordered_fields <- cfield :: cl.cl_ordered_fields; cl.cl_fields <- PMap.add cfield.cf_name cfield cl.cl_fields; if level <> 0 then cl.cl_overrides <- cfield :: cl.cl_overrides end end; let get_reverse super supertl = let kv = List.map2 (fun (_,tparam) applied -> (follow applied, follow tparam)) super.cl_params supertl in List.map (fun t -> try List.assq (follow t) kv with | Not_found -> t ) reverse_params in (match cls.cl_super with | None -> () | Some(super, supertl) -> loop super supertl (level + 1) (get_reverse super supertl)); List.iter (fun (iface, ifacetl) -> loop iface ifacetl level (get_reverse iface ifacetl) ) cls.cl_implements in loop cl (List.map snd cl.cl_params) 0 (List.map snd cl.cl_params) (* Creates a cast classfield, with the desired name Will also look for previous cast() definitions and override them, to reflect the current type and fields FIXME: this function still doesn't support generics that extend generics, and are cast as one of its subclasses. This needs to be taken care, by looking at previous superclasses and whenever a generic class is found, its cast argument must be overriden. the toughest part is to know how to type the current type correctly. *) let create_cast_cfield gen cl name = let basic = gen.gcon.basic in let cparams = List.map (fun (s,t) -> (s, TInst (map_param (get_cl_t t), []))) cl.cl_params in let cfield = mk_class_field name (TFun([], t_dynamic)) false cl.cl_pos (Method MethNormal) cparams in let params = List.map snd cparams in let fields = get_fields gen cl (List.map snd cl.cl_params) params [] in (* now create the contents of the function *) (* it will look something like: if (typeof(T) == typeof(T2)) return this; var new_me = new CurrentClass(EmptyInstnace); for (field in Reflect.fields(this)) { switch(field) { case "aNativeArray": var newArray = new NativeArray(this.aNativeArray.Length); default: Reflect.setField(new_me, field, Reflect.field(this, field)); } } *) let new_t = TInst(cl, params) in let pos = cl.cl_pos in let new_me_var = alloc_var "new_me" new_t in let local_new_me = { eexpr = TLocal(new_me_var); etype = new_t; epos = pos } in let this = { eexpr = TConst(TThis); etype = (TInst(cl, List.map snd cl.cl_params)); epos = pos } in let field_var = alloc_var "field" gen.gcon.basic.tstring in let local_field = { eexpr = TLocal(field_var); etype = field_var.v_type; epos = pos } in let i_var = alloc_var "i" gen.gcon.basic.tint in let local_i = { eexpr = TLocal(i_var); etype = gen.gcon.basic.tint; epos = pos } in let incr_i = { eexpr = TUnop(Ast.Increment, Ast.Postfix, local_i); etype = basic.tint; epos = pos } in let fields_var = alloc_var "fields" (gen.gcon.basic.tarray gen.gcon.basic.tstring) in let local_fields = { eexpr = TLocal(fields_var); etype = (gen.gcon.basic.tarray gen.gcon.basic.tstring); epos = pos } in let get_path t = match follow t with | TInst(cl,_) -> cl.cl_path | TEnum(e,_) -> e.e_path | TAbstract(a,_) -> a.a_path | TMono _ | TDynamic _ -> ([], "Dynamic") | _ -> assert false in (* this will take all fields that were *) let fields_to_cases fields = List.map (fun (cf, t_cl, t_cf) -> let this_field = { eexpr = TField(this, FInstance(cl, List.map snd cl.cl_params, cf)); etype = t_cl; epos = pos } in let expr = { eexpr = TBinop(OpAssign, { eexpr = TField(local_new_me, FInstance(cl, List.map snd cl.cl_params, cf) ); etype = t_cf; epos = pos }, try (Hashtbl.find gen.gtparam_cast (get_path t_cf)) this_field t_cf with | Not_found -> (* if not found tparam cast, it shouldn't be a valid hxgeneric *) assert false ); etype = t_cf; epos = pos; } in [ExprBuilder.make_string gen.gcon cf.cf_name pos], expr ) fields in let mk_typehandle = let thandle = alloc_var "__typeof__" t_dynamic in (fun cl -> { eexpr = TCall(mk_local thandle pos, [ ExprBuilder.make_static_this cl pos ]); etype = t_dynamic; epos = pos }) in let mk_eq cl1 cl2 = { eexpr = TBinop(Ast.OpEq, mk_typehandle cl1, mk_typehandle cl2); etype = basic.tbool; epos = pos } in let rec mk_typehandle_cond thisparams cfparams = match thisparams, cfparams with | TInst(cl_this,[]) :: [], TInst(cl_cf,[]) :: [] -> mk_eq cl_this cl_cf | TInst(cl_this,[]) :: hd, TInst(cl_cf,[]) :: hd2 -> { eexpr = TBinop(Ast.OpBoolAnd, mk_eq cl_this cl_cf, mk_typehandle_cond hd hd2); etype = basic.tbool; epos = pos } | v :: hd, v2 :: hd2 -> (match follow v, follow v2 with | (TInst(cl1,[]) as v), (TInst(cl2,[]) as v2) -> mk_typehandle_cond (v :: hd) (v2 :: hd2) | _ -> assert false ) | _ -> assert false in let fn = { tf_args = []; tf_type = t_dynamic; tf_expr = { eexpr = TBlock([ (* if (typeof(T) == typeof(T2)) return this *) { eexpr = TIf( mk_typehandle_cond (List.map snd cl.cl_params) params, mk_return this, None); etype = basic.tvoid; epos = pos; }; (* var new_me = /*special create empty with tparams construct*/ *) { eexpr = TVar(new_me_var, Some(gen.gtools.r_create_empty cl params pos)); etype = gen.gcon.basic.tvoid; epos = pos }; (* var fields = Reflect.fields(this); *) { eexpr = TVar(fields_var, Some(gen.gtools.r_fields true this)); etype = gen.gcon.basic.tvoid; epos = pos }; (* var i = 0; *) { eexpr = TVar(i_var, Some(ExprBuilder.make_int gen.gcon 0 pos)); etype = gen.gcon.basic.tvoid; epos = pos }; { eexpr = TWhile( (* while (i < fields.length) *) { eexpr = TBinop(Ast.OpLt, local_i, mk_field_access gen local_fields "length" pos); etype = gen.gcon.basic.tbool; epos = pos }, { eexpr = TBlock [ (* var field = fields[i++]; *) { eexpr = TVar(field_var, Some { eexpr = TArray (local_fields, incr_i); etype = gen.gcon.basic.tstring; epos = pos }); etype = gen.gcon.basic.tvoid; epos = pos }; ( (* default: Reflect.setField(new_me, field, Reflect.field(this, field)) *) let edef = gen.gtools.r_set_field gen.gcon.basic.tvoid local_new_me local_field (gen.gtools.r_field false gen.gcon.basic.tvoid this local_field) in if fields <> [] then (* switch(field) { ... } *) { eexpr = TSwitch(local_field, fields_to_cases fields, Some(edef)); etype = gen.gcon.basic.tvoid; epos = pos; } else edef; ) ]; etype = gen.gcon.basic.tvoid; epos = pos }, Ast.NormalWhile ); etype = gen.gcon.basic.tvoid; epos = pos; }; (* return new_me *) mk_return local_new_me ]); etype = t_dynamic; epos = pos; }; } in cfield.cf_expr <- Some( { eexpr = TFunction(fn); etype = cfield.cf_type; epos = pos } ); cfield let create_static_cast_cf gen iface cf = let p = iface.cl_pos in let basic = gen.gcon.basic in let cparams = List.map (fun (s,t) -> ("To_" ^ s, TInst (map_param (get_cl_t t), []))) cf.cf_params in let me_type = TInst(iface,[]) in let cfield = mk_class_field "__hx_cast" (TFun(["me",false,me_type], t_dynamic)) false iface.cl_pos (Method MethNormal) (cparams) in let params = List.map snd cparams in let me = alloc_var "me" me_type in let field = { eexpr = TField(mk_local me p, FInstance(iface, List.map snd iface.cl_params, cf)); etype = apply_params cf.cf_params params cf.cf_type; epos = p } in let call = { eexpr = TCall(field, []); etype = t_dynamic; epos = p; } in let call = gen.gparam_func_call call field params [] in (* since object.someCall() isn't allowed on Haxe, we need to directly apply the params and delay this call *) let delay () = cfield.cf_expr <- Some { eexpr = TFunction( { tf_args = [me,None]; tf_type = t_dynamic; tf_expr = { eexpr = TReturn( Some { eexpr = TIf( { eexpr = TBinop(Ast.OpNotEq, mk_local me p, null me.v_type p); etype = basic.tbool; epos = p }, call, Some( null me.v_type p ) ); etype = t_dynamic; epos = p; }); etype = basic.tvoid; epos = p; } }); etype = cfield.cf_type; epos = p; } in cfield, delay let default_implementation gen ifaces base_generic = let add_iface cl = gen.gadd_to_module (TClassDecl cl) (max_dep); in let implement_stub_cast cthis iface tl = let name = get_cast_name iface in if not (PMap.mem name cthis.cl_fields) then begin let cparams = List.map (fun (s,t) -> ("To_" ^ s, TInst(map_param (get_cl_t t), []))) iface.cl_params in let field = mk_class_field name (TFun([],t_dynamic)) false iface.cl_pos (Method MethNormal) cparams in let this = { eexpr = TConst TThis; etype = TInst(cthis, List.map snd cthis.cl_params); epos = cthis.cl_pos } in field.cf_expr <- Some { etype = TFun([],t_dynamic); epos = this.epos; eexpr = TFunction { tf_type = t_dynamic; tf_args = []; tf_expr = mk_block { this with eexpr = TReturn (Some this) } } }; cthis.cl_ordered_fields <- field :: cthis.cl_ordered_fields; cthis.cl_fields <- PMap.add name field cthis.cl_fields end in let rec run md = match md with | TClassDecl ({ cl_params = [] } as cl) -> (* see if we're implementing any generic interface *) let rec check (iface,tl) = if tl <> [] && set_hxgeneric gen (TClassDecl iface) then (* implement cast stub *) implement_stub_cast cl iface tl; List.iter (fun (s,stl) -> check (s, List.map (apply_params iface.cl_params tl) stl)) iface.cl_implements; in List.iter (check) cl.cl_implements; md | TClassDecl ({ cl_params = hd :: tl } as cl) when set_hxgeneric gen md -> let iface = mk_class cl.cl_module cl.cl_path cl.cl_pos in iface.cl_array_access <- Option.map (apply_params (cl.cl_params) (List.map (fun _ -> t_dynamic) cl.cl_params)) cl.cl_array_access; iface.cl_extern <- cl.cl_extern; iface.cl_module <- cl.cl_module; iface.cl_private <- cl.cl_private; iface.cl_meta <- (Meta.HxGen, [], cl.cl_pos) :: (Meta.Custom "generic_iface", [(EConst(Int(string_of_int(List.length cl.cl_params))), cl.cl_pos)], cl.cl_pos) :: iface.cl_meta; Hashtbl.add ifaces cl.cl_path iface; iface.cl_implements <- (base_generic, []) :: iface.cl_implements; iface.cl_interface <- true; cl.cl_implements <- (iface, []) :: cl.cl_implements; let name = get_cast_name cl in let cast_cf = create_cast_cfield gen cl name in if not cl.cl_interface then create_stub_casts gen cl cast_cf; let rec loop c = match c.cl_super with | None -> () | Some(sup,_) -> try let siface = Hashtbl.find ifaces sup.cl_path in iface.cl_implements <- (siface,[]) :: iface.cl_implements; () with | Not_found -> loop sup in loop cl; (if not cl.cl_interface then cl.cl_ordered_fields <- cast_cf :: cl.cl_ordered_fields); let iface_cf = mk_class_field name cast_cf.cf_type false cast_cf.cf_pos (Method MethNormal) cast_cf.cf_params in let cast_static_cf, delay = create_static_cast_cf gen iface iface_cf in cl.cl_ordered_statics <- cast_static_cf :: cl.cl_ordered_statics; cl.cl_statics <- PMap.add cast_static_cf.cf_name cast_static_cf cl.cl_statics; gen.gafter_filters_ended <- delay :: gen.gafter_filters_ended; (* do not let filters alter this expression content *) iface_cf.cf_type <- cast_cf.cf_type; iface.cl_fields <- PMap.add name iface_cf iface.cl_fields; let fields = List.filter (fun cf -> match cf.cf_kind with | Var _ | Method MethDynamic -> false | _ -> let is_override = List.memq cf cl.cl_overrides in let cf_type = if is_override && not (Meta.has Meta.Overload cf.cf_meta) then match find_first_declared_field gen cl cf.cf_name with | Some(_,_,declared_t,_,_,_,_) -> declared_t | _ -> assert false else cf.cf_type in not (has_type_params cf_type) ) cl.cl_ordered_fields in let fields = List.map (fun f -> mk_class_field f.cf_name f.cf_type f.cf_public f.cf_pos f.cf_kind f.cf_params) fields in let fields = iface_cf :: fields in iface.cl_ordered_fields <- fields; List.iter (fun f -> iface.cl_fields <- PMap.add f.cf_name f iface.cl_fields) fields; add_iface iface; md | TTypeDecl _ | TAbstractDecl _ -> md | TEnumDecl _ -> ignore (set_hxgeneric gen md); md | _ -> ignore (set_hxgeneric gen md); md in run let configure gen mapping_func = let map e = Some(mapping_func e) in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) map end;; (* create a common interface without type parameters and only a __Cast<> function *) let default_implementation gen (dyn_tparam_cast:texpr->t->texpr) ifaces = let change_expr e cl iface params = let field = mk_static_field_access_infer cl "__hx_cast" e.epos params in let elist = [mk_cast (TInst(iface,[])) e] in let call = { eexpr = TCall(field, elist); etype = t_dynamic; epos = e.epos } in gen.gparam_func_call call field params elist in let rec run e = match e.eexpr with | TCast(cast_expr, _) -> (* see if casting to a native generic class *) let t = gen.greal_type e.etype in let unifies = let ctype = gen.greal_type cast_expr.etype in match follow ctype with | TInst(cl,_) -> (try unify ctype t; true with | Unify_error el -> false) | _ -> false in let unifies = unifies && not (PMap.mem "cs_safe_casts" gen.gcon.defines) in (match follow t with | TInst(cl, p1 :: pl) when is_hxgeneric (TClassDecl cl) && not unifies && not (Meta.has Meta.Enum cl.cl_meta) -> let iface = Hashtbl.find ifaces cl.cl_path in mk_cast e.etype (change_expr (Type.map_expr run cast_expr) cl iface (p1 :: pl)) | _ -> Type.map_expr run e ) | _ -> Type.map_expr run e in run let configure gen (dyn_tparam_cast:texpr->t->texpr) ifaces base_generic = gen.ghas_tparam_cast_handler <- true; let traverse = default_implementation gen dyn_tparam_cast ifaces in let map e = Some(traverse e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map; RealTypeParamsModf.configure gen (RealTypeParamsModf.default_implementation gen ifaces base_generic) end;; (* ******************************************* *) (* Rename Type Parameters *) (* ******************************************* *) (* This module should run after everything is already applied, it will look for possible type parameter name clashing and change the classes names to a dependencies: should run after everything is already applied. There's no configure on this module, only 'run'. *) module RenameTypeParameters = struct let name = "rename_type_parameters" let run gen = let i = ref 0 in let found_types = ref PMap.empty in let check_type name on_changed = let rec loop name = incr i; let changed_name = (name ^ (string_of_int !i)) in if PMap.mem changed_name !found_types then loop name else changed_name in if PMap.mem name !found_types then begin let new_name = loop name in found_types := PMap.add new_name true !found_types; on_changed new_name end else found_types := PMap.add name true !found_types in let get_cls t = match follow t with | TInst(cl,_) -> cl | _ -> assert false in let iter_types (nt,t) = let cls = get_cls t in let orig = cls.cl_path in check_type (snd orig) (fun name -> cls.cl_path <- (fst orig, name)) in let save_params save params = List.fold_left (fun save (_,t) -> let cls = get_cls t in (cls.cl_path,t) :: save) save params in List.iter (function | TClassDecl cl -> i := 0; let save = [] in found_types := PMap.empty; let save = save_params save cl.cl_params in List.iter iter_types cl.cl_params; let cur_found_types = !found_types in let save = ref save in List.iter (fun cf -> found_types := cur_found_types; save := save_params !save cf.cf_params; List.iter iter_types cf.cf_params ) (cl.cl_ordered_fields @ cl.cl_ordered_statics); if !save <> [] then begin let save = !save in let res = cl.cl_restore in cl.cl_restore <- (fun () -> res(); List.iter (fun (path,t) -> let cls = get_cls t in cls.cl_path <- path) save ); end | TEnumDecl ( ({ e_params = hd :: tl }) ) -> i := 0; found_types := PMap.empty; List.iter iter_types (hd :: tl) | TAbstractDecl { a_params = hd :: tl } -> i := 0; found_types := PMap.empty; List.iter iter_types (hd :: tl) | _ -> () ) gen.gtypes_list end;; end;; (**************************************************************************************************************************) (* SYNTAX FILTERS *) (**************************************************************************************************************************) (* ******************************************* *) (* Expression Unwrap *) (* ******************************************* *) (* This is the most important module for source-code based targets. It will follow a convention of what's an expression and what's a statement, and will unwrap statements where expressions are expected, and vice-versa. It should be one of the first syntax filters to be applied. As a consequence, it's applied after all filters that add code to the AST, and by being the first of the syntax filters, it will also have the AST retain most of the meaning of normal Haxe code. So it's easier to detect cases which are side-effects free, for example Any target can make use of this, but there is one requirement: The target must accept null to be set to any kind of variable. For example, var i:Int = null; must be accepted. The best way to deal with this is to (like it's done in C#) make null equal to "default(Type)" dependencies: While it's best for Expression Unwrap to delay its execution as much as possible, since theoretically any filter can return an expression that needs to be unwrapped, it is also desirable for ExpresionUnwrap to have the AST as close as possible as Haxe's, so it can make some correct predictions (for example, so it can more accurately know what can be side-effects-free and what can't). This way, it will run slightly after the Normal priority, so if you don't say that a syntax filter must run before Expression Unwrap, it will run after it. TODO : While statement must become do / while, with the actual block inside an if for the condition, and else for 'break' *) module ExpressionUnwrap = struct let name = "expression_unwrap" (* priority: first syntax filter *) let priority = -10.0 (* We always need to rely on Blocks to be able to unwrap expressions correctly. So the the standard traverse will always be based on blocks. Normal block statements, like for(), while(), if(), ... will be mk_block'ed so there is always a block inside of them. At the block level, we'll define an "add_statement" function, which will allow the current expression to add statements to the block. This statement may or may not contain statements as expressions, so the texpr will be evaluated recursively before being added. - traverse will always evaluate TBlocks - for each texpr in a TBlock list, check shallow type if type is Statement or Both when it has problematic expression (var problematic_expr = count_problematic_expressions), if we can eagerly call unwrap_statement on the whole expression (try_call_unwrap_statement), use the return expression else check expr_type of each underlying type (with expr_stat_map) if it has ExprWithStatement or Statement, call problematic_expression_unwrap in it problematic_expr-- else if problematic_expr == 0, just add the unchanged expression else if NoSideEffects and doesn't have short-circuit, just add the unchanged expression else call problematic_expression_unwrap in it if type is Expression, check if there are statements or Both inside. if there are, problematic_expression_unwrap in it aftewards, use on_expr_as_statement to get it helpers: try_call_unwrap_statement: (returns texpr option) if underlying statement is TBinop(OpAssign/OpAssignOp), or TVar, with the right side being a Statement or a short circuit op, we can call apply_assign. apply_assign: if is TVar, first declare the tvar with default expression = null; will receive the left and right side of the assignment; right-side must be Statement see if right side is a short-circuit operation, call short_circuit_op_unwrap else see eexpr of the right side if it's void, just add the statement with add_statement, and set the right side as null; if not, it will have a block inside. set the left side = to the last expression on each block inside. add_statement for it. short_circuit_op_unwrap: x() && (1 + {var x = 0; x + 1;} == 2) && z() -> var x = x(); var y = false; var z = false; if (x) //for &&, neg for || { var temp = null; { var x = 0; temp = x + 1; } y = (1 + temp) == 2; if (y) { z = z(); } } expects to receive a texpr with TBinop(OpBoolAnd/OpBoolOr) will traverse the AST while there is a TBinop(OpBoolAnd/OpBoolOr) as a right-side expr, and declare new temp vars in the for each found. will collect the return value, a mapped expr with all exprs as TLocal of the temp vars created problematic_expression_unwrap: check expr_kind: if it is NoSideEffects and not short-circuit, leave it there if it is ExprWithStatement and not short-circuit, call Type.map_expr problematic_expression_unwrap if it is Statement or Expression or short-circuit expr, call add_assign for this expression add_assign: see if the type is void. If it is, just add_statement the expression argument, and return a null value else create a new variable, set TVar with Some() with the expression argument, add TVar with add_statement, and return the TLocal of this expression. map_problematic_expr: call expr_stat_map on statement with problematic_expression_unwrap types: type shallow_expr_type = | Statement | Expression | Both (* shallow expression classification. Both means that they can be either Statements as Expressions *) type expr_kind = | NormalExpr | ExprNoSideEffects (* -> short-circuit is considered side-effects *) | ExprWithStatement | Statement evaluates an expression (as in not a statement) type. If it is ExprWithStatement or Statement, it means it contains errors functions: shallow_expr_type (expr:texpr) : shallow_expr_type expr_kind (expr:texpr) : expr_kind deeply evaluates an expression type expr_stat_map (fn:texpr->texpr) (expr:texpr) : texpr it will traverse the AST looking for places where an expression is expected, and map the value according to fn aggregate_expr_type (is_side_effects_free:bool) (children:expr_type list) : expr_type helper function to deal with expr_type aggregation (e.g. an Expression + a Statement as a children, is a ExprWithStatement) check_statement_in_expression (expr:texpr) : texpr option : will check *) type shallow_expr_type = | Statement | Expression of texpr | Both of texpr (* shallow expression classification. Both means that they can be either Statements as Expressions *) type expr_kind = | KNormalExpr | KNoSideEffects (* -> short-circuit is considered side-effects *) | KExprWithStatement | KStatement let rec no_paren e = match e.eexpr with | TParenthesis e -> no_paren e | _ -> e (* must be called in a statement. Will execute fn whenever an expression (not statement) is expected *) let rec expr_stat_map fn (expr:texpr) = match (no_paren expr).eexpr with | TBinop ( (Ast.OpAssign as op), left_e, right_e ) | TBinop ( (Ast.OpAssignOp _ as op), left_e, right_e ) -> { expr with eexpr = TBinop(op, fn left_e, fn right_e) } | TParenthesis _ -> assert false | TCall(left_e, params) -> { expr with eexpr = TCall(fn left_e, List.map fn params) } | TNew(cl, tparams, params) -> { expr with eexpr = TNew(cl, tparams, List.map fn params) } | TVar(v,eopt) -> { expr with eexpr = TVar(v, Option.map fn eopt) } | TFor (v,cond,block) -> { expr with eexpr = TFor(v, fn cond, block) } | TIf(cond,eif,eelse) -> { expr with eexpr = TIf(fn cond, eif, eelse) } | TWhile(cond, block, flag) -> { expr with eexpr = TWhile(fn cond, block, flag) } | TSwitch(cond, el_block_l, default) -> { expr with eexpr = TSwitch( fn cond, List.map (fun (el,block) -> (List.map fn el, block)) el_block_l, default ) } | TReturn(eopt) -> { expr with eexpr = TReturn(Option.map fn eopt) } | TThrow (texpr) -> { expr with eexpr = TThrow(fn texpr) } | TBreak | TContinue | TTry _ | TUnop (Ast.Increment, _, _) | TUnop (Ast.Decrement, _, _) (* unop is a special case because the haxe compiler won't let us generate complex expressions with Increment/Decrement *) | TBlock _ -> expr (* there is no expected expression here. Only statements *) | TMeta(m,e) -> { expr with eexpr = TMeta(m,expr_stat_map fn e) } | _ -> assert false (* we only expect valid statements here. other expressions aren't valid statements *) let is_expr = function | Expression _ -> true | _ -> false let aggregate_expr_type map_fn side_effects_free children = let rec loop acc children = match children with | [] -> acc | hd :: children -> match acc, map_fn hd with | _, KExprWithStatement | _, KStatement | KExprWithStatement, _ | KStatement, _ -> KExprWithStatement | KNormalExpr, KNoSideEffects | KNoSideEffects, KNormalExpr | KNormalExpr, KNormalExpr -> loop KNormalExpr children | KNoSideEffects, KNoSideEffects -> loop KNoSideEffects children in loop (if side_effects_free then KNoSideEffects else KNormalExpr) children (* statements: *) (* Error CS0201: Only assignment, call, increment, *) (* decrement, and new object expressions can be used as a *) (* statement (CS0201). *) let rec shallow_expr_type expr : shallow_expr_type = match expr.eexpr with | TCall _ when not (ExtType.is_void expr.etype) -> Both expr | TNew _ | TUnop (Ast.Increment, _, _) | TUnop (Ast.Decrement, _, _) | TBinop (Ast.OpAssign, _, _) | TBinop (Ast.OpAssignOp _, _, _) -> Both expr | TIf (cond, eif, Some(eelse)) -> (match aggregate_expr_type expr_kind true [cond;eif;eelse] with | KExprWithStatement -> Statement | _ -> Both expr) | TConst _ | TLocal _ | TArray _ | TBinop _ | TField _ | TEnumParameter _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ | TFunction _ | TCast _ | TUnop _ -> Expression (expr) | TParenthesis p | TMeta(_,p) -> shallow_expr_type p | TBlock ([e]) -> shallow_expr_type e | TCall _ | TVar _ | TBlock _ | TFor _ | TWhile _ | TSwitch _ | TTry _ | TReturn _ | TBreak | TContinue | TIf _ | TThrow _ -> Statement and expr_kind expr = match shallow_expr_type expr with | Statement -> KStatement | Both expr | Expression expr -> let aggregate = aggregate_expr_type expr_kind in match expr.eexpr with | TConst _ | TLocal _ | TFunction _ | TTypeExpr _ -> KNoSideEffects | TCall (ecall, params) -> aggregate false (ecall :: params) | TNew (_,_,params) -> aggregate false params | TUnop (Increment,_,e) | TUnop (Decrement,_,e) -> aggregate false [e] | TUnop (_,_,e) -> aggregate true [e] | TBinop (Ast.OpBoolAnd, e1, e2) | TBinop (Ast.OpBoolOr, e1, e2) -> (* TODO: should OpBool never be side-effects free? *) aggregate true [e1;e2] | TBinop (Ast.OpAssign, e1, e2) | TBinop (Ast.OpAssignOp _, e1, e2) -> aggregate false [e1;e2] | TBinop (_, e1, e2) -> aggregate true [e1;e2] | TIf (cond, eif, Some(eelse)) -> (match aggregate true [cond;eif;eelse] with | KExprWithStatement -> KStatement | k -> k) | TArray (e1,e2) -> aggregate true [e1;e2] | TParenthesis e | TMeta(_,e) | TField (e,_) -> aggregate true [e] | TArrayDecl (el) -> aggregate true el | TObjectDecl (sel) -> aggregate true (List.map snd sel) | TCast (e,_) -> aggregate true [e] | _ -> trace (debug_expr expr); assert false (* should have been read as Statement by shallow_expr_type *) let is_side_effects_free e = match expr_kind e with | KNoSideEffects -> true | _ -> false let get_kinds (statement:texpr) = let kinds = ref [] in ignore (expr_stat_map (fun e -> kinds := (expr_kind e) :: !kinds; e ) statement); List.rev !kinds let has_problematic_expressions (kinds:expr_kind list) = let rec loop kinds = match kinds with | [] -> false | KStatement :: _ | KExprWithStatement :: _ -> true | _ :: tl -> loop tl in loop kinds let count_problematic_expressions (statement:texpr) = let count = ref 0 in ignore (expr_stat_map (fun e -> (match expr_kind e with | KStatement | KExprWithStatement -> incr count | _ -> () ); e ) statement); !count let apply_assign_block assign_fun elist = let rec assign acc elist = match elist with | [] -> acc | last :: [] -> (assign_fun last) :: acc | hd :: tl -> assign (hd :: acc) tl in List.rev (assign [] elist) let mk_get_block assign_fun e = match e.eexpr with | TBlock [] -> e | TBlock (el) -> { e with eexpr = TBlock(apply_assign_block assign_fun el) } | _ -> { e with eexpr = TBlock([ assign_fun e ]) } let add_assign gen add_statement expr = match expr.eexpr, follow expr.etype with | _, TAbstract ({ a_path = ([],"Void") },[]) | TThrow _, _ -> add_statement expr; null expr.etype expr.epos | _ -> let var = mk_temp gen "stmt" expr.etype in let tvars = { expr with eexpr = TVar(var,Some(expr)) } in let local = { expr with eexpr = TLocal(var) } in add_statement tvars; local (* requirement: right must be a statement *) let rec apply_assign assign_fun right = match right.eexpr with | TBlock el -> { right with eexpr = TBlock(apply_assign_block assign_fun el) } | TSwitch (cond, elblock_l, default) -> { right with eexpr = TSwitch(cond, List.map (fun (el,block) -> (el, mk_get_block assign_fun block)) elblock_l, Option.map (mk_get_block assign_fun) default) } | TTry (block, catches) -> { right with eexpr = TTry(mk_get_block assign_fun block, List.map (fun (v,block) -> (v,mk_get_block assign_fun block) ) catches) } | TIf (cond,eif,eelse) -> { right with eexpr = TIf(cond, mk_get_block assign_fun eif, Option.map (mk_get_block assign_fun) eelse) } | TThrow _ | TWhile _ | TFor _ | TReturn _ | TBreak | TContinue -> right | TParenthesis p | TMeta(_,p) -> apply_assign assign_fun p | TVar _ -> right | _ -> match follow right.etype with | TAbstract ({ a_path = ([], "Void") },[]) -> right | _ -> trace (debug_expr right); assert false (* a statement is required *) let short_circuit_op_unwrap gen add_statement expr :texpr = let do_not expr = { expr with eexpr = TUnop(Ast.Not, Ast.Prefix, expr) } in (* loop will always return its own TBlock, and the mapped expression *) let rec loop acc expr = match expr.eexpr with | TBinop ( (Ast.OpBoolAnd as op), left, right) -> let var = mk_temp gen "boolv" right.etype in let tvars = { right with eexpr = TVar(var, Some( { right with eexpr = TConst(TBool false); etype = gen.gcon.basic.tbool } )); etype = gen.gcon.basic.tvoid } in let local = { right with eexpr = TLocal(var) } in let mapped_left, ret_acc = loop ( (local, { right with eexpr = TBinop(Ast.OpAssign, local, right) } ) :: acc) left in add_statement tvars; ({ expr with eexpr = TBinop(op, mapped_left, local) }, ret_acc) (* we only accept OpBoolOr when it's the first to be evaluated *) | TBinop ( (Ast.OpBoolOr as op), left, right) when acc = [] -> let left = match left.eexpr with | TLocal _ | TConst _ -> left | _ -> add_assign gen add_statement left in let var = mk_temp gen "boolv" right.etype in let tvars = { right with eexpr = TVar(var, Some( { right with eexpr = TConst(TBool false); etype = gen.gcon.basic.tbool } )); etype = gen.gcon.basic.tvoid } in let local = { right with eexpr = TLocal(var) } in add_statement tvars; ({ expr with eexpr = TBinop(op, left, local) }, [ do_not left, { right with eexpr = TBinop(Ast.OpAssign, local, right) } ]) | _ when acc = [] -> assert false | _ -> let var = mk_temp gen "boolv" expr.etype in let tvars = { expr with eexpr = TVar(var, Some( { expr with etype = gen.gcon.basic.tbool } )); etype = gen.gcon.basic.tvoid } in let local = { expr with eexpr = TLocal(var) } in let last_local = ref local in let acc = List.map (fun (local, assign) -> let l = !last_local in last_local := local; (l, assign) ) acc in add_statement tvars; (local, acc) in let mapped_expr, local_assign_list = loop [] expr in let rec loop local_assign_list : texpr = match local_assign_list with | [local, assign] -> { eexpr = TIf(local, assign, None); etype = gen.gcon.basic.tvoid; epos = assign.epos } | (local, assign) :: tl -> { eexpr = TIf(local, { eexpr = TBlock ( assign :: [loop tl] ); etype = gen.gcon.basic.tvoid; epos = assign.epos; }, None); etype = gen.gcon.basic.tvoid; epos = assign.epos } | [] -> assert false in add_statement (loop local_assign_list); mapped_expr (* there are two short_circuit fuctions as I'm still testing the best way to do it *) (*let short_circuit_op_unwrap gen add_statement expr :texpr = let block = ref [] in let rec short_circuit_op_unwrap is_first last_block expr = match expr.eexpr with | TBinop ( (Ast.OpBoolAnd as op), left, right) | TBinop ( (Ast.OpBoolOr as op), left, right) -> let var = mk_temp gen "boolv" left.etype in let tvars = { left with eexpr = TVar([var, if is_first then Some(left) else Some( { left with eexpr = TConst(TBool false) } )]); etype = gen.gcon.basic.tvoid } in let local = { left with eexpr = TLocal(var) } in if not is_first then begin last_block := !last_block @ [ { left with eexpr = TBinop(Ast.OpAssign, local, left) } ] end; add_statement tvars; let local_op = match op with | Ast.OpBoolAnd -> local | Ast.OpBoolOr -> { local with eexpr = TUnop(Ast.Not, Ast.Prefix, local) } | _ -> assert false in let new_block = ref [] in let new_right = short_circuit_op_unwrap false new_block right in last_block := !last_block @ [ { expr with eexpr = TIf(local_op, { right with eexpr = TBlock(!new_block) }, None) } ]; { expr with eexpr = TBinop(op, local, new_right) } | _ when is_first -> assert false | _ -> let var = mk_temp gen "boolv" expr.etype in let tvars = { expr with eexpr = TVar([var, Some ( { expr with eexpr = TConst(TBool false) } ) ]); etype = gen.gcon.basic.tvoid } in let local = { expr with eexpr = TLocal(var) } in last_block := !last_block @ [ { expr with eexpr = TBinop(Ast.OpAssign, local, expr) } ]; add_statement tvars; local in let mapped_expr = short_circuit_op_unwrap true block expr in add_statement { eexpr = TBlock(!block); etype = gen.gcon.basic.tvoid; epos = expr.epos }; mapped_expr*) let twhile_with_condition_statement gen add_statement twhile cond e1 flag = (* when a TWhile is found with a problematic condition *) let basic = gen.gcon.basic in let block = if flag = Ast.NormalWhile then { e1 with eexpr = TIf(cond, e1, Some({ e1 with eexpr = TBreak; etype = basic.tvoid })) } else Type.concat e1 { e1 with eexpr = TIf({ eexpr = TUnop(Ast.Not, Ast.Prefix, mk_paren cond); etype = basic.tbool; epos = cond.epos }, { e1 with eexpr = TBreak; etype = basic.tvoid }, None); etype = basic.tvoid } in add_statement { twhile with eexpr = TWhile( { eexpr = TConst(TBool true); etype = basic.tbool; epos = cond.epos }, block, Ast.DoWhile ); } let try_call_unwrap_statement gen problematic_expression_unwrap (add_statement:texpr->unit) (expr:texpr) : texpr option = let check_left left = match expr_kind left with | KExprWithStatement -> problematic_expression_unwrap add_statement left KExprWithStatement | KStatement -> assert false (* doesn't make sense a KStatement as a left side expression *) | _ -> left in let handle_assign op left right = let left = check_left left in Some (apply_assign (fun e -> { e with eexpr = TBinop(op, left, if ExtType.is_void left.etype then e else gen.ghandle_cast left.etype e.etype e) }) right ) in let handle_return e = Some( apply_assign (fun e -> match e.eexpr with | TThrow _ -> e | _ when ExtType.is_void e.etype -> { e with eexpr = TBlock([e; { e with eexpr = TReturn None }]) } | _ -> { e with eexpr = TReturn( Some e ) } ) e ) in let is_problematic_if right = match expr_kind right with | KStatement | KExprWithStatement -> true | _ -> false in match expr.eexpr with | TBinop((Ast.OpAssign as op),left,right) | TBinop((Ast.OpAssignOp _ as op),left,right) when shallow_expr_type right = Statement -> handle_assign op left right | TReturn( Some right ) when shallow_expr_type right = Statement -> handle_return right | TBinop((Ast.OpAssign as op),left, ({ eexpr = TBinop(Ast.OpBoolAnd,_,_) } as right) ) | TBinop((Ast.OpAssign as op),left,({ eexpr = TBinop(Ast.OpBoolOr,_,_) } as right)) | TBinop((Ast.OpAssignOp _ as op),left,({ eexpr = TBinop(Ast.OpBoolAnd,_,_) } as right) ) | TBinop((Ast.OpAssignOp _ as op),left,({ eexpr = TBinop(Ast.OpBoolOr,_,_) } as right) ) -> let right = short_circuit_op_unwrap gen add_statement right in Some { expr with eexpr = TBinop(op, check_left left, right) } | TVar(v,Some({ eexpr = TBinop(Ast.OpBoolAnd,_,_) } as right)) | TVar(v,Some({ eexpr = TBinop(Ast.OpBoolOr,_,_) } as right)) -> let right = short_circuit_op_unwrap gen add_statement right in Some { expr with eexpr = TVar(v, Some(right)) } | TVar(v,Some(right)) when shallow_expr_type right = Statement -> add_statement ({ expr with eexpr = TVar(v, Some(null right.etype right.epos)) }); handle_assign Ast.OpAssign { expr with eexpr = TLocal(v); etype = v.v_type } right (* TIf handling *) | TBinop((Ast.OpAssign as op),left, ({ eexpr = TIf _ } as right)) | TBinop((Ast.OpAssignOp _ as op),left,({ eexpr = TIf _ } as right)) when is_problematic_if right -> handle_assign op left right | TVar(v,Some({ eexpr = TIf _ } as right)) when is_problematic_if right -> add_statement ({ expr with eexpr = TVar(v, Some(null right.etype right.epos)) }); handle_assign Ast.OpAssign { expr with eexpr = TLocal(v); etype = v.v_type } right | TWhile(cond, e1, flag) when is_problematic_if cond -> twhile_with_condition_statement gen add_statement expr cond e1 flag; Some (null expr.etype expr.epos) | _ -> None let configure gen (on_expr_as_statement:texpr->texpr option) = let add_assign = add_assign gen in let problematic_expression_unwrap add_statement expr e_type = let rec problematic_expression_unwrap is_first expr e_type = match e_type, expr.eexpr with | _, TBinop(Ast.OpBoolAnd, _, _) | _, TBinop(Ast.OpBoolOr, _, _) -> add_assign add_statement expr (* add_assign so try_call_unwrap_expr *) | KNoSideEffects, _ -> expr | KStatement, _ | KNormalExpr, _ -> add_assign add_statement expr | KExprWithStatement, TCall _ | KExprWithStatement, TNew _ | KExprWithStatement, TBinop (Ast.OpAssign,_,_) | KExprWithStatement, TBinop (Ast.OpAssignOp _,_,_) | KExprWithStatement, TUnop (Ast.Increment,_,_) (* all of these may have side-effects, so they must also be add_assign'ed . is_first avoids infinite loop *) | KExprWithStatement, TUnop (Ast.Decrement,_,_) when not is_first -> add_assign add_statement expr (* bugfix: Type.map_expr doesn't guarantee the correct order of execution *) | KExprWithStatement, TBinop(op,e1,e2) -> let e1 = problematic_expression_unwrap false e1 (expr_kind e1) in let e2 = problematic_expression_unwrap false e2 (expr_kind e2) in { expr with eexpr = TBinop(op, e1, e2) } | KExprWithStatement, TArray(e1,e2) -> let e1 = problematic_expression_unwrap false e1 (expr_kind e1) in let e2 = problematic_expression_unwrap false e2 (expr_kind e2) in { expr with eexpr = TArray(e1, e2) } (* bugfix: calls should not be transformed into closure calls *) | KExprWithStatement, TCall(( { eexpr = TField (ef_left, f) } as ef ), eargs) -> { expr with eexpr = TCall( { ef with eexpr = TField(problematic_expression_unwrap false ef_left (expr_kind ef_left), f) }, List.map (fun e -> problematic_expression_unwrap false e (expr_kind e)) eargs) } | KExprWithStatement, _ -> Type.map_expr (fun e -> problematic_expression_unwrap false e (expr_kind e)) expr in problematic_expression_unwrap true expr e_type in let rec traverse e = match e.eexpr with | TBlock el -> let new_block = ref [] in let rec process_statement e = let e = no_paren e in match e.eexpr, shallow_expr_type e with | TCall( { eexpr = TLocal v } as elocal, elist ), _ when String.get v.v_name 0 = '_' && Hashtbl.mem gen.gspecial_vars v.v_name -> new_block := { e with eexpr = TCall( elocal, List.map (fun e -> match e.eexpr with | TBlock _ -> traverse e | _ -> e ) elist ) } :: !new_block | _, Statement | _, Both _ -> let e = match e.eexpr with | TReturn (Some ({ eexpr = TThrow _ } as ethrow)) -> ethrow | _ -> e in let kinds = get_kinds e in if has_problematic_expressions kinds then begin match try_call_unwrap_statement gen problematic_expression_unwrap add_statement e with | Some { eexpr = TConst(TNull) } (* no op *) | Some { eexpr = TBlock [] } -> () | Some e -> if has_problematic_expressions (get_kinds e) then begin process_statement e end else new_block := (traverse e) :: !new_block | None -> ( let acc = ref kinds in let new_e = expr_stat_map (fun e -> match !acc with | hd :: tl -> acc := tl; if has_problematic_expressions (hd :: tl) then begin problematic_expression_unwrap add_statement e hd end else e | [] -> assert false ) e in new_block := (traverse new_e) :: !new_block ) end else begin new_block := (traverse e) :: !new_block end | _, Expression e -> match on_expr_as_statement e with | None -> () | Some e -> process_statement e and add_statement expr = process_statement expr in List.iter (process_statement) el; let block = List.rev !new_block in { e with eexpr = TBlock(block) } | TTry (block, catches) -> { e with eexpr = TTry(traverse (mk_block block), List.map (fun (v,block) -> (v, traverse (mk_block block))) catches) } | TSwitch (cond,el_e_l, default) -> { e with eexpr = TSwitch(cond, List.map (fun (el,e) -> (el, traverse (mk_block e))) el_e_l, Option.map (fun e -> traverse (mk_block e)) default) } | TWhile (cond,block,flag) -> {e with eexpr = TWhile(cond,traverse (mk_block block), flag) } | TIf (cond, eif, eelse) -> { e with eexpr = TIf(cond, traverse (mk_block eif), Option.map (fun e -> traverse (mk_block e)) eelse) } | TFor (v,it,block) -> { e with eexpr = TFor(v,it, traverse (mk_block block)) } | TFunction (tfunc) -> { e with eexpr = TFunction({ tfunc with tf_expr = traverse (mk_block tfunc.tf_expr) }) } | _ -> e (* if expression doesn't have a block, we will exit *) in let map e = Some(traverse e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* Casts detection v2 *) (* ******************************************* *) (* Will detect implicit casts and add TCast for them. Since everything is already followed by follow_all, typedefs are considered a new type altogether Types shouldn't be cast if: * When an instance is being coerced to a superclass or to an implemented interface * When anything is being coerced to Dynamic edit: As a matter of performance, we will also run the type parameters casts in here. Otherwise the exact same computation would have to be performed twice, with maybe even some loss of information * TAnon / TDynamic will call * Type parameter handling will be abstracted dependencies: Must run before ExpressionUnwrap *) module CastDetect = struct let name = "cast_detect_2" let priority = solve_deps name [DBefore TypeParams.priority; DBefore ExpressionUnwrap.priority] (* ******************************************* *) (* ReturnCast *) (* ******************************************* *) (* Cast detection for return types can't be done at CastDetect time, since we need an unwrapped expression to make sure we catch all return cast detections. So this module is specifically to deal with that, and is configured automatically by CastDetect dependencies: *) module ReturnCast = struct let name = "return_cast" let priority = solve_deps name [DAfter priority; DAfter ExpressionUnwrap.priority] let default_implementation gen = let rec extract_expr e = match e.eexpr with | TParenthesis e | TMeta (_,e) | TCast(e,_) -> extract_expr e | _ -> e in let current_ret_type = ref None in let handle e tto tfrom = gen.ghandle_cast (gen.greal_type tto) (gen.greal_type tfrom) e in let in_value = ref false in let rec run e = let was_in_value = !in_value in in_value := true; match e.eexpr with | TReturn (eopt) -> (* a return must be inside a function *) let ret_type = match !current_ret_type with | Some(s) -> s | None -> gen.gcon.error "Invalid return outside function declaration." e.epos; assert false in (match eopt with | None when not (ExtType.is_void ret_type) -> { e with eexpr = TReturn( Some(null ret_type e.epos)) } | None -> e | Some eret -> { e with eexpr = TReturn( Some(handle (run eret) ret_type eret.etype ) ) }) | TFunction(tfunc) -> let last_ret = !current_ret_type in current_ret_type := Some(tfunc.tf_type); let ret = Type.map_expr run e in current_ret_type := last_ret; ret | TBlock el -> { e with eexpr = TBlock ( List.map (fun e -> in_value := false; run e) el ) } | TBinop ( (Ast.OpAssign as op),e1,e2) | TBinop ( (Ast.OpAssignOp _ as op),e1,e2) when was_in_value -> let e1 = extract_expr (run e1) in let r = { e with eexpr = TBinop(op, e1, handle (run e2) e1.etype e2.etype); etype = e1.etype } in handle r e.etype e1.etype | TBinop ( (Ast.OpAssign as op),({ eexpr = TField(tf, f) } as e1), e2 ) | TBinop ( (Ast.OpAssignOp _ as op),({ eexpr = TField(tf, f) } as e1), e2 ) -> (match field_access_esp gen (gen.greal_type tf.etype) (f) with | FClassField(cl,params,_,_,is_static,actual_t,_) -> let actual_t = if is_static then actual_t else apply_params cl.cl_params params actual_t in let e1 = extract_expr (run e1) in { e with eexpr = TBinop(op, e1, handle (run e2) actual_t e2.etype); etype = e1.etype } | _ -> let e1 = extract_expr (run e1) in { e with eexpr = TBinop(op, e1, handle (run e2) e1.etype e2.etype); etype = e1.etype } ) | TBinop ( (Ast.OpAssign as op),e1,e2) | TBinop ( (Ast.OpAssignOp _ as op),e1,e2) -> let e1 = extract_expr (run e1) in { e with eexpr = TBinop(op, e1, handle (run e2) e1.etype e2.etype); etype = e1.etype } | _ -> Type.map_expr run e in run let configure gen = let map e = Some(default_implementation gen e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; let get_args t = match follow t with | TFun(args,ret) -> args,ret | _ -> trace (debug_type t); assert false (* Since this function is applied under native-context only, the type paraters will already be changed *) let map_cls gen also_implements fn super = let rec loop c tl = if c == super then fn c tl else (match c.cl_super with | None -> false | Some (cs,tls) -> let tls = gen.greal_type_param (TClassDecl cs) tls in loop cs (List.map (apply_params c.cl_params tl) tls) ) || (if also_implements then List.exists (fun (cs,tls) -> loop cs (List.map (apply_params c.cl_params tl) tls)) c.cl_implements else false) in loop let follow_dyn t = match follow t with | TMono _ | TLazy _ -> t_dynamic | t -> t (* this has a slight change from the type.ml version, in which it doesn't change a TMono into the other parameter *) let rec type_eq gen param a b = if a == b then () else match follow_dyn (gen.greal_type a) , follow_dyn (gen.greal_type b) with | TEnum (e1,tl1) , TEnum (e2,tl2) -> if e1 != e2 && not (param = EqCoreType && e1.e_path = e2.e_path) then Type.error [cannot_unify a b]; List.iter2 (type_eq gen param) tl1 tl2 | TAbstract (a1,tl1) , TAbstract (a2,tl2) -> if a1 != a2 && not (param = EqCoreType && a1.a_path = a2.a_path) then Type.error [cannot_unify a b]; List.iter2 (type_eq gen param) tl1 tl2 | TInst (c1,tl1) , TInst (c2,tl2) -> if c1 != c2 && not (param = EqCoreType && c1.cl_path = c2.cl_path) && (match c1.cl_kind, c2.cl_kind with KExpr _, KExpr _ -> false | _ -> true) then Type.error [cannot_unify a b]; List.iter2 (type_eq gen param) tl1 tl2 | TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 -> (try type_eq gen param r1 r2; List.iter2 (fun (n,o1,t1) (_,o2,t2) -> if o1 <> o2 then Type.error [Not_matching_optional n]; type_eq gen param t1 t2 ) l1 l2 with Unify_error l -> Type.error (cannot_unify a b :: l)) | TDynamic a , TDynamic b -> type_eq gen param a b | TAnon a1, TAnon a2 -> (try PMap.iter (fun n f1 -> try let f2 = PMap.find n a2.a_fields in if f1.cf_kind <> f2.cf_kind && (param = EqStrict || param = EqCoreType || not (unify_kind f1.cf_kind f2.cf_kind)) then Type.error [invalid_kind n f1.cf_kind f2.cf_kind]; try type_eq gen param f1.cf_type f2.cf_type with Unify_error l -> Type.error (invalid_field n :: l) with Not_found -> if is_closed a2 then Type.error [has_no_field b n]; if not (link (ref None) b f1.cf_type) then Type.error [cannot_unify a b]; a2.a_fields <- PMap.add n f1 a2.a_fields ) a1.a_fields; PMap.iter (fun n f2 -> if not (PMap.mem n a1.a_fields) then begin if is_closed a1 then Type.error [has_no_field a n]; if not (link (ref None) a f2.cf_type) then Type.error [cannot_unify a b]; a1.a_fields <- PMap.add n f2 a1.a_fields end; ) a2.a_fields; with Unify_error l -> Type.error (cannot_unify a b :: l)) | _ , _ -> if b == t_dynamic && (param = EqRightDynamic || param = EqBothDynamic) then () else if a == t_dynamic && param = EqBothDynamic then () else Type.error [cannot_unify a b] let type_iseq gen a b = try type_eq gen EqStrict a b; true with Unify_error _ -> false (* will return true if both arguments are compatible. If it's not the case, a runtime error is very likely *) let is_cl_related gen cl tl super superl = let is_cl_related cl tl super superl = map_cls gen (match cl.cl_kind,super.cl_kind with KTypeParameter _, _ | _,KTypeParameter _ -> false | _ -> true) (fun _ _ -> true) super cl tl in is_cl_related cl tl super superl || is_cl_related super superl cl tl let is_exactly_basic gen t1 t2 = match gen.gfollow#run_f t1, gen.gfollow#run_f t2 with | TAbstract(a1, []), TAbstract(a2, []) -> a1 == a2 && Common.defined gen.gcon Define.FastCast | TInst(c1, []), TInst(c2, []) -> c1 == c2 && Common.defined gen.gcon Define.FastCast | TEnum(e1, []), TEnum(e2, []) -> e1 == e2 && Common.defined gen.gcon Define.FastCast | _ -> false let rec is_unsafe_cast gen to_t from_t = match (follow to_t, follow from_t) with | TInst(cl_to, to_params), TInst(cl_from, from_params) -> not (is_cl_related gen cl_from from_params cl_to to_params) | TEnum(e_to, _), TEnum(e_from, _) -> e_to.e_path <> e_from.e_path | TFun _, TFun _ -> (* functions are never unsafe cast by default. This behavior might be changed *) (* with a later AST pass which will run through TFun to TFun casts *) false | TMono _, _ | _, TMono _ | TDynamic _, _ | _, TDynamic _ -> false | TAnon _, _ | _, TAnon _ -> (* anonymous are never unsafe also. *) (* Though they will generate a cast, so if this cast is unneeded it's better to avoid them by tweaking gen.greal_type *) false | TAbstract _, _ | _, TAbstract _ -> (try unify from_t to_t; false with | Unify_error _ -> try unify to_t from_t; (* still not unsafe *) false with | Unify_error _ -> true) | _ -> true let unifies tfrom tto = try unify tfrom tto; true with | _ -> false let do_unsafe_cast gen from_t to_t e = let t_path t = match t with | TInst(cl, _) -> cl.cl_path | TEnum(e, _) -> e.e_path | TType(t, _) -> t.t_path | TAbstract(a, _) -> a.a_path | TDynamic _ -> ([], "Dynamic") | _ -> raise Not_found in match gen.gfollow#run_f from_t, gen.gfollow#run_f to_t with | TInst({ cl_kind = KTypeParameter tl },_), t2 when List.exists (fun t -> unifies t t2) tl -> mk_cast to_t (mk_cast t_dynamic e) | _ -> let do_default () = gen.gon_unsafe_cast to_t e.etype e.epos; mk_cast to_t (mk_cast t_dynamic e) in (* TODO: there really should be a better way to write that *) try if (Hashtbl.find gen.gsupported_conversions (t_path from_t)) from_t to_t then mk_cast to_t e else do_default() with | Not_found -> try if (Hashtbl.find gen.gsupported_conversions (t_path to_t)) from_t to_t then mk_cast to_t e else do_default() with | Not_found -> do_default() (* ****************************** *) (* cast handler *) (* decides if a cast should be emitted, given a from and a to type *) (* this function is like a mini unify, without e.g. subtyping, which makes sense at the backend level, since most probably Anons and TInst will have a different representation there *) let rec handle_cast gen e real_to_t real_from_t = let do_unsafe_cast () = do_unsafe_cast gen real_from_t real_to_t { e with etype = real_from_t } in let to_t, from_t = real_to_t, real_from_t in let mk_cast fast t e = match e.eexpr with (* TThrow is always typed as Dynamic, we just need to type it accordingly *) | TThrow _ -> { e with etype = t } | _ -> if fast then mk_castfast t e else mk_cast t e in let e = { e with etype = real_from_t } in if try fast_eq real_to_t real_from_t with Invalid_argument("List.for_all2") -> false then e else match real_to_t, real_from_t with (* string is the only type that can be implicitly converted from any other *) | TInst( { cl_path = ([], "String") }, []), TInst( { cl_path = ([], "String") }, [] ) -> mk_cast true to_t e | TInst( { cl_path = ([], "String") }, []), _ -> mk_cast false to_t e | TInst(cl_to, params_to), TInst(cl_from, params_from) -> let ret = ref None in (* this is a little confusing: we are here mapping classes until we have the same to and from classes, applying the type parameters in each step, so we can compare the type parameters; If a class is found - meaning that the cl_from can be converted without a cast into cl_to, we still need to check their type parameters. *) ignore (map_cls gen (match cl_from.cl_kind,cl_to.cl_kind with KTypeParameter _, _ | _,KTypeParameter _ -> false | _ -> true) (fun _ tl -> try (* type found, checking type parameters *) List.iter2 (type_eq gen EqStrict) tl params_to; ret := Some e; true with | Unify_error _ -> (* type parameters need casting *) if gen.ghas_tparam_cast_handler then begin (* if we are already handling type parameter casts on other part of code (e.g. RealTypeParameters), we'll just make a cast to indicate that this place needs type parameter-involved casting *) ret := Some (mk_cast true to_t e); true end else (* if not, we're going to check if we only need a simple cast, or if we need to first cast into the dynamic version of it *) try List.iter2 (type_eq gen EqRightDynamic) tl params_to; ret := Some (mk_cast true to_t e); true with | Unify_error _ -> ret := Some (mk_cast true to_t (mk_cast true (TInst(cl_to, List.map (fun _ -> t_dynamic) params_to)) e)); true ) cl_to cl_from params_from); if is_some !ret then get !ret else if is_cl_related gen cl_from params_from cl_to params_to then mk_cast true to_t e else (* potential unsafe cast *) (do_unsafe_cast ()) | TMono _, TMono _ | TMono _, TDynamic _ | TDynamic _, TDynamic _ | TDynamic _, TMono _ -> e | TMono _, _ | TDynamic _, _ | TAnon _, _ when gen.gneeds_box real_from_t -> mk_cast false to_t e | TMono _, _ | TDynamic _, _ -> e | _, TMono _ | _, TDynamic _ -> mk_cast false to_t e | TAnon (a_to), TAnon (a_from) -> if a_to == a_from then e else if type_iseq gen to_t from_t then (* FIXME apply unify correctly *) e else mk_cast true to_t e | _, TAnon(anon) -> (try let p2 = match !(anon.a_status) with | Statics c -> TInst(c,List.map (fun _ -> t_dynamic) c.cl_params) | EnumStatics e -> TEnum(e, List.map (fun _ -> t_dynamic) e.e_params) | AbstractStatics a -> TAbstract(a, List.map (fun _ -> t_dynamic) a.a_params) | _ -> raise Not_found in let tclass = match get_type gen ([],"Class") with | TAbstractDecl(a) -> a | _ -> assert false in handle_cast gen e real_to_t (gen.greal_type (TAbstract(tclass, [p2]))) with | Not_found -> mk_cast false to_t e) | TAbstract (a_to, _), TAbstract(a_from, _) when a_to == a_from -> e | TAbstract _, TInst({ cl_kind = KTypeParameter _ }, _) | TInst({ cl_kind = KTypeParameter _ }, _), TAbstract _ -> do_unsafe_cast() | TAbstract _, _ | _, TAbstract _ -> (try unify from_t to_t; mk_cast true to_t e with | Unify_error _ -> try unify to_t from_t; mk_cast true to_t e with | Unify_error _ -> do_unsafe_cast()) | TEnum(e_to, []), TEnum(e_from, []) -> if e_to == e_from then e else (* potential unsafe cast *) (do_unsafe_cast ()) | TEnum(e_to, params_to), TEnum(e_from, params_from) when e_to.e_path = e_from.e_path -> (try List.iter2 (type_eq gen (if gen.gallow_tp_dynamic_conversion then EqRightDynamic else EqStrict)) params_from params_to; e with | Unify_error _ -> do_unsafe_cast () ) | TEnum(en, params_to), TInst(cl, params_from) | TInst(cl, params_to), TEnum(en, params_from) -> (* this is here for max compatibility with EnumsToClass module *) if en.e_path = cl.cl_path && Meta.has Meta.Class en.e_meta then begin (try List.iter2 (type_eq gen (if gen.gallow_tp_dynamic_conversion then EqRightDynamic else EqStrict)) params_from params_to; e with | Invalid_argument("List.iter2") -> (* this is a hack for RealTypeParams. Since there is no way at this stage to know if the class is the actual EnumsToClass derived from the enum, we need to imply from possible ArgumentErrors (because of RealTypeParams interfaces), that they would only happen if they were a RealTypeParams created interface *) e | Unify_error _ -> do_unsafe_cast () ) end else do_unsafe_cast () | TType(t_to, params_to), TType(t_from, params_from) when t_to == t_from -> if gen.gspecial_needs_cast real_to_t real_from_t then (try List.iter2 (type_eq gen (if gen.gallow_tp_dynamic_conversion then EqRightDynamic else EqStrict)) params_from params_to; e with | Unify_error _ -> do_unsafe_cast () ) else e | TType(t_to, _), TType(t_from,_) -> if gen.gspecial_needs_cast real_to_t real_from_t then mk_cast false to_t e else e | TType _, _ when gen.gspecial_needs_cast real_to_t real_from_t -> mk_cast false to_t e | _, TType _ when gen.gspecial_needs_cast real_to_t real_from_t -> mk_cast false to_t e (*| TType(t_to, _), TType(t_from, _) -> if t_to.t_path = t_from.t_path then e else if is_unsafe_cast gen real_to_t real_from_t then (* is_unsafe_cast will already follow both *) (do_unsafe_cast ()) else mk_cast to_t e*) | TType _, _ | _, TType _ -> if is_unsafe_cast gen real_to_t real_from_t then (* is_unsafe_cast will already follow both *) (do_unsafe_cast ()) else mk_cast false to_t e | TAnon anon, _ -> if PMap.is_empty anon.a_fields then e else mk_cast true to_t e | TFun(args, ret), TFun(args2, ret2) -> let get_args = List.map (fun (_,_,t) -> t) in (try List.iter2 (type_eq gen (EqBothDynamic)) (ret :: get_args args) (ret2 :: get_args args2); e with | Unify_error _ | Invalid_argument("List.iter2") -> mk_cast true to_t e) | _, _ -> do_unsafe_cast () (* end of cast handler *) (* ******************* *) let is_static_overload c name = match c.cl_super with | None -> false | Some (sup,_) -> let rec loop c = (PMap.mem name c.cl_statics) || (match c.cl_super with | None -> false | Some (sup,_) -> loop sup) in loop sup (* this is a workaround for issue #1743, as FInstance() is returning the incorrect classfield *) let rec clean_t t = match follow t with | TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> clean_t (Abstract.get_underlying_type a tl) | t -> t let select_overload gen applied_f overloads types params = let rec check_arg arglist elist = match arglist, elist with | [], [] -> true (* it is valid *) | (_,_,TAbstract({ a_path = (["haxe";"extern"],"Rest") }, [t])) :: [], elist -> List.for_all (fun (_,_,et) -> Type.type_iseq (clean_t et) (clean_t t)) elist | (_,_,t) :: arglist, (_,_,et) :: elist when Type.type_iseq (clean_t et) (clean_t t) -> check_arg arglist elist | _ -> false in match follow applied_f with | TFun _ -> replace_mono applied_f; let args, _ = get_fun applied_f in let elist = List.rev args in let rec check_overload overloads = match overloads with | (t, cf) :: overloads -> let cft = apply_params types params t in let cft = monomorphs cf.cf_params cft in let args, _ = get_fun cft in if check_arg (List.rev args) elist then cf,t,false else if overloads = [] then cf,t,true (* no compatible overload was found *) else check_overload overloads | [] -> assert false in check_overload overloads | _ -> match overloads with (* issue #1742 *) | (t,cf) :: [] -> cf,t,true | (t,cf) :: _ -> cf,t,false | _ -> assert false let choose_ctor gen cl tparams etl maybe_empty_t p = let ctor, sup, stl = OverloadingConstructor.cur_ctor cl tparams in (* get returned stl, with Dynamic as t_empty *) let rec get_changed_stl c tl = if c == sup then tl else match c.cl_super with | None -> stl | Some(sup,stl) -> get_changed_stl sup (List.map (apply_params c.cl_params tl) stl) in let ret_tparams = List.map (fun t -> match follow t with | TDynamic _ | TMono _ -> t_empty | _ -> t) tparams in let ret_stl = get_changed_stl cl ret_tparams in let ctors = ctor :: ctor.cf_overloads in List.iter replace_mono etl; (* first filter out or select outright maybe_empty *) let ctors, is_overload = match etl, maybe_empty_t with | [t], Some empty_t -> let count = ref 0 in let is_empty_call = Type.type_iseq t empty_t in let ret = List.filter (fun cf -> match follow cf.cf_type with (* | TFun([_,_,t],_) -> incr count; true *) | TFun([_,_,t],_) -> replace_mono t; incr count; is_empty_call = (Type.type_iseq t empty_t) | _ -> false) ctors in ret, !count > 1 | _ -> let len = List.length etl in let ret = List.filter (fun cf -> List.length (fst (get_fun cf.cf_type)) = len) ctors in ret, (match ret with | _ :: [] -> false | _ -> true) in let rec check_arg arglist elist = match arglist, elist with | [], [] -> true | (_,_,t) :: arglist, et :: elist -> (try let t = run_follow gen t in unify et t; check_arg arglist elist with | Unify_error el -> (* List.iter (fun el -> gen.gcon.warning (Typecore.unify_error_msg (print_context()) el) p) el; *) false) | _ -> false in let rec check_cf cf = let t = apply_params sup.cl_params stl cf.cf_type in replace_mono t; let args, _ = get_fun t in check_arg args etl in match is_overload, ctors with | false, [c] -> false, c, sup, ret_stl | _ -> is_overload, List.find check_cf ctors, sup, ret_stl let change_rest tfun elist = let rec loop acc arglist elist = match arglist, elist with | (_,_,TAbstract({ a_path = (["haxe";"extern"],"Rest") },[t])) :: [], elist -> List.rev (List.map (fun _ -> "rest",false,t) elist @ acc) | (n,o,t) :: arglist, _ :: elist -> loop ((n,o,t) :: acc) arglist elist | _, _ -> List.rev acc in let args,ret = get_fun tfun in TFun(loop [] args elist, ret) let fastcast_if_needed gen expr real_to_t real_from_t = if Common.defined gen.gcon Define.FastCast then begin if type_iseq gen real_to_t real_from_t then { expr with etype = real_to_t } else mk_castfast real_to_t { expr with etype=real_from_t } end else handle_cast gen expr real_to_t real_from_t (* Type parameter handling It will detect if/what type parameters were used, and call the cast handler It will handle both TCall(TField) and TCall by receiving a texpr option field: e Also it will transform the type parameters with greal_type_param and make handle_impossible_tparam - should cases where the type parameter is impossible to be determined from the called parameters be Dynamic? e.g. static function test():T {} *) (* match e.eexpr with | TCall( ({ eexpr = TField(ef, f) }) as e1, elist ) -> *) let handle_type_parameter gen e e1 ef ~clean_ef ~overloads_cast_to_base f elist calls_parameters_explicitly = (* the ONLY way to know if this call has parameters is to analyze the calling field. *) (* To make matters a little worse, on both C# and Java only in some special cases that type parameters will be used *) (* Namely, when using reflection type parameters are useless, of course. This also includes anonymous types *) (* this will have to be handled by gparam_func_call *) let return_var efield = match e with | None -> efield | Some ecall -> match follow efield.etype with | TFun(_,ret) -> (* closures will be handled by the closure handler. So we will just hint what's the expected type *) (* FIXME: should closures have also its arguments cast correctly? In the current implementation I think not. TO_REVIEW *) handle_cast gen { ecall with eexpr = TCall(efield, elist) } (gen.greal_type ecall.etype) ret | _ -> { ecall with eexpr = TCall(efield, elist) } in let real_type = gen.greal_type ef.etype in (* this part was rewritten at roughly r6477 in order to correctly support overloads *) (match field_access_esp gen real_type (f) with | FClassField (cl, params, _, cf, is_static, actual_t, declared_t) when e <> None && (cf.cf_kind = Method MethNormal || cf.cf_kind = Method MethInline) -> (* C# target changes params with a real_type function *) let params = match follow clean_ef.etype with | TInst(_,params) -> params | _ -> params in let local_mk_cast t expr = (* handle_cast gen expr t expr.etype *) if is_exactly_basic gen t expr.etype then expr else mk_castfast t expr in let ecall = get e in let ef = ref ef in let is_overload = cf.cf_overloads <> [] || Meta.has Meta.Overload cf.cf_meta || (is_static && is_static_overload cl (field_name f)) in let cf, actual_t, error = match is_overload with | false -> (* since actual_t from FClassField already applies greal_type, we're using the get_overloads helper to get this info *) let t = if cf.cf_params = [] then (* this if statement must be eliminated - it's a workaround for #3516 + infer params. *) actual_t else declared_t in cf,t,false | true -> let (cf, actual_t, error), is_static = match f with | FInstance(c,_,cf) | FClosure(Some (c,_),cf) -> (* get from overloads *) (* FIXME: this is a workaround for issue #1743 . Uncomment this code after it was solved *) (* let t, cf = List.find (fun (t,cf2) -> cf == cf2) (Overloads.get_overloads cl (field_name f)) in *) (* cf, t, false *) select_overload gen e1.etype (Overloads.get_overloads cl (field_name f)) cl.cl_params params, false | FStatic(c,f) -> (* workaround for issue #1743 *) (* f,f.cf_type, false *) select_overload gen e1.etype ((f.cf_type,f) :: List.map (fun f -> f.cf_type,f) f.cf_overloads) [] [], true | _ -> gen.gcon.warning "Overloaded classfield typed as anonymous" ecall.epos; (cf, actual_t, true), true in if not (is_static || error) then match find_first_declared_field gen cl ~exact_field:{ cf with cf_type = actual_t } cf.cf_name with | Some(cf_orig,actual_t,_,_,declared_cl,tl,tlch) -> let rec is_super e = match e.eexpr with | TConst TSuper -> true | TParenthesis p | TMeta(_,p) -> is_super p | _ -> false in if declared_cl != cl && overloads_cast_to_base && not (is_super !ef) then begin let pos = (!ef).epos in ef := { eexpr = TCall( { eexpr = TLocal(alloc_var "__as__" t_dynamic); etype = t_dynamic; epos = pos }, [!ef]); etype = TInst(declared_cl,List.map (apply_params cl.cl_params params) tl); epos = pos } end; { cf_orig with cf_name = cf.cf_name },actual_t,false | None -> gen.gcon.warning "Cannot find matching overload" ecall.epos; cf, actual_t, true else cf,actual_t,error in (* take off Rest param *) let actual_t = change_rest actual_t elist in (* set the real (selected) class field *) let f = match f with | FInstance(c,tl,_) -> FInstance(c,tl,cf) | FClosure(c,_) -> FClosure(c,cf) | FStatic(c,_) -> FStatic(c,cf) | f -> f in let error = error || (match follow actual_t with | TFun _ -> false | _ -> true) in if error then (* if error, ignore arguments *) if ExtType.is_void ecall.etype then { ecall with eexpr = TCall({ e1 with eexpr = TField(!ef, f) }, elist ) } else local_mk_cast ecall.etype { ecall with eexpr = TCall({ e1 with eexpr = TField(!ef, f) }, elist ) } else begin (* infer arguments *) (* let called_t = TFun(List.map (fun e -> "arg",false,e.etype) elist, ecall.etype) in *) let called_t = match follow e1.etype with | TFun _ -> e1.etype | _ -> TFun(List.map (fun e -> "arg",false,e.etype) elist, ecall.etype) in (* workaround for issue #1742 *) let called_t = change_rest called_t elist in let fparams = TypeParams.infer_params gen ecall.epos (get_fun (apply_params cl.cl_params params actual_t)) (get_fun called_t) cf.cf_params calls_parameters_explicitly in (* get what the backend actually sees *) (* actual field's function *) let actual_t = get_real_fun gen actual_t in let real_params = gen.greal_type_param (TClassDecl cl) params in let function_t = apply_params cl.cl_params real_params actual_t in let real_fparams = if calls_parameters_explicitly then gen.greal_type_param (TClassDecl cl) fparams else gen.greal_type_param (TClassDecl cl) (TypeParams.infer_params gen ecall.epos (get_fun function_t) (get_fun (get_real_fun gen called_t)) cf.cf_params calls_parameters_explicitly) in let function_t = get_real_fun gen (apply_params cf.cf_params real_fparams function_t) in let args_ft, ret_ft = get_fun function_t in (* applied function *) let applied = elist in (* check types list *) let new_ecall, elist = try let elist = List.map2 (fun applied (_,_,funct) -> match is_overload || real_fparams <> [], applied.eexpr with | true, TConst TNull -> mk_castfast (gen.greal_type funct) applied | true, _ -> (* when not (type_iseq gen (gen.greal_type applied.etype) funct) -> *) let ret = handle_cast gen applied (funct) (gen.greal_type applied.etype) in (match ret.eexpr with | TCast _ -> ret | _ -> local_mk_cast (funct) ret) | _ -> handle_cast gen applied (funct) (gen.greal_type applied.etype) ) applied args_ft in { ecall with eexpr = TCall( { e1 with eexpr = TField(!ef, f) }, elist); }, elist with | Invalid_argument("List.map2") -> gen.gcon.warning ("This expression may be invalid" ) ecall.epos; { ecall with eexpr = TCall({ e1 with eexpr = TField(!ef, f) }, elist) }, elist in let new_ecall = if fparams <> [] then gen.gparam_func_call new_ecall { e1 with eexpr = TField(!ef, f) } fparams elist else new_ecall in let ret = handle_cast gen new_ecall (gen.greal_type ecall.etype) (gen.greal_type ret_ft) in (match gen.gcon.platform, cf.cf_params, ret.eexpr with | _, _, TCast _ -> ret | Java, _ :: _, _ -> (* this is a workaround for a javac openjdk issue with unused type parameters and return type inference *) (* see more at issue #3123 *) mk_cast (gen.greal_type ret_ft) new_ecall | _ -> ret) end | FClassField (cl,params,_,{ cf_kind = (Method MethDynamic | Var _) },_,actual_t,_) -> (* if it's a var, we will just try to apply the class parameters that have been changed with greal_type_param *) let t = apply_params cl.cl_params (gen.greal_type_param (TClassDecl cl) params) (gen.greal_type actual_t) in return_var (handle_cast gen { e1 with eexpr = TField(ef, f) } (gen.greal_type e1.etype) (gen.greal_type t)) | FClassField (cl,params,_,cf,_,actual_t,_) -> return_var (handle_cast gen { e1 with eexpr = TField({ ef with etype = t_dynamic }, f) } e1.etype t_dynamic) (* force dynamic and cast back to needed type *) | FEnumField (en, efield, true) -> let ecall = match e with | None -> trace (field_name f); trace efield.ef_name; gen.gcon.error "This field should be called immediately" ef.epos; assert false | Some ecall -> ecall in (match en.e_params with (* | [] -> let args, ret = get_args (efield.ef_type) in let ef = { ef with eexpr = TTypeExpr( TEnumDecl en ); etype = TEnum(en, []) } in handle_cast gen { ecall with eexpr = TCall({ e1 with eexpr = TField(ef, FEnum(en, efield)) }, List.map2 (fun param (_,_,t) -> handle_cast gen param (gen.greal_type t) (gen.greal_type param.etype)) elist args) } (gen.greal_type ecall.etype) (gen.greal_type ret) *) | _ -> let pt = match e with | None -> real_type | Some _ -> snd (get_fun e1.etype) in let _params = match follow pt with | TEnum(_, p) -> p | _ -> gen.gcon.warning (debug_expr e1) e1.epos; assert false in let args, ret = get_args efield.ef_type in let actual_t = TFun(List.map (fun (n,o,t) -> (n,o,gen.greal_type t)) args, gen.greal_type ret) in (* because of differences on how is handled on the platforms, this is a hack to be able to correctly use class field type parameters with RealTypeParams *) let cf_params = List.map (fun t -> match follow t with | TDynamic _ -> t_empty | _ -> t) _params in let t = apply_params en.e_params (gen.greal_type_param (TEnumDecl en) cf_params) actual_t in let t = apply_params efield.ef_params (List.map (fun _ -> t_dynamic) efield.ef_params) t in let args, ret = get_args t in let elist = List.map2 (fun param (_,_,t) -> handle_cast gen (param) (gen.greal_type t) (gen.greal_type param.etype)) elist args in let e1 = { e1 with eexpr = TField({ ef with eexpr = TTypeExpr( TEnumDecl en ); etype = TEnum(en, _params) }, FEnum(en, efield) ) } in let new_ecall = gen.gparam_func_call ecall e1 _params elist in handle_cast gen new_ecall (gen.greal_type ecall.etype) (gen.greal_type ret) ) | FEnumField _ when is_some e -> assert false | FEnumField (en,efield,_) -> return_var { e1 with eexpr = TField({ ef with eexpr = TTypeExpr( TEnumDecl en ); },FEnum(en,efield)) } (* no target by date will uses this.so this code may not be correct at all *) | FAnonField cf -> let t = gen.greal_type cf.cf_type in return_var (handle_cast gen { e1 with eexpr = TField(ef, f) } (gen.greal_type e1.etype) t) | FNotFound | FDynamicField _ -> if is_some e then return_var { e1 with eexpr = TField(ef, f) } else return_var (handle_cast gen { e1 with eexpr = TField({ ef with etype = t_dynamic }, f) } e1.etype t_dynamic) (* force dynamic and cast back to needed type *) ) (* end of type parameter handling *) (* ****************************** *) (** overloads_cast_to_base argument will cast overloaded function types to the class that declared it. **) (** This is necessary for C#, and if true, will require the target to implement __as__, as a `quicker` form of casting **) let configure gen ?(overloads_cast_to_base = false) maybe_empty_t calls_parameters_explicitly = let handle e t1 t2 = handle_cast gen e (gen.greal_type t1) (gen.greal_type t2) in let in_value = ref false in let rec clean_cast e = match e.eexpr with | TCast(e,_) -> clean_cast e | TParenthesis(e) | TMeta(_,e) -> clean_cast e | _ -> e in let get_abstract_impl t = match t with | TAbstract(a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> Abstract.get_underlying_type a pl | t -> t in let rec is_abstract_to_struct t = match t with | TAbstract(a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> is_abstract_to_struct (Abstract.get_underlying_type a pl) | TInst(c,_) when Meta.has Meta.Struct c.cl_meta -> true | _ -> false in let binop_type op main_expr e1 e2 = let name = platform_name gen.gcon.platform in let basic = gen.gcon.basic in (* If either operand is of type decimal, the other operand is converted to type decimal, or a compile-time error occurs if the other operand is of type float or double. * Otherwise, if either operand is of type double, the other operand is converted to type double. * Otherwise, if either operand is of type float, the other operand is converted to type float. * Otherwise, if either operand is of type ulong, the other operand is converted to type ulong, or a compile-time error occurs if the other operand is of type sbyte, short, int, or long. * Otherwise, if either operand is of type long, the other operand is converted to type long. * Otherwise, if either operand is of type uint and the other operand is of type sbyte, short, or int, both operands are converted to type long. * Otherwise, if either operand is of type uint, the other operand is converted to type uint. * Otherwise, both operands are converted to type int. * *) let t1, t2 = follow (run_follow gen e1.etype), follow (run_follow gen e2.etype) in match t1, t2 with | TAbstract(a1,[]), TAbstract(a2,[]) when a1 == a2 -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e1.etype } | TInst(i1,[]), TInst(i2,[]) when i1 == i2 -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e1.etype } | TInst({ cl_path = ([],"String") },[]), _ when op = OpAdd -> { main_expr with eexpr = TBinop(op, e1, mk_cast basic.tstring e2); etype = basic.tstring } | _, TInst({ cl_path = ([],"String") },[]) when op = OpAdd -> { main_expr with eexpr = TBinop(op, mk_cast basic.tstring e1, e2); etype = basic.tstring } | TAbstract({ a_path = ([], "Float") }, []), _ -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e1.etype } | _, TAbstract({ a_path = ([], "Float") }, []) -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e2.etype } | TAbstract({ a_path = ([], "Single") }, []), _ -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e1.etype } | _, TAbstract({ a_path = ([], "Single") }, []) -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e2.etype } | TAbstract({ a_path = ([pf], "UInt64") }, []), _ when pf = name -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e1.etype } | _, TAbstract({ a_path = ([pf], "UInt64") }, []) when pf = name -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e2.etype } | TAbstract({ a_path = ([pf], "Int64") }, []), _ when pf = name -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e1.etype } | _, TAbstract({ a_path = ([pf], "Int64") }, []) when pf = name -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e2.etype } | TAbstract({ a_path = ([], "UInt") }, []), tother when like_int tother -> let ti64 = mt_to_t_dyn ( get_type gen ([name], "Int64") ) in let ret = { main_expr with eexpr = TBinop(op, e1, e2); etype = ti64 } in if op <> OpDiv then mk_cast t1 ret else ret | tother, TAbstract({ a_path = ([], "UInt") }, []) when like_int tother -> let ti64 = mt_to_t_dyn ( get_type gen ([name], "Int64") ) in let ret = { main_expr with eexpr = TBinop(op, e1, e2); etype = ti64 } in if op <> OpDiv then mk_cast t2 ret else ret | TAbstract({ a_path = ([], "UInt") }, []), _ -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e1.etype } | _, TAbstract({ a_path = ([], "UInt") }, []) -> { main_expr with eexpr = TBinop(op, e1, e2); etype = e2.etype } | TAbstract(a1,[]), TAbstract(a2,[]) -> { main_expr with eexpr = TBinop(op, e1, e2); etype = basic.tint } | _ -> { main_expr with eexpr = TBinop(op, e1, e2) } in let binop_type = if Common.defined gen.gcon Define.FastCast then binop_type else fun op main_expr e1 e2 -> { main_expr with eexpr = TBinop(op, e1, e2) } in let rec run ?(just_type = false) e = let handle = if not just_type then handle else fun e t1 t2 -> { e with etype = gen.greal_type t2 } in let was_in_value = !in_value in in_value := true; match e.eexpr with | TConst ( TInt _ | TFloat _ | TBool _ as const ) -> (* take off any Null<> that it may have *) let t = follow (run_follow gen e.etype) in (* do not allow constants typed as Single - need to cast them *) let real_t = match const with | TInt _ -> gen.gcon.basic.tint | TFloat _ -> gen.gcon.basic.tfloat | TBool _ -> gen.gcon.basic.tbool | _ -> assert false in handle e t real_t | TCast( { eexpr = TConst TNull }, _ ) -> { e with eexpr = TConst TNull } | TCast( { eexpr = TCall( { eexpr = TLocal { v_name = "__delegate__" } } as local, [del] ) } as e2, _) -> { e with eexpr = TCast({ e2 with eexpr = TCall(local, [Type.map_expr run del]) }, None) } | TBinop ( (Ast.OpAssign | Ast.OpAssignOp _ as op), e1, e2 ) -> let e1 = run ~just_type:true e1 in let e2 = handle (run e2) e1.etype e2.etype in { e with eexpr = TBinop(op, clean_cast e1, e2) } | TBinop ( (Ast.OpShl | Ast.OpShr | Ast.OpUShr as op), e1, e2 ) -> let e1 = run e1 in let e2 = handle (run e2) (gen.gcon.basic.tint) e2.etype in let rett = binop_type op e e1 e2 in { e with eexpr = TBinop(op, e1, e2); etype = rett.etype } | TBinop( (OpAdd | OpMult | OpDiv | OpSub | OpAnd | OpOr | OpXor | OpMod) as op, e1, e2 ) -> binop_type op e (run e1) (run e2) | TBinop( (OpEq | OpNotEq | OpGt | OpGte | OpLt | OpLte | OpBoolAnd | OpBoolOr) as op, e1, e2 ) -> handle { e with eexpr = TBinop(op, run e1, run e2) } e.etype gen.gcon.basic.tbool | TField(ef, f) -> handle_type_parameter gen None e (run ef) ~clean_ef:ef ~overloads_cast_to_base:overloads_cast_to_base f [] calls_parameters_explicitly | TArrayDecl el -> let et = e.etype in let base_type = match follow et with | TInst({ cl_path = ([], "Array") } as cl, bt) -> gen.greal_type_param (TClassDecl cl) bt | _ -> gen.gcon.warning (debug_type et) e.epos; (match gen.gcurrent_class with | Some cl -> print_endline (s_type_path cl.cl_path) | _ -> ()); assert false in let base_type = List.hd base_type in { e with eexpr = TArrayDecl( List.map (fun e -> handle (run e) base_type e.etype) el ); etype = et } | TCall ({ eexpr = TLocal { v_name = "__array__" } } as arr_local, el) -> let et = e.etype in let base_type = match follow et with | TInst(cl, bt) -> gen.greal_type_param (TClassDecl cl) bt | _ -> assert false in let base_type = List.hd base_type in { e with eexpr = TCall(arr_local, List.map (fun e -> handle (run e) base_type e.etype) el ); etype = et } | TCall( ({ eexpr = TLocal v } as local), params ) when String.get v.v_name 0 = '_' && String.get v.v_name 1 = '_' && Hashtbl.mem gen.gspecial_vars v.v_name -> { e with eexpr = TCall(local, List.map (fun e -> (match e.eexpr with TBlock _ -> in_value := false | _ -> ()); run e) params) } | TCall( ({ eexpr = TField(ef, f) }) as e1, elist ) -> handle_type_parameter gen (Some e) (e1) (run ef) ~clean_ef:ef ~overloads_cast_to_base:overloads_cast_to_base f (List.map run elist) calls_parameters_explicitly (* the TNew and TSuper code was modified at r6497 *) | TCall( { eexpr = TConst TSuper } as ef, eparams ) -> let cl, tparams = match follow ef.etype with | TInst(cl,p) -> cl,p | _ -> assert false in (try let is_overload, cf, sup, stl = choose_ctor gen cl tparams (List.map (fun e -> e.etype) eparams) maybe_empty_t e.epos in let handle e t1 t2 = if is_overload then let ret = handle e t1 t2 in match ret.eexpr with | TCast _ -> ret | _ -> mk_cast (gen.greal_type t1) e else handle e t1 t2 in let stl = gen.greal_type_param (TClassDecl sup) stl in let args, _ = get_fun (apply_params sup.cl_params stl cf.cf_type) in let eparams = List.map2 (fun e (_,_,t) -> handle (run e) t e.etype ) eparams args in { e with eexpr = TCall(ef, eparams) } with | Not_found -> gen.gcon.warning "No overload found for this constructor call" e.epos; { e with eexpr = TCall(ef, List.map run eparams) }) | TCall (ef, eparams) -> (match ef.etype with | TFun(p, ret) -> handle ({ e with eexpr = TCall(run ef, List.map2 (fun param (_,_,t) -> handle (run param) t param.etype) eparams p) }) e.etype ret | _ -> Type.map_expr run e ) (* the TNew and TSuper code was modified at r6497 *) | TNew ({ cl_kind = KTypeParameter _ }, _, _) -> Type.map_expr run e | TNew (cl, tparams, eparams) -> (try let is_overload, cf, sup, stl = choose_ctor gen cl tparams (List.map (fun e -> e.etype) eparams) maybe_empty_t e.epos in let handle e t1 t2 = if is_overload then let ret = handle e t1 t2 in match ret.eexpr with | TCast _ -> ret | _ -> mk_cast (gen.greal_type t1) e else handle e t1 t2 in let stl = gen.greal_type_param (TClassDecl sup) stl in let args, _ = get_fun (apply_params sup.cl_params stl cf.cf_type) in let eparams = List.map2 (fun e (_,_,t) -> handle (run e) t e.etype ) eparams args in { e with eexpr = TNew(cl, tparams, eparams) } with | Not_found -> gen.gcon.warning "No overload found for this constructor call" e.epos; { e with eexpr = TNew(cl, tparams, List.map run eparams) }) | TArray(arr, idx) -> let arr_etype = match follow arr.etype with | (TInst _ as t) -> t | TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) -> follow (Abstract.get_underlying_type a pl) | t -> t in let idx = run idx in let idx = match gen.greal_type idx.etype with | TAbstract({ a_path = [],"Int" },_) -> idx | _ -> match handle idx gen.gcon.basic.tint (gen.greal_type idx.etype) with | ({ eexpr = TCast _ } as idx) -> idx | idx -> mk_cast gen.gcon.basic.tint idx in let e = { e with eexpr = TArray(run arr, idx) } in (* get underlying class (if it's a class *) (match arr_etype with | TInst(cl, params) -> (* see if it implements ArrayAccess *) (match cl.cl_array_access with | None -> e | Some t -> (* if it does, apply current parameters (and change them) *) (* let real_t = apply_params_internal (List.map (gen.greal_type_param (TClassDecl cl))) cl params t in *) let param = apply_params cl.cl_params (gen.greal_type_param (TClassDecl cl) params) t in let real_t = apply_params cl.cl_params params param in (* see if it needs a cast *) fastcast_if_needed gen e (gen.greal_type e.etype) (gen.greal_type real_t) (* handle (e) (gen.greal_type e.etype) (gen.greal_type real_t) *) ) | _ -> Type.map_expr run e) | TVar (v, eopt) -> { e with eexpr = TVar (v, match eopt with | None -> eopt | Some e -> Some( handle (run e) v.v_type e.etype )) } (* FIXME deal with in_value when using other statements that may not have a TBlock wrapped on them *) | TIf (econd, ethen, Some(eelse)) when was_in_value -> { e with eexpr = TIf (handle (run econd) gen.gcon.basic.tbool econd.etype, handle (run ethen) e.etype ethen.etype, Some( handle (run eelse) e.etype eelse.etype ) ) } | TIf (econd, ethen, eelse) -> { e with eexpr = TIf (handle (run econd) gen.gcon.basic.tbool econd.etype, (in_value := false; run (mk_block ethen)), Option.map (fun e -> in_value := false; run (mk_block e)) eelse) } | TWhile (econd, e1, flag) -> { e with eexpr = TWhile (handle (run econd) gen.gcon.basic.tbool econd.etype, (in_value := false; run (mk_block e1)), flag) } | TSwitch (cond, el_e_l, edef) -> { e with eexpr = TSwitch(run cond, List.map (fun (el,e) -> (List.map run el, (in_value := false; run (mk_block e)))) el_e_l, Option.map (fun e -> in_value := false; run (mk_block e)) edef) } | TFor (v,cond,e1) -> { e with eexpr = TFor(v, run cond, (in_value := false; run (mk_block e1))) } | TTry (e, ve_l) -> { e with eexpr = TTry((in_value := false; run (mk_block e)), List.map (fun (v,e) -> in_value := false; (v, run (mk_block e))) ve_l) } | TBlock el -> let i = ref 0 in let len = List.length el in { e with eexpr = TBlock ( List.map (fun e -> incr i; if !i <> len || not was_in_value then in_value := false; run e ) el ) } | TCast (expr, md) when ExtType.is_void (follow e.etype) -> run expr | TCast (expr, md) -> let rec get_null e = match e.eexpr with | TConst TNull -> Some e | TParenthesis e | TMeta(_,e) -> get_null e | _ -> None in (match get_null expr with | Some enull -> if gen.gcon.platform = Cs then { enull with etype = gen.greal_type e.etype } else mk_cast (gen.greal_type e.etype) enull | _ when is_abstract_to_struct expr.etype && type_iseq gen e.etype (get_abstract_impl expr.etype) -> run { expr with etype = expr.etype } | _ when is_exactly_basic gen expr.etype e.etype -> run { expr with etype = expr.etype } | _ -> match gen.greal_type e.etype, gen.greal_type expr.etype with | (TInst(c,tl) as tinst1), TAbstract({ a_path = ["cs"],"Pointer" }, [tinst2]) when type_iseq gen tinst1 (gen.greal_type tinst2) -> run expr | _ -> let last_unsafe = gen.gon_unsafe_cast in gen.gon_unsafe_cast <- (fun t t2 pos -> ()); let ret = handle (run expr) e.etype expr.etype in gen.gon_unsafe_cast <- last_unsafe; match ret.eexpr with | TCast _ -> { ret with etype = gen.greal_type e.etype } | _ -> { e with eexpr = TCast(ret,md); etype = gen.greal_type e.etype } ) (*| TCast _ -> (* if there is already a cast, we should skip this cast check *) Type.map_expr run e*) | TFunction f -> in_value := false; Type.map_expr run e | _ -> Type.map_expr run e in gen.ghandle_cast <- (fun tto tfrom expr -> handle_cast gen expr (gen.greal_type tto) (gen.greal_type tfrom)); let map e = match gen.gcurrent_classfield with | Some(cf) when Meta.has (Meta.Custom ":skipCastDetect") cf.cf_meta -> None | _ -> Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map; ReturnCast.configure gen end;; (* ******************************************* *) (* Reflection-enabling Class fields *) (* ******************************************* *) (* This is the most hardcore codegen part of the code. There's much to improve so this code can be more readable, but at least it's running correctly right now! This will be improved. (TODO) This module will create class fields that enable reflection for targets that have a slow or inexistent reflection abilities. Because of the similarity of strategies between what should have been different modules, they are all unified in this reflection-enabling class fields. They include: * Get(throwErrors, isCheck) / Set fields . Remember to allow implements Dynamic also. * Invoke fields() -> You need to configure how many invoke_field fields there will be. + invokeDynamic * Has field -> parameter in get field that returns __undefined__ if it doesn't exist. * GetType -> return the current Class<> / Enum<> * Fields() -> returns all the fields / static fields. Remember to allow implements Dynamic also * Create(arguments array), CreateEmpty - calls new() or create empty * getInstanceFields / getClassFields -> show even function fields, everything! * deleteField -> only for implements Dynamic for enums: * createEnum -> invokeField for classes * createEnumIndex -> use invokeField as well, and use numbers e.g. "0", "1", "2" .... For this, use "@:alias" metadata * getEnumConstructs -> fields() need to be solved outside: * getEnumName * enumIndex * need to be solved by haxe code: * enumParameters -> for (field in Reflect.fields(enum)) arr.push(Reflect.field(enum, field)) Standard: if a class contains a @:$enum metadata, it's treated as a converted enum to class Optimizations: * if optimize is true, all fields will be hashed by the same hashing function as neko (31 bits int : always positive). Every function that expects a string for the field will expect also an int, for the hash a string (which is nullable for compile-time hashes) + an int. At compile-time, a collision will throw an error (like neko). At runtime, a collision will make a negative int. Negative ints will always resolve to a special Hash<> field which takes a string. * if optimize is true, Reflect.field/setField will be replaced by either the runtime version (with already hashed string), either by the own .Field()/.SetField() HxObject's version, if the type is detected to already be hxgen * TODO: if for() optimization for arrays is disabled, we can replace for(field in Reflect.fields(obj)) to: for (field in ( (Std.is(obj, HxObject) ? ((HxObject)obj).Fields() : Reflect.fields(obj)) )) // no array copying . for further optimization this could be guaranteed to return the already hashed fields. Mappings: * if create Dynamic class is true, TObjectDecl will be mapped to new DynamicClass(fields, [hashedFields], values) * dependencies: There is no big dependency from this target. Though it should be a syntax filter, mainly one of the first so most expression generation has already been done, while the AST has its meaning close to haxe's. Should run before InitFunction so it detects variables containing expressions as "always-execute" expressions, even when using CreateEmpty * Must run before switch() syntax changes *) open ClosuresToClass;; module ReflectionCFs = struct let name = "reflection_cfs" type rcf_hash_conflict_ctx = { t : t; add_names : texpr->texpr->texpr; get_conflict : texpr->texpr->texpr->texpr; set : texpr->texpr->texpr->texpr->texpr; delete : texpr->texpr->texpr->texpr; } type rcf_ctx = { rcf_gen : generator_ctx; rcf_ft : ClosuresToClass.closures_ctx; rcf_optimize : bool; rcf_object_iface : tclass; rcf_max_func_arity : int; (* the hash lookup function. can be an inlined expr or simply a function call. its only needed features is that it should return the index of the key if found, and the complement of the index of where it should be inserted if not found (Ints). hash->hash_array->length->returning expression *) rcf_hash_function : texpr->texpr->texpr->texpr; rcf_lookup_function : texpr->texpr; (* hash_array->length->pos->value *) rcf_insert_function : texpr->texpr->texpr->texpr->texpr; (* hash_array->length->pos->value *) rcf_remove_function : texpr->texpr->texpr->texpr; rcf_hash_fields : (int, string) Hashtbl.t; rcf_hash_paths : (path * int, string) Hashtbl.t; rcf_hash_conflict_ctx : rcf_hash_conflict_ctx option; (* main expr -> field expr -> field string -> possible hash int (if optimize) -> possible set expr -> should_throw_exceptions -> changed expression Changes a get / set field to the runtime resolution function *) rcf_on_getset_field : texpr->texpr->string->int32 option->texpr option->bool->texpr; rcf_on_call_field : texpr->texpr->string->int32 option->texpr list->texpr; } let new_ctx gen ft object_iface optimize dynamic_getset_field dynamic_call_field hash_function lookup_function insert_function remove_function hash_conflict_ctx = { rcf_gen = gen; rcf_ft = ft; rcf_optimize = optimize; rcf_object_iface = object_iface; rcf_max_func_arity = 10; rcf_hash_function = hash_function; rcf_lookup_function = lookup_function; rcf_insert_function = insert_function; rcf_remove_function = remove_function; rcf_hash_fields = Hashtbl.create 100; rcf_hash_paths = Hashtbl.create 100; rcf_on_getset_field = dynamic_getset_field; rcf_on_call_field = dynamic_call_field; rcf_hash_conflict_ctx = hash_conflict_ctx; } (* methods as a bool option is a little laziness of my part. None means that methods are included with normal fields; Some(true) means collect only methods Some(false) means collect only fields (and MethDynamic fields) *) let collect_fields cl (methods : bool option) = let collected = Hashtbl.create 0 in let collect cf acc = if Meta.has Meta.CompilerGenerated cf.cf_meta || Meta.has Meta.SkipReflection cf.cf_meta then acc else match methods, cf.cf_kind with | None, _ when not (Hashtbl.mem collected cf.cf_name) -> Hashtbl.add collected cf.cf_name true; ([cf.cf_name], cf) :: acc | Some true, Method MethDynamic -> acc | Some true, Method _ when not (Hashtbl.mem collected cf.cf_name) -> Hashtbl.add collected cf.cf_name true; ([cf.cf_name], cf) :: acc | Some false, Method MethDynamic | Some false, Var _ when not (Hashtbl.mem collected cf.cf_name) -> Hashtbl.add collected cf.cf_name true; ([cf.cf_name], cf) :: acc | _ -> acc in let collect_cfs cfs acc = let rec loop cfs acc = match cfs with | [] -> acc | hd :: tl -> loop tl (collect hd acc) in loop cfs acc in let rec loop cl acc = let acc = collect_cfs cl.cl_ordered_fields acc in match cl.cl_super with | None -> acc | Some(cl,_) -> if not (is_hxgen (TClassDecl cl)) then loop cl acc else acc in loop cl [] let hash f = let h = ref 0 in for i = 0 to String.length f - 1 do h := !h * 223 + int_of_char (String.unsafe_get f i); done; if Sys.word_size = 64 then Int32.to_int (Int32.shift_right (Int32.shift_left (Int32.of_int !h) 1) 1) else !h let hash_field ctx f pos = let h = hash f in (try let f2 = Hashtbl.find ctx.rcf_hash_paths (ctx.rcf_gen.gcurrent_path, h) in if f <> f2 then ctx.rcf_gen.gcon.error ("Field conflict between " ^ f ^ " and " ^ f2) pos with Not_found -> Hashtbl.add ctx.rcf_hash_paths (ctx.rcf_gen.gcurrent_path, h) f; Hashtbl.replace ctx.rcf_hash_fields h f); h (* ( tf_args, switch_var ) *) let field_type_args ctx pos = match ctx.rcf_optimize with | true -> let field_name, field_hash = alloc_var "field" ctx.rcf_gen.gcon.basic.tstring, alloc_var "hash" ctx.rcf_gen.gcon.basic.tint in [field_name, None; field_hash, None], field_hash | false -> let field_name = alloc_var "field" ctx.rcf_gen.gcon.basic.tstring in [field_name, None], field_name let hash_field_i32 ctx pos field_name = let i = hash_field ctx field_name pos in let i = Int32.of_int (i) in if i < Int32.zero then Int32.logor (Int32.logand i (Int32.of_int 0x3FFFFFFF)) (Int32.shift_left Int32.one 30) else i let switch_case ctx pos field_name = match ctx.rcf_optimize with | true -> let i = hash_field_i32 ctx pos field_name in mk (TConst (TInt i)) ctx.rcf_gen.gcon.basic.tint pos | false -> ExprBuilder.make_string ctx.rcf_gen.gcon field_name pos let call_super ctx fn_args ret_t cf cl this_t pos = { eexpr = TCall({ eexpr = TField({ eexpr = TConst(TSuper); etype = this_t; epos = pos }, FInstance(cl,List.map snd cl.cl_params,cf)); etype = TFun(fun_args fn_args, ret_t); epos = pos; }, List.map (fun (v,_) -> mk_local v pos) fn_args); etype = ret_t; epos = pos; } let mk_throw ctx str pos = { eexpr = TThrow (ExprBuilder.make_string ctx.rcf_gen.gcon str pos); etype = ctx.rcf_gen.gcon.basic.tvoid; epos = pos } let enumerate_dynamic_fields ctx cl when_found base_arr = let gen = ctx.rcf_gen in let basic = gen.gcon.basic in let pos = cl.cl_pos in let vtmp = alloc_var "i" basic.tint in let mk_for arr len = let t = if ctx.rcf_optimize then basic.tint else basic.tstring in let convert_str e = if ctx.rcf_optimize then ctx.rcf_lookup_function e else e in let tmpinc = { eexpr = TUnop(Ast.Increment, Ast.Postfix, mk_local vtmp pos); etype = basic.tint; epos = pos } in [ { eexpr = TBinop(OpAssign, mk_local vtmp pos, ExprBuilder.make_int ctx.rcf_gen.gcon 0 pos); etype = basic.tint; epos = pos }; { eexpr = TWhile ( { eexpr = TBinop(Ast.OpLt, mk_local vtmp pos, len); etype = basic.tbool; epos = pos }, mk_block (when_found (convert_str { eexpr = TArray (arr, tmpinc); etype = t; epos = pos })), Ast.NormalWhile ); etype = basic.tvoid; epos = pos } ] in let this_t = TInst(cl, List.map snd cl.cl_params) in let this = { eexpr = TConst(TThis); etype = this_t; epos = pos } in let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in { eexpr = TVar (vtmp,None); etype = basic.tvoid; epos = pos } :: if ctx.rcf_optimize then mk_for (mk_this (gen.gmk_internal_name "hx" "hashes") (gen.gclasses.nativearray basic.tint)) (mk_this (gen.gmk_internal_name "hx" "length") basic.tint) @ mk_for (mk_this (gen.gmk_internal_name "hx" "hashes_f") (gen.gclasses.nativearray basic.tint)) (mk_this (gen.gmk_internal_name "hx" "length_f") basic.tint) @ ( let conflict_ctx = Option.get ctx.rcf_hash_conflict_ctx in let ehead = mk_this (gen.gmk_internal_name "hx" "conflicts") conflict_ctx.t in [conflict_ctx.add_names ehead base_arr] ) else mk_for (mk_this (gen.gmk_internal_name "hx" "hashes") (gen.gclasses.nativearray basic.tstring)) (mk_this (gen.gmk_internal_name "hx" "length") basic.tint) @ mk_for (mk_this (gen.gmk_internal_name "hx" "hashes_f") (gen.gclasses.nativearray basic.tstring)) (mk_this (gen.gmk_internal_name "hx" "length_f") basic.tint) (* ********************* Dynamic lookup ********************* This is the behavior of standard classes. It will replace the error throwing if a field doesn't exists when looking it up. In order for it to work, an implementation for hash_function must be created. hash_function is the function to be called/inlined that will allow us to lookup the hash into a sorted array of hashes. A binary search or linear search algorithm may be implemented. The only need is that if not found, the NegBits of the place where it should be inserted must be returned. *) let abstract_dyn_lookup_implementation ctx this field_local hash_local may_value is_float pos = let gen = ctx.rcf_gen in let basic = gen.gcon.basic in let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in let a_t = if ctx.rcf_optimize then basic.tint else basic.tstring in let hx_hashes = mk_this (gen.gmk_internal_name "hx" "hashes") (gen.gclasses.nativearray a_t) in let hx_hashes_f = mk_this (gen.gmk_internal_name "hx" "hashes_f") (gen.gclasses.nativearray a_t) in let hx_dynamics = mk_this (gen.gmk_internal_name "hx" "dynamics") (gen.gclasses.nativearray t_empty) in let hx_dynamics_f = mk_this (gen.gmk_internal_name "hx" "dynamics_f") (gen.gclasses.nativearray basic.tfloat) in let hx_length = mk_this (gen.gmk_internal_name "hx" "length") (basic.tint) in let hx_length_f = mk_this (gen.gmk_internal_name "hx" "length_f") (basic.tint) in let res = alloc_var "res" basic.tint in let fst_hash, snd_hash, fst_dynamics, snd_dynamics, fst_length, snd_length = if is_float then hx_hashes_f, hx_hashes, hx_dynamics_f, hx_dynamics, hx_length_f, hx_length else hx_hashes, hx_hashes_f, hx_dynamics, hx_dynamics_f, hx_length, hx_length_f in let res_local = mk_local res pos in let gte = { eexpr = TBinop(Ast.OpGte, res_local, { eexpr = TConst(TInt(Int32.zero)); etype = basic.tint; epos = pos }); etype = basic.tbool; epos = pos; } in let mk_tarray arr idx = { eexpr = TArray(arr, idx); etype = gen.gclasses.nativearray_type arr.etype; epos = pos; } in let ret_t = if is_float then basic.tfloat else t_dynamic in match may_value with | None -> (* var res = lookup(this.__hx_hashes/f, hash); if (res < 0) { res = lookup(this.__hx_hashes_f/_, hash); if(res < 0) return null; else return __hx_dynamics_f[res]; } else { return __hx_dynamics[res]; } *) let block = [ { eexpr = TVar(res, Some(ctx.rcf_hash_function hash_local fst_hash fst_length)); etype = basic.tvoid; epos = pos }; { eexpr = TIf(gte, mk_return (mk_tarray fst_dynamics res_local), Some({ eexpr = TBlock( [ { eexpr = TBinop(Ast.OpAssign, res_local, ctx.rcf_hash_function hash_local snd_hash snd_length); etype = basic.tint; epos = pos }; { eexpr = TIf(gte, mk_return (mk_tarray snd_dynamics res_local), None); etype = ret_t; epos = pos } ]); etype = ret_t; epos = pos; })); etype = ret_t; epos = pos } ] in if ctx.rcf_optimize then let conflict_ctx = Option.get ctx.rcf_hash_conflict_ctx in let ehead = mk_this (gen.gmk_internal_name "hx" "conflicts") conflict_ctx.t in let vconflict = alloc_var "conflict" conflict_ctx.t in let local_conflict = mk_local vconflict pos in [mk (TIf ( mk (TBinop (OpLt, hash_local, ExprBuilder.make_int gen.gcon 0 pos)) basic.tbool pos, mk (TBlock [ mk (TVar (vconflict, Some (conflict_ctx.get_conflict ehead hash_local field_local))) basic.tvoid pos; mk (TIf ( mk (TBinop (OpNotEq, local_conflict, mk (TConst TNull) local_conflict.etype pos)) basic.tbool pos, mk_return (Codegen.field local_conflict "value" t_dynamic pos), None )) basic.tvoid pos; ]) basic.tvoid pos, Some (mk (TBlock block) basic.tvoid pos) )) basic.tvoid pos] else block | Some value_local -> (* //if is not float: //if (isNumber(value_local)) return this.__hx_setField_f(field, getNumber(value_local), false(not static)); var res = lookup(this.__hx_hashes/f, hash); if (res >= 0) { return __hx_dynamics/f[res] = value_local; } else { res = lookup(this.__hx_hashes_f/_, hash); if (res >= 0) { __hx_dynamics_f/_.splice(res,1); __hx_hashes_f/_.splice(res,1); } } __hx_hashses/_f.insert(~res, hash); __hx_dynamics/_f.insert(~res, value_local); return value_local; *) let neg_res = { eexpr = TUnop(Ast.NegBits, Ast.Prefix, res_local); etype = basic.tint; epos = pos } in let res2 = alloc_var "res2" basic.tint in let res2_local = mk_local res2 pos in let gte2 = { eexpr = TBinop(Ast.OpGte, res2_local, { eexpr = TConst(TInt(Int32.zero)); etype = basic.tint; epos = pos }); etype = basic.tbool; epos = pos; } in let block = [ { eexpr = TVar(res, Some(ctx.rcf_hash_function hash_local fst_hash fst_length)); etype = basic.tvoid; epos = pos }; { eexpr = TIf(gte, mk_return { eexpr = TBinop(Ast.OpAssign, mk_tarray fst_dynamics res_local, value_local); etype = value_local.etype; epos = pos }, Some({ eexpr = TBlock([ { eexpr = TVar( res2, Some(ctx.rcf_hash_function hash_local snd_hash snd_length)); etype = basic.tvoid; epos = pos }; { eexpr = TIf(gte2, { eexpr = TBlock([ ctx.rcf_remove_function snd_hash snd_length res2_local; ctx.rcf_remove_function snd_dynamics snd_length res2_local; mk (TUnop(Decrement,Postfix,snd_length)) basic.tint pos ]); etype = t_dynamic; epos = pos }, None); etype = t_dynamic; epos = pos; } ]); etype = t_dynamic; epos = pos })); etype = t_dynamic; epos = pos; }; ctx.rcf_insert_function fst_hash fst_length neg_res hash_local; ctx.rcf_insert_function fst_dynamics fst_length neg_res value_local; mk (TUnop(Increment,Postfix,fst_length)) basic.tint pos; ] in let block = if ctx.rcf_optimize then let conflict_ctx = Option.get ctx.rcf_hash_conflict_ctx in let ehead = mk_this (gen.gmk_internal_name "hx" "conflicts") conflict_ctx.t in [mk (TIf ( mk (TBinop (OpLt, hash_local, ExprBuilder.make_int gen.gcon 0 pos)) basic.tbool pos, conflict_ctx.set ehead hash_local field_local value_local, Some (mk (TBlock block) basic.tvoid pos) )) basic.tvoid pos] else block in block @ [mk_return value_local] let get_delete_field ctx cl is_dynamic = let pos = cl.cl_pos in let this_t = TInst(cl, List.map snd cl.cl_params) in let this = { eexpr = TConst(TThis); etype = this_t; epos = pos } in let gen = ctx.rcf_gen in let basic = gen.gcon.basic in let tf_args, switch_var = field_type_args ctx pos in let local_switch_var = mk_local switch_var pos in let fun_type = TFun(fun_args tf_args,basic.tbool) in let cf = mk_class_field (gen.gmk_internal_name "hx" "deleteField") fun_type false pos (Method MethNormal) [] in let body = if is_dynamic then begin let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in let a_t = if ctx.rcf_optimize then basic.tint else basic.tstring in let hx_hashes = mk_this (gen.gmk_internal_name "hx" "hashes") (gen.gclasses.nativearray a_t) in let hx_hashes_f = mk_this (gen.gmk_internal_name "hx" "hashes_f") (gen.gclasses.nativearray a_t) in let hx_dynamics = mk_this (gen.gmk_internal_name "hx" "dynamics") (gen.gclasses.nativearray t_empty) in let hx_dynamics_f = mk_this (gen.gmk_internal_name "hx" "dynamics_f") (gen.gclasses.nativearray basic.tfloat) in let hx_length = mk_this (gen.gmk_internal_name "hx" "length") (basic.tint) in let hx_length_f = mk_this (gen.gmk_internal_name "hx" "length_f") (basic.tint) in let res = alloc_var "res" basic.tint in let res_local = mk_local res pos in let gte = { eexpr = TBinop(Ast.OpGte, res_local, { eexpr = TConst(TInt(Int32.zero)); etype = basic.tint; epos = pos }); etype = basic.tbool; epos = pos; } in (* var res = lookup(this.__hx_hashes, hash); if (res >= 0) { __hx_dynamics.splice(res,1); __hx_hashes.splice(res,1); return true; } else { res = lookup(this.__hx_hashes_f, hash); if (res >= 0) { __hx_dynamics_f.splice(res,1); __hx_hashes_f.splice(res,1); return true; } } return false; *) let common = [ { eexpr = TVar(res,Some(ctx.rcf_hash_function local_switch_var hx_hashes hx_length)); etype = basic.tvoid; epos = pos }; { eexpr = TIf(gte, { eexpr = TBlock([ ctx.rcf_remove_function hx_hashes hx_length res_local; ctx.rcf_remove_function hx_dynamics hx_length res_local; mk (TUnop(Decrement,Postfix,hx_length)) basic.tint pos; mk_return { eexpr = TConst(TBool true); etype = basic.tbool; epos = pos } ]); etype = t_dynamic; epos = pos }, Some({ eexpr = TBlock([ { eexpr = TBinop(Ast.OpAssign, res_local, ctx.rcf_hash_function local_switch_var hx_hashes_f hx_length_f); etype = basic.tint; epos = pos }; { eexpr = TIf(gte, { eexpr = TBlock([ ctx.rcf_remove_function hx_hashes_f hx_length_f res_local; ctx.rcf_remove_function hx_dynamics_f hx_length_f res_local; mk (TUnop(Decrement,Postfix,hx_length_f)) basic.tint pos; mk_return { eexpr = TConst(TBool true); etype = basic.tbool; epos = pos } ]); etype = t_dynamic; epos = pos }, None); etype = t_dynamic; epos = pos } ]); etype = t_dynamic; epos = pos })); etype = t_dynamic; epos = pos; }; mk_return { eexpr = TConst(TBool false); etype = basic.tbool; epos = pos } ] in if ctx.rcf_optimize then let v_name = match tf_args with (v,_) :: _ -> v | _ -> assert false in let local_name = mk_local v_name pos in let conflict_ctx = Option.get ctx.rcf_hash_conflict_ctx in let ehead = mk_this (gen.gmk_internal_name "hx" "conflicts") conflict_ctx.t in (mk (TIf ( mk (TBinop (OpLt, local_switch_var, ExprBuilder.make_int gen.gcon 0 pos)) basic.tbool pos, mk (TReturn (Some (conflict_ctx.delete ehead local_switch_var local_name))) basic.tvoid pos, None )) basic.tvoid pos) :: common else common end else [ mk_return { eexpr = TConst(TBool false); etype = basic.tbool; epos = pos } ] in (* create function *) let fn = { tf_args = tf_args; tf_type = basic.tbool; tf_expr = { eexpr = TBlock(body); etype = t_dynamic; epos = pos } } in cf.cf_expr <- Some({ eexpr = TFunction(fn); etype = fun_type; epos = pos }); cf let rec is_first_dynamic cl = match cl.cl_super with | Some(cl,_) -> if is_some cl.cl_dynamic then false else is_first_dynamic cl | None -> true let is_override cl = match cl.cl_super with | Some (cl, _) when is_hxgen (TClassDecl cl) -> true | _ -> false let get_args t = match follow t with | TFun(args,ret) -> args,ret | _ -> assert false (* WARNING: this will only work if overloading contructors is possible on target language *) let implement_dynamic_object_ctor ctx cl = let rec is_side_effects_free e = match e.eexpr with | TConst _ | TLocal _ | TFunction _ | TTypeExpr _ -> true | TNew(clnew,[],params) when clnew == cl -> List.for_all is_side_effects_free params | TUnop(Increment,_,_) | TUnop(Decrement,_,_) | TBinop(OpAssign,_,_) | TBinop(OpAssignOp _,_,_) -> false | TUnop(_,_,e) -> is_side_effects_free e | TArray(e1,e2) | TBinop(_,e1,e2) -> is_side_effects_free e1 && is_side_effects_free e2 | TIf(cond,e1,Some e2) -> is_side_effects_free cond && is_side_effects_free e1 && is_side_effects_free e2 | TField(e,_) | TParenthesis e | TMeta(_,e) -> is_side_effects_free e | TArrayDecl el -> List.for_all is_side_effects_free el | TCast(e,_) -> is_side_effects_free e | _ -> false in let pos = cl.cl_pos in let gen = ctx.rcf_gen in let basic = gen.gcon.basic in let hasht = if ctx.rcf_optimize then basic.tint else basic.tstring in let hashes_field = gen.gmk_internal_name "hx" "hashes", gen.gclasses.nativearray hasht in let hashes_f_field = gen.gmk_internal_name "hx" "hashes_f", gen.gclasses.nativearray hasht in let dynamics_field = gen.gmk_internal_name "hx" "dynamics", gen.gclasses.nativearray t_empty in let dynamics_f_field = gen.gmk_internal_name "hx" "dynamics_f", gen.gclasses.nativearray basic.tfloat in let fields = [ hashes_field; dynamics_field; hashes_f_field; dynamics_f_field; ] in let hashes_var = alloc_var (fst hashes_field) (snd hashes_field) in let hashes_f_var = alloc_var (fst hashes_f_field) (snd hashes_f_field) in let tf_args = [ hashes_var, None; alloc_var (fst dynamics_field) (snd dynamics_field), None; hashes_f_var, None; alloc_var (fst dynamics_f_field) (snd dynamics_f_field), None; ] in let this = { eexpr = TConst TThis; etype = TInst(cl, List.map snd cl.cl_params); epos = pos } in let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in let fun_t = TFun(fun_args tf_args,basic.tvoid) in let ctor = mk_class_field "new" fun_t true pos (Method MethNormal) [] in ctor.cf_expr <- Some( { eexpr = TFunction({ tf_args = tf_args; tf_type = basic.tvoid; tf_expr = { eexpr = TBlock( List.map (fun (v,_) -> { eexpr = TBinop(Ast.OpAssign, mk_this v.v_name v.v_type, mk_local v pos); etype = v.v_type; epos = pos } ) tf_args @ [ mk (TBinop(OpAssign, mk_this (gen.gmk_internal_name "hx" "length") basic.tint, gen.gclasses.nativearray_len (mk_local hashes_var pos) pos)) basic.tint pos; mk (TBinop(OpAssign, mk_this (gen.gmk_internal_name "hx" "length_f") basic.tint, gen.gclasses.nativearray_len (mk_local hashes_f_var pos) pos)) basic.tint pos; ] ); etype = basic.tvoid; epos = pos } }); etype = fun_t; epos = pos }); add_constructor cl ctor; (* default ctor also *) let ctor = mk_class_field "new" (TFun([],basic.tvoid)) false pos (Method MethNormal) [] in ctor.cf_expr <- Some { eexpr = TFunction { tf_type = basic.tvoid; tf_args = []; tf_expr = { eexpr = TBlock(List.map (fun (f,t) -> { eexpr = TBinop(Ast.OpAssign, mk_this f t,{ eexpr = TCall(mk_local v_nativearray pos, []); etype = t; epos = pos; }); etype = t; epos = pos } ) fields); etype = basic.tvoid; epos = pos; } }; etype = ctor.cf_type; epos = pos; }; add_constructor cl ctor; (* and finally we will return a function that transforms a TObjectDecl into a new DynamicObject() call *) let rec loop objdecl acc acc_f = match objdecl with | [] -> acc,acc_f | (name,expr) :: tl -> let real_t = gen.greal_type expr.etype in match follow expr.etype with | TInst ( { cl_path = ["haxe"], "Int64" }, [] ) -> loop tl ((name, gen.ghandle_cast t_dynamic real_t expr) :: acc) acc_f | _ -> if like_float real_t && not (like_i64 real_t) then loop tl acc ((name, gen.ghandle_cast basic.tfloat real_t expr) :: acc_f) else loop tl ((name, gen.ghandle_cast t_dynamic real_t expr) :: acc) acc_f in let may_hash_field s = if ctx.rcf_optimize then begin mk (TConst (TInt (hash_field_i32 ctx pos s))) basic.tint pos end else begin ExprBuilder.make_string gen.gcon s pos end in let do_objdecl e objdecl = let exprs_before = ref [] in let rec change_exprs decl acc = match decl with | (name,expr) :: tl -> if is_side_effects_free expr then change_exprs tl ((name,expr) :: acc) else begin let var = mk_temp gen "odecl" expr.etype in exprs_before := { eexpr = TVar(var,Some expr); etype = basic.tvoid; epos = expr.epos } :: !exprs_before; change_exprs tl ((name,mk_local var expr.epos) :: acc) end | [] -> acc in let objdecl = change_exprs objdecl [] in let odecl, odecl_f = loop objdecl [] [] in let changed_expr = List.map (fun (s,e) -> (may_hash_field s,e)) in let odecl, odecl_f = changed_expr odecl, changed_expr odecl_f in let sort_fn (e1,_) (e2,_) = match e1.eexpr, e2.eexpr with | TConst(TInt i1), TConst(TInt i2) -> compare i1 i2 | TConst(TString s1), TConst(TString s2) -> compare s1 s2 | _ -> assert false in let odecl, odecl_f = List.sort sort_fn odecl, List.sort sort_fn odecl_f in let ret = { e with eexpr = TNew(cl,[], [ mk_nativearray_decl gen hasht (List.map fst odecl) pos; mk_nativearray_decl gen t_empty (List.map snd odecl) pos; mk_nativearray_decl gen hasht (List.map fst odecl_f) pos; mk_nativearray_decl gen basic.tfloat (List.map snd odecl_f) pos; ]); } in match !exprs_before with | [] -> ret | block -> { eexpr = TBlock(List.rev block @ [ret]); etype = ret.etype; epos = ret.epos; } in do_objdecl let implement_dynamics ctx cl = let pos = cl.cl_pos in let is_override = is_override cl in if is_some cl.cl_dynamic then begin if is_first_dynamic cl then begin (* * add hx_hashes, hx_hashes_f, hx_dynamics, hx_dynamics_f to class * implement hx_deleteField *) let gen = ctx.rcf_gen in let basic = gen.gcon.basic in let hasht = if ctx.rcf_optimize then basic.tint else basic.tstring in let new_fields = [ mk_class_field (gen.gmk_internal_name "hx" "hashes") (gen.gclasses.nativearray hasht) false pos (Var { v_read = AccNormal; v_write = AccNormal }) []; mk_class_field (gen.gmk_internal_name "hx" "dynamics") (gen.gclasses.nativearray t_empty) false pos (Var { v_read = AccNormal; v_write = AccNormal }) []; mk_class_field (gen.gmk_internal_name "hx" "hashes_f") (gen.gclasses.nativearray hasht) false pos (Var { v_read = AccNormal; v_write = AccNormal }) []; mk_class_field (gen.gmk_internal_name "hx" "dynamics_f") (gen.gclasses.nativearray basic.tfloat) false pos (Var { v_read = AccNormal; v_write = AccNormal }) []; ] in (if cl.cl_path <> (["haxe"; "lang"], "DynamicObject") then List.iter (fun cf -> cf.cf_expr <- Some { eexpr = TCall(mk_local v_nativearray pos, []); etype = cf.cf_type; epos = cf.cf_pos }) new_fields ); let new_fields = if ctx.rcf_optimize then let f = mk_class_field (gen.gmk_internal_name "hx" "conflicts") (Option.get ctx.rcf_hash_conflict_ctx).t false pos (Var { v_read = AccNormal; v_write = AccNormal }) [] in f :: new_fields else new_fields in let delete = get_delete_field ctx cl true in let new_fields = new_fields @ [ mk_class_field (gen.gmk_internal_name "hx" "length") (basic.tint) false pos (Var { v_read = AccNormal; v_write = AccNormal }) []; mk_class_field (gen.gmk_internal_name "hx" "length_f") (basic.tint) false pos (Var { v_read = AccNormal; v_write = AccNormal }) []; delete; ] in List.iter (fun cf -> cl.cl_fields <- PMap.add cf.cf_name cf cl.cl_fields ) new_fields; (* let rec last_ctor cl = match cl.cl_constructor with | None -> (match cl.cl_super with | None -> None | Some (cl,_) -> last_ctor cl) | Some c -> Some c in *) (* in order for the next to work, we need to execute our script before InitFunction, so the expressions inside the variables are initialized by the constructor *) (* Now we need to add their initialization. This will consist of different parts: Check if there are constructors. If not, create one and add initialization to it (calling super, ok) If there are, add as first statement (or second if there is a super() call in the first) If class has @:dynamicObject meta, also create another new() class with its parameters as constructor arguments *) cl.cl_ordered_fields <- cl.cl_ordered_fields @ new_fields; if is_override then cl.cl_overrides <- delete :: cl.cl_overrides end end else if not is_override then begin let delete = get_delete_field ctx cl false in cl.cl_ordered_fields <- cl.cl_ordered_fields @ [delete]; cl.cl_fields <- PMap.add delete.cf_name delete cl.cl_fields end (* Implements: __hx_lookupField(field:String, throwErrors:Bool, isCheck:Bool, handleProperties:Bool, isFirst:Bool):Dynamic __hx_lookupField_f(field:String, throwErrors:Bool, handleProperties:Bool, isFirst:Bool):Float __hx_lookupSetField(field:String, value:Dynamic, handleProperties:Bool, isFirst:Bool):Dynamic; __hx_lookupSetField(field:String, value:Float, handleProperties:Bool, isFirst:Bool):Float; *) let implement_final_lookup ctx cl = let gen = ctx.rcf_gen in let basic = gen.gcon.basic in let pos = cl.cl_pos in let is_override = is_override cl in let this = { eexpr = TConst(TThis); etype = TInst(cl, List.map snd cl.cl_params); epos = pos } in (* this function will create the class fields and call callback for each version callback : is_float fields_args switch_var throw_errors_option is_check_option value_option : texpr list *) let create_cfs is_dynamic callback = let create_cf is_float is_set = let name = gen.gmk_internal_name "hx" ( (if is_set then "lookupSetField" else "lookupField") ^ (if is_float then "_f" else "") ) in let field_args, switch_var = field_type_args ctx pos in let ret_t = if is_float then basic.tfloat else t_dynamic in let tf_args, throw_errors_opt = if is_set then field_args, None else let v = alloc_var "throwErrors" basic.tbool in field_args @ [v,None], Some v in let tf_args, is_check_opt = if is_set || is_float then tf_args, None else let v = alloc_var "isCheck" basic.tbool in tf_args @ [v,None], Some v in let tf_args, value_opt = if not is_set then tf_args, None else let v = alloc_var "value" ret_t in field_args @ [v,None], Some v in let fun_t = TFun(fun_args tf_args, ret_t) in let cf = mk_class_field name fun_t false pos (Method MethNormal) [] in let block = callback is_float field_args switch_var throw_errors_opt is_check_opt value_opt in let block = if not is_set then let tl = begin let throw_errors_local = mk_local (get throw_errors_opt) pos in let mk_check_throw msg = { eexpr = TIf(throw_errors_local, mk_throw ctx msg pos, Some (mk_return (null ret_t pos))); etype = ret_t; epos = pos } in let mk_may_check_throw msg = if is_dynamic then mk_return (null ret_t pos) else mk_check_throw msg in if is_float then begin [ mk_may_check_throw "Field not found or incompatible field type."; ] end else begin let is_check_local = mk_local (get is_check_opt) pos in [ { eexpr = TIf(is_check_local, mk_return (undefined pos), Some( mk_may_check_throw "Field not found." )); etype = ret_t; epos = pos; } ] end end in block @ tl else block in cf.cf_expr <- Some( { eexpr = TFunction({ tf_args = tf_args; tf_type = ret_t; tf_expr = { eexpr = TBlock(block); etype = ret_t; epos = pos } }); etype = fun_t; epos = pos } ); cf in let cfs = [ create_cf false false; create_cf true false; create_cf false true; create_cf true true ] in cl.cl_ordered_fields <- cl.cl_ordered_fields @ cfs; List.iter (fun cf -> cl.cl_fields <- PMap.add cf.cf_name cf cl.cl_fields; if is_override then cl.cl_overrides <- cf :: cl.cl_overrides ) cfs in if is_some cl.cl_dynamic then begin (* let abstract_dyn_lookup_implementation ctx this hash_local may_value is_float pos = *) (* callback : is_float fields_args switch_var throw_errors_option is_check_option value_option : texpr list *) if is_first_dynamic cl then create_cfs true (fun is_float fields_args switch_var _ _ value_opt -> let v_name = match fields_args with (v,_) :: _ -> v | _ -> assert false in abstract_dyn_lookup_implementation ctx this (mk_local v_name pos) (mk_local switch_var pos) (Option.map (fun v -> mk_local v pos) value_opt) is_float pos ) end else if not is_override then begin create_cfs false (fun is_float fields_args switch_var _ _ value_opt -> match value_opt with | None -> (* is not set *) [] | Some _ -> (* is set *) if is_float then [ mk_throw ctx "Cannot access field for writing or incompatible type." pos ] else [ mk_throw ctx "Cannot access field for writing." pos ] ) end (* *) let implement_get_set ctx cl = let gen = ctx.rcf_gen in let mk_cfield is_set is_float = let pos = cl.cl_pos in let basic = ctx.rcf_gen.gcon.basic in let tf_args, switch_var = field_type_args ctx pos in let field_args = tf_args in let local_switch_var = { eexpr = TLocal(switch_var); etype = switch_var.v_type; epos = pos } in let handle_prop = alloc_var "handleProperties" basic.tbool in let handle_prop_local = mk_local handle_prop pos in let this = { eexpr = TConst TThis; etype = TInst(cl, List.map snd cl.cl_params); epos = pos } in let mk_this_call_raw name fun_t params = { eexpr = TCall( { (mk_field_access gen this name pos) with etype = fun_t; }, params ); etype = snd (get_args fun_t); epos = pos } in let fun_type = ref (TFun([], basic.tvoid)) in let fun_name = ctx.rcf_gen.gmk_internal_name "hx" ( (if is_set then "setField" else "getField") ^ (if is_float then "_f" else "") ) in let cfield = mk_class_field fun_name !fun_type false pos (Method MethNormal) [] in let maybe_cast e = e in let t = TInst(cl, List.map snd cl.cl_params) in (* if it's not latest hxgen class -> check super *) let mk_do_default args do_default = match cl.cl_super with | None -> fun () -> maybe_cast (do_default ()) | Some (super, sparams) when not (is_hxgen (TClassDecl super)) -> fun () -> maybe_cast (do_default ()) | _ -> fun () -> mk_return { eexpr = TCall( { eexpr = TField({ eexpr = TConst TSuper; etype = t; epos = pos }, FInstance(cl, List.map snd cl.cl_params, cfield)); etype = !fun_type; epos = pos }, (List.map (fun (v,_) -> mk_local v pos) args) ); etype = if is_float then basic.tfloat else t_dynamic; epos = pos; }; in (* if it is set function, there are some different set fields to do *) let do_default, do_field, tf_args = if is_set then begin let value_var = alloc_var "value" (if is_float then basic.tfloat else t_dynamic) in let value_local = { eexpr = TLocal(value_var); etype = value_var.v_type; epos = pos } in let tf_args = tf_args @ [value_var,None; handle_prop, None; ] in let lookup_name = gen.gmk_internal_name "hx" ("lookupSetField" ^ if is_float then "_f" else "") in let do_default = fun () -> mk_return (mk_this_call_raw lookup_name (TFun(fun_args (field_args @ [value_var,None]),value_var.v_type)) ( List.map (fun (v,_) -> mk_local v pos) field_args @ [ value_local ] )) in let do_field cf cf_type = let get_field ethis = { eexpr = TField (ethis, FInstance(cl, List.map snd cl.cl_params, cf)); etype = cf_type; epos = pos } in let this = { eexpr = TConst(TThis); etype = t; epos = pos } in let value_local = if is_float then match follow cf_type with | TInst({ cl_kind = KTypeParameter _ }, _) -> mk_cast t_dynamic value_local | _ -> value_local else value_local in let ret = { eexpr = TBlock([ { eexpr = TBinop(Ast.OpAssign, get_field this, mk_cast cf_type value_local); etype = cf_type; epos = pos; }; mk_return value_local ]); etype = cf_type; epos = pos; } in match cf.cf_kind with | Var { v_write = AccCall } -> let bl = [ mk_this_call_raw ("set_" ^ cf.cf_name) (TFun(["value",false,cf.cf_type], cf.cf_type)) [ value_local ]; mk_return value_local ] in if Type.is_extern_field cf then { eexpr = TBlock bl; etype = value_local.etype; epos = pos } else { eexpr = TIf( handle_prop_local, { eexpr = TBlock bl; etype = value_local.etype; epos = pos }, Some ret); etype = value_local.etype; epos = pos; } | _ -> ret in (mk_do_default tf_args do_default, do_field, tf_args) end else begin let throw_errors = alloc_var "throwErrors" basic.tbool in let throw_errors_local = mk_local throw_errors pos in let do_default, tf_args = if not is_float then begin let is_check = alloc_var "isCheck" basic.tbool in let is_check_local = mk_local is_check pos in let tf_args = tf_args @ [ throw_errors,None; ] in (* default: if (isCheck) return __undefined__ else if(throwErrors) throw "Field not found"; else return null; *) let lookup_name = gen.gmk_internal_name "hx" "lookupField" in let do_default = fun () -> mk_return (mk_this_call_raw lookup_name (TFun(fun_args (field_args @ [throw_errors,None;is_check,None; ]),t_dynamic)) ( List.map (fun (v,_) -> mk_local v pos) field_args @ [ throw_errors_local; is_check_local; ] )) in (do_default, tf_args @ [ is_check,None; handle_prop,None; ]) end else begin let tf_args = tf_args @ [ throw_errors,None; ] in let lookup_name = gen.gmk_internal_name "hx" "lookupField_f" in let do_default = fun () -> mk_return (mk_this_call_raw lookup_name (TFun(fun_args (field_args @ [throw_errors,None; ]),basic.tfloat)) ( List.map (fun (v,_) -> mk_local v pos) field_args @ [ throw_errors_local; ] )) in (do_default, tf_args @ [ handle_prop,None; ]) end in let get_field cf cf_type ethis cl name = match cf.cf_kind with | Var { v_read = AccCall } when Type.is_extern_field cf -> mk_return (mk_this_call_raw ("get_" ^ cf.cf_name) (TFun(["value",false,cf.cf_type], cf.cf_type)) [ ]) | Var { v_read = AccCall } -> { eexpr = TIf( handle_prop_local, mk_return (mk_this_call_raw ("get_" ^ cf.cf_name) (TFun(["value",false,cf.cf_type], cf.cf_type)) [ ]), Some { eexpr = TField (ethis, FInstance(cl, List.map snd cl.cl_params, cf)); etype = cf_type; epos = pos } ); etype = cf_type; epos = pos; } | Var _ | Method MethDynamic -> { eexpr = TField (ethis, FInstance(cl,List.map snd cl.cl_params,cf)); etype = cf_type; epos = pos } | _ -> { eexpr = TField (this, FClosure(Some (cl,[]), cf)); etype = cf_type; epos = pos } (* TODO: FClosure change *) in let do_field cf cf_type = let this = { eexpr = TConst(TThis); etype = t; epos = pos } in match is_float, follow cf_type with | true, TInst( { cl_kind = KTypeParameter _ }, _ ) -> mk_return (mk_cast basic.tfloat (mk_cast t_dynamic (get_field cf cf_type this cl cf.cf_name))) | _ -> mk_return (maybe_cast (get_field cf cf_type this cl cf.cf_name )) in (mk_do_default tf_args do_default, do_field, tf_args) end in let get_fields() = let ret = collect_fields cl ( if is_float || is_set then Some (false) else None ) in let ret = if is_set then List.filter (fun (_,cf) -> match cf.cf_kind with (* | Var { v_write = AccNever } -> false *) | _ -> not (Meta.has Meta.ReadOnly cf.cf_meta)) ret else List.filter (fun (_,cf) -> match cf.cf_kind with (* | Var { v_read = AccNever } -> false *) | _ -> true) ret in if is_float then List.filter (fun (_,cf) -> (* TODO: maybe really apply_params in cf.cf_type. The benefits would be limited, though *) match follow (ctx.rcf_gen.greal_type (ctx.rcf_gen.gfollow#run_f cf.cf_type)) with | TDynamic _ | TMono _ | TInst ({ cl_kind = KTypeParameter _ }, _) -> true | t when like_float t && not (like_i64 t) -> true | _ -> false ) ret else (* dynamic will always contain all references *) ret in (* now we have do_default, do_field and tf_args *) (* so create the switch expr *) fun_type := TFun(List.map (fun (v,_) -> (v.v_name, false, v.v_type)) tf_args, if is_float then basic.tfloat else t_dynamic ); let has_fields = ref false in let content = let fields = get_fields() in let fields = List.filter (fun (_, cf) -> match is_set, cf.cf_kind with | true, Var { v_write = AccCall } -> true | false, Var { v_read = AccCall } -> true | _ -> not (Type.is_extern_field cf)) fields in (if fields <> [] then has_fields := true); let cases = List.map (fun (names, cf) -> (if names = [] then assert false); (List.map (switch_case ctx pos) names, do_field cf cf.cf_type) ) fields in let default = Some(do_default()) in mk_block { eexpr = TSwitch(local_switch_var, cases, default); etype = basic.tvoid; epos = pos } in let is_override = match cl.cl_super with | Some (cl, _) when is_hxgen (TClassDecl cl) -> true | _ -> false in if !has_fields || (not is_override) then begin let func = { tf_args = tf_args; tf_type = if is_float then basic.tfloat else t_dynamic; tf_expr = content; } in let func = { eexpr = TFunction(func); etype = !fun_type; epos = pos } in cfield.cf_type <- !fun_type; cfield.cf_expr <- Some func; cl.cl_ordered_fields <- cl.cl_ordered_fields @ [cfield]; cl.cl_fields <- PMap.add fun_name cfield cl.cl_fields; (if is_override then cl.cl_overrides <- cfield :: cl.cl_overrides) end else () in mk_cfield true true; mk_cfield true false; mk_cfield false false; mk_cfield false true let implement_getFields ctx cl = let gen = ctx.rcf_gen in let basic = gen.gcon.basic in let pos = cl.cl_pos in (* function __hx_getFields(baseArr:Array) { //add all variable fields //then: super.__hx_getFields(baseArr); } *) let name = gen.gmk_internal_name "hx" "getFields" in let v_base_arr = alloc_var "baseArr" (basic.tarray basic.tstring) in let base_arr = mk_local v_base_arr pos in let tf_args = [(v_base_arr,None)] in let t = TFun(fun_args tf_args, basic.tvoid) in let cf = mk_class_field name t false pos (Method MethNormal) [] in let e_pushfield = mk_field_access gen base_arr "push" pos in let mk_push value = mk (TCall (e_pushfield, [value])) basic.tint pos in let has_value = ref false in let map_fields = List.map (fun (_,cf) -> match cf.cf_kind with | Var _ | Method MethDynamic when not (List.memq cf cl.cl_overrides) -> has_value := true; mk_push (ExprBuilder.make_string gen.gcon cf.cf_name pos) | _ -> null basic.tvoid pos ) in (* if it is first_dynamic, then we need to enumerate the dynamic fields *) let exprs = if is_some cl.cl_dynamic && is_first_dynamic cl then begin has_value := true; enumerate_dynamic_fields ctx cl mk_push base_arr end else [] in let exprs = if is_override cl then let tparams = List.map snd cl.cl_params in let esuper = mk (TConst TSuper) (TInst(cl, tparams)) pos in let efield = mk (TField (esuper, FInstance (cl, tparams, cf))) t pos in exprs @ [mk (TCall (efield, [base_arr])) basic.tvoid pos] else exprs in let exprs = map_fields (collect_fields cl (Some false)) @ exprs in cf.cf_expr <- Some { eexpr = TFunction({ tf_args = tf_args; tf_type = basic.tvoid; tf_expr = mk (TBlock exprs) basic.tvoid pos }); etype = t; epos = pos }; if !has_value || not (is_override cl) then begin cl.cl_ordered_fields <- cl.cl_ordered_fields @ [cf]; cl.cl_fields <- PMap.add cf.cf_name cf cl.cl_fields; (if is_override cl then cl.cl_overrides <- cf :: cl.cl_overrides) end let implement_invokeField ctx ~slow_invoke cl = (* There are two ways to implement an haxe reflection-enabled class: When we extend a non-hxgen class, and when we extend the base HxObject class. Because of the added boiler plate we'd add every time we extend a non-hxgen class to implement a big IHxObject interface, we'll handle the cases differently when implementing each interface. At the IHxObject interface, there's only invokeDynamic(field, args[]), while at the HxObject class there are the other, more optimized methods, that follow the Function class interface. Since this will only be called by the Closure class, this conversion can be properly dealt with later. TODO: create the faster version. By now only invokeDynamic will be implemented *) let gen = ctx.rcf_gen in let basic = gen.gcon.basic in let pos = cl.cl_pos in let has_method = ref false in let is_override = ref false in let rec extends_hxobject cl = match cl.cl_super with | None -> true | Some (cl,_) when is_hxgen (TClassDecl cl) -> is_override := true; extends_hxobject cl | _ -> false in let field_args, switch_var = field_type_args ctx cl.cl_pos in let field_args_exprs = List.map (fun (v,_) -> mk_local v pos) field_args in let dynamic_arg = alloc_var "dynargs" (basic.tarray t_dynamic) in let all_args = field_args @ [ dynamic_arg, None ] in let fun_t = TFun(fun_args all_args, t_dynamic) in let this_t = TInst(cl, List.map snd cl.cl_params) in let this = { eexpr = TConst(TThis); etype = this_t; epos = pos } in let apply_object cf = apply_params cf.cf_params (List.map (fun _ -> t_dynamic) cf.cf_params) cf.cf_type in let mk_this_call_raw name fun_t params = { eexpr = TCall( { (mk_field_access gen this name pos) with etype = fun_t }, params ); etype = snd (get_args fun_t); epos = pos } in let mk_this_call cf params = let t = apply_object cf in (* the return type transformation into Dynamic *) (* is meant to avoid return-type casting after functions with *) (* type parameters are properly inferred at TypeParams.infer_params *) (* e.g. function getArray(t:T):Array; after infer_params, *) (* T will be inferred as SomeType, but the returned type will still be typed *) (* as Array *) let args, ret = get_args t in let ret = match follow ret with | TAbstract ({ a_path = ([], "Void") },[]) -> ret | _ -> ret in mk_this_call_raw cf.cf_name (TFun(args, ret)) params in let extends_hxobject = extends_hxobject cl in ignore extends_hxobject; (* creates a invokeField of the class fields listed here *) (* function invokeField(field, dynargs) { switch(field) { case "a": this.a(dynargs[0], dynargs[1], dynargs[2]...); default: super.invokeField //or this.getField(field).invokeDynamic(dynargs) } } *) let dyn_fun = mk_class_field (ctx.rcf_gen.gmk_internal_name "hx" "invokeField") fun_t false cl.cl_pos (Method MethNormal) [] in let mk_switch_dyn cfs old = let get_case (names,cf) = has_method := true; let i = ref 0 in let dyn_arg_local = mk_local dynamic_arg pos in let cases = List.map (switch_case ctx pos) names in (cases, { eexpr = TReturn(Some (mk_this_call cf (List.map (fun (name,_,t) -> let ret = { eexpr = TArray(dyn_arg_local, ExprBuilder.make_int ctx.rcf_gen.gcon !i pos); etype = t_dynamic; epos = pos } in incr i; ret ) (fst (get_args (cf.cf_type))) ) )); etype = basic.tvoid; epos = pos } ) in let cfs = List.filter (fun (_,cf) -> match cf.cf_kind with | Method _ -> if List.memq cf cl.cl_overrides then false else true | _ -> true) cfs in let cases = List.map get_case cfs in let cases = match old with | [] -> cases | _ -> let ncases = List.map (fun cf -> switch_case ctx pos cf.cf_name) old in ( ncases, mk_return ((get slow_invoke) this (mk_local (fst (List.hd field_args)) pos) (mk_local dynamic_arg pos)) ) :: cases in let default = if !is_override then { eexpr = TReturn(Some (call_super ctx all_args t_dynamic dyn_fun cl this_t pos) ); etype = basic.tvoid; epos = pos } else ( let field = begin let fun_name = ctx.rcf_gen.gmk_internal_name "hx" "getField" in let tf_args, _ = field_type_args ctx pos in let tf_args, args = fun_args tf_args, field_args_exprs in let tf_args, args = tf_args @ ["throwErrors",false, basic.tbool], args @ [ExprBuilder.make_bool gen.gcon true pos] in let tf_args, args = tf_args @ ["isCheck", false, basic.tbool], args @ [ExprBuilder.make_bool gen.gcon false pos] in let tf_args, args = tf_args @ ["handleProperties", false, basic.tbool], args @ [ExprBuilder.make_bool gen.gcon false pos] in mk (TCall ({ (mk_field_access gen this fun_name pos) with etype = TFun(tf_args, t_dynamic) }, args)) t_dynamic pos end in let field = mk_cast (TInst(ctx.rcf_ft.func_class,[])) field in mk_return { eexpr = TCall( mk_field_access gen field (gen.gmk_internal_name "hx" "invokeDynamic") pos, [mk_local dynamic_arg pos]); etype = t_dynamic; epos = pos } ) in { eexpr = TSwitch(mk_local switch_var pos, cases, Some default); etype = basic.tvoid; epos = pos; } in let contents = let nonstatics = collect_fields cl (Some true) in let old_nonstatics = ref [] in let nonstatics = match slow_invoke with | None -> nonstatics | Some _ -> List.filter (fun (n,cf) -> let is_old = not (PMap.mem cf.cf_name cl.cl_fields) || List.memq cf cl.cl_overrides in (if is_old then old_nonstatics := cf :: !old_nonstatics); not is_old ) nonstatics in mk_switch_dyn nonstatics !old_nonstatics in dyn_fun.cf_expr <- Some { eexpr = TFunction( { tf_args = all_args; tf_type = t_dynamic; tf_expr = mk_block contents; }); etype = TFun(fun_args all_args, t_dynamic); epos = pos; }; if !is_override && not (!has_method) then () else begin cl.cl_ordered_fields <- cl.cl_ordered_fields @ [dyn_fun]; cl.cl_fields <- PMap.add dyn_fun.cf_name dyn_fun cl.cl_fields; (if !is_override then cl.cl_overrides <- dyn_fun :: cl.cl_overrides) end let implement_varargs_cl ctx cl = let pos = cl.cl_pos in let gen = ctx.rcf_gen in let basic = gen.gcon.basic in let this_t = TInst(cl, List.map snd cl.cl_params) in let this = { eexpr = TConst(TThis); etype = this_t ; epos = pos } in let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in let invokedyn = gen.gmk_internal_name "hx" "invokeDynamic" in let idyn_t = TFun([gen.gmk_internal_name "fn" "dynargs", false, basic.tarray t_dynamic], t_dynamic) in let this_idyn = mk_this invokedyn idyn_t in let map_fn arity ret vars api = let rec loop i acc = if i < 0 then acc else let obj = api i t_dynamic None in loop (i - 1) (obj :: acc) in let call_arg = if arity = (-1) then api (-1) t_dynamic None else if arity = 0 then null (basic.tarray t_empty) pos else { eexpr = TArrayDecl(loop (arity - 1) []); etype = basic.tarray t_empty; epos = pos } in let expr = { eexpr = TCall( this_idyn, [ call_arg ] ); etype = t_dynamic; epos = pos } in let expr = if like_float ret && not (like_int ret) then mk_cast ret expr else expr in mk_return expr in let all_cfs = List.filter (fun cf -> cf.cf_name <> "new" && cf.cf_name <> (invokedyn) && match cf.cf_kind with Method _ -> true | _ -> false) (ctx.rcf_ft.map_base_classfields cl map_fn) in cl.cl_ordered_fields <- cl.cl_ordered_fields @ all_cfs; List.iter (fun cf -> cl.cl_fields <- PMap.add cf.cf_name cf cl.cl_fields ) all_cfs; List.iter (fun cf -> cl.cl_overrides <- cf :: cl.cl_overrides ) cl.cl_ordered_fields let implement_closure_cl ctx cl = let pos = cl.cl_pos in let gen = ctx.rcf_gen in let basic = gen.gcon.basic in let field_args, _ = field_type_args ctx pos in let obj_arg = alloc_var "target" (TInst(ctx.rcf_object_iface, [])) in let this_t = TInst(cl, List.map snd cl.cl_params) in let this = { eexpr = TConst(TThis); etype = this_t ; epos = pos } in let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in let tf_args = field_args @ [obj_arg, None] in let cfs, ctor_body = List.fold_left (fun (acc_cf,acc_expr) (v,_) -> let cf = mk_class_field v.v_name v.v_type false pos (Var { v_read = AccNormal; v_write = AccNormal } ) [] in let expr = { eexpr = TBinop(Ast.OpAssign, mk_this v.v_name v.v_type, mk_local v pos); etype = v.v_type; epos = pos } in (cf :: acc_cf, expr :: acc_expr) ) ([], []) tf_args in let map_fn arity ret vars api = let this_obj = mk_this "target" (TInst(ctx.rcf_object_iface, [])) in let rec loop i acc = if i < 0 then acc else let obj = api i t_dynamic None in loop (i - 1) (obj :: acc) in let call_arg = if arity = (-1) then api (-1) t_dynamic None else if arity = 0 then null (basic.tarray t_empty) pos else { eexpr = TArrayDecl(loop (arity - 1) []); etype = basic.tarray t_empty; epos = pos } in let expr = { eexpr = TCall( mk_field_access gen this_obj (gen.gmk_internal_name "hx" "invokeField") pos, (List.map (fun (v,_) -> mk_this v.v_name v.v_type) field_args) @ [ call_arg ] ); etype = t_dynamic; epos = pos } in let expr = if like_float ret && not (like_int ret) then mk_cast ret expr else expr in mk_return expr in let all_cfs = List.filter (fun cf -> cf.cf_name <> "new" && match cf.cf_kind with Method _ -> true | _ -> false) (ctx.rcf_ft.map_base_classfields cl map_fn) in List.iter (fun cf -> cl.cl_overrides <- cf :: cl.cl_overrides ) all_cfs; let all_cfs = cfs @ all_cfs in cl.cl_ordered_fields <- cl.cl_ordered_fields @ all_cfs; List.iter (fun cf -> cl.cl_fields <- PMap.add cf.cf_name cf cl.cl_fields ) all_cfs; let ctor_t = TFun(fun_args tf_args, basic.tvoid) in let ctor_cf = mk_class_field "new" ctor_t true pos (Method MethNormal) [] in ctor_cf.cf_expr <- Some { eexpr = TFunction({ tf_args = tf_args; tf_type = basic.tvoid; tf_expr = { eexpr = TBlock({ eexpr = TCall({ eexpr = TConst(TSuper); etype = TInst(cl,[]); epos = pos }, [ExprBuilder.make_int ctx.rcf_gen.gcon (-1) pos; ExprBuilder.make_int ctx.rcf_gen.gcon (-1) pos]); etype = basic.tvoid; epos = pos } :: ctor_body); etype = basic.tvoid; epos = pos } }); etype = ctor_t; epos = pos }; cl.cl_constructor <- Some ctor_cf; let closure_fun eclosure e field is_static = let f = ExprBuilder.make_string gen.gcon field eclosure.epos in let args = if ctx.rcf_optimize then [ f; { eexpr = TConst(TInt (hash_field_i32 ctx eclosure.epos field)); etype = basic.tint; epos = eclosure.epos } ] else [ f ] in let args = args @ [ mk_cast (TInst(ctx.rcf_object_iface, [])) e ] in { eclosure with eexpr = TNew(cl,[],args) } in closure_fun let get_closure_func ctx closure_cl = let gen = ctx.rcf_gen in let basic = gen.gcon.basic in let closure_func eclosure e field is_static = mk_cast eclosure.etype { eclosure with eexpr = TNew(closure_cl, [], [ e; ExprBuilder.make_string gen.gcon field eclosure.epos ] @ ( if ctx.rcf_optimize then [ { eexpr = TConst(TInt (hash_field_i32 ctx eclosure.epos field)); etype = basic.tint; epos = eclosure.epos } ] else [] )); etype = TInst(closure_cl,[]) } in closure_func (* main expr -> field expr -> field string -> possible set expr -> should_throw_exceptions -> changed expression Changes a get / set * mutable rcf_on_getset_field : texpr->texpr->string->texpr option->bool->texpr;*) let configure_dynamic_field_access ctx = let gen = ctx.rcf_gen in let is_dynamic expr fexpr field = match (field_access_esp gen (gen.greal_type fexpr.etype) field) with | FEnumField _ | FClassField _ -> false | _ -> true in let maybe_hash = if ctx.rcf_optimize then fun str pos -> Some (hash_field_i32 ctx pos str) else fun str pos -> None in DynamicFieldAccess.configure gen is_dynamic (fun expr fexpr field set is_unsafe -> let hash = maybe_hash field fexpr.epos in ctx.rcf_on_getset_field expr fexpr field hash set is_unsafe ) (fun ecall fexpr field call_list -> let hash = maybe_hash field fexpr.epos in ctx.rcf_on_call_field ecall fexpr field hash call_list ); () (* ******************************************* *) (* UniversalBaseClass *) (* ******************************************* *) (* Sets the universal base class for hxgen types (HxObject / IHxObject) dependencies: As a rule, it should be one of the last module filters to run so any @:hxgen class created in the process -Should- only run after TypeParams.RealTypeParams.Modf *) module UniversalBaseClass = struct let name = "rcf_universal_base_class" let priority = min_dep +. 10. let configure gen baseclass baseinterface basedynamic = let rec run md = if is_hxgen md then match md with | TClassDecl ({ cl_interface = true } as cl) when cl.cl_path <> baseclass.cl_path && cl.cl_path <> baseinterface.cl_path && cl.cl_path <> basedynamic.cl_path -> cl.cl_implements <- (baseinterface, []) :: cl.cl_implements | TClassDecl ({ cl_kind = KAbstractImpl _ }) -> (* don't add any base classes to abstract implementations *) () | TClassDecl ({ cl_super = None } as cl) when cl.cl_path <> baseclass.cl_path && cl.cl_path <> baseinterface.cl_path && cl.cl_path <> basedynamic.cl_path -> if is_some cl.cl_dynamic then cl.cl_super <- Some (basedynamic,[]) else cl.cl_super <- Some (baseclass,[]) | TClassDecl ({ cl_super = Some(super,_) } as cl) when cl.cl_path <> baseclass.cl_path && cl.cl_path <> baseinterface.cl_path && not (is_hxgen (TClassDecl super)) -> cl.cl_implements <- (baseinterface, []) :: cl.cl_implements | _ -> () in let map md = Some(run md; md) in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) map end;; (* Priority: must run AFTER UniversalBaseClass *) let priority = solve_deps name [DAfter UniversalBaseClass.priority] let configure ?slow_invoke ctx baseinterface = let gen = ctx.rcf_gen in let run = (fun md -> match md with | TClassDecl cl when is_hxgen md && ( not cl.cl_interface || cl.cl_path = baseinterface.cl_path ) && (match cl.cl_kind with KAbstractImpl _ -> false | _ -> true) -> (implement_dynamics ctx cl); (if not (PMap.mem (gen.gmk_internal_name "hx" "lookupField") cl.cl_fields) then implement_final_lookup ctx cl); (if not (PMap.mem (gen.gmk_internal_name "hx" "getField") cl.cl_fields) then implement_get_set ctx cl); (if not (PMap.mem (gen.gmk_internal_name "hx" "invokeField") cl.cl_fields) then implement_invokeField ctx ~slow_invoke:slow_invoke cl); (if not (PMap.mem (gen.gmk_internal_name "hx" "getFields") cl.cl_fields) then implement_getFields ctx cl); None | _ -> None) in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) run end;; (* ******************************************* *) (* Object Declaration Mapper *) (* ******************************************* *) module ObjectDeclMap = struct let name = "object_decl_map" let priority = solve_deps name [] let configure gen map_fn = let rec run e = match e.eexpr with | TObjectDecl odecl -> let e = Type.map_expr run e in (match e.eexpr with TObjectDecl odecl -> map_fn e odecl | _ -> assert false) | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* EnumToClass *) (* ******************************************* *) (* For languages that don't support parameterized enums and/or metadata in enums, we need to transform enums into normal classes. This is done at the first module pass by creating new classes with the same path inside the modules, and removing the actual enum module by setting it as en extern. * The target must create its own strategy to deal with reflection. As it is right now, we will have a base class which the class will extend, create @:$IsEnum metadata for the class, and create @:alias() metadatas for the fields, with their tag order (as a string) as their alias. If you are using ReflectionCFs, then you don't have to worry about that, as it's already generating all information needed by the haxe runtime. so they can be *) module EnumToClass = struct let name = "enum_to_class" let priority = solve_deps name [] type t = { ec_tbl : (path, tclass) Hashtbl.t; } let new_t () = { ec_tbl = Hashtbl.create 10 } (* ******************************************* *) (* EnumToClassModf *) (* ******************************************* *) (* The actual Module Filter that will transform the enum into a class dependencies: Should run before ReflectionCFs, in order to enable proper reflection access. Should run before TypeParams.RealTypeParams.RealTypeParamsModf, since generic enums must be first converted to generic classes It needs that the target platform implements __array__() as a shortcut to declare haxe.ds.Vector *) module EnumToClassModf = struct let name = "enum_to_class_mod" let priority = solve_deps name [DBefore ReflectionCFs.priority; DBefore TypeParams.RealTypeParams.RealTypeParamsModf.priority] let pmap_exists fn pmap = try PMap.iter (fun a b -> if fn a b then raise Exit) pmap; false with | Exit -> true let has_any_meta en = let has_meta meta = List.exists (fun (m,_,_) -> match m with Meta.Custom _ -> true | _ -> false) meta in has_meta en.e_meta || pmap_exists (fun _ ef -> has_meta ef.ef_meta) en.e_constrs let convert gen t base_class base_param_class en = let handle_type_params = false in (* TODO: look into this *) let basic = gen.gcon.basic in let pos = en.e_pos in (* create the class *) let cl = mk_class en.e_module en.e_path pos in Hashtbl.add t.ec_tbl en.e_path cl; (match Codegen.build_metadata gen.gcon (TEnumDecl en) with | Some expr -> let cf = mk_class_field "__meta__" expr.etype false expr.epos (Var { v_read = AccNormal; v_write = AccNormal }) [] in cf.cf_expr <- Some expr; cl.cl_statics <- PMap.add "__meta__" cf cl.cl_statics; cl.cl_ordered_statics <- cf :: cl.cl_ordered_statics | _ -> () ); let super, has_params = if Meta.has Meta.FlatEnum en.e_meta then base_class, false else base_param_class, true in cl.cl_super <- Some(super,[]); cl.cl_extern <- en.e_extern; en.e_meta <- (Meta.Class, [], pos) :: en.e_meta; cl.cl_module <- en.e_module; cl.cl_meta <- ( Meta.Enum, [], pos ) :: cl.cl_meta; (match gen.gcon.platform with | Cs when Common.defined gen.gcon Define.CoreApiSerialize -> cl.cl_meta <- ( Meta.Meta, [ (EField( (EConst (Ident "System"), null_pos ), "Serializable" ), null_pos) ], null_pos ) :: cl.cl_meta | _ -> ()); let c_types = if handle_type_params then List.map (fun (s,t) -> (s, TInst (map_param (get_cl_t t), []))) en.e_params else [] in cl.cl_params <- c_types; let i = ref 0 in let cfs = List.map (fun name -> let ef = PMap.find name en.e_constrs in let pos = ef.ef_pos in let old_i = !i in incr i; let cf = match follow ef.ef_type with | TFun(params,ret) -> let dup_types = if handle_type_params then List.map (fun (s,t) -> (s, TInst (map_param (get_cl_t t), []))) en.e_params else [] in let ef_type = let fn, types = if handle_type_params then snd, dup_types else (fun _ -> t_dynamic), en.e_params in let t = apply_params en.e_params (List.map fn types) ef.ef_type in apply_params ef.ef_params (List.map fn ef.ef_params) t in let params, ret = get_fun ef_type in let cf_params = if handle_type_params then dup_types @ ef.ef_params else [] in let cf = mk_class_field name ef_type true pos (Method MethNormal) cf_params in cf.cf_meta <- []; let tf_args = List.map (fun (name,opt,t) -> (alloc_var name t, if opt then Some TNull else None) ) params in let arr_decl = mk_nativearray_decl gen t_dynamic (List.map (fun (v,_) -> mk_local v pos) tf_args) pos in let expr = { eexpr = TFunction({ tf_args = tf_args; tf_type = ret; tf_expr = mk_block ( mk_return { eexpr = TNew(cl,List.map snd dup_types, [ExprBuilder.make_int gen.gcon old_i pos; arr_decl] ); etype = TInst(cl, List.map snd dup_types); epos = pos } ); }); etype = ef_type; epos = pos } in cf.cf_expr <- Some expr; cf | _ -> let actual_t = match follow ef.ef_type with | TEnum(e, p) -> TEnum(e, List.map (fun _ -> t_dynamic) p) | _ -> assert false in let cf = mk_class_field name actual_t true pos (Var { v_read = AccNormal; v_write = AccNever }) [] in let args = if has_params then [ExprBuilder.make_int gen.gcon old_i pos; null (gen.gclasses.nativearray t_dynamic) pos] else [ExprBuilder.make_int gen.gcon old_i pos] in cf.cf_meta <- [Meta.ReadOnly,[],pos]; cf.cf_expr <- Some { eexpr = TNew(cl, List.map (fun _ -> t_empty) cl.cl_params, args); etype = TInst(cl, List.map (fun _ -> t_empty) cl.cl_params); epos = pos; }; cf in cl.cl_statics <- PMap.add cf.cf_name cf cl.cl_statics; cf ) en.e_names in let constructs_cf = mk_class_field "__hx_constructs" (gen.gclasses.nativearray basic.tstring) true pos (Var { v_read = AccNormal; v_write = AccNever }) [] in constructs_cf.cf_meta <- [Meta.ReadOnly,[],pos]; constructs_cf.cf_expr <- Some (mk_nativearray_decl gen basic.tstring (List.map (fun s -> { eexpr = TConst(TString s); etype = basic.tstring; epos = pos }) en.e_names) pos); cl.cl_ordered_statics <- constructs_cf :: cfs @ cl.cl_ordered_statics ; cl.cl_statics <- PMap.add "__hx_constructs" constructs_cf cl.cl_statics; let getTag_cf_type = tfun [] basic.tstring in let getTag_cf = mk_class_field "getTag" getTag_cf_type true pos (Method MethNormal) [] in getTag_cf.cf_meta <- [(Meta.Final, [], pos)]; getTag_cf.cf_expr <- Some { eexpr = TFunction { tf_args = []; tf_type = basic.tstring; tf_expr = { eexpr = TReturn (Some ( let e_constructs = mk_static_field_access_infer cl "__hx_constructs" pos [] in let e_this = mk (TConst TThis) (TInst (cl,[])) pos in let e_index = mk_field_access gen e_this "index" pos in { eexpr = TArray(e_constructs,e_index); etype = basic.tstring; epos = pos; } )); epos = pos; etype = basic.tvoid; } }; etype = getTag_cf_type; epos = pos; }; cl.cl_ordered_fields <- getTag_cf :: cl.cl_ordered_fields ; cl.cl_fields <- PMap.add "getTag" getTag_cf cl.cl_fields; cl.cl_overrides <- getTag_cf :: cl.cl_overrides; cl.cl_meta <- (Meta.NativeGen,[],cl.cl_pos) :: cl.cl_meta; gen.gadd_to_module (TClassDecl cl) (max_dep); TEnumDecl en (* traverse gen - gen context convert_all : bool - should we convert all enums? If set, convert_if_has_meta will be ignored. convert_if_has_meta : bool - should we convert only if it has meta? enum_base_class : tclass - the enum base class. should_be_hxgen : bool - should the created enum be hxgen? *) let configure gen t convert_all convert_if_has_meta enum_base_class param_enum_class = let convert e = convert gen t enum_base_class param_enum_class e in let run md = match md with | TEnumDecl e when is_hxgen md -> if convert_all then convert e else if convert_if_has_meta && has_any_meta e then convert e else if not (Meta.has Meta.FlatEnum e.e_meta) then convert e else begin (* take off the :hxgen meta from it, if there's any *) e.e_meta <- List.filter (fun (n,_,_) -> not (n = Meta.HxGen)) e.e_meta; md end | _ -> md in let map md = Some(run md) in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* EnumToClassExprf *) (* ******************************************* *) (* Enum to class Expression Filter dependencies: Should run before TArrayTransform, since it generates array access expressions *) module EnumToClassExprf = struct let name = "enum_to_class_exprf" let priority = solve_deps name [DBefore TArrayTransform.priority] let configure gen t opt_get_native_enum_tag = let rec run e = let get_converted_enum_type et = let en, eparams = match follow (gen.gfollow#run_f et) with | TEnum(en,p) -> en, p | _ -> raise Not_found in let cl = Hashtbl.find t.ec_tbl en.e_path in TInst(cl, eparams) in match e.eexpr with | TCall (({eexpr = TField(_, FStatic({cl_path=[],"Type"},{cf_name="enumIndex"}))} as left), [f]) -> let f = run f in (try mk_field_access gen {f with etype = get_converted_enum_type f.etype} "index" e.epos with Not_found -> { e with eexpr = TCall(left, [f]) }) | TEnumParameter(f, _,i) -> let f = run f in (* check if en was converted to class *) (* if it was, switch on tag field and change cond type *) let f = try { f with etype = get_converted_enum_type f.etype } with Not_found -> f in let cond_array = { (mk_field_access gen f "params" f.epos) with etype = gen.gclasses.nativearray t_dynamic } in Codegen.index gen.gcon cond_array i e.etype e.epos | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gexpr_filters#add ~name:name ~priority:(PCustom priority) map end;; let configure gen opt_get_native_enum_tag convert_all convert_if_has_meta enum_base_class param_enum_class = let t = new_t () in EnumToClassModf.configure gen t convert_all convert_if_has_meta enum_base_class param_enum_class; EnumToClassExprf.configure gen t opt_get_native_enum_tag end;; (* ******************************************* *) (* IteratorsInterface *) (* ******************************************* *) (* This module will handle with Iterators, Iterables and TFor() expressions. At first, a module filter will receive a Iterator and Iterable interface, which will be implemented if hasNext(), next() or iterator() fields are detected with the correct type. At this part a custom function will be called which can adequate the class fields so they are compatible with native Iterators as well The expression filter part of this module will look for TFor() expressions, and transform like that: for (anInt in value.iterator()) { } { var s:haxe.lang.Iterator = ExternalFunction.getIterator(value.iterator()); while (s.hasNext()) { var anInt:Int = s.next(); } } dependencies: None. *) module IteratorsInterface = struct let name = "iterators_interface" (* TODO later (* ******************************************* *) (* IteratorsInterfaceModf *) (* ******************************************* *) (* The module filter for Iterators Interface, which will implement the iterator/iterable interface on each class that conforms with the typedefs Iterator<> and Iterable<> It's a very simple module and it will rely on cast detection to work correctly. This is so that when the dependencies: Must run at the Module Filters, so cast detection can detect a cast to the interface and we can *) module IteratorsInterfaceModf = struct let name = "iterators_interface_modf" let conforms_cfs has_next next = try (match follow has_next.cf_type with | TFun([],ret) when (match follow ret with | TAbstract({ a_path = ([], "Bool") }, []) -> () | _ -> raise Not_found) -> () | _ -> raise Not_found); (match follow next.cf_type with | TFun([], ret) -> ret | _ -> raise Not_found ) let conforms_type_iterator t = try match follow t with | TInst(cl,params) -> let has_next = PMap.find "hasNext" cl.cl_fields in let next = PMap.find "next" cl.cl_fields in Some (conforms_cfs has_next next) | TAnon(anon) -> let has_next = PMap.find "hasNext" anon.a_fields in let next = PMap.find "next" anon.a_fields in Some (conforms_cfs has_next next) | _ -> None with | Not_found -> None let conforms_as_iterable cl = try let iterator = PMap.find "iterator" cl.cl_fields in match follow iterator.cf_type with | TFun([], ret) -> conforms_type_iterator ret | _ -> None with | Not_found -> None let conforms_as_iterator cl = try let has_next = PMap.find "hasNext" cl.cl_fields in let next = PMap.find "next" cl.cl_fields in Some (conforms_cfs has_next next) with | Not_found -> None let priority = solve_deps name [] let traverse gen iterator_iface iterable_iface on_found_iterator on_found_iterable = let rec run md = match md with | TClassDecl cl when not cl.cl_extern && is_hxgen cl -> let conforms_iterator = conforms_as_iterator cl in let conforms_iterable = conforms_as_iterable cl in if is_some conforms_iterator then begin let it_t = get conforms_iterator in cl.cl_interfaces <- (iterator_iface, [it_t]); on_found_iterator cl end; if is_some conforms_iterable then begin let it_t = get conforms_iterable in cl.cl_interfaces <- (iterable_iface, [it_t]); on_found_iterable cl end; md | _ -> md in run let configure gen (mapping_func:texpr->texpr) = let map e = Some(mapping_func e) in gen.gexpr_filters#add ~name:name ~priority:(PCustom priority) map end;; *) (* ******************************************* *) (* IteratorsInterfaceExprf *) (* ******************************************* *) (* The expression filter for Iterators. Will look for TFor, transform it into { var iterator = // in expression here while (iterator.hasNext()) { var varName = iterator.next(); } } dependencies: Must run before Dynamic fields access is run TODO: I think TFor is always rewritten to TWhile before getting into the generator nowadays, so this filter could probably be removed. Gotta ask Simon about it. *) module IteratorsInterfaceExprf = struct let name = "iterators_interface_exprf" let priority = solve_deps name [DBefore DynamicFieldAccess.priority] let mk_access gen v name pos = let field_t = try match follow v.v_type with | TInst(cl, params) -> let field = PMap.find name cl.cl_fields in apply_params cl.cl_params params field.cf_type | TAnon(anon) -> let field = PMap.find name anon.a_fields in field.cf_type | _ -> t_dynamic with | Not_found -> t_dynamic in { (mk_field_access gen (mk_local v pos) name pos) with etype = field_t } let configure gen = let basic = gen.gcon.basic in let rec run e = match e.eexpr with | TFor(var, in_expr, block) -> let in_expr = run in_expr in let temp = mk_temp gen "iterator" in_expr.etype in let block = [ { eexpr = TVar(temp, Some(in_expr)); etype = basic.tvoid; epos = in_expr.epos }; { eexpr = TWhile( { eexpr = TCall(mk_access gen temp "hasNext" in_expr.epos, []); etype = basic.tbool; epos = in_expr.epos }, Type.concat ({ eexpr = TVar(var, Some({ eexpr = TCall(mk_access gen temp "next" in_expr.epos, []); etype = var.v_type; epos = in_expr.epos })); etype = basic.tvoid; epos = in_expr.epos }) ( run block ), Ast.NormalWhile); etype = basic.tvoid; epos = e.epos } ] in { eexpr = TBlock(block); etype = e.etype; epos = e.epos } | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gexpr_filters#add ~name:name ~priority:(PCustom priority) map end;; let configure gen = IteratorsInterfaceExprf.configure gen end;; (* ******************************************* *) (* SwitchToIf *) (* ******************************************* *) (* Just a syntax filter which changes switch expressions to if() else if() else if() ... *) module SwitchToIf = struct let name = "switch_to_if" let priority = solve_deps name [] let rec simplify_expr e = match e.eexpr with | TParenthesis e | TMeta(_,e) -> simplify_expr e | _ -> e let configure gen (should_convert:texpr->bool) = let basic = gen.gcon.basic in let rec run e = match e.eexpr with | TSwitch(cond,cases,default) when should_convert e -> let cond_etype, should_cache = match gen.gfollow#run_f cond.etype with | TType({ t_path = ([], "Null") }, [t]) -> let rec take_off_nullable t = match gen.gfollow#run_f t with | TType({ t_path = ([], "Null") }, [t]) -> take_off_nullable t | _ -> t in take_off_nullable t, true | _ -> cond.etype, false in if should_cache && not (should_convert { e with eexpr = TSwitch({ cond with etype = cond_etype }, cases, default) }) then begin { e with eexpr = TSwitch(mk_cast cond_etype (run cond), List.map (fun (cs,e) -> (List.map run cs, run e)) cases, Option.map run default) } end else begin let local, fst_block = match cond.eexpr, should_cache with | TLocal _, false -> cond, [] | _ -> let var = mk_temp gen "switch" cond_etype in let cond = run cond in let cond = if should_cache then mk_cast cond_etype cond else cond in mk_local var cond.epos, [ { eexpr = TVar(var,Some(cond)); etype = basic.tvoid; epos = cond.epos } ] in let mk_eq cond = { eexpr = TBinop(Ast.OpEq, local, cond); etype = basic.tbool; epos = cond.epos } in let rec mk_many_cond conds = match conds with | cond :: [] -> mk_eq cond | cond :: tl -> { eexpr = TBinop(Ast.OpBoolOr, mk_eq (run cond), mk_many_cond tl); etype = basic.tbool; epos = cond.epos } | [] -> assert false in let mk_many_cond conds = let ret = mk_many_cond conds in (* this might be considered a hack. But since we're on a syntax filter and the condition is guaranteed to not have run twice, we can really run the expr filters again for it (so to change e.g. OpEq accordingly *) gen.gexpr_filters#run_f ret in let rec loop cases = match cases with | (conds,e) :: [] -> { eexpr = TIf(mk_many_cond conds, run e, Option.map run default); etype = e.etype; epos = e.epos } | (conds,e) :: tl -> { eexpr = TIf(mk_many_cond conds, run e, Some(loop tl)); etype = e.etype; epos = e.epos } | [] -> match default with | None -> raise Exit | Some d -> run d in try { e with eexpr = TBlock(fst_block @ [loop cases]) } with | Exit -> { e with eexpr = TBlock [] } end | TSwitch(cond,cases,default) -> (try match (simplify_expr cond).eexpr with | TCall( { eexpr = TField(_,FStatic({ cl_path = [],"Type" }, { cf_name = "enumIndex" })) }, [enum] ) -> let real_enum = match enum.etype with | TEnum(e,_) -> e | _ -> raise Not_found in if Meta.has Meta.Class real_enum.e_meta then raise Not_found; let enum_expr = mk_mt_access (TEnumDecl(real_enum)) e.epos in let fields = Hashtbl.create (List.length real_enum.e_names) in PMap.iter (fun _ ef -> Hashtbl.add fields ef.ef_index ef) real_enum.e_constrs; let cases = List.map (fun (el,e) -> List.map (fun e -> match e.eexpr with | TConst(TInt i) -> let ef = Hashtbl.find fields (Int32.to_int i) in { e with eexpr = TField(enum_expr, FEnum(real_enum,ef)); etype = TEnum(real_enum,List.map (fun _ -> t_dynamic) real_enum.e_params) } | _ -> raise Not_found) el, run e ) cases in { e with eexpr = TSwitch(enum,cases,Option.map run default) } | _ -> raise Not_found with Not_found -> Type.map_expr run e) | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* Anonymous Class object handling *) (* ******************************************* *) (* (syntax) When we pass a class as an object, in some languages we will need a special construct to be able to access its statics as if they were normal object fields. On C# and Java the way found to do that is by handling statics reflection also by a normal instance. This also happens in hxcpp and neko, so I guess it's a valid practice. So if we want to handle the reflection of the static MyClass, here's roughly how it will be done: var x = MyClass; gets converted into Haxe.Lang.Class x = Haxe.Lang.Runtime.GetType(typeof(MyClass).RuntimeHandle); which will in turn look in its cache but roughly would do: Haxe.Lang.Class x = new Haxe.Lang.Class(new MyClass(EmptyObject.EMPTY)); This module will of course let the caller choose how this will be implemented. It will just identify all uses of class that will require it to be cast as an object. *) module ClassInstance = struct let priority = solve_deps "class_instance" [] let configure gen (change_expr:texpr->module_type->texpr) = let rec run e = match e.eexpr with | TCall( ({ eexpr = TLocal({ v_name = ("__is__" | "__as__" | "__typeof__") } as v) } as local), calls ) when Hashtbl.mem gen.gspecial_vars v.v_name -> { e with eexpr = TCall(local, List.map (fun e -> match e.eexpr with | TTypeExpr _ -> e | _ -> run e) calls) } | TField({ eexpr = TTypeExpr(mt) }, f) -> e | TField(ef, f) -> (match anon_class ef.etype with | None -> Type.map_expr run e | Some t -> { e with eexpr = TField( { ef with eexpr = TTypeExpr(t) }, f) } ) | TTypeExpr(mt) -> change_expr e mt | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:"class_instance" ~priority:(PCustom priority) map end;; (* ******************************************* *) (* HardNullableSynf *) (* ******************************************* *) (* This module will handle Null types for languages that offer a way of dealing with stack-allocated structures or tuples and generics. Essentialy on those targets a Null will be a tuple ( 'a * bool ), where bool is whether the value is null or not. At first (configure-time), we will modify the follow function so it can follow correctly nested Null>, and do not follow Null to its underlying type Then we will run a syntax filter, which will look for casts to Null and replace them by a call to the new Null creation; Also casts from Null to T or direct uses of Null (call, field access, array access, closure) will result in the actual value being accessed For compatibility with the C# target, HardNullable will accept both Null and haxe.lang.Null types dependencies: Needs to be run after all cast detection modules *) module HardNullableSynf = struct let name = "hard_nullable" let priority = solve_deps name [DAfter CastDetect.ReturnCast.priority] let rec is_null_t gen t = match gen.greal_type t with | TType( { t_path = ([], "Null") }, [of_t]) | TInst( { cl_path = (["haxe";"lang"], "Null") }, [of_t]) -> let rec take_off_null t = match is_null_t gen t with | None -> t | Some s -> take_off_null s in Some (take_off_null of_t) | TMono r -> (match !r with | Some t -> is_null_t gen t | None -> None) | TLazy f -> is_null_t gen (!f()) | TType (t, tl) -> is_null_t gen (apply_params t.t_params tl t.t_type) | _ -> None let follow_addon gen t = let rec strip_off_nullable t = let t = gen.gfollow#run_f t in match t with (* haxe.lang.Null> wouldn't be a valid construct, so only follow Null<> *) | TType ( { t_path = ([], "Null") }, [of_t] ) -> strip_off_nullable of_t | _ -> t in match t with | TType( ({ t_path = ([], "Null") } as tdef), [of_t]) -> Some( TType(tdef, [ strip_off_nullable of_t ]) ) | _ -> None let configure gen unwrap_null wrap_val null_to_dynamic has_value opeq_handler = gen.gfollow#add ~name:(name ^ "_follow") (follow_addon gen); let is_null_t = is_null_t gen in let is_string t = match gen.greal_type t with | TInst({ cl_path=([],"String") },_) -> true | _ -> false in let handle_unwrap to_t e = let e_null_t = get (is_null_t e.etype) in match gen.greal_type to_t with | TDynamic _ | TMono _ | TAnon _ -> (match e_null_t with | TDynamic _ | TMono _ | TAnon _ -> gen.ghandle_cast to_t e_null_t (unwrap_null e) | _ -> null_to_dynamic e ) | _ -> gen.ghandle_cast to_t e_null_t (unwrap_null e) in let handle_wrap e t = match e.eexpr with | TConst(TNull) -> wrap_val e t false | _ -> wrap_val e t true in let cur_block = ref [] in let add_tmp v e p = cur_block := { eexpr = TVar(v,e); etype = gen.gcon.basic.tvoid; epos = p } :: !cur_block in let get_local e = match e.eexpr with | TLocal _ -> e, e | _ -> let v = mk_temp gen "nulltmp" e.etype in add_tmp v (Some (null e.etype e.epos)) e.epos; let local = { e with eexpr = TLocal(v) } in mk_paren { e with eexpr = TBinop(Ast.OpAssign, local, e) }, local in let rec run e = match e.eexpr with | TBlock(bl) -> let lst = !cur_block in cur_block := []; List.iter (fun e -> let e = run e in cur_block := (e :: !cur_block) ) bl; let ret = !cur_block in cur_block := lst; { e with eexpr = TBlock(List.rev ret) } | TCast(v, _) -> let null_et = is_null_t e.etype in let null_vt = is_null_t v.etype in (match null_vt, null_et with | Some(vt), None when is_string e.etype -> let v = run v in { e with eexpr = TCast(null_to_dynamic v,None) } | Some(vt), None -> (match v.eexpr with (* is there an unnecessary cast to Nullable? *) | TCast(v2, _) -> run { v with etype = e.etype } | _ -> handle_unwrap e.etype (run v) ) | None, Some(et) -> handle_wrap (run v) et | Some(vt), Some(et) when not (type_iseq (run_follow gen vt) (run_follow gen et)) -> (* check if has value and convert *) let vlocal_fst, vlocal = get_local (run v) in { eexpr = TIf( has_value vlocal_fst, handle_wrap (mk_cast et (unwrap_null vlocal)) et, Some( handle_wrap (null et e.epos) et )); etype = e.etype; epos = e.epos } | _ -> Type.map_expr run e ) | TField(ef, field) when is_some (is_null_t ef.etype) -> let to_t = get (is_null_t ef.etype) in { e with eexpr = TField(handle_unwrap to_t (run ef), field) } | TCall(ecall, params) when is_some (is_null_t ecall.etype) -> let to_t = get (is_null_t ecall.etype) in { e with eexpr = TCall(handle_unwrap to_t (run ecall), List.map run params) } | TArray(earray, p) when is_some (is_null_t earray.etype) -> let to_t = get (is_null_t earray.etype) in { e with eexpr = TArray(handle_unwrap to_t (run earray), p) } | TBinop(op, e1, e2) -> let e1_t = is_null_t e1.etype in let e2_t = is_null_t e2.etype in (match op with | Ast.OpAssign | Ast.OpAssignOp _ -> (match e1_t, e2_t with | Some t1, Some t2 -> (match op with | Ast.OpAssign -> Type.map_expr run e | Ast.OpAssignOp op -> (match e1.eexpr with | TLocal _ -> { e with eexpr = TBinop( Ast.OpAssign, e1, handle_wrap { e with eexpr = TBinop (op, handle_unwrap t1 e1, handle_unwrap t2 (run e2) ) } t1 ) } | _ -> let v, e1, evars = match e1.eexpr with | TField(ef, f) -> let v = mk_temp gen "nullbinop" ef.etype in v, { e1 with eexpr = TField(mk_local v ef.epos, f) }, ef | _ -> let v = mk_temp gen "nullbinop" e1.etype in v, mk_local v e1.epos, e1 in { e with eexpr = TBlock([ { eexpr = TVar(v, Some evars); etype = gen.gcon.basic.tvoid; epos = e.epos }; { e with eexpr = TBinop( Ast.OpAssign, e1, handle_wrap { e with eexpr = TBinop (op, handle_unwrap t1 e1, handle_unwrap t2 (run e2) ) } t1 ) } ]) } ) | _ -> assert false ) | _ -> Type.map_expr run e (* casts are already dealt with normal CastDetection module *) ) | Ast.OpEq | Ast.OpNotEq -> (match e1.eexpr, e2.eexpr with | TConst(TNull), _ when is_some e2_t -> let e = has_value (run e2) in if op = Ast.OpEq then { e with eexpr = TUnop(Ast.Not, Ast.Prefix, e) } else e | _, TConst(TNull) when is_some e1_t -> let e = has_value (run e1) in if op = Ast.OpEq then { e with eexpr = TUnop(Ast.Not, Ast.Prefix, e) } else e | _ when is_some e1_t || is_some e2_t -> let e1, e2 = if not (is_some e1_t) then run e2, handle_wrap (run e1) (get e2_t) else if not (is_some e2_t) then run e1, handle_wrap (run e2) (get e1_t) else run e1, run e2 in let e = opeq_handler e1 e2 in if op = Ast.OpEq then { e with eexpr = TUnop(Ast.Not, Ast.Prefix, e) } else e | _ -> Type.map_expr run e ) | Ast.OpAdd when is_string e1.etype || is_string e2.etype -> let e1 = if is_some e1_t then null_to_dynamic (run e1) else run e1 in let e2 = if is_some e2_t then null_to_dynamic (run e2) else run e2 in let e_t = is_null_t e.etype in if is_some e_t then wrap_val { eexpr = TBinop(op,e1,e2); etype = get e_t; epos = e.epos } (get e_t) true else { e with eexpr = TBinop(op,e1,e2) } | _ -> let e1 = if is_some e1_t then handle_unwrap (get e1_t) (run e1) else run e1 in let e2 = if is_some e2_t then handle_unwrap (get e2_t) (run e2) else run e2 in (* if it is Null, we need to convert the result again to null *) let e_t = (is_null_t e.etype) in if is_some e_t then wrap_val { eexpr = TBinop(op, e1, e2); etype = get e_t; epos = e.epos } (get e_t) true else { e with eexpr = TBinop(op, e1, e2) } ) (*| TUnop( (Ast.Increment as op)*) | _ -> Type.map_expr run e in let run e = match e.eexpr with | TFunction tf -> run { e with eexpr = TFunction { tf with tf_expr = mk_block tf.tf_expr } } | TBlock _ -> run e | _ -> match run (mk_block e) with | { eexpr = TBlock([e]) } -> e | e -> e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* ArrayDeclSynf *) (* ******************************************* *) (* A syntax filter that will change array declarations to the actual native array declarations plus the haxe array initialization dependencies: Must run after ObjectDeclMap since it can add TArrayDecl expressions *) module ArrayDeclSynf = struct let name = "array_decl_synf" let priority = solve_deps name [DAfter ObjectDeclMap.priority] let configure gen native_array_cl = let rec run e = match e.eexpr with | TArrayDecl el -> let cl, params = match follow e.etype with | TInst(({ cl_path = ([], "Array") } as cl), ( _ :: _ as params)) -> cl, params | TInst(({ cl_path = ([], "Array") } as cl), []) -> cl, [t_dynamic] | _ -> assert false in let changed_params = gen.greal_type_param (TClassDecl cl) params in { e with eexpr = TNew(cl, changed_params, [ { e with eexpr = TArrayDecl(List.map run el); etype = TInst(native_array_cl, changed_params) } ] ); } | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* SwitchBreakSynf *) (* ******************************************* *) (* In most languages, 'break' is used as a statement also to break from switch statements. This generates an incompatibility with haxe code, as we can use break to break from loops from inside a switch This script will detect 'breaks' inside switch statements, and will offer the opportunity to change both when this pattern is found. Some options are possible: On languages that support goto, 'break' may mean goto " after the loop ". There also can be special labels for loops, so you can write "break label" (javascript, java, d) On languages that do not support goto, a custom solution must be enforced dependencies: Since UnreachableCodeElimination must run before it, and Unreachable should be one of the very last filters to run, we will make a fixed value which runs after UnreachableCodeElimination (meaning: it's the very last filter) *) module SwitchBreakSynf = struct let name = "switch_break_synf" let priority = min_dep -. 150.0 type add_to_block_api = texpr->bool->unit let configure gen (change_loop:texpr->int->add_to_block_api->texpr) (change_break:texpr->int->add_to_block_api->texpr) = let in_switch = ref false in let cur_block = ref [] in let to_add = ref [] in let did_found = ref (-1) in let api expr before = if before then cur_block := expr :: !cur_block else to_add := expr :: !to_add in let num = ref 0 in let cur_num = ref 0 in let rec run e = match e.eexpr with | TFunction _ -> let old_num = !num in num := 0; let ret = Type.map_expr run e in num := old_num; ret | TFor _ | TWhile _ -> let last_switch = !in_switch in let last_found = !did_found in let last_num = !cur_num in in_switch := false; incr num; cur_num := !num; did_found := -1; let new_e = Type.map_expr run e in (* assuming that no loop will be found in the condition *) let new_e = if !did_found <> -1 then change_loop new_e !did_found api else new_e in did_found := last_found; in_switch := last_switch; cur_num := last_num; new_e | TSwitch _ -> let last_switch = !in_switch in in_switch := true; let new_e = Type.map_expr run e in in_switch := last_switch; new_e | TBlock bl -> let last_block = !cur_block in let last_toadd = !to_add in to_add := []; cur_block := []; List.iter (fun e -> let new_e = run e in cur_block := new_e :: !cur_block; match !to_add with | [] -> () | _ -> cur_block := !to_add @ !cur_block; to_add := [] ) bl; let ret = List.rev !cur_block in cur_block := last_block; to_add := last_toadd; { e with eexpr = TBlock(ret) } | TBreak -> if !in_switch then (did_found := !cur_num; change_break e !cur_num api) else e | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* Unreachable Code Elimination *) (* ******************************************* *) (* In some source code platforms, the code won't compile if there is Unreachable code, so this filter will take off any unreachable code. If the parameter "handle_switch_break" is set to true, it will already add a "break" statement on switch cases when suitable; in order to not confuse with while break, it will be a special expression __sbreak__ If the parameter "handle_not_final_returns" is set to true, it will also add final returns when functions are detected to be lacking of them. (Will respect __fallback__ expressions) If the parameter "java_mode" is set to true, some additional checks following the java unreachable specs (http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21) will be added dependencies: This must run before SwitchBreakSynf (see SwitchBreakSynf dependecy value) This must be the LAST syntax filter to run. It expects ExpressionUnwrap to have run correctly, since this will only work for source-code based targets *) module UnreachableCodeEliminationSynf = struct let name = "unreachable_synf" let priority = min_dep -. 100.0 type uexpr_kind = | Normal | BreaksLoop | BreaksFunction let aggregate_kind e1 e2 = match e1, e2 with | Normal, _ | _, Normal -> Normal | BreaksLoop, _ | _, BreaksLoop -> BreaksLoop | BreaksFunction, BreaksFunction -> BreaksFunction let aggregate_constant op c1 c2= match op, c1, c2 with | OpEq, Some v1, Some v2 -> Some (TBool (v1 = v2)) | OpNotEq, Some v1, Some v2 -> Some (TBool (v1 <> v2)) | OpBoolOr, Some (TBool v1) , Some (TBool v2) -> Some (TBool (v1 || v2)) | OpBoolAnd, Some (TBool v1) , Some (TBool v2) -> Some (TBool (v1 && v2)) | OpAssign, _, Some v2 -> Some v2 | _ -> None let rec get_constant_expr e = match e.eexpr with | TConst (v) -> Some v | TBinop(op, v1, v2) -> aggregate_constant op (get_constant_expr v1) (get_constant_expr v2) | TParenthesis(e) | TMeta(_,e) -> get_constant_expr e | _ -> None let traverse gen java_mode = let basic = gen.gcon.basic in let should_warn = false in let do_warn = if should_warn then gen.gcon.warning "Unreachable code" else (fun pos -> ()) in let return_loop expr kind = match kind with | Normal | BreaksLoop -> expr, Normal | _ -> expr, kind in let sbreak = alloc_var "__sbreak__" t_dynamic in let mk_sbreak = mk_local sbreak in let rec has_fallback expr = match expr.eexpr with | TBlock(bl) -> (match List.rev bl with | { eexpr = TLocal { v_name = "__fallback__" } } :: _ -> true | ({ eexpr = TBlock(_) } as bl) :: _ -> has_fallback bl | _ -> false) | TLocal { v_name = "__fallback__" } -> true | _ -> false in let handle_case = fun (expr,kind) -> match kind with | Normal when has_fallback expr -> expr | Normal -> Type.concat expr (mk_sbreak expr.epos) | BreaksLoop | BreaksFunction -> expr in let has_break = ref false in let rec process_expr expr = match expr.eexpr with | TReturn _ | TThrow _ -> expr, BreaksFunction | TContinue -> expr, BreaksLoop | TBreak -> has_break := true; expr, BreaksLoop | TCall( { eexpr = TLocal { v_name = "__goto__" } }, _ ) -> expr, BreaksLoop | TBlock bl -> let new_block = ref [] in let is_unreachable = ref false in let ret_kind = ref Normal in List.iter (fun e -> if !is_unreachable then do_warn e.epos else begin let changed_e, kind = process_expr e in new_block := changed_e :: !new_block; match kind with | BreaksLoop | BreaksFunction -> ret_kind := kind; is_unreachable := true | _ -> () end ) bl; { expr with eexpr = TBlock(List.rev !new_block) }, !ret_kind | TFunction tf -> let changed, kind = process_expr tf.tf_expr in let changed = if not (ExtType.is_void tf.tf_type) && kind <> BreaksFunction then Type.concat changed { eexpr = TReturn( Some (null tf.tf_type expr.epos) ); etype = basic.tvoid; epos = expr.epos } else changed in { expr with eexpr = TFunction({ tf with tf_expr = changed }) }, Normal | TFor(var, cond, block) -> let last_has_break = !has_break in has_break := false; let changed_block, _ = process_expr block in has_break := last_has_break; let expr = { expr with eexpr = TFor(var, cond, changed_block) } in return_loop expr Normal | TIf(cond, eif, None) -> if java_mode then match get_constant_expr cond with | Some (TBool true) -> process_expr eif | _ -> { expr with eexpr = TIf(cond, fst (process_expr eif), None) }, Normal else { expr with eexpr = TIf(cond, fst (process_expr eif), None) }, Normal | TIf(cond, eif, Some eelse) -> let eif, eif_k = process_expr eif in let eelse, eelse_k = process_expr eelse in let k = aggregate_kind eif_k eelse_k in { expr with eexpr = TIf(cond, eif, Some eelse) }, k | TWhile(cond, block, flag) -> let last_has_break = !has_break in has_break := false; let block, k = process_expr block in if java_mode then match get_constant_expr cond, flag, !has_break with | Some (TBool true), _, false -> has_break := last_has_break; { expr with eexpr = TWhile(cond, block, flag) }, BreaksFunction | Some (TBool false), NormalWhile, _ -> has_break := last_has_break; do_warn expr.epos; null expr.etype expr.epos, Normal | _ -> has_break := last_has_break; return_loop { expr with eexpr = TWhile(cond,block,flag) } Normal else begin has_break := last_has_break; return_loop { expr with eexpr = TWhile(cond,block,flag) } Normal end | TSwitch(cond, el_e_l, None) -> { expr with eexpr = TSwitch(cond, List.map (fun (el, e) -> (el, handle_case (process_expr e))) el_e_l, None) }, Normal | TSwitch(cond, el_e_l, Some def) -> let def, k = process_expr def in let def = handle_case (def, k) in let k = ref k in let ret = { expr with eexpr = TSwitch(cond, List.map (fun (el, e) -> let e, ek = process_expr e in k := aggregate_kind !k ek; (el, handle_case (e, ek)) ) el_e_l, Some def) } in ret, !k | TTry (e, catches) -> let e, k = process_expr e in let k = ref k in let ret = { expr with eexpr = TTry(e, List.map (fun (v, e) -> let e, ek = process_expr e in k := aggregate_kind !k ek; (v, e) ) catches) } in ret, !k | _ -> expr, Normal in let run e = fst (process_expr e) in run let configure gen java_mode = let run = traverse gen java_mode in let map e = Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* DefaultArguments *) (* ******************************************* *) (* This Module Filter will go through all defined functions in all modules and change them so they set all default arguments to be of a Nullable type, and adds the unroll from nullable to the not-nullable type in the beginning of the function. dependencies: It must run before OverloadingConstructor, since OverloadingConstructor will change optional structures behavior *) module DefaultArguments = struct let name = "default_arguments" let priority = solve_deps name [ DBefore OverloadingConstructor.priority ] let gen_check basic t nullable_var const pos = let is_null t = match t with TType({t_path = ([],"Null")}, _) -> true | _ -> false in let needs_cast t1 t2 = match is_null t1, is_null t2 with | true, false | false, true -> true | _ -> false in let const_t = match const with | TString _ -> basic.tstring | TInt _ -> basic.tint | TFloat _ -> basic.tfloat | TNull -> t | TBool _ -> basic.tbool | _ -> assert false in let const = { eexpr = TConst(const); etype = const_t; epos = pos } in let const = if needs_cast t const_t then mk_cast t const else const in let arg = mk_local nullable_var pos in let arg = if needs_cast t nullable_var.v_type then mk_cast t arg else arg in { eexpr = TIf( { eexpr = TBinop(Ast.OpEq, mk_local nullable_var pos, null nullable_var.v_type pos); etype = basic.tbool; epos = pos }, const, Some(arg) ); etype = t; epos = pos; } let add_opt gen block pos (var,opt) = match opt with | None | Some TNull -> (var,opt) | Some (TString str) -> block := Codegen.set_default gen.gcon var (TString str) pos :: !block; (var, opt) | Some const -> let basic = gen.gcon.basic in let nullable_var = mk_temp gen var.v_name (basic.tnull var.v_type) in let orig_name = var.v_name in var.v_name <- nullable_var.v_name; nullable_var.v_name <- orig_name; (* var v = (temp_var == null) ? const : cast temp_var; *) let evar = mk (TVar(var, Some(gen_check basic var.v_type nullable_var const pos))) basic.tvoid pos in block := evar :: !block; (nullable_var, opt) let rec change_func gen cf = List.iter (change_func gen) cf.cf_overloads; let is_ctor = cf.cf_name = "new" in let basic = gen.gcon.basic in match cf.cf_kind, follow cf.cf_type with | Var _, _ | Method MethDynamic, _ -> () | _, TFun(args, ret) -> let found = ref false in let args = ref (List.map (fun (n,opt,t) -> (n,opt, if opt then (found := true; basic.tnull t) else t) ) args) in (match !found, cf.cf_expr with | true, Some ({ eexpr = TFunction tf } as texpr) -> let block = ref [] in let tf_args = List.map (add_opt gen block tf.tf_expr.epos) tf.tf_args in let arg_assoc = List.map2 (fun (v,o) (v2,_) -> v,(v2,o) ) tf.tf_args tf_args in let rec extract_super e = match e.eexpr with | TBlock(({ eexpr = TCall({ eexpr = TConst TSuper }, _) } as e2) :: tl) -> e2, tl | TBlock(hd :: tl) -> let e2, tl2 = extract_super hd in e2, tl2 @ tl | _ -> raise Not_found in let block = try if not is_ctor then raise Not_found; (* issue #2570 *) (* check if the class really needs the super as the first statement - just to make sure we don't inadvertently break any existing code *) let rec check cl = if not (is_hxgen (TClassDecl cl)) then () else match cl.cl_super with | None -> raise Not_found | Some (cl,_) -> check cl in (match gen.gcurrent_class with | Some cl -> check cl | _ -> ()); let super, tl = extract_super tf.tf_expr in (match super.eexpr with | TCall({ eexpr = TConst TSuper } as e1, args) -> (* any super argument will be replaced by an inlined version of the check *) let found = ref false in let rec replace_args e = match e.eexpr with | TLocal(v) -> (try let v2,o = List.assq v arg_assoc in let o = match o with | None -> raise Not_found | Some o -> o in found := true; gen_check gen.gcon.basic v.v_type v2 o e.epos with | Not_found -> e) | _ -> Type.map_expr replace_args e in let args = List.map (replace_args) args in { tf.tf_expr with eexpr = TBlock((if !found then { super with eexpr = TCall(e1,args) } else super) :: !block @ tl) } | _ -> assert false) with | Not_found -> Type.concat { tf.tf_expr with eexpr = TBlock(!block); etype = basic.tvoid } tf.tf_expr in args := fun_args tf_args; cf.cf_expr <- Some( {texpr with eexpr = TFunction( { tf with tf_args = tf_args; tf_expr = block } ); etype = TFun(!args, ret) } ); cf.cf_type <- TFun(!args, ret) | _ -> () ); (if !found then cf.cf_type <- TFun(!args, ret)) | _, _ -> assert false let configure gen = let run md = (match md with | TClassDecl cl -> List.iter (change_func gen) cl.cl_ordered_fields; List.iter (change_func gen) cl.cl_ordered_statics; Option.may (change_func gen) cl.cl_constructor; | _ -> ()); Some(md); in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) run end;; (* ******************************************* *) (* Interface Variables Removal Modf *) (* ******************************************* *) (* This module filter will take care of sanitizing interfaces for targets that do not support variables declaration in interfaces. By now this will mean that if anything is typed as the interface, and a variable access is made, a FNotFound will be returned for the field_access, so the field will be only accessible by reflection. Speed-wise, ideally it would be best to create getProp/setProp functions in this case and change the AST to call them when accessing by interface. (TODO) But right now it will be accessed by reflection. *) module InterfaceVarsDeleteModf = struct let name = "interface_vars" let priority = solve_deps name [] let configure gen = let run md = match md with | TClassDecl ({ cl_interface = true } as cl) -> let to_add = ref [] in let fields = List.filter (fun cf -> match cf.cf_kind with | Var _ when gen.gcon.platform = Cs && Meta.has Meta.Event cf.cf_meta -> true | Var vkind when not (Type.is_extern_field cf && Meta.has Meta.Property cf.cf_meta) -> (match vkind.v_read with | AccCall -> let newcf = mk_class_field ("get_" ^ cf.cf_name) (TFun([],cf.cf_type)) true cf.cf_pos (Method MethNormal) [] in to_add := newcf :: !to_add; | _ -> () ); (match vkind.v_write with | AccCall -> let newcf = mk_class_field ("set_" ^ cf.cf_name) (TFun(["val",false,cf.cf_type],cf.cf_type)) true cf.cf_pos (Method MethNormal) [] in to_add := newcf :: !to_add; | _ -> () ); cl.cl_fields <- PMap.remove cf.cf_name cl.cl_fields; false | Method MethDynamic -> (* TODO OPTIMIZATION - add a `_dispatch` method to the interface which will call the dynamic function itself *) cl.cl_fields <- PMap.remove cf.cf_name cl.cl_fields; false | _ -> true ) cl.cl_ordered_fields in cl.cl_ordered_fields <- fields; List.iter (fun cf -> match field_access gen (TInst(cl,List.map snd cl.cl_params)) cf.cf_name with | FNotFound | FDynamicField _ -> cl.cl_ordered_fields <- cf :: cl.cl_ordered_fields; cl.cl_fields <- PMap.add cf.cf_name cf cl.cl_fields | _ -> () ) !to_add | _ -> () in let map md = Some(run md; md) in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* InterfaceProps *) (* ******************************************* *) (* This module filter will go through all declared properties, and see if they are conforming to a native interface. If they are, it will add Meta.Property to it. *) module InterfaceProps = struct let name = "interface_props" let priority = solve_deps name [] let configure gen = let run md = match md with | TClassDecl ({ cl_interface = false; cl_extern = false } as cl) -> let vars = List.fold_left (fun acc (iface,_) -> if Meta.has Meta.CsNative iface.cl_meta then List.filter (fun cf -> match cf.cf_kind with | Var { v_read = AccCall } | Var { v_write = AccCall } -> true | _ -> false ) iface.cl_ordered_fields @ acc else acc ) [] cl.cl_implements in let vars = List.map (fun cf -> cf.cf_name) vars in if vars <> [] then List.iter (fun cf -> match cf.cf_kind with | Var { v_read = AccCall } | Var { v_write = AccCall } when List.mem cf.cf_name vars -> cf.cf_meta <- (Meta.Property, [], null_pos) :: cf.cf_meta | _ -> () ) cl.cl_ordered_fields | _ -> () in let map md = Some(run md; md) in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* Int Division Synf *) (* ******************************************* *) (* On targets that support int division, this module will force a float division to be performed. It will also look for casts to int or use of Std.int() to optimize this kind of operation. dependencies: since it depends on nothing, but many modules might generate division expressions, it will be one of the last modules to run *) module IntDivisionSynf = struct let name = "int_division_synf" let priority = solve_deps name [ DAfter ExpressionUnwrap.priority; DAfter ObjectDeclMap.priority; DAfter ArrayDeclSynf.priority ] let configure gen = let basic = gen.gcon.basic in let rec is_int t = match follow t with | TInst({ cl_path = (["haxe";"lang"],"Null") }, [t]) -> is_int t | t -> like_int t && not (like_i64 t) in let is_exactly_int t = match follow t with | TAbstract ({ a_path=[],"Int" }, []) -> true | _ -> false in let rec run e = match e.eexpr with | TBinop((Ast.OpDiv as op), e1, e2) when is_int e1.etype && is_int e2.etype -> { e with eexpr = TBinop(op, mk_cast basic.tfloat (run e1), run e2) } | TCall( { eexpr = TField(_, FStatic({ cl_path = ([], "Std") }, { cf_name = "int" })) }, [ ({ eexpr = TBinop((Ast.OpDiv as op), e1, e2) } as ebinop ) ] ) when is_int e1.etype && is_int e2.etype -> let e = { ebinop with eexpr = TBinop(op, run e1, run e2); etype = basic.tint } in if not (is_exactly_int e1.etype && is_exactly_int e2.etype) then mk_cast basic.tint e else e | TCast( ({ eexpr = TBinop((Ast.OpDiv as op), e1, e2) } as ebinop ), _ ) | TCast( ({ eexpr = TBinop(( (Ast.OpAssignOp Ast.OpDiv) as op), e1, e2) } as ebinop ), _ ) when is_int e1.etype && is_int e2.etype && is_int e.etype -> let ret = { ebinop with eexpr = TBinop(op, run e1, run e2); etype = e.etype } in if not (is_exactly_int e1.etype && is_exactly_int e2.etype) then mk_cast e.etype ret else e | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* UnnecessaryCastsRemoval *) (* ******************************************* *) (* This module will take care of simplifying unnecessary casts, specially those made by the compiler when inlining. Right now, it will only take care of casts used as a statement, which are always useless; TODO: Take care of more cases, e.g. when the to and from types are the same dependencies: This must run after CastDetection, but before ExpressionUnwrap *) module UnnecessaryCastsRemoval = struct let name = "casts_removal" let priority = solve_deps name [DAfter CastDetect.priority; DBefore ExpressionUnwrap.priority] let configure gen = let rec take_off_cast run e = match e.eexpr with | TCast (c, _) -> take_off_cast run c | _ -> run e in let rec traverse e = match e.eexpr with | TBlock bl -> let bl = List.map (take_off_cast traverse) bl in { e with eexpr = TBlock bl } | TTry (block, catches) -> { e with eexpr = TTry(traverse (mk_block block), List.map (fun (v,block) -> (v, traverse (mk_block block))) catches) } | TSwitch (cond,el_e_l, default) -> { e with eexpr = TSwitch(cond, List.map (fun (el,e) -> (el, traverse (mk_block e))) el_e_l, Option.map (fun e -> traverse (mk_block e)) default) } | TWhile (cond,block,flag) -> {e with eexpr = TWhile(cond,traverse (mk_block block), flag) } | TIf (cond, eif, eelse) -> { e with eexpr = TIf(cond, traverse (mk_block eif), Option.map (fun e -> traverse (mk_block e)) eelse) } | TFor (v,it,block) -> { e with eexpr = TFor(v,it, traverse (mk_block block)) } | TFunction (tfunc) -> { e with eexpr = TFunction({ tfunc with tf_expr = traverse (mk_block tfunc.tf_expr) }) } | _ -> e (* if expression doesn't have a block, we will exit *) in let map e = Some(traverse e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* AbstractImplementationFix *) (* ******************************************* *) (* This module filter will map the compiler created classes from abstract implementations to valid haxe code, as needed by gencommon dependencies: No dependencies *) module AbstractImplementationFix = struct let name = "abstract_implementation_fix" let priority = solve_deps name [] let configure gen = let run md = (match md with | TClassDecl ({ cl_kind = KAbstractImpl a } as c) -> List.iter ( function | ({ cf_name = "_new" } as cf) -> cf.cf_params <- cf.cf_params @ a.a_params | cf when Meta.has Meta.Impl cf.cf_meta -> (match cf.cf_expr with | Some({ eexpr = TFunction({ tf_args = (v, _) :: _ }) }) when Meta.has Meta.This v.v_meta -> cf.cf_params <- cf.cf_params @ a.a_params | _ -> ()) | _ -> () ) c.cl_ordered_statics | _ -> ()); Some md in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) run end;; (* ******************************************* *) (* FixOverrides *) (* ******************************************* *) (* Covariant return types, contravariant function arguments and applied type parameters may change in a way that expected implementations / overrides aren't recognized as such. This filter will fix that. dependencies: FixOverrides expects that the target platform is able to deal with overloaded functions It must run after DefaultArguments, otherwise code added by the default arguments may be invalid *) module FixOverrides = struct let name = "fix_overrides" let priority = solve_deps name [DAfter DefaultArguments.priority] (* if the platform allows explicit interface implementation (C#), specify a explicit_fn_name function (tclass->string->string) Otherwise, it expects the platform to be able to handle covariant return types *) let run ~explicit_fn_name ~get_vmtype gen = let implement_explicitly = is_some explicit_fn_name in let run md = match md with | TClassDecl ( { cl_interface = true; cl_extern = false } as c ) -> (* overrides can be removed from interfaces *) c.cl_ordered_fields <- List.filter (fun f -> try if Meta.has Meta.Overload f.cf_meta then raise Not_found; let f2 = Codegen.find_field gen.gcon c f in if f2 == 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; md | TClassDecl({ cl_extern = false } as c) -> let this = { eexpr = TConst TThis; etype = TInst(c,List.map snd c.cl_params); epos = c.cl_pos } in (* look through all interfaces, and try to find a type that applies exactly *) let rec loop_iface (iface:tclass) itl = List.iter (fun (s,stl) -> loop_iface s (List.map (apply_params iface.cl_params itl) stl)) iface.cl_implements; let real_itl = gen.greal_type_param (TClassDecl iface) itl in let rec loop_f f = List.iter loop_f f.cf_overloads; let ftype = apply_params iface.cl_params itl f.cf_type in let real_ftype = get_real_fun gen (apply_params iface.cl_params real_itl f.cf_type) in replace_mono real_ftype; let overloads = Overloads.get_overloads c f.cf_name in try let t2, f2 = match overloads with | (_, cf) :: _ when Meta.has Meta.Overload cf.cf_meta -> (* overloaded function *) (* try to find exact function *) List.find (fun (t,f2) -> Overloads.same_overload_args ~get_vmtype ftype t f f2 ) overloads | _ :: _ -> (match field_access gen (TInst(c, List.map snd c.cl_params)) f.cf_name with | FClassField(_,_,_,f2,false,t,_) -> t,f2 (* if it's not an overload, all functions should have the same signature *) | _ -> raise Not_found) | [] -> raise Not_found in replace_mono t2; (* if we find a function with the exact type of real_ftype, it means this interface has already been taken care of *) if not (type_iseq (get_real_fun gen (apply_params f2.cf_params (List.map snd f.cf_params) t2)) real_ftype) then begin (match f.cf_kind with | Method (MethNormal | MethInline) -> () | _ -> raise Not_found); let t2 = get_real_fun gen t2 in if List.length f.cf_params <> List.length f2.cf_params then raise Not_found; replace_mono t2; match follow (apply_params f2.cf_params (List.map snd f.cf_params) t2), follow real_ftype with | TFun(a1,r1), TFun(a2,r2) when not implement_explicitly && not (type_iseq r1 r2) && Overloads.same_overload_args ~get_vmtype real_ftype t2 f f2 -> (* different return types are the trickiest cases to deal with *) (* check for covariant return type *) let is_covariant = match follow r1, follow r2 with | _, TDynamic _ -> false | r1, r2 -> try unify r1 r2; true with | Unify_error _ -> false in (* we only have to worry about non-covariant issues *) if not is_covariant then begin (* override return type and cast implemented function *) let args, newr = match follow t2, follow (apply_params f.cf_params (List.map snd f2.cf_params) real_ftype) with | TFun(a,_), TFun(_,r) -> a,r | _ -> assert false in f2.cf_type <- TFun(args,newr); (match f2.cf_expr with | Some ({ eexpr = TFunction tf } as e) -> f2.cf_expr <- Some { e with eexpr = TFunction { tf with tf_type = newr } } | _ -> ()) end | TFun(a1,r1), TFun(a2,r2) -> (* just implement a function that will call the main one *) let name, is_explicit = match explicit_fn_name with | Some fn when not (type_iseq r1 r2) && Overloads.same_overload_args ~get_vmtype real_ftype t2 f f2 -> fn iface itl f.cf_name, true | _ -> f.cf_name, false in let p = f2.cf_pos in let newf = mk_class_field name real_ftype true f.cf_pos (Method MethNormal) f.cf_params in let vars = List.map (fun (n,_,t) -> alloc_var n t) a2 in let args = List.map2 (fun v (_,_,t) -> mk_cast t (mk_local v f2.cf_pos)) vars a1 in let field = { eexpr = TField(this, FInstance(c,List.map snd c.cl_params,f2)); etype = TFun(a1,r1); epos = p } in let call = { eexpr = TCall(field, args); etype = r1; epos = p } in (* let call = gen.gparam_func_call call field (List.map snd f.cf_params) args in *) let is_void = ExtType.is_void r2 in newf.cf_expr <- Some { eexpr = TFunction({ tf_args = List.map (fun v -> v,None) vars; tf_type = r2; tf_expr = (if is_void then call else { eexpr = TReturn (Some (mk_cast r2 call)); etype = r2; epos = p }) }); etype = real_ftype; epos = p; }; (try let fm = PMap.find name c.cl_fields in fm.cf_overloads <- newf :: fm.cf_overloads with | Not_found -> c.cl_fields <- PMap.add name newf c.cl_fields; c.cl_ordered_fields <- newf :: c.cl_ordered_fields) | _ -> assert false end with | Not_found -> () in List.iter (fun f -> match f.cf_kind with | Var _ -> () | _ -> loop_f f) iface.cl_ordered_fields in List.iter (fun (iface,itl) -> loop_iface iface itl) c.cl_implements; (* now go through all overrides, *) let rec check_f f = (* find the first declared field *) let is_overload = Meta.has Meta.Overload f.cf_meta in let decl = if is_overload then find_first_declared_field gen c ~get_vmtype ~exact_field:f f.cf_name else find_first_declared_field gen c ~get_vmtype f.cf_name in match decl with | Some(f2,actual_t,_,t,declared_cl,_,_) when not (Overloads.same_overload_args ~get_vmtype actual_t (get_real_fun gen f.cf_type) f2 f) -> (match f.cf_expr with | Some({ eexpr = TFunction(tf) } as e) -> let actual_args, _ = get_fun (get_real_fun gen actual_t) in let new_args, vardecl = List.fold_left2 (fun (args,vdecl) (v,_) (_,_,t) -> if not (type_iseq (gen.greal_type v.v_type) (gen.greal_type t)) then begin let new_var = mk_temp gen v.v_name t in (new_var,None) :: args, (v, Some(mk_cast v.v_type (mk_local new_var f.cf_pos))) :: vdecl end else (v,None) :: args, vdecl ) ([],[]) tf.tf_args actual_args in let block = { eexpr = TBlock(List.map (fun (v,ve) -> { eexpr = TVar(v,ve); etype = gen.gcon.basic.tvoid; epos = tf.tf_expr.epos }) vardecl); etype = gen.gcon.basic.tvoid; epos = tf.tf_expr.epos } in if Meta.has Meta.Overload f.cf_meta then begin (* if it is overload, create another field with the requested type *) let f3 = mk_class_field f.cf_name t f.cf_public f.cf_pos f.cf_kind f.cf_params in let p = f.cf_pos in let old_args, old_ret = get_fun f.cf_type in let args, ret = get_fun t in let tf_args = List.map (fun (n,o,t) -> alloc_var n t, None) args in let f3_mk_return = if ExtType.is_void ret then (fun e -> e) else (fun e -> mk_return (mk_cast ret e)) in f3.cf_expr <- Some { eexpr = TFunction({ tf_args = List.rev new_args; tf_type = ret; tf_expr = Type.concat block (mk_block (f3_mk_return { eexpr = TCall( { eexpr = TField( { eexpr = TConst TThis; etype = TInst(c, List.map snd c.cl_params); epos = p }, FInstance(c,List.map snd c.cl_params,f)); etype = f.cf_type; epos = p }, List.map2 (fun (v,_) (_,_,t) -> mk_cast t (mk_local v p)) tf_args old_args); etype = old_ret; epos = p })) }); etype = t; epos = p; }; (* make sure we skip cast detect - otherwise this new function will make the overload detection go crazy *) f3.cf_meta <- (Meta.Custom(":skipCastDetect"), [], f3.cf_pos) :: f3.cf_meta; gen.gafter_expr_filters_ended <- ((fun () -> f.cf_overloads <- f3 :: f.cf_overloads; ) :: gen.gafter_expr_filters_ended); f3 end else begin (* if it's not overload, just cast the vars *) if vardecl <> [] then f.cf_expr <- Some({ e with eexpr = TFunction({ tf with tf_args = List.rev new_args; tf_expr = Type.concat block tf.tf_expr }); }); f end | _ -> f) | _ -> f in if not c.cl_extern then c.cl_overrides <- List.map (fun f -> check_f f) c.cl_overrides; md | _ -> md in run let configure ?explicit_fn_name ~get_vmtype gen = let delay () = Hashtbl.clear gen.greal_field_types in gen.gafter_mod_filters_ended <- delay :: gen.gafter_mod_filters_ended; let run = run ~explicit_fn_name ~get_vmtype gen in let map md = Some(run md) in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* Normalize *) (* ******************************************* *) (* - Filters out enum constructor type parameters from the AST; See Issue #1796 - Filters out monomorphs - Filters out all non-whitelisted AST metadata dependencies: No dependencies; but it still should be one of the first filters to run, as it will help normalize the AST *) module Normalize = struct let name = "normalize_type" let priority = max_dep let rec filter_param t = match t with | TInst({ cl_kind = KTypeParameter _ } as c,_) when Meta.has Meta.EnumConstructorParam c.cl_meta -> t_dynamic | TMono r -> (match !r with | None -> t_dynamic | Some t -> filter_param t) | TInst(_,[]) | TEnum(_,[]) | TType(_,[]) | TAbstract(_,[]) -> t | TType(t,tl) -> TType(t,List.map filter_param tl) | TInst(c,tl) -> TInst(c,List.map filter_param tl) | TEnum(e,tl) -> TEnum(e,List.map filter_param tl) | TAbstract({ a_path = (["haxe";"extern"],"Rest") } as a,tl) -> TAbstract(a, List.map filter_param tl) | TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> filter_param (Abstract.get_underlying_type a tl) | TAbstract(a,tl) -> TAbstract(a, List.map filter_param tl) | TAnon a -> TAnon { a_fields = PMap.map (fun f -> { f with cf_type = filter_param f.cf_type }) a.a_fields; a_status = a.a_status; } | TFun(args,ret) -> TFun(List.map (fun (n,o,t) -> (n,o,filter_param t)) args, filter_param ret) | TDynamic _ -> t | TLazy f -> filter_param (!f()) let configure gen ~metas = let rec run e = match e.eexpr with | TMeta (entry, e) when not (Hashtbl.mem metas entry) -> run e | _ -> map_expr_type (fun e -> run e) filter_param (fun v -> v.v_type <- filter_param v.v_type; v) e in let map e = Some (run e) in gen.gexpr_filters#add ~name:name ~priority:(PCustom priority) map; let run md = match md with | TClassDecl cl -> let rec map cf = cf.cf_type <- filter_param cf.cf_type; List.iter map cf.cf_overloads in List.iter map cl.cl_ordered_fields; List.iter map cl.cl_ordered_statics; Option.may map cl.cl_constructor | _ -> () in let map md = Some (run md; md) in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* InterfaceMetas *) (* ******************************************* *) (* Deal with metadata on interfaces by taking it off from interface, and adding a new class with `_HxMeta` suffix dependencies: Must run before InitFunction *) module InterfaceMetas = struct let name = "interface_metas" let priority = solve_deps name [ DBefore InitFunction.priority ] let configure gen = let run md = match md with | TClassDecl ({ cl_interface = true; cl_ordered_statics = (_ :: _) } as cl) -> cl.cl_ordered_statics <- []; let path = fst cl.cl_path,snd cl.cl_path ^ "_HxMeta" in (match Codegen.build_metadata gen.gcon (TClassDecl cl) with | Some expr -> let ncls = mk_class cl.cl_module path cl.cl_pos in let cf = mk_class_field "__meta__" expr.etype false expr.epos (Var { v_read = AccNormal; v_write = AccNormal }) [] in cf.cf_expr <- Some expr; ncls.cl_statics <- PMap.add "__meta__" cf ncls.cl_statics; ncls.cl_ordered_statics <- cf :: ncls.cl_ordered_statics; gen.gadd_to_module (TClassDecl(ncls)) priority; | _ -> ()) | _ -> () in let map md = run md; Some(md) in gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) map end;; haxe_3.4.4.orig/src/generators/gencpp.ml0000664000175000017500000114411113166552354020165 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Type open Common open Globals (* Generators do not care about non-core-type abstracts, so let us follow them away by default. *) let follow = Abstract.follow_with_abstracts (* Code for generating source files. It manages creating diretories, indents, blocks and only modifying files when the content changes. *) (* A class_path is made from a package (array of strings) and a class name. Join these together, inclding a separator. eg, "/" for includes : pack1/pack2/Name or "::" for namespace "pack1::pack2::Name" *) let join_class_path path separator = let result = match fst path, snd path with | [], s -> s | el, s -> String.concat separator el ^ separator ^ s in if (String.contains result '+') then begin let idx = String.index result '+' in (String.sub result 0 idx) ^ (String.sub result (idx+1) ((String.length result) - idx -1 ) ) end else result;; let class_text path = join_class_path path "::" ;; (* The internal classes are implemented by the core hxcpp system, so the cpp classes should not be generated *) let is_internal_class = function | ([],"Int") | ([],"Void") | ([],"String") | ([], "Null") | ([], "Float") | ([],"Array") | ([], "Class") | ([], "Enum") | ([], "Bool") | ([], "Dynamic") | ([], "ArrayAccess") | (["cpp"], "FastIterator") | (["cpp"],"Pointer") | (["cpp"],"ConstPointer") | (["cpp"],"RawPointer") | (["cpp"],"RawConstPointer") | (["cpp"],"Function") -> true | (["cpp"],"VirtualArray") -> true | ([],"Math") -> true | (["cpp"],"Int8") | (["cpp"],"UInt8") | (["cpp"],"Char") | (["cpp"],"Int16") | (["cpp"],"UInt16") | (["cpp"],"Int32") | (["cpp"],"UInt32") | (["cpp"],"Int64") | (["cpp"],"UInt64") | (["cpp"],"Float32") | (["cpp"],"Float64") -> true | _ -> false;; let get_include_prefix common_ctx with_slash = try (Common.defined_value common_ctx Define.IncludePrefix) ^ (if with_slash then "/" else "") with Not_found -> "" ;; let should_prefix_include = function | x when is_internal_class x -> false | ([],"hxMath") -> true | _ -> false;; let verbatim_include file = if (String.sub file 0 1)="@" then ("@import " ^ (String.sub file 1 ((String.length file) - 1 )) ^ ";\n") else ("#include \"" ^ file ^ "\"\n") ;; let hash64 s = String.sub (Digest.to_hex (Digest.string s)) 0 16 ;; let guarded_include file = let guard_name = "INCLUDED_" ^ (hash64 file) in "#ifndef " ^ guard_name ^ "\n" ^ "#define " ^ guard_name ^ "\n" ^ (verbatim_include file) ^ "#endif\n"; class source_writer common_ctx write_header_func write_func close_func = object(this) val indent_str = "\t" val mutable indent = "" val mutable indents = [] val mutable just_finished_block = false val mutable headerLines = Hashtbl.create 0 method close = close_func(); () method write x = write_func x; just_finished_block <- false method write_h x = write_header_func x; () method write_h_unique x = if not (Hashtbl.mem headerLines x) then begin Hashtbl.add headerLines x (); this#write_h x; end method indent_one = this#write indent_str method push_indent = indents <- indent_str::indents; indent <- String.concat "" indents method pop_indent = match indents with | h::tail -> indents <- tail; indent <- String.concat "" indents | [] -> indent <- "/*?*/"; method write_i x = this#write (indent ^ x) method get_indent = indent method begin_block = this#write ("{\n"); this#push_indent method end_block = this#pop_indent; this#write_i "}\n"; just_finished_block <- true method end_block_line = this#pop_indent; this#write_i "}"; just_finished_block <- true method terminate_line = this#write (if just_finished_block then "" else ";\n") method add_big_closures = this#write_h_unique "#include \n"; method add_include class_path = ( match class_path with | (["@verbatim"],file) -> this#write_h_unique (guarded_include file) | _ -> let prefix = if should_prefix_include class_path then "" else get_include_prefix common_ctx true in this#write_h ("#ifndef INCLUDED_" ^ (join_class_path class_path "_") ^ "\n"); this#write_h ("#include <" ^ prefix ^ (join_class_path class_path "/") ^ ".h>\n"); this#write_h ("#endif\n") ) end;; let read_whole_file chan = Std.input_all chan;; (* The cached_source_writer will not write to the file if it has not changed, thus allowing the makefile dependencies to work correctly *) let cached_source_writer common_ctx filename = let header = Buffer.create 0 in let add_header str = Buffer.add_string header str in let buffer = Buffer.create 0 in let add_buf str = Buffer.add_string buffer str in let close = fun() -> Buffer.add_buffer header buffer; let contents = Buffer.contents header in let same = try let in_file = open_in filename in let old_contents = read_whole_file in_file in close_in in_file; contents=old_contents with _ -> false in if not same then begin let out_file = open_out filename in output_string out_file contents; close_out out_file; end; in new source_writer common_ctx (add_header) (add_buf) (close) ;; let make_class_directories = Common.mkdir_recursive;; let make_base_directory dir = make_class_directories "" ( ( Str.split_delim (Str.regexp "[\\/]+") dir ) );; let new_source_file common_ctx base_dir sub_dir extension class_path = let include_prefix = get_include_prefix common_ctx true in let full_dir = if (sub_dir="include") && (include_prefix<>"") then begin let dir = match fst class_path with | [] -> base_dir ^ "/include/" ^ (get_include_prefix common_ctx false) | path -> base_dir ^ "/include/" ^ include_prefix ^ ( String.concat "/" path ) in make_class_directories base_dir (["include";include_prefix]@(fst class_path)); dir end else begin make_class_directories base_dir ( sub_dir :: (fst class_path)); base_dir ^ "/" ^ sub_dir ^ "/" ^ ( String.concat "/" (fst class_path) ) end in let file = cached_source_writer common_ctx (full_dir ^ "/" ^ ((snd class_path) ^ extension)) in Codegen.map_source_header common_ctx (fun s -> file#write_h (Printf.sprintf "// %s\n" s)); file let source_file_extension common_ctx = (* no need to -D file_extension if -D objc is defined *) if Common.defined common_ctx Define.Objc then ".mm" else try "." ^ (Common.defined_value common_ctx Define.FileExtension) with Not_found -> ".cpp" ;; let new_cpp_file common_ctx base_dir = new_source_file common_ctx base_dir "src" (source_file_extension common_ctx);; let new_header_file common_ctx base_dir = new_source_file common_ctx base_dir "include" ".h";; (* CPP code generation context *) (* ctx_debug_level 0 = no debug 1 = function + line debug via macros, which can be activated at cpp compile-time 2 = include macros for HXCPP_DEBUGGER 3 = annotate source with additional info about AST and types 4 = console output at haxe compile-time normal = 1 *) type context = { ctx_common : Common.context; mutable ctx_debug_level : int; (* cached as required *) mutable ctx_file_info : (string,string) PMap.t ref; ctx_type_ids : (string,Int32.t) Hashtbl.t; (* Per file *) ctx_output : string -> unit; ctx_writer : source_writer; ctx_file_id : int ref; ctx_is_header : bool; ctx_interface_slot : (string,int) Hashtbl.t ref; ctx_interface_slot_count : int ref; (* This is for returning from the child nodes of TSwitch && TTry *) mutable ctx_real_this_ptr : bool; mutable ctx_class_member_types : (string,string) Hashtbl.t; } let new_context common_ctx debug file_info member_types = let null_file = new source_writer common_ctx ignore ignore (fun () -> () ) in let has_def def = Common.defined_value_safe common_ctx def <>"" in let result = { ctx_common = common_ctx; ctx_writer = null_file; ctx_file_id = ref (-1); ctx_type_ids = Hashtbl.create 0; ctx_is_header = false; ctx_output = (null_file#write); ctx_interface_slot = ref (Hashtbl.create 0); ctx_interface_slot_count = ref 2; ctx_debug_level = if has_def Define.AnnotateSource then 3 else if has_def Define.HxcppDebugger then 2 else debug; ctx_real_this_ptr = true; ctx_class_member_types = member_types; ctx_file_info = file_info; } in result let file_context ctx writer debug header = { ctx with ctx_writer = writer; ctx_output = (writer#write); ctx_is_header = header; ctx_file_id = ref (-1); } ;; (* The internal header files are also defined in the hx/Object.h file, so you do #include them separately. However, Math classes has its own header file (under the hxcpp tree) so these should be included *) let include_class_header = function | ([],"@Main") -> false | ([],"Math") -> true | path -> not ( is_internal_class path ) let is_cpp_class = function | ("cpp"::_ , _) -> true | ( [] , "EReg" ) -> true | ( ["haxe"] , "Log" ) -> true | _ -> false;; let is_block exp = match exp.eexpr with | TBlock _ -> true | _ -> false ;; (* todo - is this how it's done? *) let hash_keys hash = let key_list = ref [] in Hashtbl.iter (fun key value -> key_list := key :: !key_list ) hash; !key_list;; let pmap_keys pmap = let key_list = ref [] in PMap.iter (fun key _ -> key_list := key :: !key_list ) pmap; !key_list;; let pmap_values pmap = let value_list = ref [] in PMap.iter (fun _ value -> value_list := value :: !value_list ) pmap; !value_list;; (* The Hashtbl structure seems a little odd - but here is a helper function *) let hash_iterate hash visitor = let result = ref [] in Hashtbl.iter (fun key value -> result := (visitor key value) :: !result ) hash; !result let is_internal_member member = member = "toString" || ( (String.length member > 1) && (String.sub member 0 2 = "__") && (match member with | "__ArgCount" | "__ArrayImplRef" | "__CStr" | "__Compare" | "__Create" | "__CreateEmpty" | "__FieldRef" | "__FindArgCount" | "__GetFieldMap" | "__GetHandle" | "__GetItem" | "__GetScriptCallable" | "__GetScriptVTable" | "__Param" | "__Remove" | "__SGetClass" | "__Set" | "__SetItem" | "__TArrayImplRef" | "__ToDouble" | "__ToInt" | "__ToInterface" | "__ToObject" | "__Visit" | "__WCStr" | "__a" | "__blit" | "__boot" | "__boot_all" | "__compare" | "__concat" | "__construct" | "__copy" | "__filter" | "__get_args" | "__hx_dump_stack" | "__hx_field_iter" | "__hxt_gc_new" | "__indexOf" | "__insert" | "__instanceof" | "__int" | "__iterator" | "__join" | "__lastIndexOf" | "__loadprim" | "__mClass" | "__mDynamicFields" | "__map" | "__memcmp" | "__new" | "__pop" | "__prime" | "__push" | "__qsort" | "__unshift" | "__unsafeStringReference" | "__time_stamp" | "__superString" | "__splice" | "__shift" | "__slice" | "__sort" | "__s_id" | "__run" | "__root" | "__register" | "__remove" | "__removeAt" | "__reverse" | "__zero" | "__Field" | "__IField" | "__Run" | "__Is" | "__GetClass" | "__GetType" | "__ToString" | "__s" | "__GetPtr" | "__SetField" | "__length" | "__IsArray" | "__SetThis" | "__Internal" | "__EnumParams" | "__Index" | "__Tag" | "__GetFields" | "__HasField" | "__get" | "__set" | "__unsafe_get" | "__unsafe_set" | "__global__" | "__SetSize" | "__trace" | "__GetRealObject" | "__SetSizeExact" | "__cpp__" | "__URLEncode" | "__URLDecode" | "__IsEnum" -> true | _ -> (String.length member > 4) && (String.sub member 0 4 = "__hx") ) );; let is_known_member member = match member with | "__meta__" | "__rtti" | "_Compare" -> true | _ -> false;; (* Convert function names that can't be written in c++ ... *) let keyword_remap name = if (is_internal_member name) || (is_known_member name) then name else if (String.length name > 1) && (String.sub name 0 2 = "__") then "_hx_" ^ name else match name with | "int" | "Int" | "Bool" | "super" | "auto" | "char" | "const" | "delete" | "double" | "Float" | "enum" | "extern" | "float" | "friend" | "goto" | "long" | "operator" | "protected" | "register" | "short" | "signed" | "sizeof" | "template" | "typedef" | "union" | "unsigned" | "void" | "volatile" | "or" | "and" | "xor" | "or_eq" | "not" | "and_eq" | "xor_eq" | "typeof" | "stdin" | "stdout" | "stderr" | "system" | "BIG_ENDIAN" | "LITTLE_ENDIAN" | "assert" | "NULL" | "wchar_t" | "EOF" | "bool" | "const_cast" | "dynamic_cast" | "explicit" | "export" | "mutable" | "namespace" | "reinterpret_cast" | "static_cast" | "typeid" | "typename" | "virtual" | "_Complex" | "INFINITY" | "NAN" | "INT_MIN" | "INT_MAX" | "INT8_MIN" | "INT8_MAX" | "UINT8_MAX" | "INT16_MIN" | "INT16_MAX" | "UINT16_MAX" | "INT32_MIN" | "INT32_MAX" | "UINT32_MAX" | "asm" | "near" | "far" | "HX_" | "HXLINE" | "HXDLIN" | "NO" | "YES" | "abstract" | "decltype" | "finally" | "nullptr" | "static_assert" | "struct" -> "_hx_" ^ name | x -> x ;; let remap_class_path class_path = let path_remap with_keywords name = let len = String.length name in if (len > 3) && (String.sub name 0 3 = " ::") then String.sub name 3 (len-3) else if (len > 2) && (String.sub name 0 2 = "::") then String.sub name 2 (len-2) else if with_keywords then keyword_remap name else name in (List.map (path_remap true) (fst class_path)) , path_remap false (snd class_path) ;; let join_class_path_remap path separator = match join_class_path (remap_class_path path) separator with | "Class" -> "hx::Class" | x -> x ;; let get_meta_string meta key = let rec loop = function | [] -> "" | (k,[Ast.EConst (Ast.String name),_],_) :: _ when k=key-> name | _ :: l -> loop l in loop meta ;; let get_meta_string_path meta key = let rec loop = function | [] -> "" | (k,[Ast.EConst (Ast.String name),_], pos) :: _ when k=key-> (try if (String.sub name 0 2) = "./" then begin let base = if (Filename.is_relative pos.pfile) then Filename.concat (Sys.getcwd()) pos.pfile else pos.pfile in Path.normalize_path (Filename.concat (Filename.dirname base) (String.sub name 2 ((String.length name) -2) )) end else name with Invalid_argument _ -> name) | _ :: l -> loop l in loop meta ;; let get_meta_string_full_filename meta key = let rec loop = function | [] -> "" | (k,_, pos) :: _ when k=key-> if (Filename.is_relative pos.pfile) then Path.normalize_path (Filename.concat (Sys.getcwd()) pos.pfile) else pos.pfile | _ :: l -> loop l in loop meta ;; let get_meta_string_full_dirname meta key = let name = get_meta_string_full_filename meta key in try Path.normalize_path (Filename.dirname name) with Invalid_argument _ -> "" ;; let get_field_access_meta field_access key = match field_access with | FInstance(_,_,class_field) | FStatic(_,class_field) -> get_meta_string class_field.cf_meta key | _ -> "" ;; let format_code code = String.concat "\n" (ExtString.String.nsplit code "\r\n") let get_code meta key = let code = get_meta_string meta key in let magic_var = "${GENCPP_SOURCE_DIRECTORY}" in let code = if ExtString.String.exists code magic_var then begin let source_directory = get_meta_string_full_dirname meta key in let _,code = ExtString.String.replace code magic_var source_directory in code end else code in if (code<>"") then format_code code ^ "\n" else code ;; let has_meta_key meta key = List.exists (fun m -> match m with | (k,_,_) when k=key-> true | _ -> false ) meta ;; let type_has_meta_key haxe_type key = match follow haxe_type with | TInst (klass,_) -> has_meta_key klass.cl_meta key | TType (type_def,_) -> has_meta_key type_def.t_meta key | TEnum (enum_def,_) -> has_meta_key enum_def.e_meta key | _ -> false ;; (* let dump_meta meta = List.iter (fun m -> match m with | (k,_,_) -> print_endline ((fst (Meta.to_string k)) ^ "=" ^ (get_meta_string meta k) ) | _ -> () ) meta;; *) let get_class_code class_def key = match class_def.cl_kind with | KAbstractImpl abstract_def -> let value = (get_code abstract_def.a_meta key) in value | _ -> get_code class_def.cl_meta key ;; (* Add include to source code *) let add_include writer class_path = writer#add_include class_path;; let list_num l = string_of_int (List.length l);; (* This gets the class include order correct. In the header files, we forward declare the class types so the header file does not have any undefined variables. In the cpp files, we include all the required header files, providing the actual types for everything. This way there is no problem with circular class references. *) let gen_forward_decl writer class_path isNative = begin let output = writer#write in match class_path with | (["@verbatim"],file) -> writer#write (guarded_include file) | _ -> let name = fst (remap_class_path class_path) in output ((if isNative then "HX_DECLARE_NATIVE" else "HX_DECLARE_CLASS") ^ list_num name ^ "("); List.iter (fun package_part -> output (package_part ^ ",") ) name; output ( (snd class_path) ^ ")\n") end;; let real_interfaces = List.filter (function (t,pl) -> match t, pl with | { cl_path = ["cpp";"rtti"],_ },[] -> false | _ -> true );; let is_var_field field = match field.cf_kind with | Var _ -> true | Method MethDynamic -> true | _ -> false ;; let rec has_rtti_interface c interface = List.exists (function (t,pl) -> (snd t.cl_path) = interface && (match fst t.cl_path with | ["cpp";"rtti"] -> true | _ -> false ) ) c.cl_implements || (match c.cl_super with None -> false | Some (c,_) -> has_rtti_interface c interface);; let has_field_integer_lookup class_def = has_rtti_interface class_def "FieldIntegerLookup";; let has_field_integer_numeric_lookup class_def = has_rtti_interface class_def "FieldNumericIntegerLookup";; (* Output required code to place contents in required namespace *) let gen_open_namespace output class_path = List.iter (fun namespace -> output ("namespace " ^ namespace ^ "{\n")) (List.map keyword_remap (fst class_path));; let gen_close_namespace output class_path = List.iter (fun namespace -> output ( "}" ^ " // end namespace " ^ namespace ^"\n")) (fst class_path);; (* The basic types can have default values and are passesby value *) let is_numeric = function | "Int" | "Bool" | "Float" | "unsigned char" -> true | "::cpp::UInt8" | "::cpp::Int8" | "::cpp::Char" | "::cpp::UInt16" | "::cpp::Int16" | "::cpp::UInt32" | "::cpp::Int32" | "::cpp::UInt64" | "::cpp::Int64" | "::cpp::Float32" | "::cpp::Float64" | "int" | "bool" | "double" | "float" -> true | _ -> false let rec remove_parens expression = match expression.eexpr with | TParenthesis e -> remove_parens e | TMeta(_,e) -> remove_parens e | _ -> expression ;; let rec remove_parens_cast expression = match expression.eexpr with | TParenthesis e -> remove_parens_cast e | TMeta(_,e) -> remove_parens_cast e | TCast ( e,None) -> remove_parens_cast e | _ -> expression ;; let is_interface_type t = match follow t with | TInst (klass,params) -> klass.cl_interface | _ -> false ;; let is_cpp_function_instance haxe_type = match follow haxe_type with | TInst (klass,params) -> (match klass.cl_path with | ["cpp"] , "Function" -> true | _ -> false ) | _ -> false ;; let is_objc_class klass = klass.cl_extern && Meta.has Meta.Objc klass.cl_meta ;; let rec is_objc_type t = match t with | TInst(cl,_) -> cl.cl_extern && Meta.has Meta.Objc cl.cl_meta | TType(td,_) -> (Meta.has Meta.Objc td.t_meta) | TAbstract (a,_) -> (Meta.has Meta.Objc a.a_meta) | TMono r -> (match !r with | Some t -> is_objc_type t | _ -> false) | TLazy f -> is_objc_type (!f()) | _ -> false ;; let is_lvalue var = match (remove_parens var).eexpr with | TLocal _ -> true | TField (_,FStatic(_,field) ) | TField (_,FInstance(_,_,field) ) -> is_var_field field | _ -> false ;; let is_pointer haxe_type includeRaw = match follow haxe_type with | TInst (klass,params) -> (match klass.cl_path with | ["cpp"] , "Pointer" | ["cpp"] , "ConstPointer" | ["cpp"] , "Function" -> true | ["cpp"] , "RawPointer" when includeRaw -> true | ["cpp"] , "RawConstPointer" when includeRaw -> true | _ -> false ) | TType (type_def,params) -> (match type_def.t_path with | ["cpp"] , "Pointer" | ["cpp"] , "ConstPointer" | ["cpp"] , "Function" -> true | ["cpp"] , "RawPointer" when includeRaw -> true | ["cpp"] , "RawConstPointer" when includeRaw -> true | _ -> false ) | _ -> false ;; let is_dynamic_type_param class_kind = match class_kind with | KTypeParameter _ -> true | _ -> false ;; let is_native_gen_class class_def = (has_meta_key class_def.cl_meta Meta.NativeGen) || (match class_def.cl_kind with | KAbstractImpl abstract_def -> (has_meta_key abstract_def.a_meta Meta.NativeGen) | _ -> false ); ;; let is_native_gen_module = function | TClassDecl class_def -> is_native_gen_class class_def | _ -> false ;; (* Get a string to represent a type. The "suffix" will be nothing or "_obj", depending if we want the name of the pointer class or the pointee (_obj class *) let rec class_string klass suffix params remap = let type_string = type_string_remap remap in let join_class_path_remap = if remap then join_class_path_remap else join_class_path in (match klass.cl_path with (* Array class *) | ([],"Array") when is_dynamic_array_param (List.hd params) -> "cpp::ArrayBase" ^ suffix (*"cpp::VirtualArray" ^ suffix*) | ([],"Array") -> (snd klass.cl_path) ^ suffix ^ "< " ^ (String.concat "," (List.map array_element_type params) ) ^ " >" (* FastIterator class *) | (["cpp"],"FastIterator") -> "::cpp::FastIterator" ^ suffix ^ "< " ^ (String.concat "," (List.map type_string params) ) ^ " >" | (["cpp"],"Pointer") | (["cpp"],"ConstPointer") -> "::cpp::Pointer< " ^ (String.concat "," (List.map type_string params) ) ^ " >" | (["cpp"],"RawPointer") -> " " ^ (String.concat "," (List.map type_string params) ) ^ " * " | (["cpp"],"RawConstPointer") -> " const " ^ (String.concat "," (List.map type_string params) ) ^ " * " | (["cpp"],"Function") -> "::cpp::Function< " ^ (cpp_function_signature_params params) ^ " >" | _ when is_dynamic_type_param klass.cl_kind -> "Dynamic" | ([],"#Int") -> "/* # */int" | (["cpp"],"UInt8") -> "unsigned char" | ([],"Class") -> "hx::Class" | ([],"EnumValue") -> "Dynamic" | ([],"Null") -> (match params with | [t] -> (match follow t with | TAbstract ({ a_path = [],"Int" },_) | TAbstract ({ a_path = [],"Float" },_) | TAbstract ({ a_path = [],"Bool" },_) -> "Dynamic" | TAbstract ({ a_path = ["cpp"],"UInt8" },_) -> "Dynamic" | t when type_has_meta_key t Meta.NotNull -> "Dynamic" | _ -> "/*NULL*/" ^ (type_string t) ) | _ -> assert false); (* Objective-C class *) | path when is_objc_type (TInst(klass,[])) -> let str = join_class_path_remap klass.cl_path "::" in if suffix = "_obj" then str else if klass.cl_interface then "id < " ^ str ^ ">" else str ^ " *" (* Native interface - use pointer *) | _ when klass.cl_interface && is_native_gen_class klass -> (join_class_path_remap klass.cl_path "::") ^ " *" (* Normal class *) | path when klass.cl_extern && (not (is_internal_class path) )-> (join_class_path_remap klass.cl_path "::") ^ suffix | _ -> let globalNamespace = if (get_meta_string klass.cl_meta Meta.Native)<>"" then "" else "::" in globalNamespace ^ (join_class_path_remap klass.cl_path "::") ^ suffix ) and type_string_suff suffix haxe_type remap = let type_string = type_string_remap remap in let join_class_path_remap = if remap then join_class_path_remap else join_class_path in (match haxe_type with | TMono r -> (match !r with None -> "Dynamic" ^ suffix | Some t -> type_string_suff suffix t remap) | TAbstract ({ a_path = ([],"Void") },[]) -> "Void" | TAbstract ({ a_path = ([],"Bool") },[]) -> "bool" | TAbstract ({ a_path = ([],"Float") },[]) -> "Float" | TAbstract ({ a_path = ([],"Int") },[]) -> "int" | TAbstract ({ a_path = (["cpp"],"UInt8") },[]) -> "unsigned char" | TAbstract( { a_path = ([], "EnumValue") }, _ ) -> "Dynamic" | TEnum (enum,params) -> "::" ^ (join_class_path_remap enum.e_path "::") ^ suffix | TInst (klass,params) -> (class_string klass suffix params remap) | TType (type_def,params) -> (match type_def.t_path with | [] , "Null" -> (match params with | [t] -> (match follow t with | TAbstract ({ a_path = [],"Int" },_) | TAbstract ({ a_path = [],"Float" },_) | TAbstract ({ a_path = [],"Bool" },_) -> "Dynamic" ^ suffix | t when type_has_meta_key t Meta.NotNull -> "Dynamic" ^ suffix | _ -> type_string_suff suffix t remap) | _ -> assert false); | [] , "Array" -> (match params with | [t] when (type_string (follow t) ) = "Dynamic" -> "Dynamic" | [t] -> "Array< " ^ (type_string (follow t) ) ^ " >" | _ -> assert false) | ["cpp"] , "FastIterator" -> (match params with | [t] -> "::cpp::FastIterator< " ^ (type_string (follow t) ) ^ " >" | _ -> assert false) | ["cpp"] , "Pointer" | ["cpp"] , "ConstPointer" -> (match params with | [t] -> "::cpp::Pointer< " ^ (type_string (follow t) ) ^ " >" | _ -> assert false) | ["cpp"] , "RawPointer" -> (match params with | [t] -> " " ^ (type_string (follow t) ) ^ " *" | _ -> assert false) | ["cpp"] , "RawConstPointer" -> (match params with | [t] -> "const " ^ (type_string (follow t) ) ^ " *" | _ -> assert false) | ["cpp"] , "Function" -> "::cpp::Function< " ^ (cpp_function_signature_params params ) ^ " >" | _ -> type_string_suff suffix (apply_params type_def.t_params params type_def.t_type) remap ) | TFun (args,haxe_type) -> "Dynamic" ^ suffix | TAnon a -> "Dynamic" (* (match !(a.a_status) with | Statics c -> type_string_suff suffix (TInst (c,List.map snd c.cl_params)) | EnumStatics e -> type_string_suff suffix (TEnum (e,List.map snd e.e_params)) | _ -> "Dynamic" ^ suffix ) *) | TDynamic haxe_type -> "Dynamic" ^ suffix | TLazy func -> type_string_suff suffix ((!func)()) remap | TAbstract (abs,pl) when abs.a_impl <> None -> type_string_suff suffix (Abstract.get_underlying_type abs pl) remap | TAbstract (abs,pl) -> "::" ^ (join_class_path_remap abs.a_path "::") ^ suffix ) and type_string_remap remap haxe_type = type_string_suff "" haxe_type remap and type_string haxe_type = type_string_suff "" haxe_type true and array_element_type haxe_type = match type_string haxe_type with | x when cant_be_null haxe_type -> x | x when is_interface_type (follow haxe_type) -> x | "::String" -> "::String" | _ -> "::Dynamic" and is_dynamic_array_param haxe_type = if (type_string (follow haxe_type)) = "Dynamic" then true else (match follow haxe_type with | TInst (klass,params) -> (match klass.cl_path with | ([],"Array") | ([],"Class") | (["cpp"],"FastIterator") | (["cpp"],"RawPointer") |(["cpp"],"ConstRawPointer") | (["cpp"],"Pointer") |(["cpp"],"ConstPointer")|(["cpp"],"Function") -> false | _ -> (match klass.cl_kind with KTypeParameter _ -> true | _ -> false) ) | _ -> false ) and cpp_function_signature tfun abi = match follow tfun with | TFun(args,ret) -> (type_string ret) ^ " " ^ abi ^ "(" ^ (gen_tfun_interface_arg_list args) ^ ")" | _ -> "void *" and cpp_function_signature_params params = match params with | [t; abi] -> (match follow abi with | TInst (klass,_) -> cpp_function_signature t (get_meta_string klass.cl_meta Meta.Abi) | _ -> print_endline (type_string abi); assert false ) | _ -> print_endline ("Params:" ^ (String.concat "," (List.map type_string params) )); assert false; and gen_interface_arg_type_name name opt typ = let type_str = (type_string typ) in (* type_str may have already converted Null to Dynamic because of NotNull tag ... *) (if (opt && (cant_be_null typ) && type_str<>"Dynamic" ) then "hx::Null< " ^ type_str ^ " > " else type_str ) ^ " " ^ (keyword_remap name) and gen_tfun_interface_arg_list args = String.concat "," (List.map (fun (name,opt,typ) -> gen_interface_arg_type_name name opt typ) args) and cant_be_null haxe_type = is_numeric (type_string haxe_type) || (type_has_meta_key haxe_type Meta.NotNull ) ;; let is_array haxe_type = match follow haxe_type with | TInst (klass,params) -> (match klass.cl_path with | [] , "Array" -> not (is_dynamic_array_param (List.hd params)) | _ -> false ) | TType (type_def,params) -> (match type_def.t_path with | [] , "Array" -> not (is_dynamic_array_param (List.hd params)) | _ -> false ) | _ -> false ;; let is_array_or_dyn_array haxe_type = match follow haxe_type with | TInst (klass,params) -> (match klass.cl_path with | [] , "Array" -> true | _ -> false ) | TType (type_def,params) -> (match type_def.t_path with | [] , "Array" -> true | _ -> false ) | _ -> false ;; let is_array_implementer haxe_type = match follow haxe_type with | TInst (klass,params) -> (match klass.cl_array_access with | Some _ -> true | _ -> false ) | _ -> false ;; let is_static_access obj = match (remove_parens obj).eexpr with | TTypeExpr _ -> true | _ -> false ;; let is_native_with_space func = match (remove_parens func).eexpr with | TField(obj,field) when is_static_access obj -> String.contains (get_field_access_meta field Meta.Native) ' ' | _ -> false ;; let is_native_pointer expr = let t = type_string expr.etype in let l = String.length t in l>1 && (String.sub t (l-1) 1) = "*" ;; let rec is_cpp_function_member func = match (remove_parens func).eexpr with | TField(obj,field) when is_cpp_function_instance obj.etype -> true | TCall(obj,_) -> is_cpp_function_member obj | _ -> false ;; (* Get the type and output it to the stream *) (* let gen_type ctx haxe_type = ctx.ctx_output (type_string haxe_type) ;; let member_type ctx field_object member = let name = (if (is_array field_object.etype) then "::Array" else (type_string field_object.etype)) ^ "." ^ member in try ( Hashtbl.find ctx.ctx_class_member_types name ) with Not_found -> "?";; *) let is_interface obj = is_interface_type obj.etype;; let should_implement_field x = not (is_extern_field x);; let is_extern_class class_def = class_def.cl_extern || (has_meta_key class_def.cl_meta Meta.Extern) || (match class_def.cl_kind with | KAbstractImpl abstract_def -> (has_meta_key abstract_def.a_meta Meta.Extern) | _ -> false ); ;; let is_scalar_abstract abstract_def = Meta.has Meta.Scalar abstract_def.a_meta && Meta.has Meta.CoreType abstract_def.a_meta ;; let real_non_native_interfaces = List.filter (function (t,pl) -> match t, pl with | { cl_path = ["cpp";"rtti"],_ },[] -> false | _ -> not (is_native_gen_class t) );; let is_extern_class_instance obj = match follow obj.etype with | TInst (klass,params) -> klass.cl_extern | _ -> false ;; let rec is_dynamic_accessor name acc field class_def = ( ( acc ^ "_" ^ field.cf_name) = name ) && ( not (List.exists (fun f -> f.cf_name=name) class_def.cl_ordered_fields) ) && (match class_def.cl_super with None -> true | Some (parent,_) -> is_dynamic_accessor name acc field parent ) ;; (* Check to see if we are the first object in the parent tree to implement a dynamic interface *) let implement_dynamic_here class_def = let implements_dynamic c = match c.cl_dynamic with None -> false | _ -> true in let rec super_implements_dynamic c = match c.cl_super with | None -> false | Some (csup, _) -> if (implements_dynamic csup) then true else super_implements_dynamic csup; in ( (implements_dynamic class_def) && (not (super_implements_dynamic class_def) ) );; let gen_hash32 seed str = let h = ref (Int32.of_int seed) in let cycle = Int32.of_int 223 in for i = 0 to String.length str - 1 do h := Int32.add (Int32.mul !h cycle) (Int32.of_int (int_of_char (String.unsafe_get str i))); done; !h ;; let gen_hash seed str = Printf.sprintf "0x%08lx" (gen_hash32 seed str) ;; let gen_hash_small seed str = Printf.sprintf "%08lx" (gen_hash32 seed str) ;; let gen_string_hash str = let h = gen_hash32 0 str in Printf.sprintf "\"\\x%02lx\",\"\\x%02lx\",\"\\x%02lx\",\"\\x%02lx\"" (Int32.shift_right_logical (Int32.shift_left h 24) 24) (Int32.shift_right_logical (Int32.shift_left h 16) 24) (Int32.shift_right_logical (Int32.shift_left h 8) 24) (Int32.shift_right_logical h 24) ;; let gen_qstring_hash str = let h = gen_hash32 0 str in Printf.sprintf "%02lx,%02lx,%02lx,%02lx" (Int32.shift_right_logical (Int32.shift_left h 24) 24) (Int32.shift_right_logical (Int32.shift_left h 16) 24) (Int32.shift_right_logical (Int32.shift_left h 8) 24) (Int32.shift_right_logical h 24) ;; (* Make string printable for c++ code *) (* Here we know there are no utf8 characters, so use the L"" notation to avoid conversion *) let escape_stringw s l = let b = Buffer.create 0 in Buffer.add_char b 'L'; Buffer.add_char b '"'; let skip = ref 0 in for i = 0 to String.length s - 1 do if (!skip>0) then begin skip := !skip -1; l := !l-1; end else match Char.code (String.unsafe_get s i) with | c when (c>127) -> let encoded = ((c land 0x3F) lsl 6) lor ( Char.code ((String.unsafe_get s (i+1))) land 0x7F) in skip := 1; Buffer.add_string b (Printf.sprintf "\\x%X\"L\"" encoded) | c when (c < 32) -> Buffer.add_string b (Printf.sprintf "\\x%X\"L\"" c) | c -> Buffer.add_char b (Char.chr c) done; Buffer.add_char b '"'; Buffer.contents b;; let special_to_hex s = let l = String.length s in let b = Buffer.create 0 in for i = 0 to l - 1 do match Char.code (String.unsafe_get s i) with | c when (c>127) || (c<32) -> Buffer.add_string b (Printf.sprintf "\\x%02x\"\"" c) | c -> Buffer.add_char b (Char.chr c) done; Buffer.contents b;; let escape_extern s = let l = String.length s in let b = Buffer.create 0 in for i = 0 to l - 1 do match Char.code (String.unsafe_get s i) with | c when (c>127) || (c<32) || (c=34) || (c=92) -> Buffer.add_string b (Printf.sprintf "\\x%02x" c) | c -> Buffer.add_char b (Char.chr c) done; Buffer.contents b;; let has_utf8_chars s = let result = ref false in for i = 0 to String.length s - 1 do result := !result || ( Char.code (String.unsafe_get s i) > 127 ) done; !result;; let escape_command s = let b = Buffer.create 0 in String.iter (fun ch -> if (ch=='"' || ch=='\\' ) then Buffer.add_string b "\\"; Buffer.add_char b ch ) s; Buffer.contents b;; let gen_str macro gen s = let rec split s plus = let escaped = Ast.s_escape ~hex:false s in let hexed = (special_to_hex escaped) in if (String.length hexed <= 16000 ) then plus ^ " HX_CSTRING(\"" ^ hexed ^ "\")" else begin let len = String.length s in let half = len lsr 1 in (split (String.sub s 0 half) plus ) ^ (split (String.sub s half (len-half)) "+" ) end in let escaped = Ast.s_escape ~hex:false s in let hexed = (special_to_hex escaped) in if (String.length hexed <= 16000 ) then macro ^ "(\"" ^ hexed ^ "\"," ^ (gen s) ^ ")" else "(" ^ (split s "" ) ^ ")" ;; let str s = gen_str "HX_HCSTRING" gen_string_hash s;; let strq s = gen_str "HX_" gen_qstring_hash s;; let const_char_star s = let escaped = Ast.s_escape ~hex:false s in "\"" ^ special_to_hex escaped ^ "\""; ;; (* Convert an array to a comma separated list of values *) let array_arg_list inList = let i = ref (0-1) in String.concat "," (List.map (fun _ -> incr i; "inArgs[" ^ (string_of_int !i) ^ "]" ) inList) (* See if there is a haxe break statement that will be swollowed by c++ break *) exception BreakFound;; (* Decide is we should look the field up by name *) let dynamic_internal = function | "__Is" -> true | _ -> false let rec is_null expr = match expr.eexpr with | TConst TNull -> true | TParenthesis expr | TMeta (_,expr) -> is_null expr | TCast (e,None) -> is_null e | _ -> false ;; let is_virtual_array expr = (type_string expr.etype="cpp::VirtualArray") ;; let is_real_function field = match field.cf_kind with | Method MethNormal | Method MethInline-> true | _ -> false ;; let is_this expression = match (remove_parens expression).eexpr with | TConst TThis -> true | _ -> false ;; let is_super expression = match (remove_parens expression).eexpr with | TConst TSuper -> true | _ -> false ;; let rec is_dynamic_in_cpp ctx expr = let expr_type = type_string ( match follow expr.etype with TFun (args,ret) -> ret | _ -> expr.etype) in if ( expr_type="Dynamic" || expr_type="cpp::ArrayBase") then true else begin let result = ( match expr.eexpr with | TEnumParameter( obj, _, index ) -> true (* TODO? *) | TField( obj, field ) -> (is_dynamic_member_lookup_in_cpp ctx obj field) || (is_dynamic_member_return_in_cpp ctx obj field) | TArray (obj,index) -> (is_dynamic_in_cpp ctx obj || is_virtual_array obj) | TTypeExpr _ -> false | TCall(func,args) -> let is_IaCall = (match (remove_parens_cast func).eexpr with | TField ( { eexpr = TLocal { v_name = "__global__" }}, field ) -> false | TField (obj,FStatic (class_def,field) ) when is_real_function field -> false | TField (obj,FInstance (_,_,field) ) when (is_this obj) && (is_real_function field) -> false | TField (obj,FInstance (_,_,field) ) when is_super obj -> false | TField (obj,FInstance (_,_,field) ) when field.cf_name = "_hx_getIndex" -> false | TField (obj,FInstance (_,_,field) ) when field.cf_name = "__Index" || (not (is_dynamic_in_cppia ctx obj) && is_real_function field) -> false | TField (obj,FDynamic (name) ) when (is_internal_member name || (type_string obj.etype = "::String" && name="cca") ) -> false | TConst TSuper -> false | TField (_,FEnum (enum,field)) -> false | _ -> true ) in if is_IaCall then true else (match follow func.etype with | TFun (args,ret) -> is_dynamic_in_cpp ctx func | _ -> true ); | TParenthesis(expr) | TMeta(_,expr) -> is_dynamic_in_cpp ctx expr | TCast (e,None) -> (type_string expr.etype) = "Dynamic" | TLocal { v_name = "__global__" } -> false | TConst TNull -> true | _ -> false (* others ? *) ) in result end and is_dynamic_member_lookup_in_cpp ctx field_object field = let member = field_name field in if (is_internal_member member) then false else if (is_native_pointer field_object) then false else if (is_pointer field_object.etype true) then false else if (match field_object.eexpr with | TTypeExpr _ -> true | _ -> false) then false else if (is_dynamic_in_cpp ctx field_object) then true else if (is_array field_object.etype) then false else ( let tstr = type_string field_object.etype in match tstr with (* Internal classes have no dynamic members *) | "::String" | "Null" | "::hx::Class" | "::Enum" | "::Math" | "::ArrayAccess" -> false | "Dynamic" -> true | name -> let full_name = name ^ "." ^ member in if Hashtbl.mem ctx.ctx_class_member_types full_name then false else not (is_extern_class_instance field_object) ) and is_dynamic_member_return_in_cpp ctx field_object field = let member = field_name field in if (is_array field_object.etype) then false else if (is_pointer field_object.etype true) then false else if (is_internal_member member) then false else match field_object.eexpr with | TTypeExpr t -> let full_name = "::" ^ (join_class_path_remap (t_path t) "::" ) ^ "." ^ member in ( try ( let mem_type = (Hashtbl.find ctx.ctx_class_member_types full_name) in mem_type="Dynamic" || mem_type="cpp::ArrayBase" || mem_type="cpp::VirtualArray" ) with Not_found -> true ) | _ -> let tstr = type_string field_object.etype in (match tstr with (* Internal classes have no dynamic members *) | "::String" | "Null" | "::hx::Class" | "::Enum" | "::Math" | "::ArrayAccess" -> false | "Dynamic" | "cpp::ArrayBase" | "cpp::VirtualArray" -> true | name -> let full_name = name ^ "." ^ member in try ( let mem_type = (Hashtbl.find ctx.ctx_class_member_types full_name) in mem_type="Dynamic" || mem_type="cpp::ArrayBase" || mem_type="cpp::VirtualArray" ) with Not_found -> true ) and is_dynamic_in_cppia ctx expr = match expr.eexpr with | TCast(_,None) -> true | _ -> is_dynamic_in_cpp ctx expr ;; let cast_if_required ctx expr to_type = if (is_dynamic_in_cpp ctx expr) then ctx.ctx_output (".Cast< " ^ to_type ^ " >()" ) ;; let is_matching_interface_type t0 t1 = (match (follow t0),(follow t1) with | TInst (k0,_), TInst(k1,_) -> k0==k1 | _ -> false ) ;; let default_value_string = function | TInt i -> Printf.sprintf "%ld" i | TFloat float_as_string -> "((Float)" ^ float_as_string ^ ")" | TString s -> str s | TBool b -> (if b then "true" else "false") | TNull -> "null()" | _ -> "/* Hmmm */" ;; let get_nth_type field index = match follow field.ef_type with | TFun (args,_) -> let rec nth l index = match l with | [] -> raise Not_found | (_,_,t)::rest -> if index = 0 then t else nth rest (index-1) in nth args index | _ -> raise Not_found ;; let has_default_values args = List.exists ( fun (_,o) -> match o with | Some TNull -> false | Some _ -> true | _ -> false ) args ;; exception PathFound of string;; let strip_file ctx file = (match Common.defined ctx Common.Define.AbsolutePath with | true -> file | false -> let flen = String.length file in (* Not quite right - should probably test is file exists *) try List.iter (fun path -> let plen = String.length path in if (flen>plen && path=(String.sub file 0 plen )) then raise (PathFound (String.sub file plen (flen-plen)) ) ) (ctx.class_path @ ctx.std_path); file; with PathFound tail -> tail) ;; let hx_stack_push ctx output clazz func_name pos gc_stack = if ctx.ctx_debug_level > 0 then begin let stripped_file = strip_file ctx.ctx_common pos.pfile in let esc_file = (Ast.s_escape stripped_file) in ctx.ctx_file_info := PMap.add stripped_file pos.pfile !(ctx.ctx_file_info); let full_name = clazz ^ "." ^ func_name ^ ( if (clazz="*") then (" (" ^ esc_file ^ ":" ^ (string_of_int (Lexer.get_error_line pos) ) ^ ")") else "") in let hash_class_func = gen_hash 0 (clazz^"."^func_name) in let hash_file = gen_hash 0 stripped_file in let lineName = (string_of_int (Lexer.get_error_line pos) ) in incr ctx.ctx_file_id; let classId = hash64 (clazz ^ "." ^ stripped_file) in let varName = "_hx_pos_" ^ classId ^ "_" ^ lineName ^ "_" ^func_name in let decl = ( varName ^ ",\"" ^ clazz ^ "\",\"" ^ func_name ^ "\"," ^ hash_class_func ^ ",\"" ^ full_name ^ "\",\"" ^ esc_file ^ "\"," ^ lineName ^ "," ^ hash_file ) in if ctx.ctx_is_header then ctx.ctx_writer#write_h_unique ("HX_DECLARE_STACK_FRAME" ^ "(" ^ varName ^ ")\n") else ctx.ctx_writer#write_h_unique ( (if func_name="new" then "HX_DEFINE_STACK_FRAME" else "HX_LOCAL_STACK_FRAME") ^ "(" ^ decl ^ ")\n"); output ( (if gc_stack then "HX_GC_STACKFRAME" else "HX_STACKFRAME") ^ "(&" ^ varName ^ ")\n"); end else if gc_stack then output ("HX_JUST_GC_STACKFRAME\n") ;; (* { *) type tcpp = | TCppDynamic | TCppUnchanged | TCppObject | TCppObjectPtr | TCppVoid | TCppNull | TCppEnum of tenum | TCppScalar of string | TCppString | TCppFastIterator of tcpp | TCppPointer of string * tcpp | TCppRawPointer of string * tcpp | TCppFunction of tcpp list * tcpp * string | TCppObjCBlock of tcpp list * tcpp | TCppRest of tcpp | TCppReference of tcpp | TCppStruct of tcpp | TCppStar of tcpp * bool | TCppVoidStar | TCppVarArg | TCppAutoCast | TCppDynamicArray | TCppObjectArray of tcpp | TCppWrapped of tcpp | TCppScalarArray of tcpp | TCppObjC of tclass | TCppNativePointer of tclass | TCppVariant | TCppCode of tcpp | TCppInst of tclass | TCppInterface of tclass | TCppProtocol of tclass | TCppClass | TCppGlobal and tcppexpr = { cppexpr : tcpp_expr_expr; cpptype : tcpp; cpppos : pos; } and tcpp_closure = { close_type : tcpp; close_args : (tvar * tconstant option) list; close_expr : tcppexpr; close_id : int; close_undeclared : (string,tvar) Hashtbl.t; close_this : tcppthis option; } and tcppcrementop = | CppIncrement | CppDecrement and tcppunop = | CppNeg | CppNegBits | CppNot and tcppthis = | ThisReal | ThisFake | ThisDynamic and tcppvarloc = | VarLocal of tvar | VarClosure of tvar | VarThis of tclass_field | VarInstance of tcppexpr * tclass_field * string * string | VarInterface of tcppexpr * tclass_field | VarStatic of tclass * bool * tclass_field | VarInternal of tcppexpr * string * string and tcppinst = | InstPtr | InstObjC | InstStruct and tcppfuncloc = | FuncThis of tclass_field | FuncInstance of tcppexpr * tcppinst * tclass_field | FuncStatic of tclass * bool * tclass_field | FuncTemplate of tclass * tclass_field * path * bool | FuncInterface of tcppexpr * tclass * tclass_field | FuncEnumConstruct of tenum * tenum_field | FuncSuperConstruct | FuncSuper of tcppthis * tclass_field | FuncNew of tcpp | FuncExpression of tcppexpr | FuncInternal of tcppexpr * string * string | FuncGlobal of string | FuncFromStaticFunction and tcpparrayloc = | ArrayTyped of tcppexpr * tcppexpr | ArrayPointer of tcppexpr * tcppexpr | ArrayRawPointer of tcppexpr * tcppexpr | ArrayObject of tcppexpr * tcppexpr * tcpp | ArrayVirtual of tcppexpr * tcppexpr | ArrayImplements of tclass * tcppexpr * tcppexpr | ArrayDynamic of tcppexpr * tcppexpr and tcpplvalue = | CppVarRef of tcppvarloc | CppArrayRef of tcpparrayloc | CppDynamicRef of tcppexpr * string | CppGlobalRef of string and tcpp_expr_expr = | CppInt of int32 | CppFloat of string | CppString of string | CppBool of bool | CppNull | CppNullAccess | CppNil | CppThis of tcppthis | CppSuper of tcppthis | CppCode of string * tcppexpr list | CppClosure of tcpp_closure | CppVar of tcppvarloc | CppGlobal of string | CppDynamicField of tcppexpr * string | CppFunction of tcppfuncloc * tcpp | CppEnumIndex of tcppexpr | CppEnumField of tenum * tenum_field | CppCall of tcppfuncloc * tcppexpr list | CppFunctionAddress of tclass * tclass_field | CppAddressOf of tcppexpr | CppDereference of tcppexpr | CppArray of tcpparrayloc | CppCrement of tcppcrementop * Ast.unop_flag * tcpplvalue | CppSet of tcpplvalue * tcppexpr | CppModify of Ast.binop * tcpplvalue * tcppexpr | CppBinop of Ast.binop * tcppexpr * tcppexpr | CppCompare of string * tcppexpr * tcppexpr | CppNullCompare of string * tcppexpr | CppObjectDecl of (string * tcppexpr) list * bool | CppPosition of string * int32 * string * string | CppArrayDecl of tcppexpr list | CppUnop of tcppunop * tcppexpr | CppVarDecl of tvar * tcppexpr option | CppBlock of tcppexpr list * tcpp_closure list * bool | CppFor of tvar * tcppexpr * tcppexpr | CppIf of tcppexpr * tcppexpr * tcppexpr option | CppWhile of tcppexpr * tcppexpr * Ast.while_flag * int | CppIntSwitch of tcppexpr * (Int32.t list * tcppexpr) list * tcppexpr option | CppSwitch of tcppexpr * tcpp * (tcppexpr list * tcppexpr) list * tcppexpr option * int | CppTry of tcppexpr * (tvar * tcppexpr) list | CppBreak | CppContinue | CppClassOf of path * bool | CppGoto of int | CppReturn of tcppexpr option | CppThrow of tcppexpr | CppEnumParameter of tcppexpr * tenum_field * int | CppTCast of tcppexpr * tcpp | CppCast of tcppexpr * tcpp | CppCastStatic of tcppexpr * tcpp | CppCastScalar of tcppexpr * string | CppCastVariant of tcppexpr | CppCastObjC of tcppexpr * tclass | CppCastObjCBlock of tcppexpr * tcpp list * tcpp | CppCastProtocol of tcppexpr * tclass | CppCastNative of tcppexpr let rec s_tcpp = function | CppInt _ -> "CppInt" | CppFloat _ -> "CppFloat" | CppString _ -> "CppString" | CppBool _ -> "CppBool" | CppNull -> "CppNull" | CppNil -> "CppNil" | CppThis _ -> "CppThis" | CppSuper _ -> "CppSuper" | CppCode _ -> "CppCode" | CppClosure _ -> "CppClosure" | CppVar VarLocal(_) -> "CppVarLocal" | CppVar VarClosure(_) -> "CppVarClosure" | CppVar VarThis(_) -> "CppVarThis" | CppVar VarInstance(expr,field,clazz,op) -> "CppVarInstance(" ^ clazz ^ "::" ^ op ^ field.cf_name ^ ")" | CppVar VarInterface(_) -> "CppVarInterface" | CppVar VarStatic(_,true,_) -> "CppObjcVarStatic" | CppVar VarStatic(_) -> "CppVarStatic" | CppVar VarInternal(_) -> "CppVarInternal" | CppDynamicField _ -> "CppDynamicField" | CppGlobal _ -> "CppGlobal" | CppFunction _ -> "CppFunction" | CppEnumIndex _ -> "CppEnumIndex" | CppEnumField _ -> "CppEnumField" | CppNullAccess -> "CppNullAccess" | CppCall (FuncThis _,_) -> "CppCallThis" | CppCall (FuncInstance (obj,inst,field),_) -> (match inst with InstObjC -> "CppCallObjCInstance(" | InstPtr-> "CppCallInstance(" | _ -> "CppCallStruct(") ^ tcpp_to_string obj.cpptype ^ "," ^ field.cf_name ^ ")" | CppCall (FuncInterface _,_) -> "CppCallInterface" | CppCall (FuncStatic (_,objC,_),_) -> if objC then "CppCallStaticObjC" else "CppCallStatic" | CppCall (FuncTemplate _,_) -> "CppCallTemplate" | CppCall (FuncEnumConstruct _,_) -> "CppCallEnumConstruct" | CppCall (FuncSuperConstruct,_) -> "CppCallSuperConstruct" | CppCall (FuncSuper _,_) -> "CppCallSuper" | CppCall (FuncNew _,_) -> "CppCallNew" | CppCall (FuncExpression _,_) -> "CppCallExpression" | CppCall (FuncInternal _,_) -> "CppCallInternal" | CppCall (FuncGlobal _,_) -> "CppCallGlobal" | CppCall (FuncFromStaticFunction,_) -> "CppCallFromStaticFunction" | CppAddressOf _ -> "CppAddressOf" | CppDereference _ -> "CppDereference" | CppFunctionAddress _ -> "CppFunctionAddress" | CppArray _ -> "CppArray" | CppCrement _ -> "CppCrement" | CppSet _ -> "CppSet" | CppModify _ -> "CppModify" | CppBinop _ -> "CppBinop" | CppCompare _ -> "CppCompare" | CppNullCompare _ -> "CppNullCompare" | CppObjectDecl _ -> "CppObjectDecl" | CppPosition _ -> "CppPosition" | CppArrayDecl _ -> "CppArrayDecl" | CppUnop _ -> "CppUnop" | CppVarDecl _ -> "CppVarDecl" | CppBlock _ -> "CppBlock" | CppFor _ -> "CppFor" | CppIf _ -> "CppIf" | CppWhile _ -> "CppWhile" | CppIntSwitch _ -> "CppIntSwitch" | CppSwitch _ -> "CppSwitch" | CppTry _ -> "CppTry" | CppBreak -> "CppBreak" | CppContinue -> "CppContinue" | CppClassOf _ -> "CppClassOf" | CppGoto _ -> "CppGoto" | CppReturn _ -> "CppReturn" | CppThrow _ -> "CppThrow" | CppEnumParameter _ -> "CppEnumParameter" | CppTCast _ -> "CppTCast" | CppCast _ -> "CppCast" | CppCastStatic _ -> "CppCastStatic" | CppCastScalar _ -> "CppCastScalar" | CppCastVariant _ -> "CppCastVariant" | CppCastObjC _ -> "CppCastObjC" | CppCastObjCBlock _ -> "CppCastObjCBlock" | CppCastProtocol _ -> "CppCastProtocol" | CppCastNative _ -> "CppCastNative" and tcpp_to_string_suffix suffix tcpp = match tcpp with | TCppDynamic -> " ::Dynamic" | TCppUnchanged -> " ::Dynamic/*Unchanged*/" | TCppObject -> " ::Dynamic" | TCppObjectPtr -> " ::hx::Object *" | TCppReference t -> (tcpp_to_string t) ^" &" | TCppStruct t -> "cpp::Struct< " ^ (tcpp_to_string t) ^" >" | TCppStar(t,const) -> (if const then "const " else "" ) ^ (tcpp_to_string t) ^" *" | TCppVoid -> "void" | TCppVoidStar -> "void *" | TCppRest _ -> "vaarg_list" | TCppVarArg -> "vararg" | TCppAutoCast -> "::cpp::AutoCast" | TCppVariant -> "::cpp::Variant" | TCppEnum(enum) -> " ::" ^ (join_class_path_remap enum.e_path "::") ^ suffix | TCppScalar(scalar) -> scalar | TCppString -> "::String" | TCppFastIterator it -> "::cpp::FastIterator" ^ suffix ^ "< " ^ (tcpp_to_string it) ^ " >"; | TCppPointer(ptrType,valueType) -> "::cpp::" ^ ptrType ^ "< " ^ (tcpp_to_string valueType) ^ " >" | TCppRawPointer(constName,valueType) -> constName ^ (tcpp_to_string valueType) ^ "*" | TCppFunction(argTypes,retType,abi) -> let args = (String.concat "," (List.map tcpp_to_string argTypes)) in "::cpp::Function< " ^ (tcpp_to_string retType) ^ " " ^ abi ^ " (" ^ args ^ ") >" | TCppObjCBlock(argTypes,retType) -> (tcpp_objc_block_struct argTypes retType) ^ "::t" | TCppDynamicArray -> "::cpp::VirtualArray" ^ suffix | TCppObjectArray _ -> "::Array" ^ suffix ^ "< ::Dynamic>" | TCppWrapped _ -> " ::Dynamic" | TCppScalarArray(value) -> "::Array" ^ suffix ^ "< " ^ (tcpp_to_string value) ^ " >" | TCppObjC klass -> let path = join_class_path_remap klass.cl_path "::" in if klass.cl_interface then "id < " ^ path ^ ">" else path ^ " *" | TCppProtocol interface -> let path = get_meta_string interface.cl_meta Meta.ObjcProtocol in let path = if path<>"" then path else join_class_path_remap interface.cl_path "::" in "id < " ^ path ^ ">" | TCppNativePointer klass -> let name = (join_class_path_remap klass.cl_path "::") in if suffix="_obj" then name else "hx::Native< " ^ name ^ "* >"; | TCppInst klass -> (cpp_class_path_of klass) ^ suffix | TCppInterface klass when suffix="_obj" -> (cpp_class_path_of klass) ^ suffix | TCppInterface _ -> "::Dynamic" | TCppClass -> "hx::Class" ^ suffix; | TCppGlobal -> ""; | TCppNull -> " ::Dynamic"; | TCppCode _ -> "Code" and tcpp_objc_block_struct argTypes retType = let args = (String.concat "," (List.map tcpp_to_string argTypes)) in let ret = tcpp_to_string retType in let suffix = (string_of_int (List.length argTypes)) in if (ret="void") then begin if (List.length argTypes) = 0 then "hx::TObjcBlockVoidVoid" else "hx::TObjcBlockVoidArgs" ^ suffix ^ "< " ^ args ^ " >" end else begin if (List.length argTypes) = 0 then "hx::TObjcBlockRetVoid< " ^ ret ^ " >" else "hx::TObjcBlockRetArgs" ^ suffix ^ "< " ^ ret ^ "," ^ args ^ " >" end and tcpp_to_string tcpp = tcpp_to_string_suffix "" tcpp and cpp_class_path_of klass = let globalNamespace = if (get_meta_string klass.cl_meta Meta.Native)<>"" then " " else " ::" in globalNamespace ^ (join_class_path_remap klass.cl_path "::") ;; let cpp_const_type cval = match cval with | TInt i -> CppInt(i) , TCppScalar("int") | TBool b -> CppBool(b) , TCppScalar("bool") | TFloat f -> CppFloat(f) , TCppScalar("Float") | TString s -> CppString(s) , TCppString | _ -> (* TNull, TThis & TSuper should already be handled *) CppNull, TCppNull ;; let is_cpp_scalar cpp_type = match cpp_type with | TCppScalar(_) -> true | _ -> false ;; let is_cpp_array_implementer cppType = match cppType with | TCppInst (klass) | TCppInterface (klass) -> (match klass.cl_array_access with | Some _ -> true | _ -> false ) | _ -> false ;; let rec const_int_of expr = match expr.eexpr with | TConst TInt x -> x | TConst TBool x -> Int32.of_int (if x then 1 else 0) | TParenthesis e -> const_int_of e | _ -> raise Not_found ;; let rec const_float_of expr = match expr.eexpr with | TConst TInt x -> Printf.sprintf "%ld" x | TConst TFloat x -> x | TConst TBool x -> if x then "1" else "0" | TParenthesis e -> const_float_of e | _ -> raise Not_found ;; let rec const_string_of expr = match expr.eexpr with | TConst TString x -> x | TParenthesis e -> const_string_of e | _ -> raise Not_found ;; let rec cpp_is_struct_access t = match t with | TCppFunction _ -> true | TCppStruct _-> false | TCppInst (class_def) -> (has_meta_key class_def.cl_meta Meta.StructAccess) | TCppReference (r) -> cpp_is_struct_access r | _ -> false ;; let cpp_is_dynamic_type = function | TCppDynamic | TCppObject | TCppVariant | TCppWrapped _ | TCppGlobal | TCppNull | TCppInterface _ -> true | _ -> false ;; let rec cpp_type_of ctx haxe_type = (match haxe_type with | TMono r -> (match !r with None -> TCppDynamic | Some t -> cpp_type_of ctx t) | TEnum (enum,params) -> TCppEnum(enum) | TInst ({ cl_path=([],"Array"); cl_kind = KTypeParameter _},_) -> TCppObject | TInst ({ cl_kind = KTypeParameter _},_) -> TCppDynamic | TInst (klass,params) -> cpp_instance_type ctx klass params | TAbstract (abs,pl) when not (Meta.has Meta.CoreType abs.a_meta) -> cpp_type_from_path ctx abs.a_path pl (fun () -> cpp_type_of ctx (Abstract.get_underlying_type abs pl) ) | TAbstract (a,params) -> cpp_type_from_path ctx a.a_path params (fun () -> if is_scalar_abstract a then begin let native = get_meta_string a.a_meta Meta.Native in TCppScalar(if native="" then join_class_path a.a_path "::" else native) end else TCppDynamic) | TType (type_def,params) -> cpp_type_from_path ctx type_def.t_path params (fun () -> cpp_type_of ctx (apply_params type_def.t_params params type_def.t_type) ) | TFun _ -> TCppObject | TAnon _ -> TCppObject | TDynamic _ -> TCppDynamic | TLazy func -> cpp_type_of ctx ((!func)()) ) and cpp_type_from_path ctx path params default = match path,params with | ([],"Void"),_ -> TCppVoid | ([],"void"),_ -> TCppVoid (* for old code with @:void *) | ([],"Bool"),_ -> TCppScalar("bool") | ([],"Float"),_ -> TCppScalar("Float") | ([],"Int"),_ -> TCppScalar("int") | ([], "EnumValue"),_ -> TCppObject | ([], "Class"),_ -> TCppClass | ([], "Enum"),_ -> TCppClass | (["cpp"], "Char"),_ -> TCppScalar("char") | (["cpp"], "Object"),_ -> TCppObjectPtr | (["cpp"], "Float32"),_ -> TCppScalar("float") | (["cpp"], "Float64"),_ -> TCppScalar("double") | (["cpp"], "Int8"),_ -> TCppScalar("signed char") | (["cpp"], "Int16"),_ -> TCppScalar("short") | (["cpp"], "Int32"),_ -> TCppScalar("int") | (["cpp"], "Int64"),_ -> TCppScalar("::cpp::Int64") | (["cpp"], "UInt8"),_ -> TCppScalar("unsigned char") | (["cpp"], "UInt16"),_ -> TCppScalar("unsigned short") | (["cpp"], "UInt32"),_ -> TCppScalar("unsigned int") | (["cpp"], "UInt64"),_ -> TCppScalar("::cpp::UInt64") | (["cpp"], "VarArg"),_ -> TCppVarArg | (["cpp"], "AutoCast"),_ -> TCppAutoCast | ([],"String"), [] -> TCppString (* Things with type parameters hxcpp knows about ... *) | (["cpp"],"FastIterator"), [p] -> TCppFastIterator(cpp_type_of ctx p) | (["cpp"],"Pointer"), [p] -> TCppPointer("Pointer", cpp_type_of ctx p) | (["cpp"],"ConstPointer"), [p] -> TCppPointer("ConstPointer", cpp_type_of ctx p) | (["cpp"],"RawPointer"), [p] -> TCppRawPointer("", cpp_type_of ctx p) | (["cpp"],"RawConstPointer"), [p] -> TCppRawPointer("const ", cpp_type_of ctx p) | (["cpp"],"Function"), [function_type; abi] -> cpp_function_type_of ctx function_type abi; | (["cpp"],"Callable"), [function_type] | (["cpp"],"CallableData"), [function_type] -> cpp_function_type_of_string ctx function_type ""; | (("cpp"::["objc"]),"ObjcBlock"), [function_type] -> let args,ret = (cpp_function_type_of_args_ret ctx function_type) in TCppObjCBlock(args,ret) | (["haxe";"extern"], "Rest"),[rest] -> TCppRest(cpp_type_of ctx rest) | (("cpp"::["objc"]),"Protocol"), [interface_type] -> (match follow interface_type with | TInst (klass,[]) when klass.cl_interface -> TCppProtocol(klass) (* TODO - get the line number here *) | _ -> print_endline "cpp.objc.Protocol must refer to an interface"; assert false; ) | (["cpp"],"Reference"), [param] -> TCppReference(cpp_type_of ctx param) | (["cpp"],"Struct"), [param] -> TCppStruct(cpp_type_of ctx param) | (["cpp"],"Star"), [param] -> TCppStar(cpp_type_of ctx param,false) | (["cpp"],"ConstStar"), [param] -> TCppStar(cpp_type_of ctx param,true) | ([],"Array"), [p] -> let arrayOf = cpp_type_of ctx p in (match arrayOf with | TCppVoid (* ? *) | TCppDynamic -> TCppDynamicArray | TCppObject | TCppObjectPtr | TCppReference _ | TCppStruct _ | TCppStar _ | TCppEnum _ | TCppInst _ | TCppInterface _ | TCppProtocol _ | TCppClass | TCppDynamicArray | TCppObjectArray _ | TCppScalarArray _ -> TCppObjectArray(arrayOf) | _ -> TCppScalarArray(arrayOf) ) | ([],"Null"), [p] -> cpp_type_of_null ctx p | _ -> default () and cpp_type_of_null ctx p = let baseType = cpp_type_of ctx p in if (type_has_meta_key p Meta.NotNull) || (is_cpp_scalar baseType) then TCppObject else baseType (* Optional types are Dynamic if they norally could not be null *) and cpp_fun_arg_type_of ctx tvar opt = match opt with | Some _ -> cpp_type_of_null ctx tvar.t_type | _ -> cpp_type_of ctx tvar.t_type and cpp_tfun_arg_type_of ctx opt t = if opt then cpp_type_of_null ctx t else cpp_type_of ctx t and cpp_function_type_of ctx function_type abi = let abi = (match follow abi with | TInst (klass1,_) -> get_meta_string klass1.cl_meta Meta.Abi | _ -> assert false ) in cpp_function_type_of_string ctx function_type abi and cpp_function_type_of_string ctx function_type abi_string = let args,ret = cpp_function_type_of_args_ret ctx function_type in TCppFunction(args, ret, abi_string) and cpp_function_type_of_args_ret ctx function_type = match follow function_type with | TFun(args,ret) -> (* Optional types are Dynamic if they norally could not be null *) let cpp_arg_type_of = fun(_,optional,haxe_type) -> if optional then cpp_type_of_null ctx haxe_type else cpp_type_of ctx haxe_type in List.map cpp_arg_type_of args, cpp_type_of ctx ret | _ -> (* ? *) [TCppVoid], TCppVoid and cpp_instance_type ctx klass params = cpp_type_from_path ctx klass.cl_path params (fun () -> if is_objc_class klass then TCppObjC(klass) else if klass.cl_interface && is_native_gen_class klass then TCppNativePointer(klass) else if klass.cl_interface then TCppInterface(klass) else if klass.cl_extern && (not (is_internal_class klass.cl_path) ) then TCppInst(klass) else TCppInst(klass) ) ;; let cpp_return_type ctx haxe_type = match haxe_type with | TFun (_,ret) -> cpp_type_of ctx ret | _ -> TCppDynamic ;; let cpp_member_return_type ctx member = cpp_return_type ctx member.cf_type ;; let is_cpp_objc_type cpptype = match cpptype with | TCppObjC(_) -> true; | _ -> false ;; let cpp_enum_path_of enum = (* let rename = get_meta_string enum.e_meta Meta.Native in if rename <> "" then rename else *) let globalNamespace = if (get_meta_string enum.e_meta Meta.Native)<>"" then "" else "::" in globalNamespace ^ (join_class_path_remap enum.e_path "::") ;; (* let rec cpp_object_name = function | TCppString -> "::String" | TCppDynamicArray -> "::cpp::VirtualArray_obj" | TCppObjectArray _ -> "::Array_obj< ::Dynamic>" | TCppScalarArray(value) -> "::Array_obj< " ^ (tcpp_to_string value) ^ " >" | TCppObjC klass -> (cpp_class_path_of klass) ^ "_obj" | TCppInst klass -> (cpp_class_path_of klass) ^ "_obj" | TCppClass -> "hx::Class_obj"; | TCppDynamic -> "Dynamic" | TCppVoid -> "void" | TCppVoidStar -> "void *" | TCppEnum(enum) -> "::hx::EnumBase" | TCppScalar(scalar) -> scalar | TCppFastIterator it -> "::cpp::FastIterator< " ^ (tcpp_to_string it) ^ " >"; | TCppPointer(ptrType,valueType) -> "::cpp::" ^ ptrType ^ "< " ^ (tcpp_to_string valueType) ^ " >" | TCppRawPointer(constName,valueType) -> constName ^ (tcpp_to_string valueType) ^ "*" | TCppFunction(argTypes,retType,abi) -> let args = (String.concat "," (List.map tcpp_to_string argTypes)) in "::cpp::Function< " ^ abi ^ " " ^ (tcpp_to_string retType) ^ "(" ^ args ^ ") >" | TCppWrapped _ -> "Dynamic" | TCppNativePointer klass -> (cpp_class_path_of klass) ^ " *" | TCppGlobal -> ""; | TCppNull -> "Dynamic"; | TCppCode -> "/* code */" ;; *) let cpp_class_name klass = (* let rename = get_meta_string klass.cl_meta Meta.Native in if rename <> "" then rename ^ "_obj" else *) let globalNamespace = if (get_meta_string klass.cl_meta Meta.Native)<>"" then "" else "::" in let path = globalNamespace ^ (join_class_path_remap klass.cl_path "::") in if path="::String" then path else path ^ "_obj" ;; let cpp_variant_type_of t = match t with | TCppDynamic | TCppUnchanged | TCppObject | TCppObjectPtr | TCppReference _ | TCppStruct _ | TCppStar _ | TCppVoid | TCppFastIterator _ | TCppDynamicArray | TCppObjectArray _ | TCppScalarArray _ | TCppWrapped _ | TCppObjC _ | TCppObjCBlock _ | TCppRest _ | TCppInst _ | TCppInterface _ | TCppProtocol _ | TCppCode _ | TCppClass | TCppGlobal | TCppNull | TCppEnum _ -> TCppDynamic | TCppString -> TCppString | TCppFunction _ | TCppNativePointer _ | TCppPointer _ | TCppRawPointer _ | TCppAutoCast | TCppVarArg | TCppVoidStar -> TCppVoidStar | TCppScalar "Int" | TCppScalar "bool" | TCppScalar "Float" -> t | TCppScalar "double" | TCppScalar "float" -> TCppScalar("Float") | TCppScalar _ -> TCppScalar("int") | TCppVariant -> TCppVariant ;; let cpp_cast_variant_type_of t = match t with | TCppObjectArray _ | TCppScalarArray _ | TCppDynamicArray | TCppClass | TCppEnum _ | TCppInst _ -> t | _ -> cpp_variant_type_of t; ;; let cpp_base_type_of t = match cpp_variant_type_of t with | TCppDynamic -> "Object" | TCppString -> "String" | TCppVoidStar -> "Pointer" | TCppScalar "int" -> "Int" | TCppScalar "bool" -> "Bool" | TCppScalar x -> x | _ -> "Object" ;; let ctx_type_string ctx haxe_type = tcpp_to_string (cpp_type_of ctx haxe_type) ;; let ctx_cant_be_null ctx haxe_type = match cpp_type_of ctx haxe_type with | TCppScalar _ -> true | _ -> false let is_complex_compare = function | TCppScalar _ -> false | TCppString -> false | _ -> true ;; let ctx_arg_type_name ctx name default_val arg_type prefix = let remap_name = keyword_remap name in let type_str = (ctx_type_string ctx arg_type) in match default_val with | Some TNull -> (type_str,remap_name) | Some constant when (ctx_cant_be_null ctx arg_type) -> ("hx::Null< " ^ type_str ^ " > ",prefix ^ remap_name) | Some constant -> (type_str,prefix ^ remap_name) | _ -> (type_str,remap_name);; (* Generate prototype text, including allowing default values to be null *) let ctx_arg ctx name default_val arg_type prefix = let pair = ctx_arg_type_name ctx name default_val arg_type prefix in (fst pair) ^ " " ^ (snd pair);; (* Generate prototype text, including allowing default values to be null *) let ctx_arg_name ctx name default_val arg_type prefix = let pair = ctx_arg_type_name ctx name default_val arg_type prefix in (snd pair);; let ctx_arg_list ctx arg_list prefix = String.concat "," (List.map (fun (v,o) -> (ctx_arg ctx v.v_name o v.v_type prefix) ) arg_list) let ctx_arg_list_name ctx arg_list prefix = String.concat "," (List.map (fun (v,o) -> (ctx_arg_name ctx v.v_name o v.v_type prefix) ) arg_list) let cpp_arg_names args = String.concat "," (List.map (fun (name,_,_) -> keyword_remap name) args) ;; let rec ctx_tfun_arg_list ctx include_names arg_list = let oType o arg_type = let type_str = (ctx_type_string ctx arg_type) in (* type_str may have already converted Null to Dynamic because of NotNull tag ... *) if o && (ctx_cant_be_null ctx arg_type) && type_str<>"Dynamic" then "hx::Null< " ^ type_str ^ " > " else type_str in match arg_list with | [] -> "" | [(name,o,arg_type)] -> (oType o arg_type) ^ (if include_names then " " ^ (keyword_remap name) else "") | (name,o,arg_type) :: remaining -> (oType o arg_type) ^ (if include_names then " " ^ (keyword_remap name) else "") ^ "," ^ (ctx_tfun_arg_list ctx include_names remaining) let cpp_var_type_of ctx var = tcpp_to_string (cpp_type_of ctx var.v_type) ;; let cpp_macro_var_type_of ctx var = let t = tcpp_to_string (cpp_type_of ctx var.v_type) in if String.contains t ',' then Str.global_replace (Str.regexp ",") " HX_COMMA " t else t ;; let ctx_function_signature ctx include_names tfun abi = match follow tfun with | TFun(args,ret) -> (ctx_type_string ctx ret) ^ " " ^ abi ^ "(" ^ (ctx_tfun_arg_list ctx include_names args) ^ ")" | _ -> "void *" let cpp_var_name_of var = let rename = get_meta_string var.v_meta Meta.Native in if rename <> "" then rename else keyword_remap var.v_name ;; let cpp_var_debug_name_of v = let rec loop meta = match meta with | (Meta.RealPath,[EConst (String s),_],_) :: _ -> s | _ :: meta -> loop meta | [] -> v.v_name in loop v.v_meta ;; let cpp_no_debug_synbol ctx var = (ctx.ctx_debug_level<=1) || (has_meta_key var.v_meta Meta.CompilerGenerated) || match cpp_type_of ctx var.v_type with | TCppStar _ | TCppReference _ -> true | TCppInst (class_def) when (has_meta_key class_def.cl_meta Meta.StructAccess) -> true | TCppInst (class_def) when (has_meta_key class_def.cl_meta Meta.Unreflective) -> true | _-> let name = cpp_var_debug_name_of var in (String.length name) >4 && (String.sub name 0 4) = "_hx_" ;; let cpp_debug_name_of var = keyword_remap var.v_name ;; let cpp_debug_var_visible ctx var = not (cpp_no_debug_synbol ctx (fst var)) ;; let only_stack_access ctx haxe_type = let tcpp = cpp_type_of ctx haxe_type in match tcpp with | TCppInst(klass) -> has_meta_key klass.cl_meta Meta.StackOnly | _ -> false; ;; let cpp_is_real_array obj = match obj.cpptype with | TCppScalarArray _ | TCppObjectArray _ -> true | _ -> false ;; let is_array_splice_call obj member = match obj.cpptype, member.cf_name with | TCppScalarArray _, "splice" | TCppObjectArray _, "splice" -> true | _,_ -> false ;; let cpp_can_static_cast funcType inferredType = match funcType with | TCppReference(_) | TCppStar(_) | TCppStruct(_) -> false | _ -> (match inferredType with | TCppInst _ | TCppClass | TCppEnum _ -> (tcpp_to_string funcType) <> (tcpp_to_string inferredType) | _ -> false ) ;; let cpp_member_name_of member = let rename = get_meta_string member.cf_meta Meta.Native in if rename <> "" then rename else keyword_remap member.cf_name ;; let cpp_is_templated_call ctx member = has_meta_key member.cf_meta Meta.TemplatedCall ;; let cpp_is_static_extension ctx member = has_meta_key member.cf_meta Meta.NativeStaticExtension ;; let cpp_template_param path native = let path = "::" ^ (join_class_path_remap (path) "::" ) in if (native) then path else match path with | "::Array" -> "hx::ArrayBase" | "::Int" -> "int" | "::Bool" -> "bool" | x -> x ;; let cpp_append_block block expr = match block.cppexpr with | CppBlock(expr_list, closures, gc_stack) -> { block with cppexpr = CppBlock( expr_list @ [expr], closures, gc_stack) } | _ -> abort "Internal error appending expression" block.cpppos ;; let cpp_enum_name_of field = let rename = get_meta_string field.ef_meta Meta.Native in if rename <> "" then rename else keyword_remap field.ef_name ;; let is_gc_element ctx member_type = Common.defined ctx.ctx_common Define.HxcppGcGenerational && match member_type with | TCppDynamic | TCppObject | TCppObjectPtr | TCppEnum _ | TCppString | TCppFunction _ | TCppDynamicArray | TCppObjectArray _ | TCppWrapped _ | TCppScalarArray _ | TCppInst _ | TCppInterface _ | TCppClass -> true | _ -> false ;; let retype_expression ctx request_type function_args function_type expression_tree forInjection = let rev_closures = ref [] in let closureId = ref 0 in let declarations = ref (Hashtbl.create 0) in let undeclared = ref (Hashtbl.create 0) in let uses_this = ref None in let gc_stack = ref false in let injection = ref forInjection in let this_real = ref (if ctx.ctx_real_this_ptr then ThisReal else ThisDynamic) in let file_id = ctx.ctx_file_id in let function_return_type = ref (cpp_type_of ctx function_type) in let loop_stack = ref [] in let alloc_file_id () = incr file_id; !file_id in let begin_loop () = loop_stack := (alloc_file_id (),ref false) :: !loop_stack; (fun () -> match !loop_stack with | (label_id,used) :: tl -> loop_stack := tl; if !used then label_id else -1 | [] -> abort "Invalid inernal loop handling" expression_tree.epos ) in (* '__trace' is at the top-level *) Hashtbl.add !declarations "__trace" (); List.iter (fun arg -> Hashtbl.add !declarations arg.v_name () ) function_args; let rec to_lvalue value = match value.cppexpr with | CppVar( VarClosure(var) as varloc) when is_gc_element ctx (cpp_type_of ctx var.v_type) -> CppVarRef(varloc), true | CppVar( VarThis(member) as varloc) when is_gc_element ctx (cpp_type_of ctx member.cf_type) -> CppVarRef(varloc), true | CppVar( VarInstance(obj,member,_,"->") as varloc) when is_gc_element ctx (cpp_type_of ctx member.cf_type) -> CppVarRef(varloc), true | CppVar varloc -> CppVarRef(varloc), false | CppArray arrayloc -> CppArrayRef(arrayloc), false | CppDynamicField(expr, name) -> CppDynamicRef(expr,name), false | CppTCast(cppExpr,_) | CppCast(cppExpr,_) | CppCastStatic(cppExpr,_) | CppCastObjC(cppExpr,_) | CppCastObjCBlock(cppExpr,_,_) | CppCastScalar(cppExpr,_) -> to_lvalue cppExpr | CppCastVariant(cppExpr) -> to_lvalue cppExpr | CppGlobal(name) -> CppGlobalRef(name), false | _ -> abort ("Could not convert expression to l-value (" ^ s_tcpp value.cppexpr ^ ")") value.cpppos in let rec retype return_type expr = let cpp_type_of t = cpp_type_of ctx t in let mk_cppexpr newExpr newType = { cppexpr = newExpr; cpptype = newType; cpppos = expr.epos } in let retype_function_args args arg_types = let rec map_pair args types result= match args, types with | args, [TCppRest(rest)] -> (List.rev (List.map (retype rest) args) ) @ result | [], [] -> result | a::arest, t::trest -> map_pair arest trest ((retype t a) :: result ) | _, [] -> abort ("Too many args") expr.epos | [], _ -> abort ("Too many types") expr.epos in List.rev (map_pair args arg_types []) in let retypedExpr, retypedType = match expr.eexpr with | TEnumParameter( enumObj, enumField, enumIndex ) -> let retypedObj = retype TCppDynamic enumObj in CppEnumParameter( retypedObj, enumField, enumIndex ), cpp_cast_variant_type_of (cpp_type_of (get_nth_type enumField enumIndex)) | TConst TThis -> uses_this := Some !this_real; CppThis(!this_real), if !this_real=ThisDynamic then TCppDynamic else cpp_type_of expr.etype | TConst TSuper -> uses_this := Some !this_real; CppSuper(!this_real), if !this_real=ThisDynamic then TCppDynamic else cpp_type_of expr.etype | TConst TNull when is_objc_type expr.etype -> CppNil, TCppNull | TConst x -> cpp_const_type x | TLocal { v_name = "__global__" } -> CppClassOf(([],""),false), TCppGlobal | TLocal tvar -> let name = tvar.v_name in if (Hashtbl.mem !declarations name) then begin (*print_endline ("Using existing tvar " ^ tvar.v_name);*) CppVar(VarLocal(tvar)), cpp_type_of tvar.v_type end else begin (*print_endline ("Missing tvar " ^ tvar.v_name);*) Hashtbl.replace !undeclared name tvar; if tvar.v_capture then CppVar(VarClosure(tvar)), cpp_type_of tvar.v_type else CppGlobal(name), cpp_type_of tvar.v_type end | TBreak -> begin match !loop_stack with | [] -> CppBreak, TCppVoid | (label_id,used) :: _ -> used := true; (CppGoto label_id),TCppVoid end | TContinue -> CppContinue, TCppVoid | TThrow e1 -> CppThrow(retype TCppDynamic e1), TCppVoid | TMeta( (Meta.Fixed,_,_),e) -> let cppType = retype return_type e in (match cppType.cppexpr with | CppObjectDecl(def,false) -> CppObjectDecl(def,true), cppType.cpptype | _ -> cppType.cppexpr, cppType.cpptype ) | TMeta(_,e) | TParenthesis e -> let cppType = retype return_type e in cppType.cppexpr, cppType.cpptype | TField( obj, field ) -> (match field with | FInstance (clazz,params,member) | FClosure (Some (clazz,params),member) -> let funcReturn = cpp_member_return_type ctx member in let clazzType = cpp_instance_type ctx clazz params in let retypedObj = retype clazzType obj in let exprType = cpp_type_of member.cf_type in let is_objc = is_cpp_objc_type retypedObj.cpptype in if retypedObj.cpptype=TCppNull then CppNullAccess, TCppDynamic else if retypedObj.cpptype=TCppDynamic && not clazz.cl_interface then begin if is_internal_member member.cf_name then CppFunction( FuncInstance(retypedObj,InstPtr,member), funcReturn ), exprType else CppDynamicField(retypedObj, member.cf_name), TCppVariant end else if cpp_is_struct_access retypedObj.cpptype then begin match retypedObj.cppexpr with | CppThis ThisReal -> CppVar(VarThis(member)), exprType | _ -> if (is_var_field member) then CppVar( VarInstance(retypedObj,member,tcpp_to_string clazzType, ".") ), exprType else CppFunction( FuncInstance(retypedObj,InstStruct,member), funcReturn ), exprType end else if is_var_field member then begin let exprType = match retypedObj.cpptype, exprType with | TCppPointer(_,t), TCppDynamic | TCppRawPointer(_,t), TCppDynamic (* the 'type parameter' will show up as Dynamic *) -> t | _ -> exprType in match retypedObj.cppexpr with | CppThis ThisReal -> CppVar(VarThis(member) ), exprType | _ -> (match retypedObj.cpptype, member.cf_name with (* Special variable remapping ... *) | TCppDynamicArray, "length" -> CppCall(FuncInternal(retypedObj,"get_length","->"),[]), exprType | TCppInterface _,_ | TCppDynamic,_ -> CppDynamicField(retypedObj, member.cf_name), TCppVariant | TCppObjC _,_ -> CppVar(VarInstance(retypedObj,member,tcpp_to_string clazzType, ".") ), exprType | _ -> let operator = if cpp_is_struct_access retypedObj.cpptype || retypedObj.cpptype=TCppString then "." else "->" in CppVar(VarInstance(retypedObj,member,tcpp_to_string clazzType, operator) ), exprType ) end else if (clazz.cl_interface && not is_objc (* Use instance call for objc interfaces *)) then CppFunction( FuncInterface(retypedObj,clazz,member), funcReturn ), exprType else begin let isArrayObj = match retypedObj.cpptype with | TCppDynamicArray | TCppObjectArray _ | TCppScalarArray _ -> true | _ -> false in (* Special array return values *) let funcReturn = if isArrayObj then match member.cf_name with | "map" -> TCppDynamicArray | "splice" | "slice" | "concat" | "copy" | "filter" -> retypedObj.cpptype | _ -> funcReturn else match retypedObj.cpptype, funcReturn with | TCppPointer(_,t), TCppDynamic | TCppRawPointer(_,t), TCppDynamic (* the 'type parameter' will show up as Dynamic *) -> t | _ -> funcReturn in (match retypedObj.cppexpr with | CppThis ThisReal -> CppFunction( FuncThis(member), funcReturn ), exprType | CppSuper this -> CppFunction( FuncSuper(this,member), funcReturn ), exprType | _ -> CppFunction( FuncInstance(retypedObj,(if is_objc then InstObjC else InstPtr),member), funcReturn ), exprType ) end | FStatic ( _, ({cf_name="nativeFromStaticFunction"} as member) ) -> let funcReturn = cpp_member_return_type ctx member in let exprType = cpp_type_of member.cf_type in CppFunction( FuncFromStaticFunction, funcReturn ), exprType | FStatic (clazz,member) -> let funcReturn = cpp_member_return_type ctx member in let exprType = cpp_type_of member.cf_type in let objC = is_objc_class clazz in if is_var_field member then CppVar(VarStatic(clazz, objC, member)), exprType else CppFunction( FuncStatic(clazz,objC,member), funcReturn ), exprType | FClosure (None,field) | FAnon field -> let obj = retype TCppDynamic obj in let fieldName = field.cf_name in if obj.cpptype=TCppGlobal then CppGlobal(fieldName), cpp_type_of expr.etype else if obj.cpptype=TCppNull then CppNullAccess, TCppDynamic else if is_internal_member fieldName then begin let cppType = cpp_return_type ctx expr.etype in if obj.cpptype=TCppString then CppFunction( FuncInternal(obj,fieldName,"."), cppType), cppType else CppFunction( FuncInternal(obj,fieldName,"->"), cppType), cppType end else CppDynamicField(obj, field.cf_name), TCppVariant | FDynamic fieldName -> let obj = retype TCppDynamic obj in if obj.cpptype=TCppNull then CppNullAccess, TCppDynamic else if fieldName="cca" && obj.cpptype=TCppString then CppFunction( FuncInternal(obj,"cca","."), TCppScalar("int")), TCppDynamic else if fieldName="__s" && obj.cpptype=TCppString then CppVar( VarInternal(obj,".","__s")), TCppPointer("ConstPointer", TCppScalar("char")) else if fieldName="__Index" then CppEnumIndex(obj), TCppScalar("int") else if is_internal_member fieldName || cpp_is_real_array obj then begin let cppType = cpp_return_type ctx expr.etype in if obj.cpptype=TCppString then CppFunction( FuncInternal(obj,fieldName,"."), cppType), cppType else CppFunction( FuncInternal(obj,fieldName,"->"), cppType), cppType end else if (obj.cpptype=TCppGlobal) then CppGlobal(fieldName), cpp_type_of expr.etype else if (obj.cpptype=TCppClass) then begin match obj.cppexpr with | CppClassOf(path,_) -> CppGlobal ( (join_class_path_remap path "::" ) ^ "_obj::" ^ fieldName ), cpp_type_of expr.etype | _ -> CppVar( VarInternal(obj,"->",fieldName)), cpp_type_of expr.etype end else CppDynamicField(obj, fieldName), TCppVariant | FEnum (enum, enum_field) -> CppEnumField(enum, enum_field), TCppEnum(enum) ) | TCall( {eexpr = TLocal { v_name = "__cpp__" }}, arg_list ) -> let cppExpr = match arg_list with | [{ eexpr = TConst (TString code) }] -> CppCode(code, []) | ({ eexpr = TConst (TString code) }) :: remaining -> let retypedArgs = List.map (fun arg -> retype (TCppCode(cpp_type_of arg.etype)) arg) remaining in CppCode(code, retypedArgs) | _ -> abort "__cpp__'s first argument must be a string" expr.epos; in cppExpr, TCppCode(cpp_type_of expr.etype) | TCall( func, args ) -> let retypedFunc = retype TCppUnchanged func in (match retypedFunc.cpptype with | TCppNull -> CppNullAccess, TCppDynamic | TCppFunction(argTypes,retType,_) -> let retypedArgs = retype_function_args args argTypes in CppCall( FuncExpression(retypedFunc) ,retypedArgs), retType | TCppObjCBlock(argTypes,retType) -> let retypedArgs = retype_function_args args argTypes in CppCall( FuncExpression(retypedFunc) ,retypedArgs), retType | _ -> let cppType = cpp_type_of expr.etype in (match retypedFunc.cppexpr with | CppFunction(FuncFromStaticFunction ,returnType) -> let retypedArgs = List.map (retype TCppDynamic ) args in ( match retypedArgs with | [ {cppexpr=CppFunction( FuncStatic(clazz,false,member), funcReturn)} ] -> CppFunctionAddress(clazz,member), funcReturn | _ -> abort "cpp.Function.fromStaticFunction must be called on static function" expr.epos; ) | CppEnumIndex(_) -> (* Not actually a TCall...*) retypedFunc.cppexpr, retypedFunc.cpptype | CppFunction( FuncInstance(obj, InstPtr, member), _ ) when return_type=TCppVoid && is_array_splice_call obj member -> let retypedArgs = List.map (retype TCppDynamic ) args in CppCall( FuncInstance(obj, InstPtr, {member with cf_name="removeRange"}), retypedArgs), TCppVoid | CppFunction( FuncStatic(obj, false, member), _ ) when member.cf_name = "hx::AddressOf" -> let arg = retype TCppUnchanged (List.hd args) in CppAddressOf(arg), TCppRawPointer("", arg.cpptype) | CppFunction( FuncStatic(obj, false, member), _ ) when member.cf_name = "_hx_create_array_length" -> let retypedArgs = List.map (retype TCppDynamic ) args in (* gc_stack - not needed yet *) (match return_type with | TCppObjectArray _ | TCppScalarArray _ -> CppCall( FuncNew(return_type), retypedArgs), return_type | _ -> CppCall( FuncNew(TCppDynamicArray), retypedArgs), return_type ) | CppFunction( FuncStatic(obj, false, member), returnType ) when cpp_is_templated_call ctx member -> let retypedArgs = List.map (retype TCppDynamic ) args in (match retypedArgs with | {cppexpr = CppClassOf(path,native) }::rest -> CppCall( FuncTemplate(obj,member,path,native), rest), returnType | _ -> abort "First parameter of template function must be a Class" retypedFunc.cpppos ) | CppFunction( FuncInstance(obj,InstPtr,member) as func, returnType ) when cpp_can_static_cast returnType cppType -> let retypedArgs = List.map (retype TCppDynamic ) args in let call = mk_cppexpr (CppCall(func,retypedArgs)) returnType in CppCastStatic(call, cppType), cppType (* let error_printer file line = Printf.sprintf "%s:%d:" file line in let epos = Lexer.get_error_pos error_printer expr.epos in print_endline ( "fixed override " ^ member.cf_name ^ " @ " ^ epos ^ " " ^ (tcpp_to_string returnType) ^ "->" ^ (ctx_type_string ctx expr.etype) ); CppCall(func,retypedArgs), returnType *) (* Other functions ... *) | CppFunction( FuncInstance(_,_,{cf_type=TFun(arg_types,_)} ) as func, returnType ) | CppFunction( FuncStatic(_,_,{cf_type=TFun(arg_types,_)} ) as func, returnType ) | CppFunction( FuncThis({cf_type=TFun(arg_types,_)} ) as func, returnType ) -> let arg_types = List.map (fun (_,opt,t) -> cpp_tfun_arg_type_of ctx opt t) arg_types in (* retype args specifically (not just CppDynamic) *) let retypedArgs = retype_function_args args arg_types in CppCall(func,retypedArgs), returnType | CppFunction(func,returnType) -> let retypedArgs = List.map (retype TCppDynamic ) args in CppCall(func,retypedArgs), returnType | CppEnumField(enum, field) -> (* TODO - proper re-typing *) let retypedArgs = List.map (retype TCppDynamic ) args in CppCall( FuncEnumConstruct(enum,field),retypedArgs), cppType | CppSuper(_) -> (* TODO - proper re-typing *) let retypedArgs = List.map (retype TCppDynamic ) args in CppCall( FuncSuperConstruct ,retypedArgs), TCppVoid | CppDynamicField(expr,name) -> let retypedArgs = List.map (retype TCppDynamic ) args in (* Special function calls *) (match expr.cpptype, name with | TCppGlobal, _ -> CppCall( FuncGlobal(name),retypedArgs), cppType | TCppString, _ -> CppCall( FuncInternal(expr,name,"."),retypedArgs), cppType | _, "__Tag" -> CppCall( FuncInternal(expr,"_hx_getTag","->"),retypedArgs), cppType | _, name when is_internal_member name -> CppCall( FuncInternal(expr,name,"->"),retypedArgs), cppType | _ -> (* not special *) CppCall( FuncExpression(retypedFunc), retypedArgs), TCppDynamic ) | CppGlobal(_) -> let retypedArgs = List.map (retype TCppDynamic ) args in CppCall( FuncExpression(retypedFunc) ,retypedArgs), cppType | _ -> let retypedArgs = List.map (retype TCppDynamic ) args in CppCall( FuncExpression(retypedFunc), retypedArgs), TCppDynamic ) ) | TNew (clazz,params,args) -> (* New DynamicArray ? *) let retypedArgs = List.map (retype TCppDynamic ) args in let created_type = cpp_type_of expr.etype in gc_stack := !gc_stack || (match created_type with | TCppInst(_) -> true | _ -> false ); CppCall( FuncNew(created_type), retypedArgs), created_type | TFunction func -> let old_this_real = !this_real in this_real := ThisFake; (* TODO - this_dynamic ? *) let old_undeclared = Hashtbl.copy !undeclared in let old_declarations = Hashtbl.copy !declarations in let old_uses_this = !uses_this in let old_gc_stack = !gc_stack in let old_return_type = !function_return_type in let ret =cpp_type_of func.tf_type in function_return_type := ret; uses_this := None; undeclared := Hashtbl.create 0; declarations := Hashtbl.create 0; List.iter ( fun (tvar,_) -> Hashtbl.add !declarations tvar.v_name () ) func.tf_args; let cppExpr = retype TCppVoid (mk_block func.tf_expr) in let result = { close_expr=cppExpr; close_id= !closureId; close_undeclared= !undeclared; close_type= ret; close_args= func.tf_args; close_this= !uses_this; } in incr closureId; declarations := old_declarations; undeclared := old_undeclared; Hashtbl.iter (fun name tvar -> if not (Hashtbl.mem !declarations name) then Hashtbl.replace !undeclared name tvar; ) result.close_undeclared; function_return_type := old_return_type; this_real := old_this_real; uses_this := if !uses_this != None then Some old_this_real else old_uses_this; gc_stack := old_gc_stack; rev_closures := result:: !rev_closures; CppClosure(result), TCppDynamic | TArray (e1,e2) -> let retypedObj = retype TCppDynamic e1 in let retypedIdx = retype (TCppScalar("int")) e2 in let arrayExpr, elemType = (match retypedObj.cpptype with | TCppScalarArray scalar -> CppArray( ArrayTyped(retypedObj,retypedIdx) ), scalar | TCppPointer (_,elem) -> CppArray( ArrayPointer(retypedObj, retypedIdx) ), elem | TCppRawPointer (_,elem) -> CppArray( ArrayRawPointer(retypedObj, retypedIdx) ), elem | TCppObjectArray TCppDynamic -> CppArray( ArrayObject(retypedObj,retypedIdx,TCppDynamic) ), TCppDynamic | TCppObjectArray elem -> CppArray( ArrayObject(retypedObj,retypedIdx,elem) ), elem | TCppInst({cl_array_access = Some _ } as klass) -> CppArray( ArrayImplements(klass, retypedObj,retypedIdx) ), cpp_type_of expr.etype | TCppDynamicArray -> CppArray( ArrayVirtual(retypedObj, retypedIdx) ), TCppDynamic | _ -> CppArray( ArrayDynamic(retypedObj, retypedIdx) ), TCppDynamic ) in let returnType = cpp_type_of expr.etype in if cpp_can_static_cast elemType returnType then CppCastStatic(mk_cppexpr arrayExpr returnType, returnType), returnType else arrayExpr, elemType | TTypeExpr module_type -> let path = t_path module_type in CppClassOf(path, is_native_gen_module module_type), TCppClass | TBinop (op,e1,e2) -> let objC1 = (is_objc_type e1.etype) in let objC2 = (is_objc_type e2.etype) in let compareObjC = (objC1<>objC2) && (op=OpEq || op=OpNotEq) in let e2 = retype (if compareObjC && objC2 then TCppUnchanged else cpp_type_of (if op=OpAssign then e1 else e2).etype) e2 in let e1 = retype (if compareObjC && objC1 then TCppUnchanged else cpp_type_of e1.etype) e1 in let complex = (is_complex_compare e1.cpptype) || (is_complex_compare e2.cpptype) in let e1_null = e1.cpptype=TCppNull in let e2_null = e2.cpptype=TCppNull in let reference = match op with | OpAssign -> let lvalue, gc = to_lvalue e1 in if gc then gc_stack := true; CppSet(lvalue, e2) | OpAssignOp op -> let lvalue, gc = to_lvalue e1 in if gc then gc_stack := true; CppModify(op, lvalue, e2) | OpEq when e1_null && e2_null-> CppBool(true) | OpGte when e1_null && e2_null-> CppBool(true) | OpLte when e1_null && e2_null-> CppBool(true) | OpNotEq when e1_null && e2_null-> CppBool(false) | _ when e1_null && e2_null-> CppBool(false) | OpEq when e1_null -> CppNullCompare("IsNull", e2) | OpGte when e1_null -> CppNullCompare("IsNull", e2) | OpLte when e1_null -> CppNullCompare("IsNull", e2) | OpNotEq when e1_null -> CppNullCompare("IsNotNull", e2) | OpEq when e2_null -> CppNullCompare("IsNull", e1) | OpGte when e2_null -> CppNullCompare("IsNull", e1) | OpLte when e2_null -> CppNullCompare("IsNull", e1) | OpNotEq when e2_null -> CppNullCompare("IsNotNull", e1) | OpEq when complex -> CppCompare("IsEq", e1, e2) | OpNotEq when complex -> CppCompare("IsNotEq", e1, e2) | OpGte when complex -> CppCompare("IsGreaterEq", e1, e2) | OpLte when complex -> CppCompare("IsLessEq", e1, e2) | OpGt when complex -> CppCompare("IsGreater", e1, e2) | OpLt when complex -> CppCompare("IsLess", e1, e2) | _ -> CppBinop(op,e1,e2) in reference, cpp_type_of expr.etype | TUnop (op,pre,e1) -> let targetType = match op with | Not -> TCppScalar("bool") | NegBits -> TCppScalar("int") | _ -> cpp_type_of e1.etype in let e1 = retype targetType e1 in let reference = match op with | Increment -> let lvalue, gc = to_lvalue e1 in if gc then gc_stack := true; CppCrement( CppIncrement, pre, lvalue) | Decrement -> let lvalue, gc = to_lvalue e1 in if gc then gc_stack := true; CppCrement( CppDecrement, pre, lvalue) | Neg -> CppUnop(CppNeg,e1) | Not -> CppUnop(CppNot,e1) | NegBits -> CppUnop(CppNegBits,e1) in reference, cpp_type_of expr.etype | TFor (v,init,block) -> let old_declarations = Hashtbl.copy !declarations in Hashtbl.add !declarations v.v_name (); let init = retype (cpp_type_of v.v_type) init in let block = retype TCppVoid (mk_block block) in declarations := old_declarations; CppFor(v,init,block), TCppVoid | TWhile (e1,e2,flag) -> let condition = retype (TCppScalar("bool")) e1 in let close = begin_loop() in let block = retype TCppVoid (mk_block e2) in CppWhile(condition, block, flag, close()), TCppVoid | TArrayDecl el -> let retypedEls = List.map (retype TCppDynamic) el in CppArrayDecl(retypedEls), cpp_type_of expr.etype | TBlock expr_list -> let inject = !injection in injection := false; if (return_type<>TCppVoid) then print_endline ("Value from a block not handled " ^ (expr.epos.pfile ) ^ " " ^ (string_of_int (Lexer.get_error_line expr.epos) )); let old_declarations = Hashtbl.copy !declarations in let old_closures = !rev_closures in rev_closures := []; let local_closures = ref [] in let remaining = ref (List.length expr_list) in let cppExprs = List.map ( fun expr -> let targetType = if inject && (!remaining=1) then cpp_type_of expr.etype else TCppVoid in decr remaining; let result = retype targetType expr in local_closures := !rev_closures @ !local_closures; rev_closures := []; result ) expr_list in declarations := old_declarations; rev_closures := old_closures; CppBlock(cppExprs, List.rev !local_closures, !gc_stack ), TCppVoid | TObjectDecl ( ("fileName" , { eexpr = (TConst (TString file)) }) :: ("lineNumber" , { eexpr = (TConst (TInt line)) }) :: ("className" , { eexpr = (TConst (TString class_name)) }) :: ("methodName", { eexpr = (TConst (TString meth)) }) :: [] ) -> CppPosition(file,line,class_name,meth), TCppDynamic | TObjectDecl el -> let retypedEls = List.map ( fun(v,e) -> v, retype TCppDynamic e) el in (match return_type with | TCppVoid -> CppObjectDecl(retypedEls,false), TCppVoid | _ -> CppObjectDecl(retypedEls,false), TCppDynamic ) | TVar (v,eo) -> let varType = cpp_type_of v.v_type in let init = match eo with None -> None | Some e -> Some (retype varType e) in Hashtbl.add !declarations v.v_name (); CppVarDecl(v, init), varType | TIf (ec,e1,e2) -> let ec = retype (TCppScalar("bool")) ec in let blockify = if return_type!=TCppVoid then fun e -> e else mk_block in let e1 = retype return_type (blockify e1) in let e2 = match e2 with None->None | Some e -> Some (retype return_type (blockify e)) in CppIf(ec, e1, e2), if return_type=TCppVoid then TCppVoid else cpp_type_of expr.etype (* Switch internal return - wrap whole thing in block *) | TSwitch (condition,cases,def) -> if return_type<>TCppVoid then abort "Value from a switch not handled" expr.epos; let conditionType = cpp_type_of condition.etype in let condition = retype conditionType condition in let cppDef = match def with None -> None | Some e -> Some (retype TCppVoid (mk_block e)) in (try (match conditionType with TCppScalar("int") | TCppScalar("bool") -> () | _ -> raise Not_found ); let cases = List.map (fun (el,e2) -> (List.map const_int_of el), (retype TCppVoid (mk_block e2)) ) cases in CppIntSwitch(condition, cases, cppDef), TCppVoid with Not_found -> let label = alloc_file_id () in (* do something better maybe ... *) let cases = List.map (fun (el,e2) -> let cppBlock = retype TCppVoid (mk_block e2) in let gotoExpr = { cppexpr = CppGoto(label); cpptype = TCppVoid; cpppos = e2.epos } in let cppBlock = cpp_append_block cppBlock gotoExpr in (List.map (retype conditionType) el), cppBlock ) cases in CppSwitch(condition, conditionType, cases, cppDef, label), TCppVoid ) | TTry (try_block,catches) -> (* TTry internal return - wrap whole thing in block ? *) if return_type<>TCppVoid then abort "Value from a try-block not handled" expr.epos; let cppBlock = retype TCppVoid try_block in let cppCatches = List.map (fun (tvar,catch_block) -> let old_declarations = Hashtbl.copy !declarations in Hashtbl.add !declarations tvar.v_name (); let cppCatchBlock = retype TCppVoid catch_block in declarations := old_declarations; tvar, cppCatchBlock; ) catches in CppTry(cppBlock, cppCatches), TCppVoid | TReturn eo -> CppReturn(match eo with None -> None | Some e -> Some (retype (!function_return_type) e)), TCppVoid | TCast (base,None) -> (* Use auto-cast rules *) let return_type = cpp_type_of expr.etype in let baseCpp = retype (return_type) base in let baseStr = (tcpp_to_string baseCpp.cpptype) in let returnStr = (tcpp_to_string return_type) in if baseStr=returnStr then baseCpp.cppexpr, baseCpp.cpptype (* nothing to do *) else (match return_type with | TCppObjC(k) -> CppCastObjC(baseCpp,k), return_type | TCppPointer(_,_) | TCppInst(_) -> CppCast(baseCpp,return_type), return_type | TCppString -> CppCastScalar(baseCpp,"::String"), return_type | TCppCode(t) when baseStr <> (tcpp_to_string t) -> CppCast(baseCpp, t), t | TCppNativePointer(klass) -> CppCastNative(baseCpp), return_type | TCppObjCBlock(args,ret) -> CppCastObjCBlock(baseCpp,args,ret), return_type | TCppProtocol(p) -> CppCastProtocol(baseCpp,p), return_type | TCppDynamic when baseCpp.cpptype=TCppClass -> CppCast(baseCpp,TCppDynamic), TCppDynamic | _ -> baseCpp.cppexpr, baseCpp.cpptype (* use autocasting rules *) ) | TCast (base,Some t) -> let baseCpp = retype (cpp_type_of base.etype) base in let baseStr = (tcpp_to_string baseCpp.cpptype) in let return_type = if return_type=TCppUnchanged then cpp_type_of expr.etype else return_type in let returnStr = (tcpp_to_string return_type) in if baseStr=returnStr then baseCpp.cppexpr, baseCpp.cpptype (* nothing to do *) else (match return_type with | TCppNativePointer(klass) -> CppCastNative(baseCpp), return_type | TCppVoid -> baseCpp.cppexpr, TCppVoid | TCppInterface _ -> baseCpp.cppexpr, return_type | TCppDynamic -> baseCpp.cppexpr, baseCpp.cpptype | _ -> CppTCast(baseCpp, return_type), return_type ) in let cppExpr = mk_cppexpr retypedExpr retypedType in (* Autocast rules... *) if return_type=TCppVoid then mk_cppexpr retypedExpr TCppVoid else if return_type=TCppVarArg then begin match cpp_variant_type_of cppExpr.cpptype with | TCppVoidStar | TCppScalar _ -> cppExpr | TCppString -> mk_cppexpr (CppVar(VarInternal(cppExpr,".","__s"))) (TCppPointer("ConstPointer", TCppScalar("char"))) | TCppDynamic -> mk_cppexpr (CppCastNative(cppExpr)) TCppVoidStar | _ -> let toDynamic = mk_cppexpr (CppCast(cppExpr, TCppDynamic)) TCppDynamic in mk_cppexpr (CppCastNative(toDynamic)) TCppVoidStar end else if (cppExpr.cpptype=TCppVariant || cppExpr.cpptype=TCppDynamic) then begin match return_type with | TCppUnchanged -> cppExpr | TCppInst(t) when (has_meta_key t.cl_meta Meta.StructAccess) -> let structType = TCppStruct( TCppInst(t) ) in let structCast = mk_cppexpr (CppCast(cppExpr,structType)) structType in mk_cppexpr (CppCast(structCast,(TCppInst t))) (TCppInst t) | TCppObjectArray _ | TCppScalarArray _ | TCppNativePointer _ | TCppDynamicArray | TCppObjectPtr | TCppVarArg | TCppInst _ -> mk_cppexpr (CppCast(cppExpr,return_type)) return_type | TCppObjC k -> mk_cppexpr (CppCastObjC(cppExpr,k)) return_type | TCppObjCBlock(ret,args) -> mk_cppexpr (CppCastObjCBlock(cppExpr,ret,args)) return_type | TCppScalar(scalar) -> mk_cppexpr (CppCastScalar(cppExpr,scalar)) return_type | TCppString -> mk_cppexpr (CppCastScalar(cppExpr,"::String")) return_type | TCppInterface _ when cppExpr.cpptype=TCppVariant -> mk_cppexpr (CppCastVariant(cppExpr)) return_type | TCppDynamic when cppExpr.cpptype=TCppVariant -> mk_cppexpr (CppCastVariant(cppExpr)) return_type | TCppStar(t,const) -> let ptrType = TCppPointer((if const then "ConstPointer" else "Pointer"),t) in let ptrCast = mk_cppexpr (CppCast(cppExpr,ptrType)) ptrType in mk_cppexpr (CppCast(ptrCast,TCppStar(t,const))) (TCppStar(t,const)) | _ -> cppExpr end else match cppExpr.cpptype, return_type with | _, TCppUnchanged -> cppExpr (* Using the 'typedef hack', where we use typedef X = T, allows the haxe compiler to use these types interchangeably. We then work out the correct way to convert between them when one is expected, but another provided. TCppFunction: these do not really interact with the haxe function type, T Since they are implemented with cpp::Function, conversion to/from Dynamic should happen automatically CallableData = T; FunctionData = T; TCppObjCBlock can move in and out of Dyanmic ObjcBlock = T; TCppProtocol can move in and out of Dyanmic, via delegate creation Protocol = T; Explicitly wrapped type - already interacts well with Dynamic and T Struct = T; TCppStar, TCppStruct, TCppReference - for interacting with native code Star = T; ConstStar = T; Reference = T; T may be an extern class, with @:structAccess - in which case Dynamic interaction must be handled explicitly These types, plus Dynamic can be used interchangeably by haxe Derived/inherited types may also be mixed in *) | TCppAutoCast, _ | TCppObjC(_), TCppDynamic | TCppObjCBlock(_), TCppDynamic -> mk_cppexpr (CppCast(cppExpr,return_type)) return_type (* Infer type from right-hand-side for pointer or reference to Dynamic *) | TCppReference(TCppDynamic), TCppReference(_) -> cppExpr | TCppReference(TCppDynamic), t -> mk_cppexpr retypedExpr (TCppReference(t)) | TCppStar(TCppDynamic,_), TCppStar(_,_) -> cppExpr | TCppStar(TCppDynamic,const), t -> mk_cppexpr retypedExpr (TCppStar(t,const)) | TCppStar(t,const), TCppDynamic -> let ptrType = TCppPointer((if const then "ConstPointer" else "Pointer"),t) in let ptrCast = mk_cppexpr (CppCast(cppExpr,ptrType)) ptrType in mk_cppexpr (CppCast(ptrCast,TCppDynamic)) TCppDynamic | TCppStar(t,const), TCppInst _ | TCppStar(t,const), TCppStruct _ -> mk_cppexpr (CppDereference(cppExpr)) return_type | TCppInst _, TCppStar(p,const) | TCppStruct _, TCppStar(p,const) -> mk_cppexpr (CppAddressOf(cppExpr)) return_type | TCppObjectPtr, TCppObjectPtr -> cppExpr | TCppObjectPtr, _ -> mk_cppexpr (CppCast(cppExpr,TCppDynamic)) TCppDynamic | TCppProtocol _, TCppProtocol _ -> cppExpr | t, TCppProtocol protocol -> mk_cppexpr (CppCastProtocol(cppExpr,protocol)) return_type | TCppInst(t), TCppDynamic when (has_meta_key t.cl_meta Meta.StructAccess) -> let structType = TCppStruct( TCppInst(t) ) in let structCast = mk_cppexpr (CppCast(cppExpr,structType)) structType in mk_cppexpr (CppCast(structCast,TCppDynamic)) TCppDynamic | _, TCppObjectPtr -> mk_cppexpr (CppCast(cppExpr,TCppObjectPtr)) TCppObjectPtr | _ -> cppExpr in retype request_type expression_tree ;; type tinject = { inj_prologue : bool -> unit; inj_setvar : string; inj_tail : string; } let mk_injection prologue set_var tail = Some { inj_prologue=prologue; inj_setvar=set_var; inj_tail=tail } ;; let cpp_arg_type_name ctx tvar default_val prefix = let remap_name = (cpp_var_name_of tvar) in let type_str = (cpp_var_type_of ctx tvar) in match default_val with | Some TNull -> (tcpp_to_string (cpp_type_of_null ctx tvar.v_type)),remap_name | Some constant -> (tcpp_to_string (cpp_type_of_null ctx tvar.v_type)),prefix ^ remap_name | _ -> type_str,remap_name ;; let cpp_gen_default_values ctx args prefix = List.iter ( fun (tvar,o) -> match o with | Some TNull -> () | Some const -> let name = cpp_var_name_of tvar in ctx.ctx_output ((cpp_var_type_of ctx tvar) ^ " " ^ name ^ " = " ^ prefix ^ name ^ ".Default(" ^ (default_value_string const) ^ ");\n") | _ -> () ) args; ;; let is_constant_zero expr = match expr.cppexpr with | CppFloat x when (float_of_string x) = 0.0 -> true | CppInt i when i = Int32.of_int 0 -> true | _ -> false ;; let cpp_is_const_scalar_array arrayType expressions = List.length expressions>0 && (match arrayType with | TCppScalarArray _ -> List.for_all (fun expr -> match expr.cppexpr with | CppInt _ | CppFloat _ | CppString _ | CppBool _ -> true | _ -> false ) expressions | _ -> false) ;; (* Generate prototype text, including allowing default values to be null *) let cpp_arg_string ctx tvar default_val prefix = let t,n = cpp_arg_type_name ctx tvar default_val prefix in t ^ " " ^ n ;; let cpp_arg_list ctx args prefix = String.concat "," (List.map (fun (v,o) -> (cpp_arg_string ctx v o prefix) ) args) ;; let ctx_default_values ctx args prefix = cpp_gen_default_values ctx args prefix ;; let gen_type ctx haxe_type = ctx.ctx_output (ctx_type_string ctx haxe_type) ;; let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_type injection tree = let writer = ctx.ctx_writer in let out = ctx.ctx_output in let lastLine = ref (-1) in let tempId = ref 0 in let spacer = if (ctx.ctx_debug_level>0) then " \t" else "" in let output_i value = out spacer; writer#write_i value in let output_p expr value = if (ctx.ctx_debug_level>0) then begin let line = Lexer.get_error_line expr.cpppos in let lineName = Printf.sprintf "%4d" line in let macro = if (line != !lastLine) then "HXLINE" else "HXDLIN" in out (macro ^ "(" ^ lineName ^ ")\t" ); lastLine := line; end; writer#write_i value in let forInjection = match injection with Some inject -> inject.inj_setvar<>"" | _ -> false in let cppTree = retype_expression ctx TCppVoid function_args function_type tree forInjection in let label_name i = Printf.sprintf "_hx_goto_%i" i in let class_hash = gen_hash_small 0 class_name in let rec gen_with_injection injection expr = (match expr.cppexpr with | CppBlock(exprs,closures,gc_stack) -> writer#begin_block; List.iter gen_closure closures; (match injection with Some inject -> inject.inj_prologue gc_stack | _ -> () ); let remaining = ref (List.length exprs) in lastLine := Lexer.get_error_line tree.epos; List.iter (fun e -> output_p e ""; if (!remaining=1) then (match injection with Some inject -> out inject.inj_setvar | _ -> () ); gen e; decr remaining; writer#terminate_line; ) exprs; (match injection with Some inject -> out inject.inj_tail | _ -> () ); out spacer; writer#end_block; | CppInt i -> out (Printf.sprintf "(int)%ld" i) | CppFloat float_as_string -> out ("((Float)" ^ float_as_string ^")") | CppString s -> out (strq s) | CppBool b -> out (if b then "true" else "false") | CppNull -> out "null()" | CppNil -> out "nil" | CppThis ThisReal -> out "hx::ObjectPtr(this)" | CppThis _ -> out "__this" | CppSuper thiscall -> out ("hx::ObjectPtr(" ^ (if thiscall=ThisReal then "this" else "__this.mPtr") ^ ")") | CppBreak -> out "break" | CppContinue -> out "continue" | CppGoto label -> out ("goto " ^ (label_name label)); | CppVarDecl(var,init) -> let name = cpp_var_name_of var in if cpp_no_debug_synbol ctx var then out ( (cpp_var_type_of ctx var) ^ " " ^ name ) else begin let dbgName = cpp_var_debug_name_of var in let macro = if init=None then "HX_VAR" else "HX_VARI" in let varType = cpp_macro_var_type_of ctx var in if name<>dbgName then out ( macro ^ "_NAME( " ^ varType ^ "," ^ name ^ ",\"" ^ dbgName ^ "\")" ) else out ( macro ^ "( " ^ varType ^ "," ^ name ^ ")"); end; (match init with Some init -> out " = "; gen init | _ -> () ); | CppEnumIndex(obj) -> gen obj; (*if cpp_is_dynamic_type obj.cpptype then*) out ".StaticCast< ::hx::EnumBase >()"; out "->getIndex()" | CppNullAccess -> out ("hx::Throw(" ^ strq "Null access" ^ ")") | CppFunction(func,_) -> (match func with | FuncThis(field) -> out ("this->" ^ (cpp_member_name_of field) ^ "_dyn()"); | FuncInstance(expr,inst,field) -> gen expr; out ((if expr.cpptype=TCppString || inst=InstStruct then "." else "->") ^ (cpp_member_name_of field) ^ "_dyn()"); | FuncInterface(expr,_,field) -> gen expr; out ("->__Field(" ^ strq field.cf_name ^ ", hx::paccDynamic)") | FuncStatic(clazz,_,field) -> let rename = get_meta_string field.cf_meta Meta.Native in if rename<>"" then out rename else (out (cpp_class_name clazz); out ("::" ^ (cpp_member_name_of field) ^ "_dyn()")) | FuncExpression(expr) -> gen expr; | FuncGlobal(name) -> out ("::" ^ name); | FuncInternal(expr,name,_) -> gen expr; out ("->__Field(" ^ (strq name) ^ ",hx::paccDynamic)") | FuncSuper _ | FuncSuperConstruct -> abort "Can't create super closure" expr.cpppos | FuncNew _ -> abort "Can't create new closure" expr.cpppos | FuncEnumConstruct _ -> abort "Enum constructor outside of CppCall" expr.cpppos | FuncFromStaticFunction -> abort "Can't create cpp.Function.fromStaticFunction closure" expr.cpppos | FuncTemplate _ -> abort "Can't create template function closure" expr.cpppos ); | CppCall( FuncInterface(expr,clazz,field), args) when not (is_native_gen_class clazz)-> out ( cpp_class_name clazz ^ "::" ^ cpp_member_name_of field ^ "("); gen expr; List.iter (fun arg -> out ","; gen arg ) args; out ")"; | CppCall(FuncStatic(_,true,field) as func, arg_list) | CppCall(FuncInstance(_,InstObjC,field) as func, arg_list) -> out "[ "; (match func with | FuncStatic(cl,_,_) -> out (join_class_path_remap cl.cl_path "::") | FuncInstance(expr,_,_) -> gen expr | _ ->() ); let names = ExtString.String.nsplit field.cf_name ":" in let field_name, arg_names = match names with | name :: args -> name, args | _ -> assert false (* per nsplit specs, this should never happen *) in out (" " ^ field_name); (try match arg_list, arg_names with | [], _ -> () | [single_arg], _ -> out ": "; gen single_arg | first_arg :: args, arg_names -> out ": "; gen first_arg; List.iter2 (fun arg arg_name -> out (" " ^ arg_name ^ ": "); gen arg) args arg_names with | Invalid_argument _ -> (* not all arguments names are known *) abort ( "The function called here with name " ^ (String.concat ":" names) ^ " does not contain the right amount of arguments' names as required" ^ " by the objective-c calling / naming convention:" ^ " expected " ^ (string_of_int (List.length arg_list)) ^ " and found " ^ (string_of_int (List.length arg_names))) expr.cpppos); out " ]" | CppCall(FuncNew( TCppInst klass), args) -> out ((cpp_class_path_of klass) ^ "_obj::__alloc( HX_CTX "); List.iter (fun arg -> out ","; gen arg ) args; out (")") | CppCall(func, args) -> let closeCall = ref "" in let argsRef = ref args in (match func with | FuncThis(field) -> out ("this->" ^ (cpp_member_name_of field) ); | FuncInstance(expr,inst,field) -> let operator = if (expr.cpptype = TCppString || inst=InstStruct) then "." else "->" in gen expr; out (operator ^ (cpp_member_name_of field) ); | FuncInterface(expr,_,field) -> gen expr; out ("->" ^ (cpp_member_name_of field) ); | FuncStatic(clazz,false,field) when cpp_is_static_extension ctx field -> (match args with | fst :: remaining -> argsRef := remaining; gen fst; out ("->" ^ (cpp_member_name_of field) ); | _ -> abort "Native static extensions must have at least 1 argument" expr.cpppos ); | FuncStatic(clazz,_,field) -> let rename = get_meta_string field.cf_meta Meta.Native in if rename<>"" then begin (* This is the case if you use @:native('new foo'). c++ wil group the space undesirably *) if String.contains rename ' ' then begin out "("; closeCall := ")" end; out rename end else (out (cpp_class_name clazz); out ("::" ^ (cpp_member_name_of field) )) | FuncTemplate(clazz,field,tpath,native) -> let rename = get_meta_string field.cf_meta Meta.Native in if rename<>"" then begin (* This is the case if you use @:native('new foo'). c++ wil group the space undesirably *) if String.contains rename ' ' then begin out "("; closeCall := ")" end; out rename end else (out (cpp_class_name clazz); out ("::" ^ (cpp_member_name_of field) )); out ("< " ^ (cpp_template_param tpath native) ^ " >") | FuncFromStaticFunction -> abort "Unexpected FuncFromStaticFunction" expr.cpppos | FuncEnumConstruct(enum,field) -> out ((string_of_path enum.e_path) ^ "::" ^ (cpp_enum_name_of field)); | FuncSuperConstruct -> out ((if not ctx.ctx_real_this_ptr then "__this->" else "") ^ "super::__construct") | FuncSuper(this,field) -> out ( (if this==ThisReal then "this->" else "__->") ^ "super::" ^ (cpp_member_name_of field) ) | FuncNew(newType) -> let objName = match newType with | TCppString -> "::String" | TCppDynamicArray -> "::cpp::VirtualArray_obj::__new" | TCppObjectArray _ -> "::Array_obj< ::Dynamic>::__new" | TCppScalarArray(value) -> "::Array_obj< " ^ (tcpp_to_string value) ^ " >::__new" | TCppObjC klass -> (cpp_class_path_of klass) ^ "_obj::__new" | TCppNativePointer klass -> "new " ^ (cpp_class_path_of klass); | TCppInst klass -> (cpp_class_path_of klass) ^ "_obj::__new" | TCppClass -> "hx::Class_obj::__new"; | TCppFunction _ -> tcpp_to_string newType | _ -> abort ("Unknown 'new' target " ^ (tcpp_to_string newType)) expr.cpppos in out objName | FuncInternal(func,name,join) -> gen func; out (join ^ name); | FuncGlobal(name) -> out ("::" ^ name); | FuncExpression(expr) -> gen expr; ); let sep = ref "" in out "("; List.iter (fun arg -> out !sep; sep := ","; gen arg; ) !argsRef; out (")" ^ !closeCall); | CppAddressOf(e) -> out ("&("); gen e; out ")"; | CppDereference(e) -> out ("(*("); gen e; out "))"; | CppFunctionAddress(klass, member) -> let signature = ctx_function_signature ctx false member.cf_type "" in let name = cpp_member_name_of member in (*let void_cast = has_meta_key field.cf_meta Meta.Void in*) out ("::cpp::Function< " ^ signature ^">(hx::AnyCast("); out ("&::" ^(join_class_path_remap klass.cl_path "::")^ "_obj::" ^ name ); out " ))" | CppGlobal(name) -> out ("::" ^ name) | CppDynamicField(obj,name) -> gen obj; out ("->__Field(" ^ (strq name) ^ ",hx::paccDynamic)"); | CppArray(arrayLoc) -> (match arrayLoc with | ArrayTyped(arrayObj,index) -> gen arrayObj; out "->__get("; gen index; out ")" | ArrayPointer(arrayObj,index) -> gen arrayObj; out ".ptr["; gen index; out "]" | ArrayRawPointer(arrayObj,index) -> gen arrayObj; out "["; gen index; out "]" | ArrayObject(arrayObj,index,elem) -> let close = if cpp_is_dynamic_type elem then "" else if elem=TCppDynamicArray then begin out (tcpp_to_string elem ^ "( "); ")" end else ".StaticCast< " ^ tcpp_to_string elem ^ " >()" in gen arrayObj; out "->__get("; gen index; out (")" ^ close); | ArrayVirtual(arrayObj,index) -> gen arrayObj; out "->__get("; gen index; out ")"; | ArrayDynamic(arrayObj,index) -> gen arrayObj; out "->__GetItem("; gen index; out ")" | ArrayImplements(_,arrayObj,index) -> gen arrayObj; out "->__get("; gen index; out ")"; ) | CppSet(lvalue,rvalue) -> let close = if expr.cpptype=TCppVoid then "" else (out "("; ")" ) in (match lvalue with | CppVarRef( VarClosure(var)) when is_gc_element ctx (cpp_type_of ctx var.v_type) -> out ("this->_hx_set_" ^ (cpp_var_name_of var) ^ "(HX_CTX, "); gen rvalue; out ")" | CppVarRef( VarThis(member)) when is_gc_element ctx (cpp_type_of ctx member.cf_type) -> out ("this->_hx_set_" ^ (cpp_member_name_of member) ^ "(HX_CTX, "); gen rvalue; out ")" | CppVarRef( VarInstance(obj,member,_,"->")) when is_gc_element ctx (cpp_type_of ctx member.cf_type) -> gen obj; out ("->_hx_set_" ^ (cpp_member_name_of member) ^ "(HX_CTX, "); gen rvalue; out ")" | CppVarRef( VarInternal(obj,operator,member) ) -> gen obj; out (operator ^ member) | CppVarRef varLoc -> gen_val_loc varLoc true; out " = "; gen rvalue; | CppArrayRef arrayLoc -> (match arrayLoc with | ArrayObject(arrayObj, index, _) when (is_gc_element ctx TCppDynamic) -> gen arrayObj; out "->setCtx( HX_CTX, "; gen index; out ","; gen rvalue; out ")" | ArrayObject(arrayObj, index, _) | ArrayTyped(arrayObj, index) | ArrayRawPointer(arrayObj, index) -> gen arrayObj; out "["; gen index; out "] = "; gen rvalue | ArrayPointer(arrayObj, index) -> gen arrayObj; out ".ptr["; gen index; out "] = "; gen rvalue | ArrayVirtual(arrayObj, index) -> gen arrayObj; out "->set("; gen index; out ","; gen rvalue; out ")" | ArrayDynamic(arrayObj, index) -> gen arrayObj; out "->__SetItem("; gen index; out ","; gen rvalue; out ")" | ArrayImplements(_,arrayObj,index) -> gen arrayObj; out "->__set("; gen index; out ","; gen rvalue; out ")" ) | CppDynamicRef(expr,name) -> gen expr; out ("->__SetField(" ^ (strq name) ^ ","); gen rvalue; out ",hx::paccDynamic)" | CppGlobalRef(name) -> out ("::" ^ name ^ " = "); ); out close; | CppCrement(incFlag,preFlag, lvalue) -> let op = if incFlag==CppIncrement then "++" else "--" in if (preFlag==Prefix) then out op; gen_lvalue lvalue; if (preFlag==Postfix) then out op | CppModify(op,lvalue,rvalue) -> out (string_of_op_eq op expr.cpppos); out "("; gen_lvalue lvalue; out ","; gen rvalue; out ")" | CppPosition(name,line,clazz,func) -> out ("hx::SourceInfo(" ^ strq name ^ "," ^ string_of_int(Int32.to_int line) ^ "," ^ strq clazz ^ "," ^ strq func ^ ")") | CppClassOf (path,native) -> let path = "::" ^ (join_class_path_remap (path) "::" ) in let path = match path with | "::Int" -> "int" | "::Bool" -> "bool" | x -> x in if (native) then out "null()" else if (path="::Array") then out "hx::ArrayBase::__mClass" else out ("hx::ClassOf< " ^ path ^ " >()") | CppVar(loc) -> gen_val_loc loc false; | CppClosure closure -> out (" ::Dynamic(new _hx_Closure_" ^ (string_of_int(closure.close_id)) ^ "("); let separator = ref "" in (match closure.close_this with | Some this -> out (if this=ThisReal then "this" else "__this"); separator := ","; | _ -> () ); Hashtbl.iter (fun name value -> out !separator; separator := ","; out (keyword_remap name) ) closure.close_undeclared; out "))"; | CppObjectDecl (values,isStruct) -> let length = List.length values in let lengthStr = string_of_int length in if (expr.cpptype!=TCppVoid) then out " ::Dynamic("; if (isStruct) && length>0 && length<=5 then begin out ("hx::AnonStruct" ^ lengthStr ^"_obj< " ^ (String.concat "," (List.map (fun (_,value) -> tcpp_to_string value.cpptype) values) ) ^ " >::Create(" ); let sep = ref "" in List.iter (fun (name,value) -> out (!sep ^ (strq name) ^ "," ); sep:=","; gen value ) values; out ")"; end else begin out ("hx::Anon_obj::Create(" ^ lengthStr ^")"); let sorted = List.sort (fun (_,_,h0) (_,_,h1) -> Int32.compare h0 h1 ) (List.map (fun (name,value) -> name,value,(gen_hash32 0 name ) ) values) in writer#push_indent; ExtList.List.iteri (fun idx (name,value,_) -> out ("\n" ^ spacer); writer#write_i ("->setFixed(" ^ (string_of_int idx) ^ "," ^ (strq name) ^ ","); gen value; out ")"; ) sorted; end; if (expr.cpptype!=TCppVoid) then out ")"; writer#pop_indent; | CppArrayDecl(exprList) when cpp_is_const_scalar_array expr.cpptype exprList -> let arrayType = match expr.cpptype with TCppScalarArray(value) -> value | _ -> assert false in let typeName = tcpp_to_string arrayType in incr ctx.ctx_file_id; let id = "_hx_array_data_" ^ class_hash ^ "_" ^ string_of_int( !(ctx.ctx_file_id) ) in let out_top = ctx.ctx_writer#write_h in out_top ("static const " ^ typeName ^ " " ^ id ^ "[] = {\n\t"); List.iter (fun expr -> match expr.cppexpr with | CppInt i -> out_top (Printf.sprintf "(%s)%ld," typeName i) | CppFloat f -> out_top ( f ^ "," ) | CppString s -> out_top ( (strq s) ^ "," ) | CppBool b -> out_top (if b then "1," else "0,") | _ -> assert false ) exprList; out_top ("\n};\n"); out ("::Array_obj< " ^ typeName ^ " >::fromData( " ^ id ^ "," ^ list_num exprList ^ ")"); | CppArrayDecl(exprList) -> let count = List.length exprList in let countStr = string_of_int count in let arrayType,close = match expr.cpptype with | TCppObjectArray _ -> "::Array_obj< ::Dynamic>","" | TCppScalarArray(value) -> "::Array_obj< " ^ (tcpp_to_string value) ^ " >","" | TCppDynamicArray -> "::cpp::VirtualArray_obj","" | _ -> " ::Dynamic( ::cpp::VirtualArray_obj",")" in out (arrayType ^ "::__new(" ^ countStr ^ ")" ); ExtList.List.iteri ( fun idx elem -> out ("->init(" ^ (string_of_int idx) ^ ","); gen elem; out ")" ) exprList; out close; | CppBinop( Ast.OpUShr, left, right) -> out "hx::UShr("; gen left; out ","; gen right; out ")"; | CppBinop( Ast.OpMod, left, right) -> if is_constant_zero right then begin out "hx::Mod("; gen left; out ",(double)( "; gen right; out " ))"; end else begin out "hx::Mod("; gen left; out ","; gen right; out ")"; end | CppBinop( Ast.OpDiv, left, right) when is_constant_zero right -> out "hx::DivByZero("; gen left; out ")"; | CppBinop(op, left, right) -> let op = string_of_op op expr.cpppos in let castOpen, castClose = (match op with | ">>" | "<<" | "&" | "|" | "^" -> "(int)", "" | "&&" | "||" -> "(bool)", "" | "/" -> "(Float)", "" | _ -> "","") in out "("; out castOpen; gen left; out castClose; out (" " ^ op ^ " "); out castOpen; gen right; out castClose; out ")"; | CppCompare(op, left, right) -> out ("hx::" ^ op ^ "( "); gen left; out (","); gen right; out (" )"); | CppNullCompare(op, left) -> out ("hx::" ^ op ^ "( "); gen left; out (" )"); | CppThrow(value) -> out "HX_STACK_DO_THROW("; gen value; out ")"; | CppReturn None -> out "return"; | CppReturn Some value -> out "return "; gen value; | CppEnumField(enum,field) -> out ((string_of_path enum.e_path) ^ "::" ^ (cpp_enum_name_of field) ^ "_dyn()" ); | CppEnumParameter(obj,field,index) -> let valueType = cpp_type_of ctx (get_nth_type field index) in let baseType = cpp_base_type_of valueType in gen obj; if cpp_is_dynamic_type obj.cpptype then out ".StaticCast< ::hx::EnumBase >()"; out ( "->_hx_get" ^ baseType ^ "(" ^ (string_of_int index) ^ ")"); (match valueType with | TCppObjectArray _ | TCppScalarArray _ | TCppDynamicArray | TCppClass | TCppEnum _ | TCppInst _ -> out (".StaticCast< " ^ (tcpp_to_string valueType ) ^ " >()") | _ ->() ) | CppIntSwitch(condition, cases, defVal) -> out "switch((int)("; gen condition; out "))"; writer#begin_block; List.iter (fun (values,expr) -> out spacer; writer#write_i ""; List.iter (fun value -> out ("case (int)" ^ (Printf.sprintf "%ld" value) ^ ": " ) ) values; gen expr; out spacer; writer#write_i "break;\n"; ) cases; (match defVal with | Some expr -> output_i "default:"; gen expr; | _ -> () ); out spacer; writer#end_block; | CppSwitch(condition, conditionType, cases, optional_default, label) -> let tmp_name = "_hx_switch_" ^ (string_of_int !tempId) in incr tempId; out ( (tcpp_to_string conditionType) ^ " " ^ tmp_name ^ " = " ); gen condition; out ";\n"; List.iter (fun (cases,expression) -> output_i "if ( "; let or_str = ref "" in List.iter (fun value -> out (!or_str ^ " (" ^ tmp_name ^ "=="); gen value; out ")"; or_str := " || "; ) cases; out (" )"); gen expression; ) cases; (match optional_default with | None -> () | Some default -> output_i "/* default */"; gen default; ); output_i ((label_name label) ^ ":") | CppUnop(unop,value) -> out (match unop with | CppNot -> "!" | CppNeg -> "-" | CppNegBits -> "~" ); out "("; gen value; out ")" | CppWhile(condition, block, while_flag, loop_id) -> (match while_flag with | NormalWhile -> out "while("; gen condition; out (")"); gen block; | DoWhile -> out ("do "); gen block; out "while("; gen condition; out ")" ); if loop_id > -1 then output_i ((label_name loop_id) ^ ":"); | CppIf (condition,block,None) -> out "if ("; gen condition; out (") "); gen block; | CppIf (condition,block,Some elze) when expr.cpptype = TCppVoid -> out "if ("; gen condition; out (") "); gen block; output_i ("else "); gen elze; | CppIf (condition,block,Some elze) -> gen condition; out " ? "; gen block; out " : "; gen elze; | CppFor (tvar, init, loop) -> let varType = cpp_var_type_of ctx tvar in out ("for(::cpp::FastIterator_obj< " ^ varType ^ " > *__it = ::cpp::CreateFastIterator< "^ varType ^ " >("); gen init; out ("); __it->hasNext(); )"); let prologue = fun _ -> output_i ( varType ^ " " ^ (cpp_var_name_of tvar) ^ " = __it->next();\n" ); in gen_with_injection (mk_injection prologue "" "") loop; | CppTry(block,catches) -> let prologue = function _ -> ExtList.List.iteri (fun idx (v,_) -> output_i ("HX_STACK_CATCHABLE(" ^ cpp_macro_var_type_of ctx v ^ ", " ^ string_of_int idx ^ ");\n") ) catches in out ("try "); gen_with_injection (mk_injection prologue "" "" ) block; if (List.length catches > 0 ) then begin output_i "catch( ::Dynamic _hx_e)"; writer#begin_block; let seen_dynamic = ref false in let else_str = ref "" in List.iter (fun (v,catch) -> let type_name = cpp_var_type_of ctx v in if (type_name="Dynamic") then begin seen_dynamic := true; output_i !else_str; end else output_i (!else_str ^ "if (_hx_e.IsClass< " ^ type_name ^ " >() )"); let prologue = function _ -> output_i "HX_STACK_BEGIN_CATCH\n"; output_i (type_name ^ " " ^ (cpp_var_name_of v) ^ " = _hx_e;\n"); in gen_with_injection (mk_injection prologue "" "") catch; else_str := "else "; ) catches; if (not !seen_dynamic) then begin output_i "else {\n"; output_i "\tHX_STACK_DO_THROW(_hx_e);\n"; output_i "}\n"; end; out spacer; writer#end_block; end | CppCode(value, exprs) -> Codegen.interpolate_code ctx.ctx_common (format_code value) exprs out (fun e -> gen e) expr.cpppos | CppTCast(expr,cppType) -> let toType = tcpp_to_string cppType in if toType="Dynamic" then (out " ::Dynamic("; gen expr; out ")") else (out ("hx::TCast< " ^ toType ^ " >::cast("); gen expr; out ")") | CppCastStatic(expr,toType) -> let close = match expr.cpptype with | TCppDynamic -> "" | _ -> out "Dynamic( "; ")" in gen expr; out (close ^ ".StaticCast< " ^ tcpp_to_string toType ^" >()") | CppCast(expr,toType) -> (match expr.cppexpr, expr.cpptype with | CppCall( FuncInternal _, _), _ -> gen expr; out (".StaticCast< " ^ tcpp_to_string toType ^" >()") | _, TCppObjC(_) | _, TCppObjCBlock(_) -> out ("( ("^ tcpp_to_string toType ^")((id) ( "); gen expr; out (") ))") | _,_ -> (match toType with | TCppObjectPtr -> out ("hx::DynamicPtr("); gen expr; out (")") | t -> out ("( ("^ tcpp_to_string t ^")("); gen expr; out (") )") ) ) | CppCastScalar(expr,scalar) -> out ("( ("^scalar^")("); gen expr; out (") )"); | CppCastVariant(expr) -> out " ::Dynamic("; gen expr; out ")"; | CppCastObjC(expr,klass) -> let path = join_class_path_remap klass.cl_path "::" in let toType = if klass.cl_interface then "id < " ^ path ^ ">" else path ^ " *" in out ("( (" ^ toType ^ ") (id) ("); gen expr; out ") )" | CppCastObjCBlock(expr,args,ret) -> out (tcpp_objc_block_struct args ret ^ "::create( "); gen expr; out ")" | CppCastProtocol(expr,klass) -> out ( (join_class_path_remap klass.cl_path "::" ) ^ "_obj::_hx_toProtocol( "); gen expr; out ")" | CppCastNative(expr) -> out "("; gen expr; out ").mPtr" ); if (ctx.ctx_debug_level >= 3) then out ("/* " ^ (s_tcpp expr.cppexpr) ^ ":" ^ tcpp_to_string expr.cpptype ^ " */") and gen expr = gen_with_injection None expr and gen_lvalue lvalue = match lvalue with | CppVarRef varLoc -> gen_val_loc varLoc true | CppArrayRef arrayLoc -> (match arrayLoc with | ArrayObject(arrayObj, index, _) -> out "hx::IndexRef("; gen arrayObj; out ".mPtr,"; gen index; out ")"; | ArrayTyped(arrayObj, index) -> gen arrayObj; out "["; gen index; out "]"; | ArrayPointer(arrayObj, index) -> gen arrayObj; out ".ptr["; gen index; out "]"; | ArrayRawPointer(arrayObj, index) -> gen arrayObj; out "["; gen index; out "]"; | ArrayVirtual(arrayObj, index) | ArrayDynamic(arrayObj, index) -> out "hx::IndexRef("; gen arrayObj; out ".mPtr,"; gen index; out ")"; | ArrayImplements(_,arrayObj,index) -> out "hx::__ArrayImplRef("; gen arrayObj; out ","; gen index; out ")"; ) | CppGlobalRef(name) -> out ("::" ^ name) | CppDynamicRef(expr,name) -> let objPtr = match expr.cpptype with | TCppVariant -> "getObject()" | _ -> ".mPtr" in out "hx::FieldRef(("; gen expr ; out (")" ^ objPtr ^ "," ^ strq name ^ ")") and gen_val_loc loc lvalue = match loc with | VarClosure(var) -> out (cpp_var_name_of var) | VarLocal(local) -> out (cpp_var_name_of local) | VarStatic(clazz,objc,member) -> let rename = get_meta_string member.cf_meta Meta.Native in if rename <> "" then out rename else if objc then (out ( (join_class_path_remap clazz.cl_path "::") ); out ("." ^ (cpp_member_name_of member))) else (out (cpp_class_name clazz ); out ("::" ^ (cpp_member_name_of member))) | VarThis(member) -> out ("this->" ^ (cpp_member_name_of member)) | VarInstance(obj,member,_,operator) -> gen obj; out (operator ^ (cpp_member_name_of member)) | VarInternal(obj,operator,member) -> gen obj; out (operator ^ member) | VarInterface(obj,member) -> gen obj; out ("->" ^ (cpp_member_name_of member) ^ "_get()" ) and string_of_op_eq op pos = match op with | OpAdd -> "hx::AddEq" | OpMult -> "hx::MultEq" | OpDiv -> "hx::DivEq" | OpSub -> "hx::SubEq" | OpAnd -> "hx::AndEq" | OpOr -> "hx::OrEq" | OpXor -> "hx::XorEq" | OpShl -> "hx::ShlEq" | OpShr -> "hx::ShrEq" | OpUShr -> "hx::UShrEq" | OpMod -> "hx::ModEq" | _ -> abort "Bad assign op" pos and string_of_op op pos = match op with | OpAdd -> "+" | OpMult -> "*" | OpDiv -> "/" | OpSub -> "-" | OpEq -> "==" | OpNotEq -> "!=" | OpGt -> ">" | OpGte -> ">=" | OpLt -> "<" | OpLte -> "<=" | OpAnd -> "&" | OpOr -> "|" | OpXor -> "^" | OpBoolAnd -> "&&" | OpBoolOr -> "||" | OpShl -> "<<" | OpShr -> ">>" | OpUShr -> "<<<" | OpMod -> "%" | OpInterval -> "..." | OpArrow -> "->" | OpAssign | OpAssignOp _ -> abort "Unprocessed OpAssign" pos and string_of_path path = "::" ^ (join_class_path_remap path "::") ^ "_obj" and gen_closure closure = let argc = Hashtbl.length closure.close_undeclared in let size = string_of_int argc in if argc >= 62 then (* Limited by c++ macro size of 128 args *) abort "Too many capture variables" closure.close_expr.cpppos; if argc >= 20 || (List.length closure.close_args) >= 20 then writer#add_big_closures; let argsCount = list_num closure.close_args in output_i ("HX_BEGIN_LOCAL_FUNC_S" ^ size ^ "("); out (if closure.close_this != None then "hx::LocalThisFunc," else "hx::LocalFunc,"); out ("_hx_Closure_" ^ (string_of_int closure.close_id) ); Hashtbl.iter (fun name var -> out ("," ^ (cpp_macro_var_type_of ctx var) ^ "," ^ (keyword_remap name)); ) closure.close_undeclared; out (") HXARGC(" ^ argsCount ^")\n"); let func_type = tcpp_to_string closure.close_type in output_i (func_type ^ " _hx_run(" ^ (cpp_arg_list ctx closure.close_args "__o_") ^ ")"); let prologue = function gc_stack -> cpp_gen_default_values ctx closure.close_args "__o_"; hx_stack_push ctx output_i class_name func_name closure.close_expr.cpppos gc_stack; if (ctx.ctx_debug_level>=2) then begin if (closure.close_this != None) then output_i ("HX_STACK_THIS(__this.mPtr)\n"); List.iter (fun (v,_) -> output_i ("HX_STACK_ARG(" ^ (cpp_var_name_of v) ^ ",\"" ^ (cpp_debug_name_of v) ^"\")\n") ) (List.filter (cpp_debug_var_visible ctx) closure.close_args); let line = Lexer.get_error_line closure.close_expr.cpppos in let lineName = Printf.sprintf "%4d" line in out ("HXLINE(" ^ lineName ^ ")\n" ); end in gen_with_injection (mk_injection prologue "" "") closure.close_expr; let return = match closure.close_type with TCppVoid -> "(void)" | _ -> "return" in output_i ("HX_END_LOCAL_FUNC" ^ argsCount ^ "(" ^ return ^ ")\n\n"); in (*out "\t";*) gen_with_injection injection cppTree; ;; (* } *) let gen_cpp_function_body ctx clazz is_static func_name function_def head_code tail_code no_debug = let output = ctx.ctx_output in let dot_name = join_class_path clazz.cl_path "." in if no_debug then ctx.ctx_debug_level <- 0; let prologue = function gc_stack -> let spacer = if no_debug then "\t" else " \t" in let output_i = fun s -> output (spacer ^ s) in ctx_default_values ctx function_def.tf_args "__o_"; hx_stack_push ctx output_i dot_name func_name function_def.tf_expr.epos gc_stack; if ctx.ctx_debug_level >= 2 then begin if (not is_static) then output_i ("HX_STACK_THIS(" ^ (if ctx.ctx_real_this_ptr then "this" else "__this") ^")\n"); List.iter (fun (v,_) -> if not (cpp_no_debug_synbol ctx v) then output_i ("HX_STACK_ARG(" ^ (cpp_var_name_of v) ^ ",\"" ^ v.v_name ^"\")\n") ) function_def.tf_args; let line = Lexer.get_error_line function_def.tf_expr.epos in let lineName = Printf.sprintf "%4d" line in output ("HXLINE(" ^ lineName ^ ")\n" ); end; if (head_code<>"") then output_i (head_code ^ "\n"); in let args = List.map fst function_def.tf_args in let injection = mk_injection prologue "" tail_code in gen_cpp_ast_expression_tree ctx dot_name func_name args function_def.tf_type injection (mk_block function_def.tf_expr); ;; let gen_cpp_init ctx dot_name func_name var_name expr = let output = ctx.ctx_output in let prologue = function gc_stack -> let spacer = if ctx.ctx_debug_level > 0 then " \t" else "\t" in let output_i = fun s -> output (spacer ^ s) in hx_stack_push ctx output_i dot_name func_name expr.epos gc_stack; in let injection = mk_injection prologue var_name "" in gen_cpp_ast_expression_tree ctx dot_name func_name [] t_dynamic injection (mk_block expr); ;; (* let is_dynamic_haxe_method f = match follow f.cf_type with | TFun _ when f.cf_expr = None -> true | _ -> (match f.cf_expr with | Some { eexpr = TFunction fd } when f.cf_set = MethodAccess true -> true | Some { eexpr = TFunction fd } when f.cf_set = NormalAccess -> true | _ -> false);; *) let is_dynamic_haxe_method f = (match f.cf_expr, f.cf_kind with | Some { eexpr = TFunction _ }, (Var _ | Method MethDynamic) -> true | _ -> false);; let is_data_member field = match field.cf_kind with | Var _ | Method MethDynamic -> true | _ -> false;; let is_override class_def field = List.exists (fun f -> f.cf_name = field) class_def.cl_overrides ;; let current_virtual_functions clazz = List.rev (List.fold_left (fun result elem -> match follow elem.cf_type, elem.cf_kind with | _, Method MethDynamic -> result | TFun (args,return_type), Method _ when not (is_override clazz elem.cf_name ) -> (elem,args,return_type) :: result | _,_ -> result ) [] clazz.cl_ordered_fields) ;; let all_virtual_functions clazz = let rec all_virtual_functions clazz = (match clazz.cl_super with | Some def -> all_virtual_functions (fst def) | _ -> [] ) @ current_virtual_functions clazz in all_virtual_functions clazz ;; let rec unreflective_type t = match follow t with | TInst (klass,_) -> Meta.has Meta.Unreflective klass.cl_meta | TFun (args,ret) -> List.fold_left (fun result (_,_,t) -> result || (unreflective_type t)) (unreflective_type ret) args; | _ -> false ;; let reflective class_def field = not ( (Meta.has Meta.NativeGen class_def.cl_meta) || (Meta.has Meta.Unreflective class_def.cl_meta) || (Meta.has Meta.Unreflective field.cf_meta) || unreflective_type field.cf_type ) ;; let field_arg_count field = match follow field.cf_type, field.cf_kind with | _, Method MethDynamic -> -1 | TFun (args,return_type), Method _ -> List.length args | _,_ -> -1 ;; let native_field_name_remap is_static field = let remap_name = keyword_remap field.cf_name in if not is_static then remap_name else begin let nativeImpl = get_meta_string field.cf_meta Meta.Native in if nativeImpl<>"" then begin let r = Str.regexp "^[a-zA-Z_0-9]+$" in if Str.string_match r remap_name 0 then "_hx_" ^ remap_name else "_hx_f" ^ (gen_hash 0 remap_name) end else remap_name end ;; let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface field = let output = ctx.ctx_output in ctx.ctx_real_this_ptr <- not is_static; let remap_name = keyword_remap field.cf_name in let decl = get_meta_string field.cf_meta Meta.Decl in let has_decl = decl <> "" in if (is_interface) then begin (* Just the dynamic glue - not even that ... *) () end else (match field.cf_expr with (* Function field *) | Some { eexpr = TFunction function_def } -> let return_type_str = (ctx_type_string ctx function_def.tf_type) in let nargs = string_of_int (List.length function_def.tf_args) in let return_type = (cpp_type_of ctx function_def.tf_type ) in let is_void = return_type = TCppVoid in let ret = if is_void then "(void)" else "return " in let needsWrapper t = match t with | TCppStar _ -> true | TCppInst(t) -> has_meta_key t.cl_meta Meta.StructAccess | _ -> false in let orig_debug = ctx.ctx_debug_level in let no_debug = has_meta_key field.cf_meta Meta.NoDebug in if (not (is_dynamic_haxe_method field)) then begin (* The actual function definition *) let nativeImpl = get_meta_string field.cf_meta Meta.Native in let remap_name = native_field_name_remap is_static field in output (if is_void then "void" else return_type_str ); output (" " ^ class_name ^ "::" ^ remap_name ^ "(" ); output (ctx_arg_list ctx function_def.tf_args "__o_"); output ")"; ctx.ctx_real_this_ptr <- true; let code = (get_code field.cf_meta Meta.FunctionCode) in let tail_code = (get_code field.cf_meta Meta.FunctionTailCode) in if nativeImpl<>"" && is_static then begin output " {\n"; output ("\t" ^ ret ^ "::" ^ nativeImpl ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n"); output "}\n\n"; end else gen_cpp_function_body ctx class_def is_static field.cf_name function_def code tail_code no_debug; output "\n\n"; let nonVirtual = has_meta_key field.cf_meta Meta.NonVirtual in let doDynamic = (nonVirtual || not (is_override class_def field.cf_name ) ) && (reflective class_def field ) in (* generate dynamic version too ... *) if ( doDynamic ) then begin let tcpp_args = List.map (fun (v,_) -> cpp_type_of ctx v.v_type ) function_def.tf_args in let wrap = (needsWrapper return_type) || (List.exists needsWrapper tcpp_args) in if wrap then begin let wrapName = "_hx_wrap" ^ class_name ^ "_" ^ remap_name in output ("static ::Dynamic " ^ wrapName ^ "( " ); let sep = ref " " in if not is_static then begin output "hx::Object *obj"; sep := ","; end; ExtList.List.iteri (fun i _ -> output (!sep ^ "const Dynamic &a" ^ (string_of_int i)) ; sep:=",") tcpp_args; output ( ") {\n\t"); if not is_void then begin match return_type with | TCppStar _ -> output "return (cpp::Pointer) " | TCppInst(t) when has_meta_key t.cl_meta Meta.StructAccess -> output ("return (cpp::Struct< " ^ (tcpp_to_string return_type) ^ " >) "); | _ -> output "return "; end; if is_static then output (class_name ^ "::" ^ remap_name ^ "(") else output ("reinterpret_cast< " ^ class_name ^ " *>(obj)->" ^ remap_name ^ "("); sep := ""; ExtList.List.iteri (fun i arg -> output !sep; sep := ","; (match arg with | TCppStar (t,const) -> output ("(cpp::" ^ (if const then "Const" else "") ^"Pointer<" ^ (tcpp_to_string t)^" >) ") | TCppInst(t) when has_meta_key t.cl_meta Meta.StructAccess -> output ("(cpp::Struct< " ^ (tcpp_to_string return_type) ^ " >) "); | _ -> () ); output ("a" ^ (string_of_int i)); ) tcpp_args; output ");\n"; if is_void then output "\treturn null();\n"; output "}\n"; let nName = string_of_int (List.length tcpp_args) in output ("::Dynamic " ^ class_name ^ "::" ^ remap_name ^ "_dyn() {\n\treturn "); if is_static then output ("hx::CreateStaticFunction" ^ nName ^ "(\"" ^ remap_name ^ "\"," ^ wrapName ^ ");") else output ("hx::CreateMemberFunction" ^ nName ^ "(\"" ^ remap_name ^ "\",this," ^ wrapName ^ ");"); output "}\n"; end else begin if (is_static) then output "STATIC_"; output ("HX_DEFINE_DYNAMIC_FUNC" ^ nargs ^ "(" ^ class_name ^ "," ^ remap_name ^ "," ^ ret ^ ")\n\n"); end end; end else begin ctx.ctx_real_this_ptr <- false; let func_name = "__default_" ^ (remap_name) in output ("HX_BEGIN_DEFAULT_FUNC(" ^ func_name ^ "," ^ class_name ^ ")\n"); output return_type_str; output (" _hx_run(" ^ (ctx_arg_list ctx function_def.tf_args "__o_") ^ ")"); gen_cpp_function_body ctx class_def is_static func_name function_def "" "" no_debug; output ("HX_END_LOCAL_FUNC" ^ nargs ^ "(" ^ ret ^ ")\n"); output ("HX_END_DEFAULT_FUNC\n\n"); if (is_static) then output ( "::Dynamic " ^ class_name ^ "::" ^ remap_name ^ ";\n\n"); end; ctx.ctx_debug_level <- orig_debug (* Data field *) | _ when has_decl -> if is_static then begin output ( class_name ^ "::" ^ remap_name ^ "_decl "); output ( " " ^ class_name ^ "::" ^ remap_name ^ ";\n\n"); end | _ -> if is_static && (not (is_extern_field field)) then begin gen_type ctx field.cf_type; output ( " " ^ class_name ^ "::" ^ remap_name ^ ";\n\n"); end ) ;; let gen_field_init ctx class_def field = let dot_name = join_class_path class_def.cl_path "." in let output = ctx.ctx_output in let remap_name = keyword_remap field.cf_name in match field.cf_expr with (* Function field *) | Some { eexpr = TFunction function_def } -> if (is_dynamic_haxe_method field) then begin let func_name = "__default_" ^ (remap_name) in output ( "\t" ^ remap_name ^ " = new " ^ func_name ^ ";\n\n" ); end (* Data field *) | Some expr -> let var_name = ( match remap_name with | "__meta__" -> "__mClass->__meta__" | "__rtti" -> "__mClass->__rtti__" | _ -> remap_name ) in gen_cpp_init ctx dot_name "boot" (var_name ^ " = ") expr | _ -> () ;; let cpp_interface_impl_name ctx interface = "_hx_" ^ (join_class_path interface.cl_path "_" ) ;; let cpp_class_hash interface = gen_hash 0 (join_class_path interface.cl_path "::" ) ;; let has_field_init field = match field.cf_expr with (* Function field *) | Some { eexpr = TFunction function_def } -> is_dynamic_haxe_method field (* Data field *) | Some _ -> true | _ -> false ;; let gen_member_def ctx class_def is_static is_interface field = let output = ctx.ctx_output in let remap_name = keyword_remap field.cf_name in let nativeGen = has_meta_key class_def.cl_meta Meta.NativeGen in if (is_interface) then begin match follow field.cf_type, field.cf_kind with | _, Method MethDynamic -> () | TFun (args,return_type), Method _ -> let gen_args = ctx_tfun_arg_list ctx true in if is_static || nativeGen then begin output ( (if (not is_static) then " virtual " else " " ) ^ (ctx_type_string ctx return_type) ); output (" " ^ remap_name ^ "( " ); output (gen_args args); output (if (not is_static) then ")=0;\n" else ");\n"); if (reflective class_def field) then begin if (Common.defined ctx.ctx_common Define.DynamicInterfaceClosures) then output (" inline ::Dynamic " ^ remap_name ^ "_dyn() { return __Field( " ^ (str field.cf_name) ^ ", hx::paccDynamic); }\n" ) else output (" virtual ::Dynamic " ^ remap_name ^ "_dyn()=0;\n" ); end end else begin let argList = gen_args args in let returnType = ctx_type_string ctx return_type in let returnStr = if returnType = "void" then "" else "return " in let commaArgList = if argList="" then argList else "," ^ argList in let cast = "static_cast< ::" ^ join_class_path_remap class_def.cl_path "::" ^ "_obj *>" in output (" " ^ returnType ^ " (hx::Object :: *_hx_" ^ remap_name ^ ")(" ^ argList ^ "); \n"); output (" static inline " ^ returnType ^ " " ^ remap_name ^ "( ::Dynamic _hx_" ^ commaArgList ^ ") {\n"); output (" " ^ returnStr ^ "(_hx_.mPtr->*( " ^ cast ^ "(_hx_.mPtr->_hx_getInterface(" ^ (cpp_class_hash class_def) ^ ")))->_hx_" ^ remap_name ^ ")(" ^ cpp_arg_names args ^ ");\n }\n" ); end | _ -> ( ) end else begin let decl = get_meta_string field.cf_meta Meta.Decl in let has_decl = decl <> "" in if (has_decl) then output ( " typedef " ^ decl ^ ";\n" ); output (if is_static then "\t\tstatic " else "\t\t"); (match field.cf_expr with | Some { eexpr = TFunction function_def } -> let nonVirtual = has_meta_key field.cf_meta Meta.NonVirtual in let doDynamic = (nonVirtual || not (is_override class_def field.cf_name ) ) && (reflective class_def field ) in if ( is_dynamic_haxe_method field ) then begin if ( doDynamic ) then begin output ("::Dynamic " ^ remap_name ^ ";\n"); if (not is_static) && (is_gc_element ctx TCppDynamic) then output ("\t\tinline ::Dynamic _hx_set_" ^ remap_name ^ "(hx::Ctx *_hx_ctx,::Dynamic _hx_v) { HX_OBJ_WB(this,_hx_v) return " ^ remap_name ^ "=_hx_v; }\n"); output (if is_static then "\t\tstatic " else "\t\t"); output ("inline ::Dynamic &" ^ remap_name ^ "_dyn() " ^ "{return " ^ remap_name^ "; }\n") end end else begin let return_type = (ctx_type_string ctx function_def.tf_type) in if ( not is_static && not nonVirtual ) then begin let scriptable = Common.defined ctx.ctx_common Define.Scriptable in if (not (is_internal_member field.cf_name) && not scriptable ) then begin let key = (join_class_path class_def.cl_path ".") ^ "." ^ field.cf_name in try output (Hashtbl.find ctx.ctx_class_member_types key) with Not_found -> () end else output "virtual "; end; output (if return_type="Void" then "void" else return_type ); let remap_name = native_field_name_remap is_static field in output (" " ^ remap_name ^ "(" ); output (ctx_arg_list ctx function_def.tf_args "" ); output ");\n"; if ( doDynamic ) then begin output (if is_static then "\t\tstatic " else "\t\t"); output ("::Dynamic " ^ remap_name ^ "_dyn();\n" ) end; end; output "\n"; | _ when has_decl -> output ( remap_name ^ "_decl " ^ remap_name ^ ";\n" ); (* Variable access *) | _ -> (* Variable access *) let tcpp = cpp_type_of ctx field.cf_type in let tcppStr = tcpp_to_string tcpp in if not is_static && only_stack_access ctx field.cf_type then abort ("Variables of type " ^ tcppStr ^ " may not be used as members") field.cf_pos; output (tcppStr ^ " " ^ remap_name ^ ";\n" ); if not is_static && (is_gc_element ctx tcpp) then output ("\t\tinline " ^ tcppStr ^ " _hx_set_" ^ remap_name ^ "(hx::Ctx *_hx_ctx," ^ tcppStr ^ " _hx_v) { HX_OBJ_WB(this,_hx_v) return " ^ remap_name ^ "=_hx_v; }\n"); (* Add a "dyn" function for variable to unify variable/function access *) (match follow field.cf_type with | _ when nativeGen -> () | TFun (_,_) -> output (if is_static then "\t\tstatic " else "\t\t"); output ("Dynamic " ^ remap_name ^ "_dyn() { return " ^ remap_name ^ ";}\n" ) | _ -> (match field.cf_kind with | Var { v_read = AccCall } when (not is_static) && (is_dynamic_accessor ("get_" ^ field.cf_name) "get" field class_def) -> output ("\t\tDynamic get_" ^ field.cf_name ^ ";\n" ) | _ -> () ); (match field.cf_kind with | Var { v_write = AccCall } when (not is_static) && (is_dynamic_accessor ("set_" ^ field.cf_name) "set" field class_def) -> output ("\t\tDynamic set_" ^ field.cf_name ^ ";\n" ) | _ -> () ) ) ); end ;; let path_of_string path = ["@verbatim"], path ;; (* Get a list of all classes referred to by the class/enum definition These are used for "#include"ing the appropriate header files, or for building the dependencies in the Build.xml file *) let find_referenced_types_flags ctx obj field_name super_deps constructor_deps header_only for_depends include_super_args = let types = ref PMap.empty in let rec add_type_flag isNative in_path = if ( not (PMap.mem in_path !types)) then begin types := (PMap.add in_path isNative !types); try List.iter (add_type_flag isNative) (Hashtbl.find super_deps in_path); with Not_found -> () end and add_type in_path = add_type_flag false in_path in let add_extern_type decl = let tinfo = t_infos decl in let include_file = get_meta_string_path tinfo.mt_meta (if for_depends then Meta.Depend else Meta.Include) in if (include_file<>"") then add_type ( path_of_string include_file ) else if (not for_depends) && (has_meta_key tinfo.mt_meta Meta.Include) then add_type tinfo.mt_path in let add_extern_class klass = add_extern_type (TClassDecl klass) in let add_native_gen_class klass = let include_file = get_meta_string_path klass.cl_meta (if for_depends then Meta.Depend else Meta.Include) in if (include_file<>"") then add_type ( path_of_string include_file ) else if for_depends then add_type klass.cl_path else begin let path = klass.cl_path in if not klass.cl_interface then (* Always include native struct headers directly ... *) add_type ( path_of_string ( (join_class_path path "/") ^ ".h") ) else begin add_type_flag true klass.cl_path end end in let visited = ref [] in let rec visit_type in_type = if not (List.exists (fun t2 -> Type.fast_eq in_type t2) !visited) then begin visited := in_type :: !visited; begin match follow in_type with | TMono r -> (match !r with None -> () | Some t -> visit_type t) | TEnum (enum,params) -> add_type enum.e_path (* If a class has a template parameter, then we treat it as dynamic - except for the Array, Class, FastIterator or Pointer classes, for which we do a fully typed object *) | TInst (klass,params) -> (match klass.cl_path with | ([],"Array") | ([],"Class") | (["cpp"],"FastIterator") | (["cpp"],"Pointer") | (["cpp"],"ConstPointer") | (["cpp"],"Function") | (["cpp"],"RawPointer") | (["cpp"],"RawConstPointer") -> List.iter visit_type params | _ when is_native_gen_class klass -> add_native_gen_class klass | _ when is_extern_class klass -> add_extern_class klass | _ -> (match klass.cl_kind with KTypeParameter _ -> () | _ -> add_type klass.cl_path); ) | TAbstract (a,params) when is_scalar_abstract a -> add_extern_type (TAbstractDecl a) | TFun (args,haxe_type) -> visit_type haxe_type; List.iter (fun (_,_,t) -> visit_type t; ) args; | _ -> () end; visited := List.tl !visited; end in let rec visit_params expression = begin let rec visit_expression = fun expression -> (* Expand out TTypeExpr (ie, the name of a class, as used for static access etc ... *) (match expression.eexpr with | TTypeExpr type_def -> ( match type_def with | TClassDecl class_def when is_native_gen_class class_def -> add_native_gen_class class_def | TClassDecl class_def when is_extern_class class_def -> add_extern_class class_def | _ -> add_type (t_path type_def) ) (* Must visit the types, Type.iter will visit the expressions ... *) | TTry (e,catches) -> List.iter (fun (v,_) -> visit_type v.v_type) catches (* Must visit type too, Type.iter will visit the expressions ... *) | TNew (klass,params,_) -> begin visit_type (TInst (klass,params)); try let construct_type = Hashtbl.find constructor_deps klass.cl_path in visit_type construct_type.cf_type with Not_found -> (); end (* Must visit type too, Type.iter will visit the expressions ... *) | TVar (v,_) -> visit_type v.v_type (* Must visit enum type too, Type.iter will visit the expressions ... *) | TEnumParameter (_,ef,_) -> visit_type (follow ef.ef_type) (* Must visit args too, Type.iter will visit the expressions ... *) | TFunction func_def -> List.iter (fun (v,_) -> visit_type v.v_type) func_def.tf_args; | TField( obj, field ) -> (match field with | FInstance (clazz,params,_) | FClosure (Some (clazz,params),_) -> visit_type (TInst (clazz,params)) | _ -> () ) | TConst TSuper -> (match follow expression.etype with | TInst (klass,params) -> (try let construct_type = Hashtbl.find constructor_deps klass.cl_path in visit_type construct_type.cf_type with Not_found -> () ) | _ -> print_endline ("TSuper : Odd etype ?" ^ ( (ctx_type_string ctx expression.etype)) ) ) | _ -> () ); Type.iter visit_expression expression; visit_type (follow expression.etype) in visit_expression expression end in let visit_field field = (* Add the type of the expression ... *) visit_type field.cf_type; if (not header_only) then (match field.cf_expr with | Some expression -> visit_params expression | _ -> ()); in let visit_class class_def = let fields = List.append class_def.cl_ordered_fields class_def.cl_ordered_statics in let fields_and_constructor = List.append fields (match class_def.cl_constructor with | Some expr -> [expr] | _ -> [] ) in let fields_and_constructor = if field_name="*" then fields_and_constructor else List.filter (fun f -> f.cf_name=field_name) fields_and_constructor in List.iter visit_field fields_and_constructor; if (include_super_args) then List.iter visit_field (List.map (fun (a,_,_) -> a ) (all_virtual_functions class_def )); (* Add super & interfaces *) if is_native_gen_class class_def then add_native_gen_class class_def else add_type class_def.cl_path; in let visit_enum enum_def = add_type enum_def.e_path; PMap.iter (fun _ constructor -> (match constructor.ef_type with | TFun (args,_) -> List.iter (fun (_,_,t) -> visit_type t; ) args; | _ -> () ); ) enum_def.e_constrs; if (not header_only) then begin let meta = Codegen.build_metadata ctx.ctx_common (TEnumDecl enum_def) in match meta with Some expr -> visit_params expr | _ -> (); end; in let inc_cmp i1 i2 = String.compare (join_class_path i1 ".") (join_class_path i2 ".") in (* Body of main function *) (match obj with | TClassDecl class_def -> visit_class class_def; (match class_def.cl_init with Some expression -> visit_params expression | _ -> ()) | TEnumDecl enum_def -> visit_enum enum_def | TTypeDecl _ | TAbstractDecl _ -> (* These are expanded *) ()); let deps = List.sort inc_cmp (List.filter (fun path -> (include_class_header path) ) (pmap_keys !types)) in let flags = List.map (fun dep -> PMap.find dep !types) deps in deps, flags ;; let find_referenced_types ctx obj super_deps constructor_deps header_only for_depends include_super_args = let deps,_ = find_referenced_types_flags ctx obj "*" super_deps constructor_deps header_only for_depends include_super_args in deps ;; let generate_main_header output_main = output_main "#include \n\n"; output_main "#include \n\n"; output_main "extern \"C\" void __hxcpp_main();\n\n"; output_main "extern \"C\" void __hxcpp_lib_main();\n\n" ;; let generate_main_footer1 output_main = output_main "void __hxcpp_main() {\n";; let generate_main_footer2 output_main = output_main " }\n\n"; output_main "void __hxcpp_lib_main() {\n"; output_main " HX_TOP_OF_STACK\n"; output_main " hx::Boot();\n"; output_main " __boot_all();\n"; output_main " __hxcpp_main();\n"; output_main " }\n" ;; let generate_main ctx super_deps class_def = let common_ctx = ctx.ctx_common in (* main routine should be a single static function *) let main_expression = (match class_def.cl_ordered_statics with | [{ cf_expr = Some expression }] -> expression; | _ -> assert false ) in ignore(find_referenced_types ctx (TClassDecl class_def) super_deps (Hashtbl.create 0) false false false); let depend_referenced = find_referenced_types ctx (TClassDecl class_def) super_deps (Hashtbl.create 0) false true false in let generate_startup filename is_main = (*make_class_directories base_dir ( "src" :: []);*) let cpp_file = new_cpp_file common_ctx common_ctx.file ([],filename) in let output_main = (cpp_file#write) in generate_main_header (cpp_file#write_h); List.iter ( add_include cpp_file ) depend_referenced; output_main "\n\n"; if is_main then output_main "\n#include \n\n"; generate_main_footer1 output_main; let ctx = file_context ctx cpp_file 1 false in gen_cpp_init ctx "hxcpp" "__hxcpp_main" "" main_expression; generate_main_footer2 output_main; cpp_file#close; in generate_startup "__main__" true; generate_startup "__lib__" false ;; let generate_dummy_main common_ctx = let generate_startup filename is_main = let main_file = new_cpp_file common_ctx common_ctx.file ([],filename) in let output_main = (main_file#write) in generate_main_header (main_file#write_h); if is_main then output_main "\n#include \n\n"; generate_main_footer1 output_main; generate_main_footer2 output_main; main_file#close; in generate_startup "__main__" true; generate_startup "__lib__" false ;; let generate_boot ctx boot_enums boot_classes nonboot_classes init_classes = let common_ctx = ctx.ctx_common in (* Write boot class too ... *) let base_dir = common_ctx.file in let boot_file = new_cpp_file common_ctx base_dir ([],"__boot__") in let output_boot = (boot_file#write) in boot_file#write_h "#include \n\n"; List.iter ( fun class_path -> boot_file#add_include class_path ) (boot_enums @ boot_classes @ nonboot_classes); let newScriptable = (Common.defined common_ctx Define.Scriptable) in if newScriptable then begin output_boot "#include \n"; let funcs = hash_iterate !(ctx.ctx_interface_slot) (fun name id -> (name,id) ) in let sorted = List.sort (fun (_,id1) (_,id2) -> id1-id2 ) funcs in output_boot "static const char *scriptableInterfaceFuncs[] = {\n\t0,\n\t0,\n"; List.iter (fun (name,id) -> output_boot ("\t\"" ^ name ^ "\", //" ^ (string_of_int (-id) ) ^ "\n")) sorted; output_boot "};\n"; end; output_boot "\nvoid __files__boot();\n"; output_boot "\nvoid __boot_all()\n{\n"; output_boot "__files__boot();\n"; output_boot "hx::RegisterResources( hx::GetResources() );\n"; if newScriptable then output_boot ("hx::ScriptableRegisterNameSlots(scriptableInterfaceFuncs," ^ (string_of_int !(ctx.ctx_interface_slot_count) ) ^ ");\n"); List.iter ( fun class_path -> output_boot ("::" ^ ( join_class_path_remap class_path "::" ) ^ "_obj::__register();\n") ) (boot_enums @ boot_classes @ nonboot_classes); let dump_boot = List.iter ( fun class_path -> output_boot ("::" ^ ( join_class_path_remap class_path "::" ) ^ "_obj::__boot();\n") ) in dump_boot boot_enums; List.iter ( fun class_path -> output_boot ("::" ^ ( join_class_path_remap class_path "::" ) ^ "_obj::__init__();\n") ) (List.rev init_classes); dump_boot (List.filter (fun path -> is_cpp_class path ) (List.rev boot_classes)); dump_boot (List.filter (fun path -> not (is_cpp_class path) ) (List.rev boot_classes)); output_boot "}\n\n"; boot_file#close;; let generate_files common_ctx file_info = (* Write __files__ class too ... *) let base_dir = common_ctx.file in let files_file = new_cpp_file common_ctx base_dir ([],"__files__") in let output_files = (files_file#write) in let types = common_ctx.types in files_file#write_h "#include \n\n"; output_files "namespace hx {\n"; output_files "const char *__hxcpp_all_files[] = {\n"; output_files "#ifdef HXCPP_DEBUGGER\n"; List.iter ( fun file -> output_files ((const_char_star file)^",\n" ) ) ( List.sort String.compare ( pmap_keys !file_info) ); output_files "#endif\n"; output_files " 0 };\n"; output_files "\n"; output_files "const char *__hxcpp_all_files_fullpath[] = {\n"; output_files "#ifdef HXCPP_DEBUGGER\n"; List.iter ( fun file -> output_files ((const_char_star ( Path.get_full_path (try Common.find_file common_ctx file with Not_found -> file) ))^",\n" ) ) ( List.sort String.compare ( pmap_keys !file_info) ); output_files "#endif\n"; output_files " 0 };\n"; output_files "\n"; output_files "const char *__hxcpp_all_classes[] = {\n"; output_files "#ifdef HXCPP_DEBUGGER\n"; List.iter ( fun object_def -> (match object_def with | TClassDecl class_def when is_extern_class class_def -> ( ) | TClassDecl class_def when class_def.cl_interface -> ( ) | TClassDecl class_def -> output_files ((const_char_star (join_class_path class_def.cl_path "." )) ^ ",\n") | _ -> ( ) ) ) types; output_files "#endif\n"; output_files " 0 };\n"; output_files "} // namespace hx\n"; output_files "void __files__boot() { __hxcpp_set_debugger_info(hx::__hxcpp_all_classes, hx::__hxcpp_all_files_fullpath); }\n"; files_file#close;; let begin_header_file output_h def_string nativeGen = output_h ("#ifndef INCLUDED_" ^ def_string ^ "\n"); output_h ("#define INCLUDED_" ^ def_string ^ "\n\n"); output_h "#ifndef HXCPP_H\n"; if nativeGen then begin output_h "#ifdef HXCPP_API_LEVEL\n"; output_h "#include \n"; output_h "#else\n"; output_h "#include \n"; output_h "#endif\n" end else begin output_h "#include \n" end; output_h "#endif\n\n";; let end_header_file output_h def_string = output_h ("\n#endif /* INCLUDED_" ^ def_string ^ " */ \n");; let new_placed_cpp_file common_ctx class_path = let base_dir = common_ctx.file in if (Common.defined common_ctx Define.Vcproj ) then begin make_class_directories base_dir ("src"::[]); cached_source_writer common_ctx ( base_dir ^ "/src/" ^ ( String.concat "-" (fst class_path) ) ^ "-" ^ (snd class_path) ^ (source_file_extension common_ctx) ) end else new_cpp_file common_ctx common_ctx.file class_path;; let generate_enum_files baseCtx enum_def super_deps meta = let common_ctx = baseCtx.ctx_common in let class_path = enum_def.e_path in let just_class_name = (snd class_path) in let class_name = just_class_name ^ "_obj" in let remap_class_name = ("::" ^ (join_class_path_remap class_path "::") ) in (*let cpp_file = new_cpp_file common_ctx.file class_path in*) let cpp_file = new_placed_cpp_file common_ctx class_path in let output_cpp = (cpp_file#write) in let debug = if (has_meta_key enum_def.e_meta Meta.NoDebug) || ( Common.defined common_ctx Define.NoDebug) then 0 else 1 in let ctx = file_context baseCtx cpp_file debug false in if (debug>1) then print_endline ("Found enum definition:" ^ (join_class_path class_path "::" )); cpp_file#write_h "#include \n\n"; let referenced,flags = find_referenced_types_flags ctx (TEnumDecl enum_def) "*" super_deps (Hashtbl.create 0) false false false in List.iter (add_include cpp_file) referenced; gen_open_namespace output_cpp class_path; output_cpp "\n"; PMap.iter (fun _ constructor -> let name = keyword_remap constructor.ef_name in match constructor.ef_type with | TFun (args,_) -> output_cpp (remap_class_name ^ " " ^ class_name ^ "::" ^ name ^ "(" ^ (ctx_tfun_arg_list ctx true args) ^")\n"); output_cpp ("{\n\treturn hx::CreateEnum< " ^ class_name ^ " >(" ^ (strq name) ^ "," ^ (string_of_int constructor.ef_index) ^ "," ^ (string_of_int (List.length args)) ^ ")" ); ExtList.List.iteri (fun i (arg,_,_) -> output_cpp ("->_hx_init(" ^ (string_of_int i) ^ "," ^ (keyword_remap arg) ^ ")")) args; output_cpp ";\n}\n\n" | _ -> output_cpp ( remap_class_name ^ " " ^ class_name ^ "::" ^ name ^ ";\n\n" ) ) enum_def.e_constrs; let constructor_arg_count constructor = (match constructor.ef_type with | TFun(args,_) -> List.length args | _ -> 0 ) in output_cpp ("bool " ^ class_name ^ "::__GetStatic(const ::String &inName, ::Dynamic &outValue, hx::PropertyAccess inCallProp)\n{\n"); PMap.iter (fun _ constructor -> let name = constructor.ef_name in let dyn = if constructor_arg_count constructor > 0 then "_dyn()" else "" in output_cpp ("\tif (inName==" ^ strq name ^ ") { outValue = " ^ class_name ^ "::" ^ keyword_remap name ^ dyn ^ "; return true; }\n" ); ) enum_def.e_constrs; output_cpp ("\treturn super::__GetStatic(inName, outValue, inCallProp);\n}\n\n"); output_cpp ("HX_DEFINE_CREATE_ENUM(" ^ class_name ^ ")\n\n"); output_cpp ("int " ^ class_name ^ "::__FindIndex(::String inName)\n{\n"); PMap.iter (fun _ constructor -> let name = constructor.ef_name in let idx = string_of_int constructor.ef_index in output_cpp ("\tif (inName==" ^ (strq name) ^ ") return " ^ idx ^ ";\n") ) enum_def.e_constrs; output_cpp ("\treturn super::__FindIndex(inName);\n"); output_cpp ("}\n\n"); (* Dynamic versions of constructors *) let dump_dynamic_constructor _ constr = let count = constructor_arg_count constr in if (count>0) then begin let nargs = string_of_int count in output_cpp ("STATIC_HX_DEFINE_DYNAMIC_FUNC" ^ nargs ^ "(" ^ class_name ^ "," ^ (keyword_remap constr.ef_name) ^ ",return)\n\n"); end in PMap.iter dump_dynamic_constructor enum_def.e_constrs; output_cpp ("int " ^ class_name ^ "::__FindArgCount(::String inName)\n{\n"); PMap.iter (fun _ constructor -> let name = constructor.ef_name in let count = string_of_int (constructor_arg_count constructor) in output_cpp ("\tif (inName==" ^ (strq name) ^ ") return " ^ count ^ ";\n") ) enum_def.e_constrs; output_cpp ("\treturn super::__FindArgCount(inName);\n"); output_cpp ("}\n\n"); (* Dynamic "Get" Field function - string version *) output_cpp ("hx::Val " ^ class_name ^ "::__Field(const ::String &inName,hx::PropertyAccess inCallProp)\n{\n"); let dump_constructor_test _ constr = output_cpp ("\tif (inName==" ^ (strq constr.ef_name) ^ ") return " ^ (keyword_remap constr.ef_name) ); if ( (constructor_arg_count constr) > 0 ) then output_cpp "_dyn()"; output_cpp (";\n") in PMap.iter dump_constructor_test enum_def.e_constrs; output_cpp ("\treturn super::__Field(inName,inCallProp);\n}\n\n"); output_cpp ("static ::String " ^ class_name ^ "_sStaticFields[] = {\n"); let sorted = List.sort (fun f1 f2 -> (PMap.find f1 enum_def.e_constrs ).ef_index - (PMap.find f2 enum_def.e_constrs ).ef_index ) (pmap_keys enum_def.e_constrs) in List.iter (fun name -> output_cpp ("\t" ^ (strq name) ^ ",\n") ) sorted; output_cpp "\t::String(null())\n};\n\n"; (* ENUM - Mark static as used by GC *) output_cpp ("static void " ^ class_name ^ "_sMarkStatics(HX_MARK_PARAMS) {\n"); PMap.iter (fun _ constructor -> let name = keyword_remap constructor.ef_name in match constructor.ef_type with | TFun (_,_) -> () | _ -> output_cpp ("\tHX_MARK_MEMBER_NAME(" ^ class_name ^ "::" ^ name ^ ",\"" ^ name ^ "\");\n") ) enum_def.e_constrs; output_cpp "};\n\n"; (* ENUM - Visit static as used by GC *) output_cpp "#ifdef HXCPP_VISIT_ALLOCS\n"; output_cpp ("static void " ^ class_name ^ "_sVisitStatic(HX_VISIT_PARAMS) {\n"); output_cpp ("\tHX_VISIT_MEMBER_NAME(" ^ class_name ^ "::__mClass,\"__mClass\");\n"); PMap.iter (fun _ constructor -> let name = keyword_remap constructor.ef_name in match constructor.ef_type with | TFun (_,_) -> () | _ -> output_cpp ("\tHX_VISIT_MEMBER_NAME(" ^ class_name ^ "::" ^ name ^ ",\"" ^ name ^ "\");\n") ) enum_def.e_constrs; output_cpp "};\n"; output_cpp "#endif\n\n"; output_cpp ("hx::Class " ^ class_name ^ "::__mClass;\n\n"); output_cpp ("Dynamic __Create_" ^ class_name ^ "() { return new " ^ class_name ^ "; }\n\n"); output_cpp ("void " ^ class_name ^ "::__register()\n{\n"); let text_name = str (join_class_path class_path ".") in output_cpp ("\nhx::Static(__mClass) = hx::_hx_RegisterClass(" ^ text_name ^ ", hx::TCanCast< " ^ class_name ^ " >," ^ class_name ^ "_sStaticFields,0,\n"); output_cpp ("\t&__Create_" ^ class_name ^ ", &__Create,\n"); output_cpp ("\t&super::__SGetClass(), &Create" ^ class_name ^ ", " ^ class_name ^ "_sMarkStatics\n"); output_cpp("#ifdef HXCPP_VISIT_ALLOCS\n , " ^ class_name ^ "_sVisitStatic\n#endif\n"); output_cpp ("#ifdef HXCPP_SCRIPTABLE\n , 0\n#endif\n"); output_cpp (");\n"); output_cpp ("\t__mClass->mGetStaticField = &" ^ class_name ^"::__GetStatic;\n"); output_cpp "}\n\n"; output_cpp ("void " ^ class_name ^ "::__boot()\n{\n"); (match meta with | Some expr -> let ctx = file_context ctx cpp_file 1 false in gen_cpp_init ctx class_name "boot" "__mClass->__meta__ = " expr | _ -> () ); PMap.iter (fun _ constructor -> let name = constructor.ef_name in match constructor.ef_type with | TFun (_,_) -> () | _ -> output_cpp ( (keyword_remap name) ^ " = hx::CreateEnum< " ^ class_name ^ " >(" ^ (str name) ^ "," ^ (string_of_int constructor.ef_index) ^ ",0);\n" ) ) enum_def.e_constrs; output_cpp ("}\n\n"); output_cpp "\n"; gen_close_namespace output_cpp class_path; cpp_file#close; let h_file = new_header_file common_ctx common_ctx.file class_path in let super = "hx::EnumBase_obj" in let output_h = (h_file#write) in let def_string = join_class_path class_path "_" in let ctx = file_context baseCtx h_file debug true in begin_header_file (h_file#write_h) def_string false; List.iter2 (fun r f -> gen_forward_decl h_file r f) referenced flags; gen_open_namespace output_h class_path; output_h "\n\n"; output_h ("class " ^ class_name ^ " : public " ^ super ^ "\n"); output_h ("{\n\ttypedef " ^ super ^ " super;\n"); output_h ("\t\ttypedef " ^ class_name ^ " OBJ_;\n"); output_h "\n\tpublic:\n"; output_h ("\t\t" ^ class_name ^ "() {};\n"); output_h ("\t\tHX_DO_ENUM_RTTI;\n"); output_h ("\t\tstatic void __boot();\n"); output_h ("\t\tstatic void __register();\n"); output_h ("\t\tstatic bool __GetStatic(const ::String &inName, Dynamic &outValue, hx::PropertyAccess inCallProp);\n"); output_h ("\t\t::String GetEnumName( ) const { return " ^ (str (join_class_path class_path ".")) ^ "; }\n" ); output_h ("\t\t::String __ToString() const { return " ^ (str (just_class_name ^ ".") )^ " + _hx_tag; }\n\n"); PMap.iter (fun _ constructor -> let name = keyword_remap constructor.ef_name in output_h ( "\t\tstatic " ^ remap_class_name ^ " " ^ name ); match constructor.ef_type with | TFun (args,_) -> output_h ( "(" ^ (ctx_tfun_arg_list ctx true args) ^");\n"); output_h ( "\t\tstatic ::Dynamic " ^ name ^ "_dyn();\n"); | _ -> output_h ";\n"; output_h ( "\t\tstatic inline " ^ remap_class_name ^ " " ^ name ^ "_dyn() { return " ^name ^ "; }\n" ); ) enum_def.e_constrs; output_h "};\n\n"; gen_close_namespace output_h class_path; end_header_file output_h def_string; h_file#close ;; let generate_enum_deps ctx enum_def super_deps = find_referenced_types ctx (TEnumDecl enum_def) super_deps (Hashtbl.create 0) false true false ;; let list_iteri func in_list = let idx = ref 0 in List.iter (fun elem -> func !idx elem; idx := !idx + 1 ) in_list ;; let has_new_gc_references ctx class_def = match class_def.cl_dynamic with | Some _ -> true | _ -> ( let is_gc_reference field = (should_implement_field field) && (is_data_member field) && not (ctx_cant_be_null ctx field.cf_type) in List.exists is_gc_reference class_def.cl_ordered_fields ) ;; let rec has_gc_references ctx class_def = ( match class_def.cl_super with | Some def when has_gc_references ctx (fst def) -> true | _ -> false ) || has_new_gc_references ctx class_def ;; let rec find_next_super_iteration ctx class_def = match class_def.cl_super with | Some (klass,params) when has_new_gc_references ctx klass -> tcpp_to_string_suffix "_obj" (cpp_instance_type ctx klass params) | Some (klass,_) -> find_next_super_iteration ctx klass | _ -> ""; ;; let has_init_field class_def = match class_def.cl_init with | Some _ -> true | _ -> false;; let is_abstract_impl class_def = match class_def.cl_kind with | KAbstractImpl _ -> true | _ -> false ;; let variable_field field = (match field.cf_expr with | Some { eexpr = TFunction function_def } -> is_dynamic_haxe_method field | _ -> true) ;; let is_readable class_def field = (match field.cf_kind with | Var { v_read = AccNever } when (is_extern_field field) -> false | Var { v_read = AccInline } -> false | Var _ when is_abstract_impl class_def -> false | _ -> true) ;; let is_writable class_def field = (match field.cf_kind with | Var { v_write = AccNever } when (is_extern_field field) -> false | Var { v_read = AccInline } -> false | Var _ when is_abstract_impl class_def -> false | _ -> true) ;; let statics_except_meta class_def = (List.filter (fun static -> static.cf_name <> "__meta__" && static.cf_name <> "__rtti") class_def.cl_ordered_statics);; let has_set_member_field class_def = implement_dynamic_here class_def || ( let reflect_fields = List.filter (reflective class_def) (class_def.cl_ordered_fields) in let reflect_writable = List.filter (is_writable class_def) reflect_fields in List.exists variable_field reflect_writable ) ;; let has_set_static_field class_def = let reflect_fields = List.filter (reflective class_def) (statics_except_meta class_def) in let reflect_writable = List.filter (is_writable class_def) reflect_fields in List.exists variable_field reflect_writable ;; let has_get_fields class_def = implement_dynamic_here class_def || ( let is_data_field field = (match follow field.cf_type with | TFun _ -> false | _ -> true) in List.exists is_data_field class_def.cl_ordered_fields ) ;; let has_get_member_field class_def = implement_dynamic_here class_def || ( let reflect_fields = List.filter (reflective class_def) (class_def.cl_ordered_fields) in List.exists (is_readable class_def) reflect_fields ) ;; let has_get_static_field class_def = let reflect_fields = List.filter (reflective class_def) (statics_except_meta class_def) in List.exists (is_readable class_def) reflect_fields ;; let has_boot_field class_def = match class_def.cl_init with | None -> List.exists has_field_init (List.filter should_implement_field class_def.cl_ordered_statics) | _ -> true ;; let cpp_tfun_signature ctx include_names args return_type = let argList = ctx_tfun_arg_list ctx include_names args in let returnType = ctx_type_string ctx return_type in ("( " ^ returnType ^ " (hx::Object::*)(" ^ argList ^ "))") ;; exception FieldFound of tclass_field;; let find_class_implementation ctx class_def name interface = let rec find def = List.iter (fun f -> if f.cf_name=name then raise (FieldFound f) ) def.cl_ordered_fields; match def.cl_super with | Some (def,_) -> find def | _ -> () in try find class_def; abort ("Could not find implementation of " ^ name ^ " in " ^ (join_class_path class_def.cl_path ".") ^ " required by " ^ (join_class_path interface.cl_path ".")) class_def.cl_pos with FieldFound field -> match follow field.cf_type, field.cf_kind with | _, Method MethDynamic -> "" | TFun (args,return_type), Method _ -> cpp_tfun_signature ctx false args return_type | _,_ -> "" ;; let is_macro meta = Meta.has Meta.Macro meta ;; let cpp_get_interface_slot ctx name = try Hashtbl.find !(ctx.ctx_interface_slot) name with Not_found -> begin let result = !(ctx.ctx_interface_slot_count) in Hashtbl.replace !(ctx.ctx_interface_slot) name result; ctx.ctx_interface_slot_count := !(ctx.ctx_interface_slot_count) + 1; result end ;; let access_str a = match a with | AccNormal -> "AccNormal" | AccNo -> "AccNo" | AccNever -> "AccNever" | AccResolve -> "AccResolve" | AccCall -> "AccCall" | AccInline -> "AccInline" | AccRequire(_,_) -> "AccRequire" ;; let script_type t optional = if optional then begin match type_string t with | "::String" -> "String" | _ -> "Object" end else match type_string t with | "bool" -> "Int" | "int" -> "Int" | "Float" -> "Float" | "::String" -> "String" | "Null" -> "Void" | "Void" -> "Void" | _ -> "Object" ;; let script_signature t optional = match script_type t optional with | "Bool" -> "b" | "Int" -> "i" | "Float" -> "f" | "String" -> "s" | "Void" -> "v" | "void" -> "v" | _ -> "o" ;; let script_size_type t optional = match script_type t optional with | "Object" -> "void *" | "Int" -> "int" | "Bool" -> "bool" | x -> x ;; let constructor_arg_var_list class_def ctx = match class_def.cl_constructor with | Some definition -> (match definition.cf_expr with | Some { eexpr = TFunction function_def } -> List.map (fun (v,o) -> (v.v_name, ctx_arg_type_name ctx v.v_name o v.v_type "__o_")) function_def.tf_args; | _ -> (match follow definition.cf_type with | TFun (args,_) -> List.map (fun (a,_,t) -> (a, (ctx_type_string ctx t, a)) ) args | _ -> []) ) | _ -> [] ;; let can_inline_constructor ctx class_def super_deps constructor_deps = match class_def.cl_constructor with | Some { cf_expr= Some super_func } -> let is_simple = ref true in let rec check_simple e = (match e.eexpr with | TReturn _ -> is_simple := false | TArrayDecl e when List.length e > 0 -> is_simple := false | _ -> () ); if !is_simple then Type.iter check_simple e in check_simple super_func; !is_simple && ( let rec known_classes class_def so_far = match class_def.cl_super with | Some super -> known_classes (fst super) ((fst super).cl_path :: so_far) | _ -> so_far in let allowed = known_classes class_def [class_def.cl_path] in (* Check to see if all the types required by the constructor are already in the header *) (* This is quite restrictive, since most classes are forward-declared *) let deps,_ = find_referenced_types_flags ctx (TClassDecl class_def) "new" super_deps constructor_deps false false true in List.for_all (fun dep -> List.mem dep allowed ) deps ) | _ -> true ;; let has_dynamic_member_functions class_def = List.fold_left (fun result field -> match field.cf_expr with | Some { eexpr = TFunction function_def } when is_dynamic_haxe_method field -> true | _ -> result ) false class_def.cl_ordered_fields ;; let generate_protocol_delegate ctx class_def output = let protocol = get_meta_string class_def.cl_meta Meta.ObjcProtocol in let full_class_name = ("::" ^ (join_class_path_remap class_def.cl_path "::") ) ^ "_obj" in let name = "_hx_" ^ protocol ^ "_delegate" in output ("@interface " ^ name ^ " : NSObject<" ^ protocol ^ "> {\n"); output ("\t::hx::Object *haxeObj;\n"); output ("}\n"); output ("@end\n\n"); output ("@implementation " ^ name ^ "\n"); output ("- (id)initWithImplementation:( ::hx::Object *)inInplemnetation {\n"); output (" if (self = [super init]) {\n"); output (" self->haxeObj = inInplemnetation;\n"); output (" GCAddRoot(&self->haxeObj);\n"); output (" }\n"); output (" return self;\n"); output ("}\n"); output ("- (void)dealloc {\n"); output (" GCRemoveRoot(&self->haxeObj);\n"); output (" #ifndef OBJC_ARC\n"); output (" [super dealloc];\n"); output (" #endif\n"); output ("}\n\n"); let dump_delegate field = match field.cf_type with | TFun(args,ret) -> let retStr = ctx_type_string ctx ret in let nativeName = get_meta_string field.cf_meta Meta.ObjcProtocol in let fieldName,argNames = if nativeName<>"" then begin let parts = ExtString.String.nsplit nativeName ":" in List.hd parts, parts end else field.cf_name, List.map (fun (n,_,_) -> n ) args in output ("- (" ^ retStr ^ ") " ^ fieldName ); let first = ref true in (try List.iter2 (fun (name,_,argType) signature_name -> if !first then output (" :(" ^ (ctx_type_string ctx argType) ^ ")" ^ name ) else output (" " ^ signature_name ^ ":(" ^ (ctx_type_string ctx argType) ^ ")" ^ name ); first := false; ) args argNames; with Invalid_argument _ -> begin abort ( let argString = String.concat "," (List.map (fun (name,_,_) -> name) args) in "Invalid arg count in delegate in " ^ field.cf_name ^ " '" ^ field.cf_name ^ "," ^ (argString) ^ "' != '" ^ (String.concat "," argNames) ^ "'" ) field.cf_pos end); output (" {\n"); output ("\thx::NativeAttach _hx_attach;\n"); output ( (if retStr="void" then "\t" else "\treturn ") ^ full_class_name ^ "::" ^ (keyword_remap field.cf_name) ^ "(haxeObj"); List.iter (fun (name,_,_) -> output ("," ^ name)) args; output (");\n}\n\n"); | _ -> () in List.iter dump_delegate class_def.cl_ordered_fields; output ("@end\n\n"); ;; (* Generate class header and cpp files *) let generate_class_files baseCtx super_deps constructor_deps class_def inScriptable = (* Shorcuts *) let common_ctx = baseCtx.ctx_common in let class_path = class_def.cl_path in let nativeGen = has_meta_key class_def.cl_meta Meta.NativeGen in let class_name = (snd class_path) ^ (if nativeGen then "" else "_obj") in let dot_name = join_class_path class_path "." in let smart_class_name = (snd class_path) in let class_name_text = join_class_path class_path "." in let gcName = const_char_star class_name_text in let ptr_name = "hx::ObjectPtr< " ^ class_name ^ " >" in let debug = if (has_meta_key class_def.cl_meta Meta.NoDebug) || ( Common.defined baseCtx.ctx_common Define.NoDebug) then 0 else 1 in let scriptable = inScriptable && not class_def.cl_private in let classId = try Hashtbl.find baseCtx.ctx_type_ids (class_text class_def.cl_path) with Not_found -> Int32.of_int 0 in let classIdTxt = Printf.sprintf "0x%08lx" classId in (* Config *) let implement_dynamic = implement_dynamic_here class_def in let override_iteration = (not nativeGen) && (has_new_gc_references baseCtx class_def) in let dynamic_interface_closures = (Common.defined baseCtx.ctx_common Define.DynamicInterfaceClosures) in (* All interfaces (and sub-interfaces) implemented *) let implemented_hash = Hashtbl.create 0 in let native_implemented = Hashtbl.create 0 in List.iter (fun imp -> let rec descend_interface interface = let intf_def = (fst interface) in let interface_name = cpp_interface_impl_name baseCtx intf_def in let hash = if is_native_gen_class intf_def then native_implemented else implemented_hash in if ( not (Hashtbl.mem hash interface_name) ) then begin Hashtbl.replace hash interface_name intf_def; List.iter descend_interface intf_def.cl_implements; end; match intf_def.cl_super with | Some (interface,params) -> descend_interface (interface,params) | _ -> () in descend_interface imp ) (real_interfaces class_def.cl_implements); let implemented = hash_keys implemented_hash in let implementsNative = (Hashtbl.length native_implemented) > 0 in let dynamic_functions = List.fold_left (fun result field -> match field.cf_expr with | Some { eexpr = TFunction function_def } when is_dynamic_haxe_method field -> (keyword_remap field.cf_name) :: result | _ -> result ) [] class_def.cl_ordered_fields in (* Field groups *) let statics_except_meta = statics_except_meta class_def in let implemented_fields = List.filter should_implement_field statics_except_meta in let implemented_instance_fields = List.filter should_implement_field class_def.cl_ordered_fields in let reflect_member_fields = List.filter (reflective class_def) class_def.cl_ordered_fields in let reflect_member_readable = List.filter (is_readable class_def) reflect_member_fields in let reflect_member_writable = List.filter (is_writable class_def) reflect_member_fields in let reflect_write_member_variables = List.filter variable_field reflect_member_writable in let reflect_static_fields = List.filter (reflective class_def) (statics_except_meta) in let reflect_static_readable = List.filter (is_readable class_def) reflect_static_fields in let reflect_static_writable = List.filter (is_writable class_def) reflect_static_fields in let reflect_write_static_variables = List.filter variable_field reflect_static_writable in let reflective_members = List.filter (reflective class_def) implemented_instance_fields in (* native interface glue *) let neededInterfaceFunctions = if not implementsNative then [] else begin let have = Hashtbl.create 0 in List.iter (fun field -> Hashtbl.replace have field.cf_name () ) implemented_instance_fields; let want = ref [] in Hashtbl.iter (fun _ intf_def -> List.iter (fun field -> if not (Hashtbl.mem have field.cf_name) then begin Hashtbl.replace have field.cf_name (); want := field :: !want; end ) intf_def.cl_ordered_fields; ) native_implemented; !want; end in let not_toString = fun (field,args,_) -> field.cf_name<>"toString" || class_def.cl_interface in let functions = List.filter not_toString (all_virtual_functions class_def) in (* Constructor definition *) let cargs = (constructor_arg_var_list class_def baseCtx) in let constructor_type_var_list = List.map snd cargs in let constructor_var_list = List.map snd constructor_type_var_list in let constructor_type_args = String.concat "," (List.map (fun (t,a) -> t ^ " " ^ a) constructor_type_var_list) in let constructor_args = String.concat "," constructor_var_list in let isContainer = if (has_gc_references common_ctx class_def) then "true" else "false" in let outputConstructor ctx out isHeader = let classScope = if isHeader then "" else class_name ^ "::" in out (ptr_name ^ " " ^ classScope ^ "__new(" ^constructor_type_args ^") {\n"); out ("\t" ^ ptr_name ^ " __this = new " ^ class_name ^ "();\n"); out ("\t__this->__construct(" ^ constructor_args ^ ");\n"); out ("\treturn __this;\n"); out ("}\n\n"); out ((if isHeader then "static " else "") ^ ptr_name ^ " " ^ classScope ^ "__alloc(hx::Ctx *_hx_ctx" ^ (if constructor_type_args="" then "" else "," ^constructor_type_args) ^") {\n"); out ("\t" ^ class_name ^ " *__this = (" ^ class_name ^ "*)(hx::Ctx::alloc(_hx_ctx, sizeof(" ^ class_name ^ "), " ^ isContainer ^", " ^ gcName ^ "));\n"); out ("\t*(void **)__this = " ^ class_name ^ "::_hx_vtable;\n"); let rec dump_dynamic class_def = if has_dynamic_member_functions class_def then out ("\t" ^ (join_class_path_remap class_def.cl_path "::") ^ "_obj::__alloc_dynamic_functions(_hx_ctx,__this);\n") else match class_def.cl_super with | Some super -> dump_dynamic (fst super) | _ -> () in dump_dynamic class_def; if isHeader then begin match class_def.cl_constructor with | Some ( { cf_expr = Some ( { eexpr = TFunction(function_def) } ) } as definition ) -> let old_debug = ctx.ctx_debug_level in if has_meta_key definition.cf_meta Meta.NoDebug then ctx.ctx_debug_level <- 0; ctx.ctx_real_this_ptr <- false; gen_cpp_function_body ctx class_def false "new" function_def "" "" (has_meta_key definition.cf_meta Meta.NoDebug); out "\n"; ctx.ctx_debug_level <- old_debug; | _ -> () end else out ("\t__this->__construct(" ^ constructor_args ^ ");\n"); out ("\treturn __this;\n"); out ("}\n\n"); in (* State *) let header_glue = ref [] in let cpp_file = new_placed_cpp_file baseCtx.ctx_common class_path in let cpp_ctx = file_context baseCtx cpp_file debug false in let inlineContructor = can_inline_constructor cpp_ctx class_def super_deps constructor_deps in (* Generate cpp code *) let generate_class_cpp () = (*let cpp_file = new_cpp_file common_ctx.file class_path in*) let ctx = cpp_ctx in let output_cpp = (cpp_file#write) in let class_super_name = (match class_def.cl_super with | Some (klass, params) -> (tcpp_to_string_suffix "_obj" (cpp_instance_type ctx klass params) ) | _ -> "") in if (debug>1) then print_endline ("Found class definition:" ^ (join_class_path class_def.cl_path "::")); cpp_file#write_h "#include \n\n"; let all_referenced = find_referenced_types ctx (TClassDecl class_def) super_deps constructor_deps false false scriptable in List.iter ( add_include cpp_file ) all_referenced; if (scriptable) then cpp_file#write_h "#include \n"; cpp_file#write_h "\n"; output_cpp ( get_class_code class_def Meta.CppFileCode ); let inc = get_meta_string_path class_def.cl_meta Meta.CppInclude in if (inc<>"") then output_cpp ("#include \"" ^ inc ^ "\"\n"); gen_open_namespace output_cpp class_path; output_cpp "\n"; output_cpp ( get_class_code class_def Meta.CppNamespaceCode ); if (not class_def.cl_interface) && not nativeGen then begin output_cpp ("void " ^ class_name ^ "::__construct(" ^ constructor_type_args ^ ")"); (match class_def.cl_constructor with | Some ( { cf_expr = Some ( { eexpr = TFunction(function_def) } ) } as definition ) -> let old_debug = ctx.ctx_debug_level in if has_meta_key definition.cf_meta Meta.NoDebug then ctx.ctx_debug_level <- 0; gen_cpp_function_body ctx class_def false "new" function_def "" "" (has_meta_key definition.cf_meta Meta.NoDebug); output_cpp "\n"; ctx.ctx_debug_level <- old_debug; | _ -> output_cpp " { }\n\n" ); (* Destructor goes in the cpp file so we can "see" the full definition of the member vars *) output_cpp ("Dynamic " ^ class_name ^ "::__CreateEmpty() { return new " ^ class_name ^ "; }\n\n"); output_cpp ("void *" ^ class_name ^ "::_hx_vtable = 0;\n\n"); output_cpp ("Dynamic " ^ class_name ^ "::__Create(hx::DynamicArray inArgs)\n"); output_cpp ("{\n\t" ^ ptr_name ^ " _hx_result = new " ^ class_name ^ "();\n"); output_cpp ("\t_hx_result->__construct(" ^ (array_arg_list constructor_var_list) ^ ");\n"); output_cpp ("\treturn _hx_result;\n}\n\n"); let rec addParent cls others = match cls.cl_super with | Some (super,_) -> ( try ( let parentId = Hashtbl.find ctx.ctx_type_ids (class_text super.cl_path) in addParent super (parentId :: others); ) with Not_found -> others ) | _ -> others in let implemented_classes = addParent class_def [classId ; (Int32.of_int 1)] in let implemented_classes = List.sort compare implemented_classes in output_cpp ("bool " ^ class_name ^ "::_hx_isInstanceOf(int inClassId) {\n"); let txt cId = Printf.sprintf "0x%08lx" cId in let rec dump_classes indent classes = match classes with | [] -> () | [c] -> output_cpp (indent ^ "return inClassId==(int)" ^ (txt c) ^ ";\n" ) | [c;c1] -> output_cpp (indent ^ "return inClassId==(int)" ^ (txt c) ^ " || inClassId==(int)" ^ (txt c1) ^ ";\n" ) | _ -> let len = List.length classes in let mid = List.nth classes (len / 2) in let low,high = List.partition (fun e -> e<=mid) classes in output_cpp (indent ^ "if (inClassId<=(int)" ^ (txt mid) ^ ") {\n"); dump_classes (indent ^ "\t") low; output_cpp (indent ^ "} else {\n"); dump_classes (indent ^ "\t") high; output_cpp (indent ^ "}\n"); in dump_classes "\t" implemented_classes; output_cpp ("}\n\n"); if ( List.length implemented) > 0 then begin let alreadyGlued = Hashtbl.create 0 in let cname = "_hx_" ^ (join_class_path class_def.cl_path "_") in let implname = (cpp_class_name class_def) in let cpp_glue = ref [] in List.iter (fun interface_name -> (try let interface = Hashtbl.find implemented_hash interface_name in output_cpp ("static " ^ cpp_class_name interface ^ " " ^ cname ^ "_" ^ interface_name ^ "= {\n" ); let rec gen_interface_funcs interface = let gen_field field = (match follow field.cf_type, field.cf_kind with | _, Method MethDynamic -> () | TFun (args,return_type), Method _ -> let cast = cpp_tfun_signature ctx false args return_type in let class_implementation = find_class_implementation ctx class_def field.cf_name interface in let realName= cpp_member_name_of field in let castKey = realName ^ "::" ^ cast in (* C++ can't work out which function it needs to take the addrss of when the implementation is overloaded - currently the map-set functions. Change the castKey to force a glue function in this case (could double-cast the pointer, but it is ugly) *) let castKey = if interface_name="_hx_haxe_IMap" && realName="set" then castKey ^ "*" else castKey in let implementationKey = realName ^ "::" ^ class_implementation in if castKey <> implementationKey && not (Hashtbl.mem alreadyGlued castKey) then begin Hashtbl.replace alreadyGlued castKey (); let glue = Printf.sprintf "%s_%08lx" field.cf_name (gen_hash32 0 cast) in let argList = ctx_tfun_arg_list ctx true args in let returnType = ctx_type_string ctx return_type in let returnStr = if returnType="void" then "" else "return " in let cppCode = returnType ^ " " ^ class_name ^ "::" ^ glue ^ "(" ^ argList ^ ") {\n" ^ "\t\t\t" ^ returnStr ^ realName ^ "(" ^ cpp_arg_names args ^ ");\n}\n" in let headerCode = "\t\t" ^ returnType ^ " " ^ glue ^ "(" ^ argList ^ ");\n" in header_glue := headerCode :: !header_glue; cpp_glue := cppCode :: !cpp_glue; output_cpp (" " ^ cast ^ "&" ^ implname ^ "::" ^ glue ^ ",\n"); end else output_cpp (" " ^ cast ^ "&" ^ implname ^ "::" ^ realName ^ ",\n"); | _ -> () ) in (match interface.cl_super with | Some super -> gen_interface_funcs (fst super) | _ -> ()); List.iter gen_field interface.cl_ordered_fields; in gen_interface_funcs interface; output_cpp "};\n\n"; with Not_found -> () ) ) implemented; output_cpp (String.concat "\n" !cpp_glue); output_cpp ("void *" ^ class_name ^ "::_hx_getInterface(int inHash) {\n"); output_cpp "\tswitch(inHash) {\n"; List.iter (fun interface_name -> try let interface = Hashtbl.find implemented_hash interface_name in output_cpp ("\t\tcase (int)" ^ (cpp_class_hash interface) ^ ": return &" ^ cname ^ "_" ^ interface_name ^ ";\n") with Not_found -> () ) implemented; output_cpp "\t}\n"; if class_super_name="" then begin output_cpp ("\t#ifdef HXCPP_SCRIPTABLE\n"); output_cpp ("\treturn super::_hx_getInterface(inHash);\n"); output_cpp ("\t#else\n"); output_cpp ("\treturn 0;\n"); output_cpp ("\t#endif\n") end else output_cpp ("\treturn super::_hx_getInterface(inHash);\n"); output_cpp ("}\n\n"); end; end; (match class_def.cl_init with | Some expression -> let ctx = file_context baseCtx cpp_file debug false in output_cpp ("void " ^ class_name^ "::__init__()"); gen_cpp_init ctx (cpp_class_name class_def) "__init__" "" (mk_block expression); output_cpp "\n\n"; | _ -> ()); let dump_field_name = (fun field -> output_cpp ("\t" ^ (str field.cf_name) ^ ",\n")) in List.iter (gen_field ctx class_def class_name smart_class_name dot_name false class_def.cl_interface) class_def.cl_ordered_fields; List.iter (gen_field ctx class_def class_name smart_class_name dot_name true class_def.cl_interface) statics_except_meta; output_cpp "\n"; if (List.length dynamic_functions > 0) then begin output_cpp ("void " ^ class_name ^ "::__alloc_dynamic_functions(hx::Ctx *_hx_ctx," ^ class_name ^ " *_hx_obj) {\n"); List.iter (fun name -> output_cpp ("\tif (!_hx_obj->" ^ name ^".mPtr) _hx_obj->" ^ name ^ " = new __default_" ^ name ^ "(_hx_obj);\n") ) dynamic_functions; (match class_def.cl_super with | Some super -> let rec find_super class_def = if has_dynamic_member_functions class_def then begin let super_name = (join_class_path_remap class_def.cl_path "::" ) ^ "_obj" in output_cpp ("\t" ^ super_name ^ "::__alloc_dynamic_functions(_hx_ctx,_hx_obj);\n") end else match class_def.cl_super with | Some super -> find_super (fst super) | _ -> () in find_super (fst super); | _ -> () ); output_cpp ("}\n"); end; if (not class_def.cl_interface) && not nativeGen && not inlineContructor then outputConstructor ctx output_cpp false; (* Initialise non-static variables *) if ( (not class_def.cl_interface) && (not nativeGen) ) then begin output_cpp (class_name ^ "::" ^ class_name ^ "()\n{\n"); List.iter (fun name -> output_cpp ("\t" ^ name ^ " = new __default_" ^ name ^ "(this);\n") ) dynamic_functions; output_cpp "}\n\n"; let dump_field_iterator macro field = if (is_data_member field) then begin let remap_name = keyword_remap field.cf_name in output_cpp ("\t" ^ macro ^ "(" ^ remap_name ^ ",\"" ^ field.cf_name^ "\");\n"); (match field.cf_kind with Var { v_read = AccCall } when (is_dynamic_accessor ("get_" ^ field.cf_name) "get" field class_def) -> let name = "get_" ^ field.cf_name in output_cpp ("\t" ^ macro ^ "(" ^ name ^ "," ^ "\"" ^ name ^ "\");\n" ) | _ -> ()); (match field.cf_kind with Var { v_write = AccCall } when (is_dynamic_accessor ("set_" ^ field.cf_name) "set" field class_def) -> let name = "set_" ^ field.cf_name in output_cpp ("\t" ^ macro ^ "(" ^ name ^ "," ^ "\"" ^ name ^ "\");\n" ) | _ -> ()); end in if (override_iteration) then begin let super_needs_iteration = find_next_super_iteration ctx class_def in (* MARK function - explicitly mark all child pointers *) output_cpp ("void " ^ class_name ^ "::__Mark(HX_MARK_PARAMS)\n{\n"); output_cpp ("\tHX_MARK_BEGIN_CLASS(" ^ smart_class_name ^ ");\n"); if (implement_dynamic) then output_cpp "\tHX_MARK_DYNAMIC;\n"; List.iter (dump_field_iterator "HX_MARK_MEMBER_NAME") implemented_instance_fields; (match super_needs_iteration with | "" -> () | super -> output_cpp ("\t" ^ super^"::__Mark(HX_MARK_ARG);\n" ) ); output_cpp "\tHX_MARK_END_CLASS();\n"; output_cpp "}\n\n"; (* Visit function - explicitly visit all child pointers *) output_cpp ("void " ^ class_name ^ "::__Visit(HX_VISIT_PARAMS)\n{\n"); if (implement_dynamic) then output_cpp "\tHX_VISIT_DYNAMIC;\n"; List.iter (dump_field_iterator "HX_VISIT_MEMBER_NAME") implemented_instance_fields; (match super_needs_iteration with | "" -> () | super -> output_cpp ("\t" ^ super ^ "::__Visit(HX_VISIT_ARG);\n") ); output_cpp "}\n\n"; end; let dump_quick_field_test fields = if ( (List.length fields) > 0) then begin let len = function (_,l,_) -> l in let sfields = List.sort (fun f1 f2 -> (len f1)-(len f2)) fields in let len_case = ref (-1) in output_cpp "\tswitch(inName.length) {\n"; List.iter (fun (field,l,result) -> if (l <> !len_case) then begin if (!len_case>=0) then output_cpp "\t\tbreak;\n"; output_cpp ("\tcase " ^ (string_of_int l) ^ ":\n"); len_case := l; end; output_cpp ("\t\tif (HX_FIELD_EQ(inName,\"" ^ (Ast.s_escape field) ^ "\") ) { " ^ result ^ " }\n"); ) sfields; output_cpp "\t}\n"; end; in let checkPropCall field = if ( (has_meta_key class_def.cl_meta Meta.NativeProperty) || (has_meta_key field.cf_meta Meta.NativeProperty) || (Common.defined common_ctx Define.ForceNativeProperty) ) then "inCallProp != hx::paccNever" else "inCallProp == hx::paccAlways" in let toCommon t f value = t ^ "( " ^ ( match cpp_type_of ctx f.cf_type with | TCppInst(t) as inst when (has_meta_key t.cl_meta Meta.StructAccess) -> "cpp::Struct< " ^ (tcpp_to_string inst) ^ " >( " ^ value ^ " )" | TCppStar(t,_) -> "cpp::Pointer( " ^ value ^ " )" | _ -> value ) ^ " )" in let toVal f value = toCommon "hx::Val" f value in let toDynamic f value = toCommon "" f value in if (has_get_member_field class_def) then begin (* Dynamic "Get" Field function - string version *) output_cpp ("hx::Val " ^ class_name ^ "::__Field(const ::String &inName,hx::PropertyAccess inCallProp)\n{\n"); let get_field_dat = List.map (fun f -> (f.cf_name, String.length f.cf_name, (match f.cf_kind with | Var { v_read = AccCall } when is_extern_field f -> "if (" ^ (checkPropCall f) ^ ") return " ^ (toVal f ((keyword_remap ("get_" ^ f.cf_name)) ^ "()" ) ) ^ ";" | Var { v_read = AccCall } -> "return " ^ (toVal f ((checkPropCall f) ^ " ? " ^ (keyword_remap ("get_" ^ f.cf_name)) ^ "() : " ^ ((keyword_remap f.cf_name) ^ (if (variable_field f) then "" else "_dyn()")) ) ) ^ ";" | _ -> "return " ^ (toVal f (((keyword_remap f.cf_name) ^ if (variable_field f) then "" else "_dyn()"))) ^ ";" ) ) ) in dump_quick_field_test (get_field_dat reflect_member_readable); if (implement_dynamic) then output_cpp "\tHX_CHECK_DYNAMIC_GET_FIELD(inName);\n"; output_cpp ("\treturn super::__Field(inName,inCallProp);\n}\n\n"); end; if (has_get_static_field class_def) then begin output_cpp ("bool " ^ class_name ^ "::__GetStatic(const ::String &inName, Dynamic &outValue, hx::PropertyAccess inCallProp)\n{\n"); let get_field_dat = List.map (fun f -> (f.cf_name, String.length f.cf_name, (match f.cf_kind with | Var { v_read = AccCall } when is_extern_field f -> "if (" ^ (checkPropCall f) ^ ") { outValue = " ^ (toDynamic f (keyword_remap ("get_" ^ f.cf_name) ^ "()")) ^ "; return true; }" | Var { v_read = AccCall } -> "outValue = " ^ (toDynamic f ((checkPropCall f) ^ " ? " ^ (keyword_remap ("get_" ^ f.cf_name)) ^ "() : " ^ ((keyword_remap f.cf_name) ^ if (variable_field f) then "" else "_dyn()"))) ^ "; return true;"; | _ when variable_field f -> "outValue = " ^ (toDynamic f (keyword_remap f.cf_name)) ^ "; return true;" | _ -> "outValue = " ^ ((native_field_name_remap true f) ^ "_dyn(); return true;") ) ) ) in dump_quick_field_test (get_field_dat reflect_static_readable); output_cpp ("\treturn false;\n}\n\n"); end; let castable f = match cpp_type_of ctx f.cf_type with | TCppInst(t) as inst when (has_meta_key t.cl_meta Meta.StructAccess) -> "cpp::Struct< " ^ (tcpp_to_string inst) ^ " > " | TCppStar(t,_) -> "cpp::Pointer< " ^ ( tcpp_to_string t ) ^ " >" | _ -> ctx_type_string ctx f.cf_type in (* Dynamic "Set" Field function *) if (has_set_member_field class_def) then begin output_cpp ("hx::Val " ^ class_name ^ "::__SetField(const ::String &inName,const hx::Val &inValue,hx::PropertyAccess inCallProp)\n{\n"); let set_field_dat = List.map (fun f -> let default_action = if is_gc_element ctx (cpp_type_of ctx f.cf_type) then "_hx_set_" ^ (keyword_remap f.cf_name) ^ "(HX_CTX_GET,inValue.Cast< " ^ (castable f) ^ " >());" ^ " return inValue;" else (keyword_remap f.cf_name) ^ "=inValue.Cast< " ^ (castable f) ^ " >();" ^ " return inValue;" in (f.cf_name, String.length f.cf_name, (match f.cf_kind with | Var { v_write = AccCall } -> let inVal = "(inValue.Cast< " ^ (castable f) ^ " >())" in let setter = keyword_remap ("set_" ^ f.cf_name) in "if (" ^ (checkPropCall f) ^ ") return " ^ (toVal f (setter ^inVal) ) ^ ";" ^ ( if is_extern_field f then "" else default_action ) | _ -> default_action ) ) ) in dump_quick_field_test (set_field_dat reflect_write_member_variables); if (implement_dynamic) then begin output_cpp ("\ttry { return super::__SetField(inName,inValue,inCallProp); }\n"); output_cpp ("\tcatch(Dynamic e) { HX_DYNAMIC_SET_FIELD(inName,inValue); }\n"); output_cpp "\treturn inValue;\n}\n\n"; end else output_cpp ("\treturn super::__SetField(inName,inValue,inCallProp);\n}\n\n"); end; if (has_set_static_field class_def) then begin output_cpp ("bool " ^ class_name ^ "::__SetStatic(const ::String &inName,Dynamic &ioValue,hx::PropertyAccess inCallProp)\n{\n"); let set_field_dat = List.map (fun f -> let default_action = (keyword_remap f.cf_name) ^ "=ioValue.Cast< " ^ (castable f) ^ " >(); return true;" in (f.cf_name, String.length f.cf_name, (match f.cf_kind with | Var { v_write = AccCall } -> let inVal = "(ioValue.Cast< " ^ (castable f) ^ " >())" in let setter = keyword_remap ("set_" ^ f.cf_name) in "if (" ^ (checkPropCall f) ^ ") ioValue = " ^ (toDynamic f (setter ^ inVal) ) ^ ";" ^ ( if is_extern_field f then "" else " else " ^ default_action ) | _ -> default_action ) ) ) in dump_quick_field_test (set_field_dat reflect_write_static_variables); output_cpp ("\treturn false;\n}\n\n"); end; (* For getting a list of data members (eg, for serialization) *) if (has_get_fields class_def) then begin let append_field = (fun field -> output_cpp ("\toutFields->push(" ^( str field.cf_name )^ ");\n")) in let is_data_field field = (match follow field.cf_type with | TFun _ -> false | _ -> true) in output_cpp ("void " ^ class_name ^ "::__GetFields(Array< ::String> &outFields)\n{\n"); List.iter append_field (List.filter is_data_field class_def.cl_ordered_fields); if (implement_dynamic) then output_cpp "\tHX_APPEND_DYNAMIC_FIELDS(outFields);\n"; output_cpp "\tsuper::__GetFields(outFields);\n"; output_cpp "};\n\n"; end; let storage field = match type_string field.cf_type with | "bool" -> "hx::fsBool" | "int" -> "hx::fsInt" | "Float" -> "hx::fsFloat" | "::String" -> "hx::fsString" | str -> "hx::fsObject" ^ " /*" ^ str ^ "*/ " in let dump_member_storage = (fun field -> output_cpp ("\t{" ^ (storage field) ^ ",(int)offsetof(" ^ class_name ^"," ^ (keyword_remap field.cf_name) ^")," ^ (str field.cf_name) ^ "},\n") ) in let dump_static_storage = (fun field -> output_cpp ("\t{" ^ (storage field) ^ ",(void *) &" ^ class_name ^"::" ^ (keyword_remap field.cf_name) ^"," ^ (str field.cf_name) ^ "},\n") ) in output_cpp "#if HXCPP_SCRIPTABLE\n"; let stored_fields = List.filter is_data_member implemented_instance_fields in if ( (List.length stored_fields) > 0) then begin output_cpp ("static hx::StorageInfo " ^ class_name ^ "_sMemberStorageInfo[] = {\n"); List.iter dump_member_storage stored_fields; output_cpp "\t{ hx::fsUnknown, 0, null()}\n};\n"; end else output_cpp ("static hx::StorageInfo *" ^ class_name ^ "_sMemberStorageInfo = 0;\n"); let stored_statics = List.filter is_data_member implemented_fields in if ( (List.length stored_statics) > 0) then begin output_cpp ("static hx::StaticInfo " ^ class_name ^ "_sStaticStorageInfo[] = {\n"); List.iter dump_static_storage stored_statics; output_cpp "\t{ hx::fsUnknown, 0, null()}\n};\n"; end else output_cpp ("static hx::StaticInfo *" ^ class_name ^ "_sStaticStorageInfo = 0;\n"); output_cpp "#endif\n\n"; end; (* cl_interface *) let sMemberFields = if List.length reflective_members>0 then begin let memberFields = class_name ^ "_sMemberFields" in output_cpp ("static ::String " ^ memberFields ^ "[] = {\n"); List.iter dump_field_name reflective_members; output_cpp "\t::String(null()) };\n\n"; memberFields end else "0 /* sMemberFields */"; in if (not nativeGen) then begin (* Mark static variables as used *) output_cpp ("static void " ^ class_name ^ "_sMarkStatics(HX_MARK_PARAMS) {\n"); output_cpp ("\tHX_MARK_MEMBER_NAME(" ^ class_name ^ "::__mClass,\"__mClass\");\n"); List.iter (fun field -> if (is_data_member field) then output_cpp ("\tHX_MARK_MEMBER_NAME(" ^ class_name ^ "::" ^ (keyword_remap field.cf_name) ^ ",\"" ^ field.cf_name ^ "\");\n") ) implemented_fields; output_cpp "};\n\n"; (* Visit static variables *) output_cpp "#ifdef HXCPP_VISIT_ALLOCS\n"; output_cpp ("static void " ^ class_name ^ "_sVisitStatics(HX_VISIT_PARAMS) {\n"); output_cpp ("\tHX_VISIT_MEMBER_NAME(" ^ class_name ^ "::__mClass,\"__mClass\");\n"); List.iter (fun field -> if (is_data_member field) then output_cpp ("\tHX_VISIT_MEMBER_NAME(" ^ class_name ^ "::" ^ (keyword_remap field.cf_name) ^ ",\"" ^ field.cf_name ^ "\");\n") ) implemented_fields; output_cpp "};\n\n"; output_cpp "#endif\n\n"; end; let generate_script_function isStatic field scriptName callName = match follow field.cf_type with | TFun (args,return_type) when not (is_data_member field) -> output_cpp ("\nstatic void CPPIA_CALL " ^ scriptName ^ "(hx::CppiaCtx *ctx) {\n"); let ret = script_signature return_type false in if (ret<>"v") then output_cpp ("ctx->return" ^ (script_type return_type false) ^ "("); if class_def.cl_interface then begin output_cpp (class_name ^ "::" ^ callName ^ "(ctx->getThis()" ^ (if (List.length args) > 0 then "," else "")); end else if isStatic then output_cpp (class_name ^ "::" ^ callName ^ "(") else output_cpp ("((" ^ class_name ^ "*)ctx->getThis())->" ^ callName ^ "("); let (signature,_,_) = List.fold_left (fun (signature,sep,size) (_,opt,t) -> output_cpp (sep ^ "ctx->get" ^ (script_type t opt) ^ "(" ^ size ^ ")"); (signature ^ (script_signature t opt ), ",", (size^"+sizeof(" ^ (script_size_type t opt) ^ ")") ) ) (ret,"","sizeof(void*)") args in output_cpp ")"; if (ret<>"v") then output_cpp (")"); output_cpp (";\n}\n"); signature; | _ -> "" in let newInteface = class_def.cl_interface in if (scriptable && not nativeGen) then begin let delegate = "this->" in let dump_script_field idx (field,f_args,return_t) = let args = ctx_tfun_arg_list ctx true f_args in let names = List.map (fun (n,_,_) -> keyword_remap n) f_args in let return_type = ctx_type_string ctx return_t in let ret = if (return_type="Void" || return_type="void") then " " else "return " in let name = keyword_remap field.cf_name in let vtable = "__scriptVTable[" ^ (string_of_int (idx+1) ) ^ "] " in let args_varray = (List.fold_left (fun l n -> l ^ ".Add(" ^ n ^ ")") "Array()" names) in output_cpp (" " ^ return_type ^ " " ^ name ^ "( " ^ args ^ " ) {\n"); if newInteface then begin output_cpp ("\t\thx::CppiaCtx *__ctx = hx::CppiaCtx::getCurrent();\n" ); output_cpp ("\t\thx::AutoStack __as(__ctx);\n" ); output_cpp ("\t\t__ctx->pushObject(this);\n" ); List.iter (fun (name,opt, t ) -> output_cpp ("\t\t__ctx->push" ^ (script_type t opt) ^ "(" ^ (keyword_remap name) ^ ");\n" ); ) f_args; let interfaceSlot = string_of_int( -(cpp_get_interface_slot ctx name) ) in output_cpp ("\t\t" ^ ret ^ "__ctx->run" ^ (script_type return_t false) ^ "(__GetScriptVTable()[" ^ interfaceSlot ^ "]);\n" ); output_cpp "\t}\n"; end else begin output_cpp ("\tif (" ^ vtable ^ ") {\n" ); output_cpp ("\t\thx::CppiaCtx *__ctx = hx::CppiaCtx::getCurrent();\n" ); output_cpp ("\t\thx::AutoStack __as(__ctx);\n" ); output_cpp ("\t\t__ctx->pushObject(" ^ (if class_def.cl_interface then "mDelegate.mPtr" else "this" ) ^");\n" ); List.iter (fun (name,opt, t ) -> output_cpp ("\t\t__ctx->push" ^ (script_type t opt) ^ "(" ^ (keyword_remap name) ^ ");\n" ); ) f_args; output_cpp ("\t\t" ^ ret ^ "__ctx->run" ^ (script_type return_t false) ^ "(" ^ vtable ^ ");\n" ); output_cpp ("\t} else " ^ ret ); if (class_def.cl_interface) then begin output_cpp (" " ^ delegate ^ "__Field(HX_CSTRING(\"" ^ field.cf_name ^ "\"), hx::paccNever)"); if (List.length names <= 5) then output_cpp ("->__run(" ^ (String.concat "," names) ^ ");") else output_cpp ("->__Run(" ^ args_varray ^ ");"); end else output_cpp (class_name ^ "::" ^ name ^ "(" ^ (String.concat "," names)^ ");"); if (return_type<>"void") then output_cpp "return null();"; output_cpp "}\n"; if (class_def.cl_interface) && not dynamic_interface_closures then begin output_cpp (" Dynamic " ^ name ^ "_dyn() { return mDelegate->__Field(HX_CSTRING(\"" ^ field.cf_name ^ "\"), hx::paccNever); }\n\n"); end end in let new_sctipt_functions = if newInteface then all_virtual_functions class_def else current_virtual_functions class_def in let sctipt_name = class_name ^ "__scriptable" in if newInteface then begin output_cpp ("class " ^ sctipt_name ^ " : public hx::Object {\n" ); output_cpp "public:\n"; end else begin output_cpp ("class " ^ sctipt_name ^ " : public " ^ class_name ^ " {\n" ); output_cpp (" typedef "^sctipt_name ^" __ME;\n"); output_cpp (" typedef "^class_name ^" super;\n"); let has_funky_toString = List.exists (fun f -> f.cf_name="toString") class_def.cl_ordered_statics || List.exists (fun f -> f.cf_name="toString" && field_arg_count f <> 0) class_def.cl_ordered_fields in let super_string = if has_funky_toString then class_name ^ "::super" else class_name in output_cpp (" typedef "^ super_string ^" __superString;\n"); if (class_def.cl_interface) then output_cpp (" HX_DEFINE_SCRIPTABLE_INTERFACE\n") else begin output_cpp (" HX_DEFINE_SCRIPTABLE(HX_ARR_LIST" ^ (string_of_int (List.length constructor_var_list) ) ^ ")\n"); if (not implement_dynamic) then output_cpp "\tHX_DEFINE_SCRIPTABLE_DYNAMIC;\n"; end; end; list_iteri dump_script_field functions; output_cpp ("};\n\n"); let sigs = Hashtbl.create 0 in let static_functions = (List.filter (fun f-> not (is_data_member f) ) reflect_static_fields) in let all_script_functions = (List.map (fun (f,_,_)->f) new_sctipt_functions) @ static_functions in if (List.length all_script_functions) > 0 then begin List.iter (fun (f,_,_) -> let s = generate_script_function false f ("__s_" ^f.cf_name) (keyword_remap f.cf_name) in Hashtbl.add sigs f.cf_name s ) new_sctipt_functions; let dump_script_static f = let s = generate_script_function true f ("__s_" ^f.cf_name) (keyword_remap f.cf_name) in Hashtbl.add sigs f.cf_name s in List.iter dump_script_static class_def.cl_ordered_statics; output_cpp "static hx::ScriptNamedFunction __scriptableFunctions[] = {\n"; let dump_func f isStaticFlag = let s = try Hashtbl.find sigs f.cf_name with Not_found -> "v" in output_cpp (" hx::ScriptNamedFunction(\"" ^ f.cf_name ^ "\",__s_" ^ f.cf_name ^ ",\"" ^ s ^ "\", " ^ isStaticFlag ^ " ),\n" ) in List.iter (fun (f,_,_) -> dump_func f "false") new_sctipt_functions; List.iter (fun f -> dump_func f "true") static_functions; output_cpp " hx::ScriptNamedFunction(0,0,0) };\n"; end else output_cpp "static hx::ScriptNamedFunction *__scriptableFunctions = 0;\n"; if newInteface then begin output_cpp ("\n\n" ^ class_name ^ " " ^ class_name ^ "_scriptable = {\n"); List.iter (fun (f,args,return_type) -> let cast = cpp_tfun_signature ctx true args return_type in output_cpp ("\t" ^ cast ^ "&" ^ sctipt_name ^ "::" ^ (keyword_remap f.cf_name) ^ ",\n") ) new_sctipt_functions; output_cpp ("};\n"); end; end; let class_name_text = join_class_path class_path "." in (* Initialise static in boot function ... *) if (not class_def.cl_interface && not nativeGen) then begin (* Remap the specialised "extern" classes back to the generic names *) output_cpp ("hx::Class " ^ class_name ^ "::__mClass;\n\n"); if (scriptable) then begin (match class_def.cl_constructor with | Some field -> let signature = generate_script_function false field "__script_construct_func" "__construct" in output_cpp ("hx::ScriptFunction " ^ class_name ^ "::__script_construct(__script_construct_func,\"" ^ signature ^ "\");\n"); | _ -> output_cpp ("hx::ScriptFunction " ^ class_name ^ "::__script_construct(0,0);\n"); ); end; let reflective_statics = List.filter (reflective class_def) implemented_fields in let sStaticFields = if List.length reflective_statics > 0 then begin output_cpp ("static ::String " ^ class_name ^ "_sStaticFields[] = {\n"); List.iter dump_field_name reflective_statics; output_cpp "\t::String(null())\n};\n\n"; class_name ^ "_sStaticFields"; end else "0 /* sStaticFields */" in output_cpp ("void " ^ class_name ^ "::__register()\n{\n"); output_cpp ("\thx::Object *dummy = new " ^ class_name ^ ";\n"); output_cpp ("\t" ^ class_name ^ "::_hx_vtable = *(void **)dummy;\n"); output_cpp ("\thx::Static(__mClass) = new hx::Class_obj();\n"); output_cpp ("\t__mClass->mName = " ^ (str class_name_text) ^ ";\n"); output_cpp ("\t__mClass->mSuper = &super::__SGetClass();\n"); output_cpp ("\t__mClass->mConstructEmpty = &__CreateEmpty;\n"); output_cpp ("\t__mClass->mConstructArgs = &__Create;\n"); output_cpp ("\t__mClass->mGetStaticField = &" ^ ( if (has_get_static_field class_def) then class_name ^ "::__GetStatic;\n" else "hx::Class_obj::GetNoStaticField;\n" )); output_cpp ("\t__mClass->mSetStaticField = &" ^ ( if (has_set_static_field class_def) then class_name ^ "::__SetStatic;\n" else "hx::Class_obj::SetNoStaticField;\n" )); output_cpp ("\t__mClass->mMarkFunc = " ^ class_name ^ "_sMarkStatics;\n"); output_cpp ("\t__mClass->mStatics = hx::Class_obj::dupFunctions(" ^ sStaticFields ^ ");\n"); output_cpp ("\t__mClass->mMembers = hx::Class_obj::dupFunctions(" ^ sMemberFields ^ ");\n"); output_cpp ("\t__mClass->mCanCast = hx::TCanCast< " ^ class_name ^ " >;\n"); output_cpp ("#ifdef HXCPP_VISIT_ALLOCS\n\t__mClass->mVisitFunc = " ^ class_name ^ "_sVisitStatics;\n#endif\n"); output_cpp ("#ifdef HXCPP_SCRIPTABLE\n\t__mClass->mMemberStorageInfo = " ^ class_name ^ "_sMemberStorageInfo;\n#endif\n"); output_cpp ("#ifdef HXCPP_SCRIPTABLE\n\t__mClass->mStaticStorageInfo = " ^ class_name ^ "_sStaticStorageInfo;\n#endif\n"); output_cpp ("\thx::_hx_RegisterClass(__mClass->mName, __mClass);\n"); if (scriptable) then output_cpp (" HX_SCRIPTABLE_REGISTER_CLASS(\""^class_name_text^"\"," ^ class_name ^ ");\n"); Hashtbl.iter (fun _ intf_def -> output_cpp ("\tHX_REGISTER_VTABLE_OFFSET( " ^ class_name ^ "," ^ (join_class_path_remap intf_def.cl_path "::")^ ");\n"); ) native_implemented; output_cpp ("}\n\n"); end else if not nativeGen then begin output_cpp ("hx::Class " ^ class_name ^ "::__mClass;\n\n"); output_cpp ("void " ^ class_name ^ "::__register()\n{\n"); output_cpp ("\thx::Static(__mClass) = new hx::Class_obj();\n"); output_cpp ("\t__mClass->mName = " ^ (str class_name_text) ^ ";\n"); output_cpp ("\t__mClass->mSuper = &super::__SGetClass();\n"); output_cpp ("\t__mClass->mMarkFunc = " ^ class_name ^ "_sMarkStatics;\n"); (*output_cpp ("\t__mClass->mStatics = hx::Class_obj::dupFunctions(" ^ sStaticFields ^ ");\n");*) output_cpp ("\t__mClass->mMembers = hx::Class_obj::dupFunctions(" ^ sMemberFields ^ ");\n"); output_cpp ("\t__mClass->mCanCast = hx::TIsInterface< (int)" ^ (cpp_class_hash class_def) ^ " >;\n"); output_cpp ("#ifdef HXCPP_VISIT_ALLOCS\n\t__mClass->mVisitFunc = " ^ class_name ^ "_sVisitStatics;\n#endif\n"); output_cpp ("\thx::_hx_RegisterClass(__mClass->mName, __mClass);\n"); if (scriptable) then output_cpp (" HX_SCRIPTABLE_REGISTER_INTERFACE(\""^class_name_text^"\"," ^ class_name ^ ");\n"); output_cpp ("}\n\n"); end; if (has_boot_field class_def) then begin output_cpp ("void " ^ class_name ^ "::__boot()\n{\n"); List.iter (gen_field_init ctx class_def ) (List.filter should_implement_field class_def.cl_ordered_statics); output_cpp ("}\n\n"); end; gen_close_namespace output_cpp class_path; if class_def.cl_interface && has_meta_key class_def.cl_meta Meta.ObjcProtocol then begin let full_class_name = ("::" ^ (join_class_path_remap class_path "::") ) ^ "_obj" in let protocol = get_meta_string class_def.cl_meta Meta.ObjcProtocol in generate_protocol_delegate ctx class_def output_cpp; output_cpp ("id<" ^ protocol ^ "> " ^ full_class_name ^ "::_hx_toProtocol(Dynamic inImplementation) {\n"); output_cpp ("\treturn [ [_hx_" ^ protocol ^ "_delegate alloc] initWithImplementation:inImplementation.mPtr];\n"); output_cpp ("}\n\n"); end; cpp_file#close; in (* Header code *) let generate_class_header () = let common_ctx = baseCtx.ctx_common in let class_path = class_def.cl_path in let nativeGen = has_meta_key class_def.cl_meta Meta.NativeGen in let class_name = (snd class_path) ^ (if nativeGen then "" else "_obj") in let smart_class_name = (snd class_path) in let scriptable = inScriptable && not class_def.cl_private in (*let cpp_file = new_cpp_file common_ctx.file class_path in*) let debug = if (has_meta_key class_def.cl_meta Meta.NoDebug) || ( Common.defined baseCtx.ctx_common Define.NoDebug) then 0 else 1 in let h_file = new_header_file common_ctx common_ctx.file class_path in let ctx = file_context baseCtx h_file debug true in let parent,super = match class_def.cl_super with | Some (klass,params) -> let name = (tcpp_to_string_suffix "_obj" (cpp_instance_type ctx klass params) ) in (if class_def.cl_interface && nativeGen then "virtual " else "" ) ^ name, name | None when nativeGen && class_def.cl_interface -> "virtual hx::NativeInterface", "hx::NativeInterface" | None when class_def.cl_interface -> "", "hx::Object" | None when nativeGen -> "", "" | None -> "hx::Object", "hx::Object" in let output_h = (h_file#write) in let def_string = join_class_path class_path "_" in begin_header_file (h_file#write_h) def_string nativeGen; (* Include the real header file for the super class *) (match class_def.cl_super with | Some super -> let super_path = (fst super).cl_path in h_file#add_include super_path | _ -> () ); (* And any interfaces ... *) List.iter (fun imp-> let interface = fst imp in let include_file = get_meta_string_path interface.cl_meta Meta.Include in h_file#add_include (if include_file="" then interface.cl_path else path_of_string include_file) ) (real_interfaces class_def.cl_implements); (* Only need to forward-declare classes that are mentioned in the header file (ie, not the implementation) *) let header_referenced,header_flags = find_referenced_types_flags ctx (TClassDecl class_def) "*" super_deps (Hashtbl.create 0) true false scriptable in List.iter2 ( fun r f -> gen_forward_decl h_file r f ) header_referenced header_flags; output_h "\n"; output_h ( get_class_code class_def Meta.HeaderCode ); let inc = get_meta_string_path class_def.cl_meta Meta.HeaderInclude in if (inc<>"") then output_h ("#include \"" ^ inc ^ "\"\n"); gen_open_namespace output_h class_path; output_h "\n\n"; output_h ( get_class_code class_def Meta.HeaderNamespaceCode ); let extern_class = Common.defined common_ctx Define.DllExport in let attribs = "HXCPP_" ^ (if extern_class then "EXTERN_" else "") ^ "CLASS_ATTRIBUTES" in let dump_native_interfaces () = List.iter ( fun(c,params) -> output_h (" , public virtual " ^ (join_class_path c.cl_path "::") ) ) (List.filter (fun (t,_) -> is_native_gen_class t) class_def.cl_implements); in if (class_def.cl_interface && not nativeGen) then begin output_h ("class " ^ attribs ^ " " ^ class_name ^ " {\n"); output_h "\tpublic:\n"; output_h ("\t\ttypedef " ^ super ^ " super;\n"); end else if (super="") then begin output_h ("class " ^ attribs ^ " " ^ class_name); dump_native_interfaces(); output_h "\n{\n\tpublic:\n"; end else begin output_h ("class " ^ attribs ^ " " ^ class_name ^ " : public " ^ parent ); dump_native_interfaces(); output_h "\n{\n\tpublic:\n"; if not nativeGen then begin output_h ("\t\ttypedef " ^ super ^ " super;\n"); output_h ("\t\ttypedef " ^ class_name ^ " OBJ_;\n"); end end; if (not class_def.cl_interface && not nativeGen) then begin output_h ("\t\t" ^ class_name ^ "();\n"); output_h "\n\tpublic:\n"; output_h ("\t\tenum { _hx_ClassId = " ^ classIdTxt ^ " };\n\n"); output_h ("\t\tvoid __construct(" ^ constructor_type_args ^ ");\n"); output_h ("\t\tinline void *operator new(size_t inSize, bool inContainer=" ^ isContainer ^",const char *inName=" ^ gcName ^ ")\n" ); output_h ("\t\t\t{ return hx::Object::operator new(inSize,inContainer,inName); }\n" ); output_h ("\t\tinline void *operator new(size_t inSize, int extra)\n" ); output_h ("\t\t\t{ return hx::Object::operator new(inSize+extra," ^ isContainer ^ "," ^ gcName ^ "); }\n" ); if inlineContructor then begin output_h "\n"; outputConstructor ctx (fun str -> output_h ("\t\t" ^ str) ) true end else begin output_h ("\t\tstatic " ^ptr_name^ " __new(" ^constructor_type_args ^");\n"); output_h ("\t\tstatic " ^ptr_name^ " __alloc(hx::Ctx *_hx_ctx" ^ (if constructor_type_args="" then "" else "," ^constructor_type_args) ^");\n"); end; output_h ("\t\tstatic void * _hx_vtable;\n"); output_h ("\t\tstatic Dynamic __CreateEmpty();\n"); output_h ("\t\tstatic Dynamic __Create(hx::DynamicArray inArgs);\n"); if (List.length dynamic_functions > 0) then output_h ("\t\tstatic void __alloc_dynamic_functions(hx::Ctx *_hx_alloc," ^ class_name ^ " *_hx_obj);\n"); if (scriptable) then output_h ("\t\tstatic hx::ScriptFunction __script_construct;\n"); output_h ("\t\t//~" ^ class_name ^ "();\n\n"); output_h ("\t\tHX_DO_RTTI_ALL;\n"); if (has_get_member_field class_def) then output_h ("\t\thx::Val __Field(const ::String &inString, hx::PropertyAccess inCallProp);\n"); if (has_get_static_field class_def) then output_h ("\t\tstatic bool __GetStatic(const ::String &inString, Dynamic &outValue, hx::PropertyAccess inCallProp);\n"); if (has_set_member_field class_def) then output_h ("\t\thx::Val __SetField(const ::String &inString,const hx::Val &inValue, hx::PropertyAccess inCallProp);\n"); if (has_set_static_field class_def) then output_h ("\t\tstatic bool __SetStatic(const ::String &inString, Dynamic &ioValue, hx::PropertyAccess inCallProp);\n"); if (has_get_fields class_def) then output_h ("\t\tvoid __GetFields(Array< ::String> &outFields);\n"); if (implement_dynamic) then output_h ("\t\tHX_DECLARE_IMPLEMENT_DYNAMIC;\n"); output_h ("\t\tstatic void __register();\n"); if (override_iteration) then begin output_h ("\t\tvoid __Mark(HX_MARK_PARAMS);\n"); output_h ("\t\tvoid __Visit(HX_VISIT_PARAMS);\n"); end; if (implementsNative) then begin output_h ("\n\t\tHX_NATIVE_IMPLEMENTATION\n"); List.iter (fun field -> match follow field.cf_type, field.cf_kind with | _, Method MethDynamic -> () | TFun (args,return_type), _ -> let retVal = ctx_type_string ctx return_type in let ret = if retVal="void" then "" else "return " in let name = keyword_remap field.cf_name in let argNames = List.map (fun (name,_,_) -> keyword_remap name ) args in output_h ( "\t\t" ^ retVal ^" " ^ name ^ "( " ^ ctx_tfun_arg_list ctx true args ^ ") {\n"); output_h ( "\t\t\t" ^ ret ^ "super::" ^ name ^ "( " ^ (String.concat "," argNames) ^ ");\n\t\t}\n"); | _ -> () ) neededInterfaceFunctions; output_h ("\n"); end; output_h ("\t\tbool _hx_isInstanceOf(int inClassId);\n"); if ( (List.length implemented) > 0 ) then begin output_h "\t\tvoid *_hx_getInterface(int inHash);\n"; output_h (String.concat "\n" !header_glue); end; if (has_init_field class_def) then output_h "\t\tstatic void __init__();\n\n"; output_h ("\t\t::String __ToString() const { return " ^ (str smart_class_name) ^ "; }\n\n"); end else if not nativeGen then begin output_h ("\t\tHX_DO_INTERFACE_RTTI;\n\n"); end else begin (* native interface *) ( ) end; if (has_boot_field class_def) then output_h ("\t\tstatic void __boot();\n"); (match class_def.cl_array_access with | Some t -> output_h ("\t\ttypedef " ^ (type_string t) ^ " __array_access;\n") | _ -> ()); List.iter (gen_member_def ctx class_def true class_def.cl_interface) (List.filter should_implement_field class_def.cl_ordered_statics); if class_def.cl_interface then begin List.iter (fun (field,_,_) -> gen_member_def ctx class_def false true field) functions; end else begin List.iter (gen_member_def ctx class_def false false) (List.filter should_implement_field class_def.cl_ordered_fields); end; if class_def.cl_interface && has_meta_key class_def.cl_meta Meta.ObjcProtocol then begin let protocol = get_meta_string class_def.cl_meta Meta.ObjcProtocol in output_h ("\t\tstatic id<" ^ protocol ^ "> _hx_toProtocol(Dynamic inImplementation);\n"); end; output_h ( get_class_code class_def Meta.HeaderClassCode ); output_h "};\n\n"; gen_close_namespace output_h class_path; end_header_file output_h def_string; h_file#close; in (* create header and cpp files *) if not (nativeGen && class_def.cl_interface) then generate_class_cpp (); generate_class_header () ;; let generate_class_deps ctx class_def super_deps constructor_deps = find_referenced_types ctx (TClassDecl class_def) super_deps constructor_deps false true false ;; let write_resources common_ctx = let idx = ref 0 in Hashtbl.iter (fun _ data -> let id = "__res_" ^ (string_of_int !idx) in let resource_file = new_cpp_file common_ctx common_ctx.file (["resources"],id) in resource_file#write "namespace hx {\n"; resource_file#write_i ("unsigned char " ^ id ^ "[] = {\n"); resource_file#write_i "0xff, 0xff, 0xff, 0xff,\n"; for i = 0 to String.length data - 1 do let code = Char.code (String.unsafe_get data i) in resource_file#write (Printf.sprintf "%d," code); if ( (i mod 10) = 9) then resource_file#write "\n"; done; resource_file#write ("0x00 };\n"); incr idx; resource_file#write ("}\n"); resource_file#close; ) common_ctx.resources; let resource_file = new_cpp_file common_ctx common_ctx.file ([],"__resources__") in resource_file#write_h "#include \n\n"; resource_file#write "namespace hx {\n"; idx := 0; Hashtbl.iter (fun _ data -> let id = "__res_" ^ (string_of_int !idx) in resource_file#write_i ("extern unsigned char " ^ id ^ "[];\n"); incr idx; ) common_ctx.resources; resource_file#write "}\n\n"; idx := 0; resource_file#write "hx::Resource __Resources[] = "; resource_file#begin_block; Hashtbl.iter (fun name data -> let id = "__res_" ^ (string_of_int !idx) in resource_file#write_i ("{ " ^ (str name) ^ "," ^ (string_of_int (String.length data)) ^ "," ^ "hx::" ^ id ^ " + 4 },\n"); incr idx; ) common_ctx.resources; resource_file#write_i "{ ::String(null()),0,0 }\n"; resource_file#end_block_line; resource_file#write ";\n\n"; resource_file#write "namespace hx { Resource *GetResources() { return __Resources; } }\n"; resource_file#close;; let write_build_data common_ctx filename classes main_deps boot_deps build_extra extern_src exe_name = let buildfile = open_out filename in let include_prefix = get_include_prefix common_ctx true in let add_class_to_buildfile class_path deps fileXml = let cpp = (join_class_path class_path "/") ^ (source_file_extension common_ctx) in output_string buildfile ( " "" then output_string buildfile fileXml; output_string buildfile (">\n" ); let project_deps = List.filter (fun path -> not (is_internal_class path) ) deps in List.iter (fun path-> output_string buildfile (" file | _ -> "include/" ^ include_prefix ^ (join_class_path path "/") ^ ".h" ) ^ "\"/>\n") ) project_deps; output_string buildfile ( " \n" ) in let add_classdef_to_buildfile (class_path, deps, object_def ) = let fileXml = match object_def with | TClassDecl class_def -> get_meta_string class_def.cl_meta Meta.FileXml | TEnumDecl enum_def -> get_meta_string enum_def.e_meta Meta.FileXml | _ -> "" in add_class_to_buildfile class_path deps fileXml in output_string buildfile "\n"; output_string buildfile ("\n"); output_string buildfile "\n"; output_string buildfile "\n"; List.iter add_classdef_to_buildfile classes; add_class_to_buildfile ( [] , "__boot__") boot_deps ""; add_class_to_buildfile ( [] , "__files__") [] "if='HXCPP_DEBUGGER'"; output_string buildfile (" \n"); add_class_to_buildfile ( [] , "__resources__") [] ""; output_string buildfile "\n"; output_string buildfile "\n"; output_string buildfile "\n"; add_class_to_buildfile ( [] , "__lib__") main_deps ""; output_string buildfile "\n"; output_string buildfile "\n"; output_string buildfile "\n"; add_class_to_buildfile ( [] , "__main__") main_deps ""; output_string buildfile "\n"; output_string buildfile "\n"; let idx = ref 0 in let ext = source_file_extension common_ctx in Hashtbl.iter (fun _ data -> let id = "__res_" ^ (string_of_int !idx) in output_string buildfile ("\n"); incr idx; ) common_ctx.resources; output_string buildfile "\n"; output_string buildfile "\n"; List.iter (fun src -> output_string buildfile ("\n") ) extern_src; output_string buildfile "\n"; output_string buildfile ("\n"); output_string buildfile "\n"; output_string buildfile build_extra; output_string buildfile "\n"; close_out buildfile;; let write_build_options common_ctx filename defines = let writer = cached_source_writer common_ctx filename in PMap.iter ( fun name value -> match name with | "true" | "sys" | "dce" | "cpp" | "debug" -> () | _ -> writer#write (name ^ "="^(escape_command value)^ "\n" ) ) defines; let cmd = Unix.open_process_in "haxelib path hxcpp" in writer#write ("hxcpp=" ^ (Pervasives.input_line cmd)); Pervasives.ignore (Unix.close_process_in cmd); writer#close;; let create_member_types common_ctx = let result = Hashtbl.create 0 in List.iter (fun object_def -> (match object_def with | TClassDecl class_def when not class_def.cl_interface -> let rec add_override to_super = let class_name = (join_class_path to_super.cl_path ".") in List.iter (fun member -> Hashtbl.add result (class_name ^ "." ^ member.cf_name) "virtual " ) class_def.cl_ordered_fields; match to_super.cl_super with | Some super -> add_override (fst super) | _ -> () in (match class_def.cl_super with Some super -> add_override (fst super) | _->()) | _ -> () ) ) common_ctx.types; result;; (* Builds inheritance tree, so header files can include parents defs. *) let create_super_dependencies common_ctx = let result = Hashtbl.create 0 in List.iter (fun object_def -> (match object_def with | TClassDecl class_def when not class_def.cl_extern -> let deps = ref [] in (match class_def.cl_super with Some super -> if not (fst super).cl_extern then deps := ((fst super).cl_path) :: !deps | _ ->() ); List.iter (fun imp -> if not (fst imp).cl_extern then deps := (fst imp).cl_path :: !deps) (real_non_native_interfaces class_def.cl_implements); Hashtbl.add result class_def.cl_path !deps; | TEnumDecl enum_def when not enum_def.e_extern -> Hashtbl.add result enum_def.e_path []; | _ -> () ); ) common_ctx.types; result;; let create_constructor_dependencies common_ctx = let result = Hashtbl.create 0 in List.iter (fun object_def -> (match object_def with | TClassDecl class_def when not class_def.cl_extern -> (match class_def.cl_constructor with | Some func_def -> Hashtbl.add result class_def.cl_path func_def | _ -> () ) | _ -> () ); ) common_ctx.types; result;; let is_assign_op op = match op with | OpAssign | OpAssignOp _ -> true | _ -> false ;; let rec script_type_string haxe_type = match haxe_type with | TType ({ t_path = ([],"Null") },[t]) -> (match follow t with | TAbstract ({ a_path = [],"Int" },_) | TAbstract ({ a_path = [],"Float" },_) | TAbstract ({ a_path = [],"Bool" },_) -> "Dynamic" | _ -> script_type_string t) | TInst ({cl_path=[],"Null"},[t]) -> (match follow t with | TAbstract ({ a_path = [],"Int" },_) | TAbstract ({ a_path = [],"Float" },_) | TAbstract ({ a_path = [],"Bool" },_) -> "Dynamic" | _ -> script_type_string t ) | _ -> match follow haxe_type with | TType ({t_path = [],"Array"},params) -> "Array" | TInst ({cl_path=[],"Array"},params) -> (match params with | [t] -> (match type_string_suff "" t false with | "int" -> "Array.int" | "Float" -> "Array.Float" | "bool" -> "Array.bool" | "::String" -> "Array.String" | "unsigned char" -> "Array.unsigned char" | "::cpp::UInt8" -> "Array.unsigned char" | "Dynamic" -> "Array.Any" | _ -> "Array.Object" ) | _ -> "Array.Object" ) | TAbstract (abs,pl) when abs.a_impl <> None -> script_type_string (Abstract.get_underlying_type abs pl); | _ -> type_string_suff "" haxe_type false ;; type array_of = | ArrayInterface of int | ArrayData of string | ArrayObject | ArrayAny | ArrayNone ;; let is_template_type t = false ;; type cppia_op = | IaFunction | IaVar | IaToInterface | IaToDynArray | IaToDataArray | IaToInterfaceArray | IaFun | IaCast | IaTCast | IaBlock | IaBreak | IaContinue | IaIsNull | IaNotNull | IaSet | IaCall | IaCallGlobal | IaCallStatic | IaCallMember | IaCallSuper | IaCallThis | IaCallSuperNew | IaCreateEnum | IaADef | IaIf | IaIfElse | IaFStatic | IaFName | IaFThisInst | IaFLink | IaFThisName | IaFEnum | IaThrow | IaArrayI | IaPlusPlus | IaPlusPlusPost | IaMinusMinus | IaMinusMinusPost | IaNeg | IaBitNot | IaLogicNot | IaTVars | IaVarDecl | IaVarDeclI | IaNew | IaReturn | IaRetVal | IaPosInfo | IaObjDef | IaClassOf | IaWhile | IaFor | IaEnumI | IaSwitch | IaTry | IaImplDynamic | IaConstInt | IaConstFloat | IaConstString | IaConstFalse | IaConstTrue | IaConstNull | IaConsThis | IaConstSuper | IaCastInt | IaCastBool | IaInterface | IaClass | IaAccessNormal | IaAccessNot | IaAccessResolve | IaAccessCall | IaEnum | IaInline | IaMain | IaNoMain | IaResources | IaReso | IaNoCast | IaAccessCallNative | IaBinOp of Ast.binop ;; let cppia_op_info = function | IaFunction -> ("FUNCTION", 1) | IaVar -> ("VAR", 2) | IaToInterface -> ("TOINTERFACE", 3) | IaToDynArray -> ("TODYNARRAY", 4) | IaToDataArray -> ("TODATAARRAY", 5) | IaToInterfaceArray -> ("TOINTERFACEARRAY", 6) | IaFun -> ("FUN", 7) | IaCast -> ("CAST", 8) | IaBlock -> ("BLOCK", 9) | IaBreak -> ("BREAK", 10) | IaContinue -> ("CONTINUE", 11) | IaIsNull -> ("ISNULL", 12) | IaNotNull -> ("NOTNULL", 13) | IaSet -> ("SET", 14) | IaCall -> ("CALL", 15) | IaCallGlobal -> ("CALLGLOBAL", 16) | IaCallStatic -> ("CALLSTATIC", 17) | IaCallMember -> ("CALLMEMBER", 18) | IaCallSuper -> ("CALLSUPER", 19) | IaCallThis -> ("CALLTHIS", 20) | IaCallSuperNew -> ("CALLSUPERNEW", 21) | IaCreateEnum -> ("CREATEENUM", 22) | IaADef -> ("ADEF", 23) | IaIf -> ("IF", 24) | IaIfElse -> ("IFELSE", 25) | IaFName -> ("FNAME", 27) | IaFStatic -> ("FSTATIC", 28) | IaFThisInst -> ("FTHISINST", 29) | IaFLink -> ("FLINK", 30) | IaFThisName -> ("FTHISNAME", 31) | IaFEnum -> ("FENUM", 32) | IaThrow -> ("THROW", 33) | IaArrayI -> ("ARRAYI", 34) | IaPlusPlus -> ("++", 35) | IaPlusPlusPost -> ("+++", 36) | IaMinusMinus -> ("--", 37) | IaMinusMinusPost -> ("---", 38) | IaNeg -> ("NEG", 39) | IaBitNot -> ("~", 40) | IaLogicNot -> ("!", 41) | IaTVars -> ("TVARS", 42) | IaVarDecl -> ("VARDECL", 43) | IaVarDeclI -> ("VARDECLI", 44) | IaNew -> ("NEW", 45) | IaReturn -> ("RETURN", 46) | IaRetVal -> ("RETVAL", 47) | IaPosInfo -> ("POSINFO", 48) | IaObjDef -> ("OBJDEF", 49) | IaClassOf -> ("CLASSOF", 50) | IaWhile -> ("WHILE", 51) | IaFor -> ("FOR", 52) | IaEnumI -> ("ENUMI", 53) | IaSwitch -> ("SWITCH", 54) | IaTry -> ("TRY", 55) | IaImplDynamic -> ("IMPLDYNAMIC", 56) | IaConstInt -> ("i", 57) | IaConstFloat -> ("f", 58) | IaConstString -> ("s", 59) | IaConstFalse -> ("false", 60) | IaConstTrue -> ("true", 61) | IaConstNull -> ("NULL", 62) | IaConsThis -> ("THIS", 63) | IaConstSuper -> ("SUPER", 64) | IaCastInt -> ("CASTINT", 65) | IaCastBool -> ("CASTBOOL", 66) | IaInterface -> ("INTERFACE", 67) | IaClass -> ("CLASS", 68) | IaAccessNormal -> ("N", 69) | IaAccessNot -> ("n", 70) | IaAccessResolve -> ("R", 71) | IaAccessCall -> ("C", 72) | IaEnum -> ("ENUM", 73) | IaInline -> ("INLINE", 74) | IaMain -> ("MAIN", 75) | IaNoMain -> ("NOMAIN", 76) | IaResources -> ("RESOURCES", 77) | IaReso -> ("RESO", 78) | IaNoCast -> ("NOCAST", 79) | IaAccessCallNative -> ("V", 80) | IaBinOp OpAdd -> ("+", 101) | IaBinOp OpMult -> ("*", 102) | IaBinOp OpDiv -> ("/", 103) | IaBinOp OpSub -> ("-", 104) | IaBinOp OpAssign -> ("=", 105) | IaBinOp OpEq -> ("==", 106) | IaBinOp OpNotEq -> ("!=", 107) | IaBinOp OpGte -> (">=", 108) | IaBinOp OpLte -> ("<=", 109) | IaBinOp OpGt -> (">", 110) | IaBinOp OpLt -> ("<", 111) | IaBinOp OpAnd -> ("&", 112) | IaBinOp OpOr -> ("|", 113) | IaBinOp OpXor -> ("^", 114) | IaBinOp OpBoolAnd -> ("&&", 115) | IaBinOp OpBoolOr -> ("||", 116) | IaBinOp OpShr -> (">>", 117) | IaBinOp OpUShr -> (">>>", 118) | IaBinOp OpShl -> ("<<", 119) | IaBinOp OpMod -> ("%", 120) | IaBinOp OpInterval -> ("...", 121) | IaBinOp OpArrow -> ("=>", 122) | IaBinOp OpAssignOp OpAdd -> ("+=", 201) | IaBinOp OpAssignOp OpMult -> ("*=", 202) | IaBinOp OpAssignOp OpDiv -> ("/=", 203) | IaBinOp OpAssignOp OpSub -> ("-=", 204) | IaBinOp OpAssignOp OpAnd -> ("&=", 212) | IaBinOp OpAssignOp OpOr -> ("|=", 213) | IaBinOp OpAssignOp OpXor -> ("^=", 214) | IaBinOp OpAssignOp OpBoolAnd -> ("&&=", 215) | IaBinOp OpAssignOp OpBoolOr -> ("||=", 216) | IaBinOp OpAssignOp OpShr -> (">>=", 217) | IaBinOp OpAssignOp OpUShr -> (">>>=", 218) | IaBinOp OpAssignOp OpShl -> ("<<=", 219) | IaBinOp OpAssignOp OpMod -> ("%=", 220) | IaBinOp OpAssignOp OpInterval | IaBinOp OpAssignOp OpAssign | IaBinOp OpAssignOp OpEq | IaBinOp OpAssignOp OpNotEq | IaBinOp OpAssignOp OpGte | IaBinOp OpAssignOp OpLte | IaBinOp OpAssignOp OpGt | IaBinOp OpAssignOp OpLt | IaBinOp OpAssignOp OpAssignOp _ | IaBinOp OpAssignOp OpArrow -> assert false | IaTCast -> ("TCAST", 221) ;; class script_writer ctx filename asciiOut = object(this) val debug = asciiOut val doComment = asciiOut && (Common.defined ctx.ctx_common Define.AnnotateSource) val indent_str = if asciiOut then "\t" else "" val mutable indent = "" val mutable indents = [] val mutable just_finished_block = false val mutable classCount = 0 val mutable return_type = TMono(ref None) val buffer = Buffer.create 0 val identTable = Hashtbl.create 0 val fileTable = Hashtbl.create 0 val identBuffer = Buffer.create 0 method stringId name = try ( Hashtbl.find identTable name ) with Not_found -> begin let size = Hashtbl.length identTable in Hashtbl.add identTable name size; Buffer.add_string identBuffer ((string_of_int (String.length name)) ^ " " ^ name ^ "\n"); size; end method incClasses = classCount <- classCount +1 method stringText name = (string_of_int (this#stringId name)) ^ " " val typeTable = Hashtbl.create 0 val typeBuffer = Buffer.create 0 method typeId name = let name = if name="::hx::Class" then "::Class" else name in try ( Hashtbl.find typeTable name ) with Not_found -> begin let size = Hashtbl.length typeTable in Hashtbl.add typeTable name size; Buffer.add_string typeBuffer ((string_of_int (String.length name)) ^ " " ^ name ^ "\n"); size; end method write str = if asciiOut then Buffer.add_string buffer str else begin let push i = Buffer.add_char buffer (Char.chr i) in let pushI32 i = push (Int32.to_int (Int32.logand i (Int32.of_int 255))) in List.iter (fun i -> if ((Int32.compare i Int32.zero) >= 0) && ((Int32.compare i (Int32.of_int 254)) < 0) then pushI32 i else if ((Int32.compare i Int32.zero) >= 0) && ((Int32.compare i (Int32.of_int 65536)) < 0) then begin push 254; pushI32 i; pushI32 (Int32.shift_right i 8); end else begin push 255; pushI32 i; pushI32 (Int32.shift_right i 8); pushI32 (Int32.shift_right i 16); pushI32 (Int32.shift_right i 24); end ) (List.map Int32.of_string (Str.split (Str.regexp "[\n\t ]+") str) ); end; just_finished_block <- false method comment text = if doComment then this#write ("# " ^ text ^ "\n") method commentOf text = if doComment then " # " ^ text else "" method typeTextString typeName = (string_of_int (this#typeId typeName)) ^ " " method typeText typeT = (string_of_int (this#typeId (script_type_string typeT))) ^ " " method writeType typeT = this#write (this#typeText typeT) method boolText value = if value then "1" else "0" method writeBool value = this#write (if value then "1 " else "0 ") method staticText value = if value then "1" else "0" method writeData str = Buffer.add_string buffer str; method wint ival = this#write ((string_of_int ival)^" ") method ident name = this#wint (this#stringId name) method instText clazz = match clazz.cl_path with | ([],"Array") -> string_of_int (this#typeId "Array< ::Dynamic >") ^ " " | _ -> this#typeText (TInst(clazz,[])) method instName clazz = this#write (this#instText clazz) method enumText e = this#typeText (TEnum(e,[])) method enumName e = this#write (this#enumText e) method close = let out_file = open_out_bin filename in output_string out_file (if asciiOut then "CPPIA\n" else "CPPIB\n"); let idents = Buffer.contents identBuffer in output_string out_file ((string_of_int (Hashtbl.length identTable)) ^ "\n"); output_string out_file idents; let types = Buffer.contents typeBuffer in output_string out_file ((string_of_int (Hashtbl.length typeTable)) ^ "\n"); output_string out_file types; output_string out_file ( (string_of_int classCount) ^ "\n" ); let contents = Buffer.contents buffer in output_string out_file contents; close_out out_file method fileId file = try ( Hashtbl.find fileTable file ) with Not_found -> begin let stripped_file = strip_file ctx.ctx_common file in let result = this#stringId stripped_file in Hashtbl.add fileTable file result; result; end method constText c = match c with | TInt i -> (this#op IaConstInt) ^ (Printf.sprintf "%ld " i) | TFloat f -> (this#op IaConstFloat) ^ (this#stringText f) | TString s -> (this#op IaConstString) ^ (this#stringText s) | TBool true -> (this#op IaConstTrue) | TBool false -> (this#op IaConstFalse) | TNull -> (this#op IaConstNull) | TThis -> (this#op IaConsThis) | TSuper -> (this#op IaConstSuper) method get_array_type t = match follow t with | TInst ({cl_path=[],"Array"},[param]) -> let typeName = type_string_suff "" param false in (match typeName with | "::String" -> ArrayData "String" | "int" | "Float" | "bool" | "String" | "unsigned char" | "::cpp::UInt8" -> ArrayData typeName | "cpp::ArrayBase" | "cpp::VirtualArray" | "Dynamic" -> ArrayAny | _ when is_interface_type param -> ArrayInterface (this#typeId (script_type_string param)) | _ -> ArrayObject ) | TAbstract (abs,pl) when abs.a_impl <> None -> this#get_array_type (Abstract.get_underlying_type abs pl); | _ -> ArrayNone; method pushReturn inType = let oldReturnType = return_type in return_type <- inType; fun () -> return_type <- oldReturnType; method fileText file = string_of_int (this#fileId file) method indent_one = this#write indent_str method push_indent = indents <- indent_str::indents; indent <- String.concat "" indents method pop_indent = match indents with | h::tail -> indents <- tail; indent <- String.concat "" indents | [] -> indent <- "/*?*/"; method write_i x = this#write (indent ^ x) method get_indent = indent method begin_expr = this#push_indent method end_expr = if not just_finished_block then this#write "\n"; this#pop_indent; just_finished_block <- true method op x = match cppia_op_info x with | (name,index) -> (if debug then name else string_of_int index) ^ " " method writeOp o = this#write (this#op o) method writeOpLine o = this#write ((this#op o) ^ "\n") method voidFunc isStatic isDynamic funcName fieldExpression = this#comment funcName; this#write ( (this#op IaFunction) ^ (this#staticText isStatic) ^ " " ^(this#boolText isDynamic) ^ " " ^(this#stringText funcName) ^ " "); this#write ((this#typeTextString "Void") ^ "0\n"); this#gen_expression fieldExpression method func isStatic isDynamic funcName ret args isInterface fieldExpression = this#comment funcName; this#write ( (this#op IaFunction) ^ (this#staticText isStatic) ^ " " ^(this#boolText isDynamic) ^ " " ^(this#stringText funcName) ^ " "); this#write ((this#typeText ret) ^ (string_of_int (List.length args)) ^ " "); List.iter (fun (name,opt,typ) -> this#write ( (this#stringText name) ^ (this#boolText opt) ^ " " ^ (this#typeText typ) ^ " " )) args; this#write "\n"; if (not isInterface) then begin match fieldExpression with | Some ({ eexpr = TFunction function_def } as e) -> this#gen_expression e | _ -> print_endline ("Missing function body for " ^ funcName ); end method var readAcc writeAcc isExtern isStatic name varType varExpr = this#write ( (this#op IaVar) ^ (this#staticText isStatic) ^ " " ^ (this#op readAcc) ^ (this#op writeAcc) ^ (this#boolText isExtern) ^ " " ^ (this#stringText name)^ (this#typeText varType) ^ (match varExpr with Some _ -> "1" | _ -> "0" ) ^ (if doComment then (" # " ^ name ^ "\n") else "\n") ); match varExpr with | Some expression -> this#gen_expression expression | _ -> () method implDynamic = this#writeOpLine IaImplDynamic; method writeVar v = this#ident v.v_name; this#wint v.v_id; this#writeBool v.v_capture; this#writeType v.v_type; method writeList prefix len = this#write (prefix ^" " ^ (string_of_int (len)) ^ "\n"); method writePos expr = if debug then this#write ( (this#fileText expr.epos.pfile) ^ "\t" ^ (string_of_int (Lexer.get_error_line expr.epos) ) ^ indent); method checkCast toType expr forceCast fromGenExpression= let write_cast text = if (not fromGenExpression) then this#writePos expr; this#write (text ^"\n" ); this#begin_expr; this#gen_expression expr; this#end_expr; true; in let was_cast = if (is_interface_type toType) then begin if (is_dynamic_in_cppia ctx expr) then begin write_cast ( (this#op IaToInterface) ^ (this#typeText toType) ^ " " ^ (this#typeTextString "Dynamic") ) end else if (not (is_matching_interface_type toType expr.etype)) then begin write_cast ( (this#op IaToInterface) ^ (this#typeText toType) ^ " " ^ (this#typeText expr.etype) ) end else false end else begin let get_array_expr_type expr = if is_dynamic_in_cppia ctx expr then ArrayNone else this#get_array_type expr.etype in match (this#get_array_type toType), (get_array_expr_type expr) with | ArrayAny, _ -> false | ArrayObject, ArrayData _ -> write_cast (this#op IaToDynArray) | ArrayObject, ArrayObject -> false | ArrayObject, ArrayNone | ArrayObject, ArrayAny -> write_cast ((this#op IaToDataArray) ^ (this#typeTextString ("Array.Object"))) | ArrayData t, ArrayNone | ArrayData t, ArrayObject | ArrayData t, ArrayAny -> write_cast ((this#op IaToDataArray) ^ (this#typeTextString ("Array." ^ t))) | ArrayInterface t, ArrayNone | ArrayInterface t, ArrayAny -> write_cast ((this#op IaToInterfaceArray) ^ (string_of_int t)) | _,_ -> (* a0,a1 -> let arrayString a = match a with | ArrayNone -> "ArrayNone" | ArrayAny -> "ArrayAny" | ArrayObject -> "ArrayObject" | ArrayData _ -> "ArrayData" | ArrayInterface _ -> "ArrayInterface" in this#write ("NOCAST " ^ (arrayString a0) ^ "=" ^ (arrayString a1)); *) false end in if (not was_cast) then begin if (forceCast) then begin let op =match (type_string expr.etype) with | "int" -> IaCastInt | "bool" -> IaCastBool | _ when is_interface_type toType -> IaNoCast | _ -> IaCast in this#writeOpLine op; end; this#gen_expression expr; end method gen_expression expr = let expression = remove_parens expr in this#begin_expr; (*this#write ( (this#fileText expression.epos.pfile) ^ "\t" ^ (string_of_int (Lexer.get_error_line expression.epos) ) ^ indent);*) this#writePos expression; (match expression.eexpr with | TFunction function_def -> this#write ( (this#op IaFun) ^ (this#typeText function_def.tf_type) ^ (string_of_int (List.length function_def.tf_args)) ^ "\n" ); List.iter (fun(arg,init) -> this#write (indent ^ indent_str ); this#writeVar arg; match init with | Some const -> this#write ("1 " ^ (this#constText const) ^ "\n") | _ -> this#write "0\n"; ) function_def.tf_args; let pop = this#pushReturn function_def.tf_type in this#gen_expression function_def.tf_expr; pop (); | TBlock expr_list -> this#writeList (this#op IaBlock) (List.length expr_list); List.iter this#gen_expression expr_list; | TConst const -> this#write (this#constText const) | TBreak -> this#writeOp IaBreak | TContinue -> this#writeOp IaContinue | TBinop (op,e1,e2) when op=OpAssign -> this#writeOpLine IaSet; this#gen_expression e1; this#checkCast e1.etype e2 false false; | TBinop (OpEq ,e1, { eexpr = TConst TNull } ) -> this#writeOpLine IaIsNull; this#gen_expression e1; | TBinop (OpNotEq ,e1, { eexpr = TConst TNull }) -> this#writeOpLine IaNotNull; this#gen_expression e1; | TBinop (OpEq , { eexpr = TConst TNull }, e1) -> this#writeOpLine IaIsNull; this#gen_expression e1; | TBinop (OpNotEq, { eexpr = TConst TNull }, e1) -> this#writeOpLine IaNotNull; this#gen_expression e1; | TBinop (op,e1,e2) -> this#writeOpLine (IaBinOp op); this#gen_expression e1; this#gen_expression e2; | TThrow e -> this#writeOpLine IaThrow; this#gen_expression e; | TArrayDecl expr_list -> this#write ( (this#op IaADef) ^ (this#typeText expression.etype) ^ " " ^(string_of_int (List.length expr_list))^"\n"); List.iter this#gen_expression expr_list; | TIf (e,e1,e2) -> (match e2 with | None -> this#writeOpLine IaIf; this#gen_expression e; this#gen_expression e1; | Some elze -> this#writeOpLine IaIfElse; this#gen_expression e; this#gen_expression e1; this#gen_expression elze; ) | TCall (func, arg_list) -> let argN = (string_of_int (List.length arg_list)) ^ " " in let gen_call () = (match (remove_parens_cast func).eexpr with | TField ( { eexpr = TLocal { v_name = "__global__" }}, field ) -> this#write ( (this#op IaCallGlobal) ^ (this#stringText (field_name field)) ^ argN ^ (this#commentOf (field_name field)) ^ "\n"); | TField (obj,FStatic (class_def,field) ) when is_real_function field -> this#write ( (this#op IaCallStatic) ^ (this#instText class_def) ^ " " ^ (this#stringText field.cf_name) ^ argN ^ (this#commentOf ( join_class_path class_def.cl_path "." ^ "." ^ field.cf_name) ) ^ "\n"); | TField (obj,FInstance (_,_,field) ) when (is_this obj) && (is_real_function field) -> this#write ( (this#op IaCallThis) ^ (this#typeText obj.etype) ^ " " ^ (this#stringText field.cf_name) ^ argN ^ (this#commentOf field.cf_name) ^ "\n"); | TField (obj,FInstance (_,_,field) ) when is_super obj -> this#write ( (this#op IaCallSuper) ^ (this#typeText obj.etype) ^ " " ^ (this#stringText field.cf_name) ^ argN ^ (this#commentOf field.cf_name) ^ "\n"); (* Cppia does not have a "GetEnumIndex" op code - must use IaCallMember hx::EnumBase.__Index *) | TField (obj,FInstance (_,_,field) ) when field.cf_name = "_hx_getIndex" && (script_type_string obj.etype)="hx::EnumBase" -> this#write ( (this#op IaCallMember) ^ (this#typeTextString "hx::EnumBase") ^ " " ^ (this#stringText "__Index") ^ argN ^ (this#commentOf ("Enum index") ) ^ "\n"); this#gen_expression obj; | TField (obj,FInstance (_,_,field) ) when field.cf_name = "__Index" || (not (is_dynamic_in_cppia ctx obj) && is_real_function field) -> this#write ( (this#op IaCallMember) ^ (this#typeText obj.etype) ^ " " ^ (this#stringText field.cf_name) ^ argN ^ (this#commentOf field.cf_name) ^ "\n"); this#gen_expression obj; | TField (obj,FDynamic (name) ) when (is_internal_member name || (type_string obj.etype = "::String" && name="cca") ) -> this#write ( (this#op IaCallMember) ^ (this#typeText obj.etype) ^ " " ^ (this#stringText name) ^ argN ^ (this#commentOf name) ^ "\n"); this#gen_expression obj; | TConst TSuper -> this#write ((this#op IaCallSuperNew) ^ (this#typeText func.etype) ^ " " ^ argN ^ "\n"); | TField (_,FEnum (enum,field)) -> this#write ((this#op IaCreateEnum) ^ (this#enumText enum) ^ " " ^ (this#stringText field.ef_name) ^ argN ^ (this#commentOf field.ef_name) ^ "\n"); | _ -> this#write ( (this#op IaCall) ^ argN ^ "\n"); this#gen_expression func; ); let matched_args = match func.etype with | TFun (args,_) -> ( try ( List.iter2 (fun (_,_,protoT) arg -> this#checkCast protoT arg false false) args arg_list; true; ) with Invalid_argument _ -> (*print_endline "Bad count?";*) false ) | _ -> false in if not matched_args then List.iter this#gen_expression arg_list; in (match (remove_parens_cast func).eexpr with | TField(obj,field) when is_array_or_dyn_array obj.etype && (field_name field)="map" -> (match this#get_array_type expression.etype with | ArrayData t -> this#write ( (this#op IaToDataArray) ^ (this#typeTextString ("Array." ^ t)) ^ "\n"); this#begin_expr; this#writePos func; gen_call(); this#end_expr; | ArrayInterface t -> this#write ( (this#op IaToInterfaceArray) ^ (string_of_int t) ^ "\n"); this#begin_expr; this#writePos func; gen_call(); this#end_expr; | _ -> gen_call(); ) | _ -> gen_call(); ); | TField (obj, acc) -> let objType = if is_dynamic_in_cppia ctx obj then "Dynamic" else script_type_string obj.etype in let typeText = if is_dynamic_in_cppia ctx obj then this#typeTextString "Dynamic" else this#typeText obj.etype in (match acc with | FDynamic name -> this#write ( (this#op IaFName) ^ typeText ^ " " ^ (this#stringText name) ^ (this#commentOf name) ^ "\n"); this#gen_expression obj; | FStatic (class_def,field) -> this#write ( (this#op IaFStatic) ^ (this#instText class_def) ^ " " ^ (this#stringText field.cf_name) ^ (this#commentOf field.cf_name) ); | FInstance (_,_,field) when is_this obj -> this#write ( (this#op IaFThisInst) ^ typeText ^ " " ^ (this#stringText field.cf_name) ^ (this#commentOf field.cf_name) ); | FInstance (_,_,field) -> this#write ( (this#op IaFLink) ^ typeText ^ " " ^ (this#stringText field.cf_name) ^ (this#commentOf ( objType ^ "." ^ field.cf_name)) ^ "\n"); this#gen_expression obj; | FClosure (_,field) when is_this obj -> this#write ( (this#op IaFThisName) ^typeText ^ " " ^ (this#stringText field.cf_name) ^ "\n") | FAnon (field) when is_this obj -> this#write ( (this#op IaFThisName) ^typeText ^ " " ^ (this#stringText field.cf_name) ^ (this#commentOf field.cf_name) ^ "\n") | FClosure (_,field) | FAnon (field) -> this#write ( (this#op IaFName) ^typeText ^ " " ^ (this#stringText field.cf_name) ^ (this#commentOf field.cf_name) ^ "\n"); this#gen_expression obj; | FEnum (enum,field) -> this#write ( (this#op IaFEnum) ^ (this#enumText enum) ^ " " ^ (this#stringText field.ef_name) ^ (this#commentOf field.ef_name) ); ) | TArray (e1, e2) -> this#write ((this#op IaArrayI) ^ (this#typeText e1.etype) ^ "\n"); this#gen_expression e1; this#gen_expression e2; | TUnop (op, flag, e) -> this#writeOpLine (match op,flag with | Increment, Prefix -> IaPlusPlus | Increment, _ -> IaPlusPlusPost | Decrement, Prefix -> IaMinusMinus | Decrement, _ -> IaMinusMinusPost | Not, _ -> IaLogicNot | Neg, _ -> IaNeg | NegBits, _ -> IaBitNot ); this#gen_expression e; (* TODO - lval op-assign local/member/array *) | TLocal var -> this#write ((this#op IaVar) ^ (string_of_int var.v_id) ^ (this#commentOf var.v_name) ); | TVar (tvar,optional_init) -> this#write ( (this#op IaTVars) ^ (string_of_int (1)) ^ (this#commentOf (tvar.v_name ^ ":" ^ (script_type_string tvar.v_type)) ) ^ "\n"); this#write ("\t\t" ^ indent); (match optional_init with | None -> this#writeOp IaVarDecl; this#writeVar tvar; | Some init ->this#writeOp IaVarDeclI; let init = remove_parens init in this#writeVar tvar; this#write (" " ^ (this#typeText init.etype)); this#write "\n"; this#checkCast tvar.v_type init false false); | TNew (clazz,params,arg_list) -> this#write ((this#op IaNew) ^ (this#typeText (TInst(clazz,params))) ^ (string_of_int (List.length arg_list)) ^ "\n"); let rec matched_args clazz = match clazz.cl_constructor, clazz.cl_super with | None, Some super -> matched_args (fst super) | None, _ -> false | Some ctr, _ -> (match ctr.cf_type with | TFun(args,_) -> ( try ( List.iter2 (fun (_,_,protoT) arg -> this#checkCast protoT arg false false) args arg_list; true; ) with Invalid_argument _ -> (*print_endline "Bad count?";*) false ) | _ -> false ) in if not (matched_args clazz) then List.iter this#gen_expression arg_list; | TReturn optval -> (match optval with | None -> this#writeOpLine IaReturn; | Some value -> this#write ( (this#op IaRetVal) ^ (this#typeText value.etype) ^ "\n"); this#checkCast return_type value false false; ) | TObjectDecl ( ("fileName" , { eexpr = (TConst (TString file)) }) :: ("lineNumber" , { eexpr = (TConst (TInt line)) }) :: ("className" , { eexpr = (TConst (TString class_name)) }) :: ("methodName", { eexpr = (TConst (TString meth)) }) :: [] ) -> this#write ( (this#op IaPosInfo) ^ (this#stringText file) ^ (Printf.sprintf "%ld" line) ^ " " ^ (this#stringText class_name) ^ " " ^ (this#stringText meth)) | TObjectDecl values ->this#write ( (this#op IaObjDef) ^ (string_of_int (List.length values))); this#write " "; List.iter (fun (name,_) -> this#write (this#stringText name) ) values; this#write "\n"; List.iter (fun (_,e) -> this#gen_expression e ) values; | TTypeExpr type_expr -> let klass = "::" ^ (join_class_path (t_path type_expr) "::" ) in this#write ((this#op IaClassOf) ^ (string_of_int (this#typeId klass))) | TWhile (e1,e2,flag) -> this#write ( (this#op IaWhile) ^ (if flag=NormalWhile then "1" else "0" ) ^ "\n"); this#gen_expression e1; this#gen_expression e2; | TFor (tvar,init,loop) -> this#writeOp IaFor; this#writeVar tvar; this#write "\n"; this#gen_expression init; this#gen_expression loop; | TEnumParameter (expr,ef,i) -> let enum = match follow ef.ef_type with | TEnum(en,_) | TFun(_,TEnum(en,_)) -> en | _ -> assert false in this#write ( (this#op IaEnumI) ^ (this#typeText (TEnum(enum,[])) ) ^ (string_of_int i) ^ "\n"); this#gen_expression expr; | TSwitch (condition,cases,optional_default) -> this#write ( (this#op IaSwitch) ^ (string_of_int (List.length cases)) ^ " " ^ (match optional_default with None -> "0" | Some _ -> "1") ^ "\n"); this#gen_expression condition; List.iter (fun (cases_list,expression) -> this#writeList ("\t\t\t"^indent) (List.length cases_list); List.iter (fun value -> this#gen_expression value ) cases_list; this#gen_expression expression; ) cases; (match optional_default with None -> () | Some expr -> this#gen_expression expr); | TTry (e,catches) -> this#writeList (this#op IaTry) (List.length catches); this#gen_expression e; List.iter ( fun (tvar,catch_expr) -> this#write ("\t\t\t"^indent); this#writeVar tvar; this#write "\n"; this#gen_expression catch_expr; ) catches; | TCast (cast,Some (TClassDecl t)) -> this#write ((this#op IaTCast) ^ (this#typeText (TInst(t,[])) ) ^ "\n"); this#gen_expression cast; | TCast (cast,_) -> this#checkCast expression.etype cast true true; | TParenthesis _ -> abort "Unexpected parens" expression.epos | TMeta(_,_) -> abort "Unexpected meta" expression.epos ); this#end_expr; end;; let generate_script_class common_ctx script class_def = script#incClasses; let classText = (join_class_path class_def.cl_path ".") in script#comment ("Class " ^ classText); script#writeOp (if class_def.cl_interface then IaInterface else IaClass ); script#instName class_def; (match class_def.cl_super with | None -> script#ident "" | Some (c,_) -> script#instName c); script#wint (List.length class_def.cl_implements); List.iter (fun(c,_) -> script#instName c) class_def.cl_implements; script#write "\n"; (* Looks like some map impl classes have their bodies discarded - not sure best way to filter *) let non_dodgy_function field = class_def.cl_interface || match field.cf_kind, field.cf_expr with | Var _, _ -> true | Method MethDynamic, _ -> true | Method _, Some _ -> true | _ -> false in let ordered_statics = List.filter non_dodgy_function class_def.cl_ordered_statics in let ordered_fields = List.filter non_dodgy_function class_def.cl_ordered_fields in script#write ((string_of_int ( (List.length ordered_fields) + (List.length ordered_statics) + (match class_def.cl_constructor with Some _ -> 1 | _ -> 0 ) + (if (implement_dynamic_here class_def) then 1 else 0) + (match class_def.cl_init with Some _ -> 1 | _ -> 0 ) ) ) ^ "\n"); let generate_field isStatic field = match field.cf_kind, follow field.cf_type with | Var { v_read = AccInline; v_write = AccNever },_ -> script#writeOpLine IaInline; | Var v,_ -> let mode_code mode = match mode with | AccNormal -> IaAccessNormal | AccNo -> IaAccessNot | AccNever -> IaAccessNot | AccResolve -> IaAccessResolve | AccCall -> if ( (has_meta_key class_def.cl_meta Meta.NativeProperty) || (has_meta_key field.cf_meta Meta.NativeProperty) || (Common.defined common_ctx Define.ForceNativeProperty) ) then IaAccessCallNative else IaAccessCall; | AccInline -> IaAccessNormal | AccRequire (_,_) -> IaAccessNormal in let isExtern = is_extern_field field in script#var (mode_code v.v_read) (mode_code v.v_write) isExtern isStatic field.cf_name field.cf_type field.cf_expr | Method MethDynamic, TFun(args,ret) -> script#func isStatic true field.cf_name ret args class_def.cl_interface field.cf_expr | Method _, TFun(args,ret) when field.cf_name="new" -> script#func true false "new" (TInst(class_def,[])) args false field.cf_expr | Method _, TFun (args,ret) -> script#func isStatic false field.cf_name ret args class_def.cl_interface field.cf_expr | Method _, _ -> print_endline ("Unknown method type " ^ (join_class_path class_def.cl_path "." ) ^ "." ^field.cf_name ) in (match class_def.cl_constructor with | Some field -> generate_field true field | _ -> () ); (match class_def.cl_init with | Some expression -> script#voidFunc true false "__init__" expression | _ -> () ); List.iter (generate_field false) ordered_fields; List.iter (generate_field true) ordered_statics; if (implement_dynamic_here class_def) then script#implDynamic; script#write "\n"; ;; let generate_script_enum common_ctx script enum_def meta = script#incClasses; let sorted_items = List.sort (fun f1 f2 -> (f1.ef_index - f2.ef_index ) ) (pmap_values enum_def.e_constrs) in script#writeList ((script#op IaEnum) ^ (script#enumText enum_def)) (List.length sorted_items); List.iter (fun constructor -> let name = script#stringText constructor.ef_name in match constructor.ef_type with | TFun (args,_) -> script#write ( name ^ " " ^ (string_of_int (List.length args)) ); List.iter (fun (arg,_,t) -> script#write ( " " ^ (script#stringText arg) ^ " " ^ (script#typeText t) ) ) args; script#write "\n"; | _ -> script#write ( name ^ " 0\n" ) ) sorted_items; match meta with | Some expr -> script#write "1\n"; script#gen_expression expr | _ -> script#write "0\n"; script#write "\n" ;; let generate_cppia ctx = let common_ctx = ctx.ctx_common in let debug = ctx.ctx_debug_level in let script = new script_writer ctx common_ctx.file common_ctx.debug in ignore (script#stringId ""); ignore (script#typeId ""); List.iter (fun object_def -> (match object_def with | TClassDecl class_def when class_def.cl_extern -> () (*if (gen_externs) then gen_extern_class common_ctx class_def;*) | TClassDecl class_def -> let is_internal = is_internal_class class_def.cl_path in if (is_internal || (is_macro class_def.cl_meta)) then ( if (debug>=4) then print_endline (" internal class " ^ (join_class_path class_def.cl_path ".") )) else begin generate_script_class common_ctx script class_def end | TEnumDecl enum_def when enum_def.e_extern -> () | TEnumDecl enum_def -> let is_internal = is_internal_class enum_def.e_path in if (is_internal) then (if (debug>=4) then print_endline (" internal enum " ^ (join_class_path enum_def.e_path ".") )) else begin let meta = Codegen.build_metadata common_ctx object_def in if (enum_def.e_extern) then (if (debug>=4) then print_endline ("external enum " ^ (join_class_path enum_def.e_path ".") )); generate_script_enum common_ctx script enum_def meta end | TTypeDecl _ | TAbstractDecl _ -> (* already done *) () ); ) common_ctx.types; (match common_ctx.main with | None -> script#writeOpLine IaNoMain; | Some e -> script#writeOpLine IaMain; script#gen_expression e ); script#write ( (script#op IaResources) ^ (string_of_int (Hashtbl.length common_ctx.resources)) ^ "\n"); Hashtbl.iter (fun name data -> script#write ((script#op IaReso) ^ (script#stringText name) ^ (string_of_int (String.length data)) ^ "\n"); ) common_ctx.resources; Hashtbl.iter (fun _ data -> script#writeData data) common_ctx.resources; script#close ;; (* The common_ctx contains the haxe AST in the "types" field and the resources *) let generate_source ctx = let common_ctx = ctx.ctx_common in let debug = ctx.ctx_debug_level in make_base_directory common_ctx.file; let exe_classes = ref [] in let boot_classes = ref [] in let boot_enums = ref [] in let nonboot_classes = ref [] in let init_classes = ref [] in let super_deps = create_super_dependencies common_ctx in let constructor_deps = create_constructor_dependencies common_ctx in let main_deps = ref [] in let extern_src = ref [] in let jobs = ref [] in let build_xml = ref "" in let scriptable = (Common.defined common_ctx Define.Scriptable) in let existingIds = Hashtbl.create 0 in List.iter (fun object_def -> (* check if any @:objc class is referenced while '-D objc' is not defined This will guard all code changes to this flag *) (if not (Common.defined common_ctx Define.Objc) then match object_def with | TClassDecl class_def when Meta.has Meta.Objc class_def.cl_meta -> abort "In order to compile '@:objc' classes, please define '-D objc'" class_def.cl_pos | _ -> ()); (match object_def with | TClassDecl class_def when is_extern_class class_def -> build_xml := !build_xml ^ (get_class_code class_def Meta.BuildXml); let source = get_meta_string_path class_def.cl_meta Meta.SourceFile in if (source<>"") then extern_src := source :: !extern_src; | TClassDecl class_def -> let name = class_text class_def.cl_path in let is_internal = is_internal_class class_def.cl_path in if (is_internal || (is_macro class_def.cl_meta)) then ( if (debug>=4) then print_endline (" internal class " ^ name )) else begin let rec makeId class_name seed = let id = gen_hash32 seed class_name in (* reserve first 100 ids for runtime *) if id < Int32.of_int 100 || Hashtbl.mem existingIds id then makeId class_name (seed+100) else begin Hashtbl.add existingIds id true; Hashtbl.add ctx.ctx_type_ids class_name id; end in makeId name 0; build_xml := !build_xml ^ (get_class_code class_def Meta.BuildXml); if (has_init_field class_def) then init_classes := class_def.cl_path :: !init_classes; if (has_boot_field class_def) then boot_classes := class_def.cl_path :: !boot_classes else if not (has_meta_key class_def.cl_meta Meta.NativeGen) then nonboot_classes := class_def.cl_path :: !nonboot_classes; jobs := (fun () -> generate_class_files ctx super_deps constructor_deps class_def scriptable ) :: !jobs; let deps = generate_class_deps ctx class_def super_deps constructor_deps in if not (class_def.cl_interface && (is_native_gen_class class_def)) then exe_classes := (class_def.cl_path, deps, object_def) :: !exe_classes; end | TEnumDecl enum_def when enum_def.e_extern -> () | TEnumDecl enum_def -> let name = class_text enum_def.e_path in let is_internal = is_internal_class enum_def.e_path in if (is_internal) then (if (debug>1) then print_endline (" internal enum " ^ name )) else begin let meta = Codegen.build_metadata common_ctx object_def in if (enum_def.e_extern) then (if (debug>1) then print_endline ("external enum " ^ name )); boot_enums := enum_def.e_path :: !boot_enums; jobs := (fun () -> generate_enum_files ctx enum_def super_deps meta ) :: !jobs; let deps = generate_enum_deps ctx enum_def super_deps in exe_classes := (enum_def.e_path, deps, object_def) :: !exe_classes; end | TTypeDecl _ | TAbstractDecl _ -> (* already done *) () ); ) common_ctx.types; List.iter (fun job -> job () ) !jobs; (match common_ctx.main with | None -> generate_dummy_main common_ctx | Some e -> let main_field = { cf_name = "__main__"; cf_type = t_dynamic; cf_expr = Some e; cf_expr_unoptimized = None; cf_pos = e.epos; cf_name_pos = null_pos; cf_public = true; cf_meta = []; cf_overloads = []; cf_doc = None; cf_kind = Var { v_read = AccNormal; v_write = AccNormal; }; cf_params = [] } in let class_def = { null_class with cl_path = ([],"@Main"); cl_ordered_statics = [main_field] } in main_deps := find_referenced_types ctx (TClassDecl class_def) super_deps constructor_deps false true false; generate_main ctx super_deps class_def ); generate_boot ctx !boot_enums !boot_classes !nonboot_classes !init_classes; generate_files common_ctx ctx.ctx_file_info; write_resources common_ctx; (* Output class info if requested *) if (scriptable || (Common.defined common_ctx Define.DllExport) ) then begin let filename = try let value = Common.defined_value common_ctx Define.DllExport in if value="1" then raise Not_found; value with Not_found -> "export_classes.info" in if (filename <> "") then begin let escape s = let b = Buffer.create 0 in for i = 0 to String.length s - 1 do let c = String.unsafe_get s i in match c with | '\\' -> Buffer.add_char b c; Buffer.add_char b c; | ' ' -> Buffer.add_char b '\\'; Buffer.add_char b 's'; | '\n' -> Buffer.add_char b '\\'; Buffer.add_char b 'n'; | _ -> Buffer.add_char b c; done; Buffer.contents b; in let exeClasses = open_out filename in let out = output_string exeClasses in let outline str = output_string exeClasses (str ^ "\n") in let spath path = (join_class_path path ".") in List.iter (fun (name,_,def) -> match def with | TClassDecl class_def -> outline ((if class_def.cl_interface then "interface " else "class ") ^ (spath name) ); | TEnumDecl enum_def -> out ("enum " ^ (spath name) ^ "\n"); | _ -> () ) !exe_classes; (* Output file info too *) List.iter ( fun file -> let full_path = Path.get_full_path (try Common.find_file common_ctx file with Not_found -> file) in if file <> "?" then out ("file " ^ (escape file) ^ " " ^ (escape full_path) ^"\n") ) ( List.sort String.compare ( pmap_keys !(ctx.ctx_file_info) ) ); close_out exeClasses; end; end; let output_name = match common_ctx.main_class with | Some path -> (snd path) | _ -> "output" in write_build_data common_ctx (common_ctx.file ^ "/Build.xml") !exe_classes !main_deps (!boot_enums@ !boot_classes) !build_xml !extern_src output_name; let cmd_defines = ref "" in PMap.iter ( fun name value -> match name with | "true" | "sys" | "dce" | "cpp" | "debug" -> () | _ -> cmd_defines := !cmd_defines ^ " -D" ^ name ^ "=\"" ^ (escape_command value) ^ "\"" ) common_ctx.defines; write_build_options common_ctx (common_ctx.file ^ "/Options.txt") common_ctx.defines; if ( not (Common.defined common_ctx Define.NoCompilation) ) then begin let t = Common.timer ["generate";"cpp";"native compilation"] in let old_dir = Sys.getcwd() in Sys.chdir common_ctx.file; let cmd = ref "haxelib run hxcpp Build.xml haxe" in if (common_ctx.debug) then cmd := !cmd ^ " -Ddebug"; cmd := !cmd ^ !cmd_defines; cmd := List.fold_left (fun cmd path -> cmd ^ " -I\"" ^ (escape_command path) ^ "\"" ) !cmd common_ctx.class_path; common_ctx.print (!cmd ^ "\n"); if common_ctx.run_command !cmd <> 0 then failwith "Build failed"; Sys.chdir old_dir; t() end ;; let generate common_ctx = if (Common.defined common_ctx Define.Cppia) then begin let ctx = new_context common_ctx 1 (ref PMap.empty) (Hashtbl.create 0) in generate_cppia ctx end else begin let ctx = new_context common_ctx 1 (ref PMap.empty) (create_member_types common_ctx) in generate_source ctx end ;; haxe_3.4.4.orig/src/generators/gencs.ml0000664000175000017500000050072513166552354020016 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open Gencommon.ReflectionCFs open Ast open Common open Type open Gencommon open Gencommon.SourceWriter open Codegen open Printf open Option open ExtString let netname_to_hx name = let len = String.length name in let chr = String.get name 0 in String.make 1 (Char.uppercase chr) ^ (String.sub name 1 (len-1)) let rec is_cs_basic_type t = match follow t with | TInst( { cl_path = (["haxe"], "Int32") }, [] ) | TInst( { cl_path = (["haxe"], "Int64") }, [] ) | TAbstract ({ a_path = (["cs"], "Int64") },[]) | TAbstract ({ a_path = (["cs"], "UInt64") },[]) | TAbstract ({ a_path = ([], "Int") },[]) | TAbstract ({ a_path = ([], "Float") },[]) | TAbstract ({ a_path = ([], "Bool") },[]) -> true | TAbstract ({ a_path = (["cs"], "Pointer") },_) -> false | TAbstract _ when like_float t -> true | TAbstract(a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> is_cs_basic_type (Abstract.get_underlying_type a pl) | TEnum(e, _) when not (Meta.has Meta.Class e.e_meta) -> true | TInst(cl, _) when Meta.has Meta.Struct cl.cl_meta -> true | _ -> false (* see http://msdn.microsoft.com/en-us/library/2sk3x8a7(v=vs.71).aspx *) let cs_binops = [Ast.OpAdd, "op_Addition"; Ast.OpSub, "op_Subtraction"; Ast.OpMult, "op_Multiply"; Ast.OpDiv, "op_Division"; Ast.OpMod, "op_Modulus"; Ast.OpXor, "op_ExclusiveOr"; Ast.OpOr, "op_BitwiseOr"; Ast.OpAnd, "op_BitwiseAnd"; Ast.OpBoolAnd, "op_LogicalAnd"; Ast.OpBoolOr, "op_LogicalOr"; Ast.OpAssign, "op_Assign"; Ast.OpShl, "op_LeftShift"; Ast.OpShr, "op_RightShift"; Ast.OpShr, "op_SignedRightShift"; Ast.OpUShr, "op_UnsignedRightShift"; Ast.OpEq, "op_Equality"; Ast.OpGt, "op_GreaterThan"; Ast.OpLt, "op_LessThan"; Ast.OpNotEq, "op_Inequality"; Ast.OpGte, "op_GreaterThanOrEqual"; Ast.OpLte, "op_LessThanOrEqual"; Ast.OpAssignOp Ast.OpMult, "op_MultiplicationAssignment"; Ast.OpAssignOp Ast.OpSub, "op_SubtractionAssignment"; Ast.OpAssignOp Ast.OpXor, "op_ExclusiveOrAssignment"; Ast.OpAssignOp Ast.OpShl, "op_LeftShiftAssignment"; Ast.OpAssignOp Ast.OpMod, "op_ModulusAssignment"; Ast.OpAssignOp Ast.OpAdd, "op_AdditionAssignment"; Ast.OpAssignOp Ast.OpAnd, "op_BitwiseAndAssignment"; Ast.OpAssignOp Ast.OpOr, "op_BitwiseOrAssignment"; (* op_Comma *) Ast.OpAssignOp Ast.OpDiv, "op_DivisionAssignment";] let cs_unops = [Ast.Decrement, "op_Decrement"; Ast.Increment, "op_Increment"; Ast.Neg, "op_UnaryNegation"; Ast.Not, "op_LogicalNot"; Ast.NegBits, "op_OnesComplement"] let binops_names = List.fold_left (fun acc (op,n) -> PMap.add n op acc) PMap.empty cs_binops let unops_names = List.fold_left (fun acc (op,n) -> PMap.add n op acc) PMap.empty cs_unops let get_item = "get_Item" let set_item = "set_Item" let is_tparam t = match follow t with | TInst( { cl_kind = KTypeParameter _ }, [] ) -> true | _ -> false let rec is_int_float gen t = match follow (gen.greal_type t) with | TInst( { cl_path = (["haxe"], "Int32") }, [] ) | TAbstract ({ a_path = ([], "Int") },[]) | TAbstract ({ a_path = ([], "Float") },[]) -> true | TAbstract _ when like_float t && not (like_i64 t) -> true | TInst( { cl_path = (["haxe"; "lang"], "Null") }, [t] ) -> is_int_float gen t | _ -> false let is_bool t = match follow t with | TAbstract ({ a_path = ([], "Bool") },[]) -> true | _ -> false let is_exactly_bool gen t = match gen.gfollow#run_f t with | TAbstract ({ a_path = ([], "Bool") },[]) -> true | _ -> false let is_dynamic gen t = match follow (gen.greal_type t) with | TDynamic _ -> true | _ -> false let is_pointer gen t = match follow (gen.greal_type t) with | TAbstract( ( {a_path = ["cs"], "Pointer"}, _ ) ) | TInst( {cl_path = ["cs"], "Pointer"}, _ ) -> true | _ -> false let rec is_null t = match t with | TInst( { cl_path = (["haxe"; "lang"], "Null") }, _ ) | TType( { t_path = ([], "Null") }, _ ) -> true | TType( t, tl ) -> is_null (apply_params t.t_params tl t.t_type) | TMono r -> (match !r with | Some t -> is_null t | _ -> false) | TLazy f -> is_null (!f()) | _ -> false let rec get_ptr e = match e.eexpr with | TParenthesis e | TMeta(_,e) | TCast(e,_) -> get_ptr e | TCall( { eexpr = TLocal({ v_name = "__ptr__" }) }, [ e ] ) -> Some e | _ -> None let parse_explicit_iface = let regex = Str.regexp "\\." in let parse_explicit_iface str = let split = Str.split regex str in let rec get_iface split pack = match split with | clname :: fn_name :: [] -> fn_name, (List.rev pack, clname) | pack_piece :: tl -> get_iface tl (pack_piece :: pack) | _ -> assert false in get_iface split [] in parse_explicit_iface let is_string t = match follow t with | TInst( { cl_path = ([], "String") }, [] ) -> true | _ -> false let rec change_md = function | TAbstractDecl(a) when Meta.has Meta.Delegate a.a_meta && not (Meta.has Meta.CoreType a.a_meta) -> change_md (t_to_md a.a_this) | TClassDecl( { cl_kind = KAbstractImpl ({ a_this = TInst(impl,_) } as a) }) when Meta.has Meta.Delegate a.a_meta -> TClassDecl impl | TClassDecl( { cl_kind = KAbstractImpl (a) }) when Meta.has Meta.CoreType a.a_meta -> TAbstractDecl a | md -> md (* used in c#-specific filters to skip some of them for the special haxe.lang.Runtime class *) let in_runtime_class gen = match gen.gcurrent_class with | Some { cl_path = ["haxe";"lang"],"Runtime"} -> true | _ -> false (* ******************************************* *) (* CSharpSpecificESynf *) (* ******************************************* *) (* Some CSharp-specific syntax filters that must run before ExpressionUnwrap dependencies: It must run before ExprUnwrap, as it may not return valid Expr/Statement expressions It must run before ClassInstance, as it will detect expressions that need unchanged TTypeExpr *) module CSharpSpecificESynf = struct let name = "csharp_specific_e" let priority = solve_deps name [DBefore ExpressionUnwrap.priority; DBefore ClassInstance.priority; DAfter TryCatchWrapper.priority] let get_cl_from_t t = match follow t with | TInst(cl,_) -> cl | _ -> assert false let get_ab_from_t t = match follow t with | TAbstract(ab,_) -> ab | _ -> assert false let configure gen runtime_cl = let basic = gen.gcon.basic in let uint = match get_type gen ([], "UInt") with | TTypeDecl t -> TType(t, []) | TAbstractDecl a -> TAbstract(a, []) | _ -> assert false in let is_var = alloc_var "__is__" t_dynamic in let rec run e = match e.eexpr with (* Std.is() *) | TCall( { eexpr = TField( _, FStatic({ cl_path = ([], "Std") }, { cf_name = "is" })) }, [ obj; { eexpr = TTypeExpr(TClassDecl { cl_path = [], "Dynamic" } | TAbstractDecl { a_path = [], "Dynamic" }) }] ) -> Type.map_expr run e | TCall( { eexpr = TField( _, FStatic({ cl_path = ([], "Std") }, { cf_name = "is"}) ) }, [ obj; { eexpr = TTypeExpr(md) }] ) -> let md = change_md md in let mk_is obj md = { e with eexpr = TCall( { eexpr = TLocal is_var; etype = t_dynamic; epos = e.epos }, [ obj; { eexpr = TTypeExpr md; etype = t_dynamic (* this is after all a syntax filter *); epos = e.epos } ] ) } in let mk_or a b = { eexpr = TBinop(Ast.OpBoolOr, a, b); etype = basic.tbool; epos = e.epos } in let wrap_if_needed obj f = (* introduce temp variable for complex expressions *) match obj.eexpr with | TLocal(v) -> f obj | _ -> let var = mk_temp gen "is" obj.etype in let added = { obj with eexpr = TVar(var, Some(obj)); etype = basic.tvoid } in let local = mk_local var obj.epos in { eexpr = TBlock([ added; f local ]); etype = basic.tbool; epos = e.epos } in let obj = run obj in (match follow_module follow md with | TAbstractDecl{ a_path = ([], "Float") } when not (in_runtime_class gen) -> (* on the special case of seeing if it is a Float, we need to test if both it is a float and if it is an Int *) let mk_is local = (* we check if it float or int or uint *) let eisint = mk_is local (TAbstractDecl (get_ab_from_t basic.tint)) in let eisuint = mk_is local (TAbstractDecl (get_ab_from_t uint)) in let eisfloat = mk_is local md in mk_paren (mk_or eisfloat (mk_or eisint eisuint)) in wrap_if_needed obj mk_is | TAbstractDecl{ a_path = ([], "Int") } when not (in_runtime_class gen) -> (* int can be stored in double variable because of anonymous functions, check that case *) let mk_isint_call local = { eexpr = TCall( mk_static_field_access_infer runtime_cl "isInt" e.epos [], [ local ] ); etype = basic.tbool; epos = e.epos } in let mk_is local = let eisint = mk_is local (TAbstractDecl (get_ab_from_t basic.tint)) in let eisuint = mk_is local (TAbstractDecl (get_ab_from_t uint)) in mk_paren (mk_or (mk_or eisint eisuint) (mk_isint_call local)) in wrap_if_needed obj mk_is | TAbstractDecl{ a_path = ([], "UInt") } when not (in_runtime_class gen) -> (* uint can be stored in double variable because of anonymous functions, check that case *) let mk_isuint_call local = { eexpr = TCall( mk_static_field_access_infer runtime_cl "isUInt" e.epos [], [ local ] ); etype = basic.tbool; epos = e.epos } in let mk_is local = let eisuint = mk_is local (TAbstractDecl (get_ab_from_t uint)) in mk_paren (mk_or eisuint (mk_isuint_call local)) in wrap_if_needed obj mk_is | _ -> mk_is obj md ) (* end Std.is() *) | TBinop( Ast.OpUShr, e1, e2 ) -> mk_cast e.etype { e with eexpr = TBinop( Ast.OpShr, mk_cast uint (run e1), run e2 ) } | TBinop( Ast.OpAssignOp Ast.OpUShr, e1, e2 ) -> let mk_ushr local = { e with eexpr = TBinop(Ast.OpAssign, local, run { e with eexpr = TBinop(Ast.OpUShr, local, run e2) }) } in let mk_local obj = let var = mk_temp gen "opUshr" obj.etype in let added = { obj with eexpr = TVar(var, Some(obj)); etype = basic.tvoid } in let local = mk_local var obj.epos in local, added in let e1 = run e1 in let ret = match e1.eexpr with | TField({ eexpr = TLocal _ }, _) | TField({ eexpr = TTypeExpr _ }, _) | TArray({ eexpr = TLocal _ }, _) | TLocal(_) -> mk_ushr e1 | TField(fexpr, field) -> let local, added = mk_local fexpr in { e with eexpr = TBlock([ added; mk_ushr { e1 with eexpr = TField(local, field) } ]); } | TArray(ea1, ea2) -> let local, added = mk_local ea1 in { e with eexpr = TBlock([ added; mk_ushr { e1 with eexpr = TArray(local, ea2) } ]); } | _ -> (* invalid left-side expression *) assert false in ret | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* CSharpSpecificSynf *) (* ******************************************* *) (* Some CSharp-specific syntax filters that can run after ExprUnwrap dependencies: Runs after ExprUnwrap *) module CSharpSpecificSynf = struct let name = "csharp_specific" let priority = solve_deps name [ DAfter ExpressionUnwrap.priority; DAfter ObjectDeclMap.priority; DAfter ArrayDeclSynf.priority; DAfter HardNullableSynf.priority ] let get_cl_from_t t = match follow t with | TInst(cl,_) -> cl | _ -> assert false let is_tparam t = match follow t with | TInst( { cl_kind = KTypeParameter _ }, _ ) -> true | _ -> false let configure gen runtime_cl = let basic = gen.gcon.basic in let tchar = match ( get_type gen (["cs"], "Char16") ) with | TTypeDecl t -> TType(t,[]) | TAbstractDecl a -> TAbstract(a,[]) | _ -> assert false in let string_ext = get_cl ( get_type gen (["haxe";"lang"], "StringExt")) in let clstring = match basic.tstring with | TInst(cl,_) -> cl | _ -> assert false in let ti64 = match ( get_type gen (["cs"], "Int64") ) with | TTypeDecl t -> TType(t,[]) | TAbstractDecl a -> TAbstract(a,[]) | _ -> assert false in let boxed_ptr = if Common.defined gen.gcon Define.Unsafe then get_cl (get_type gen (["haxe";"lang"], "BoxedPointer")) (* get_abstract (get_type gen (["cs"],"Pointer")) *) else null_class in let is_struct t = (* not basic type *) match follow t with | TInst(cl, _) when Meta.has Meta.Struct cl.cl_meta -> true | _ -> false in let is_cl t = match gen.greal_type t with | TInst ( { cl_path = (["System"], "Type") }, [] ) -> true | _ -> false in let as_var = alloc_var "__as__" t_dynamic in let fast_cast = Common.defined gen.gcon Define.FastCast in let rec run e = match e.eexpr with (* Std.int() *) | TCall( { eexpr = TField( _, FStatic({ cl_path = ([], "Std") }, { cf_name = "int" }) ) }, [obj] ) -> run (mk_cast basic.tint obj) (* end Std.int() *) (* TODO: change cf_name *) | TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = "length" })) -> { e with eexpr = TField(run ef, FDynamic "Length") } | TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = "toLowerCase" })) -> { e with eexpr = TField(run ef, FDynamic "ToLowerInvariant") } | TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = "toUpperCase" })) -> { e with eexpr = TField(run ef, FDynamic "ToUpperInvariant") } | TCall( { eexpr = TField(_, FStatic({ cl_path = [], "String" }, { cf_name = "fromCharCode" })) }, [cc] ) -> { e with eexpr = TNew(get_cl_from_t basic.tstring, [], [mk_cast tchar (run cc); ExprBuilder.make_int gen.gcon 1 cc.epos]) } | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("charAt" as field) })) }, args ) | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("charCodeAt" as field) })) }, args ) | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("indexOf" as field) })) }, args ) | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("lastIndexOf" as field) })) }, args ) | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("split" as field) })) }, args ) | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("substring" as field) })) }, args ) | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("substr" as field) })) }, args ) -> { e with eexpr = TCall(mk_static_field_access_infer string_ext field e.epos [], [run ef] @ (List.map run args)) } | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("toString") })) }, [] ) -> run ef | TNew( { cl_path = ([], "String") }, [], [p] ) -> run p (* new String(myString) -> myString *) | TCast(expr, _) when like_float expr.etype && is_pointer gen e.etype -> let expr = run expr in mk_cast e.etype (mk_cast ti64 expr) | TCast(expr, _) when is_dynamic gen expr.etype && is_pointer gen e.etype -> (match get_ptr expr with | None -> (* unboxing *) let expr = run expr in mk_cast e.etype (mk_field_access gen (mk_cast (TInst(boxed_ptr,[])) expr) "value" e.epos) | Some e -> run e) | TCast(expr, _) when is_pointer gen expr.etype && is_dynamic gen e.etype -> (match get_ptr expr with | None -> (* boxing *) let expr = run expr in { e with eexpr = TNew(boxed_ptr,[],[expr]) } | Some e -> run e) | TCast(expr, _) when is_bool e.etype && is_dynamic gen expr.etype -> { eexpr = TCall( mk_static_field_access_infer runtime_cl "toBool" expr.epos [], [ run expr ] ); etype = basic.tbool; epos = e.epos } | TCast(expr, _) when is_int_float gen e.etype && is_dynamic gen expr.etype && ( Common.defined gen.gcon Define.EraseGenerics || not (is_null e.etype) ) && not (in_runtime_class gen) -> let needs_cast = match gen.gfollow#run_f e.etype with | TInst _ -> false | _ -> true in let fun_name = if like_int e.etype then "toInt" else "toDouble" in let ret = { eexpr = TCall( mk_static_field_access_infer runtime_cl fun_name expr.epos [], [ run expr ] ); etype = basic.tint; epos = expr.epos } in if needs_cast then mk_cast e.etype ret else ret | TCast(expr, _) when Common.defined gen.gcon Define.EraseGenerics && like_i64 e.etype && is_dynamic gen expr.etype && not (in_runtime_class gen) -> { eexpr = TCall( mk_static_field_access_infer runtime_cl "toLong" expr.epos [], [ run expr ] ); etype = ti64; epos = expr.epos } | TCast(expr, Some(TClassDecl cls)) when fast_cast && cls == null_class -> if is_cs_basic_type (gen.greal_type e.etype) || is_tparam (gen.greal_type e.etype) then { e with eexpr = TCast(run expr, Some(TClassDecl null_class)) } else { e with eexpr = TCall(mk_local as_var e.epos, [run expr]) } | TCast(expr, _) when (is_string e.etype) && (not (is_string expr.etype)) && not (in_runtime_class gen) -> { e with eexpr = TCall( mk_static_field_access_infer runtime_cl "toString" expr.epos [], [run expr] ) } | TBinop( (Ast.OpNotEq as op), e1, e2) | TBinop( (Ast.OpEq as op), e1, e2) when is_string e1.etype || is_string e2.etype -> let mk_ret e = match op with | Ast.OpNotEq -> { e with eexpr = TUnop(Ast.Not, Ast.Prefix, e) } | _ -> e in mk_ret { e with eexpr = TCall({ eexpr = TField(ExprBuilder.make_static_this clstring e.epos, FDynamic "Equals"); etype = TFun(["obj1",false,basic.tstring; "obj2",false,basic.tstring], basic.tbool); epos = e1.epos }, [ run e1; run e2 ]) } | TCast(expr, _) when is_tparam e.etype && not (in_runtime_class gen) && not (Common.defined gen.gcon Define.EraseGenerics) -> let static = mk_static_field_access_infer (runtime_cl) "genericCast" e.epos [e.etype] in { e with eexpr = TCall(static, [mk_local (alloc_var "$type_param" e.etype) expr.epos; run expr]); } | TBinop( (Ast.OpNotEq as op), e1, e2) | TBinop( (Ast.OpEq as op), e1, e2) when is_struct e1.etype || is_struct e2.etype -> let mk_ret e = match op with | Ast.OpNotEq -> { e with eexpr = TUnop(Ast.Not, Ast.Prefix, e) } | _ -> e in mk_ret { e with eexpr = TCall({ eexpr = TField(run e1, FDynamic "Equals"); etype = TFun(["obj1",false,t_dynamic;], basic.tbool); epos = e1.epos }, [ run e2 ]) } | TBinop ( (Ast.OpEq as op), e1, e2 ) | TBinop ( (Ast.OpNotEq as op), e1, e2 ) when is_cl e1.etype && not (in_runtime_class gen) -> let static = mk_static_field_access_infer (runtime_cl) "typeEq" e.epos [] in let ret = { e with eexpr = TCall(static, [run e1; run e2]); } in if op = Ast.OpNotEq then { ret with eexpr = TUnop(Ast.Not, Ast.Prefix, ret) } else ret | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; let add_cast_handler gen = let basic = gen.gcon.basic in (* starting to set gtparam_cast. *) (* NativeArray: the most important. *) (* var new_arr = new NativeArray(old_arr.Length); var i = -1; while( i < old_arr.Length ) { new_arr[i] = (TO_T) old_arr[i]; } *) let native_arr_cl = get_cl ( get_type gen (["cs"], "NativeArray") ) in let get_narr_param t = match follow t with | TInst({ cl_path = (["cs"], "NativeArray") }, [param]) -> param | _ -> assert false in let gtparam_cast_native_array e to_t = let old_param = get_narr_param e.etype in let new_param = get_narr_param to_t in let new_v = mk_temp gen "new_arr" to_t in let i = mk_temp gen "i" basic.tint in let old_len = mk_field_access gen e "Length" e.epos in let obj_v = mk_temp gen "obj" t_dynamic in let check_null = {eexpr = TBinop(Ast.OpNotEq, e, null e.etype e.epos); etype = basic.tbool; epos = e.epos} in let block = [ { eexpr = TVar( new_v, Some( { eexpr = TNew(native_arr_cl, [new_param], [old_len] ); etype = to_t; epos = e.epos } ) ); etype = basic.tvoid; epos = e.epos }; { eexpr = TVar(i, Some( ExprBuilder.make_int gen.gcon (-1) e.epos )); etype = basic.tvoid; epos = e.epos }; { eexpr = TWhile( { eexpr = TBinop( Ast.OpLt, { eexpr = TUnop(Ast.Increment, Ast.Prefix, mk_local i e.epos); etype = basic.tint; epos = e.epos }, old_len ); etype = basic.tbool; epos = e.epos }, { eexpr = TBlock [ { eexpr = TVar(obj_v, Some (mk_cast t_dynamic { eexpr = TArray(e, mk_local i e.epos); etype = old_param; epos = e.epos })); etype = basic.tvoid; epos = e.epos }; { eexpr = TIf({ eexpr = TBinop(Ast.OpNotEq, mk_local obj_v e.epos, null e.etype e.epos); etype = basic.tbool; epos = e.epos }, { eexpr = TBinop( Ast.OpAssign, { eexpr = TArray(mk_local new_v e.epos, mk_local i e.epos); etype = new_param; epos = e.epos }, mk_cast new_param (mk_local obj_v e.epos) ); etype = new_param; epos = e.epos }, None); etype = basic.tvoid; epos = e.epos } ]; etype = basic.tvoid; epos = e.epos }, Ast.NormalWhile ); etype = basic.tvoid; epos = e.epos; }; mk_local new_v e.epos ] in { eexpr = TIf( check_null, { eexpr = TBlock(block); etype = to_t; epos = e.epos; }, Some(null new_v.v_type e.epos) ); etype = to_t; epos = e.epos; } in Hashtbl.add gen.gtparam_cast (["cs"], "NativeArray") gtparam_cast_native_array (* end set gtparam_cast *) let connecting_string = "?" (* ? see list here http://www.fileformat.info/info/unicode/category/index.htm and here for C# http://msdn.microsoft.com/en-us/library/aa664670.aspx *) let default_package = "cs" (* I'm having this separated as I'm still not happy with having a cs package. Maybe dotnet would be better? *) let strict_mode = ref false (* strict mode is so we can check for unexpected information *) (* reserved c# words *) let reserved = let res = Hashtbl.create 120 in List.iter (fun lst -> Hashtbl.add res lst ("@" ^ lst)) ["abstract"; "as"; "base"; "bool"; "break"; "byte"; "case"; "catch"; "char"; "checked"; "class"; "const"; "continue"; "decimal"; "default"; "delegate"; "do"; "double"; "else"; "enum"; "event"; "explicit"; "extern"; "false"; "finally"; "fixed"; "float"; "for"; "foreach"; "goto"; "if"; "implicit"; "in"; "int"; "interface"; "internal"; "is"; "lock"; "long"; "namespace"; "new"; "null"; "object"; "operator"; "out"; "override"; "params"; "private"; "protected"; "public"; "readonly"; "ref"; "return"; "sbyte"; "sealed"; "short"; "sizeof"; "stackalloc"; "static"; "string"; "struct"; "switch"; "this"; "throw"; "true"; "try"; "typeof"; "uint"; "ulong"; "unchecked"; "unsafe"; "ushort"; "using"; "virtual"; "volatile"; "void"; "while"; "add"; "ascending"; "by"; "descending"; "dynamic"; "equals"; "from"; "get"; "global"; "group"; "into"; "join"; "let"; "on"; "orderby"; "partial"; "remove"; "select"; "set"; "value"; "var"; "where"; "yield"]; res let dynamic_anon = TAnon( { a_fields = PMap.empty; a_status = ref Closed } ) let rec get_class_modifiers meta cl_type cl_access cl_modifiers = match meta with | [] -> cl_type,cl_access,cl_modifiers | (Meta.Struct,[],_) :: meta -> get_class_modifiers meta "struct" cl_access cl_modifiers | (Meta.Protected,[],_) :: meta -> get_class_modifiers meta cl_type "protected" cl_modifiers | (Meta.Internal,[],_) :: meta -> get_class_modifiers meta cl_type "internal" cl_modifiers (* no abstract for now | (":abstract",[],_) :: meta -> get_class_modifiers meta cl_type cl_access ("abstract" :: cl_modifiers) | (":static",[],_) :: meta -> get_class_modifiers meta cl_type cl_access ("static" :: cl_modifiers) TODO: support those types *) | (Meta.Final,[],_) :: meta -> get_class_modifiers meta cl_type cl_access ("sealed" :: cl_modifiers) | (Meta.Unsafe,[],_) :: meta -> get_class_modifiers meta cl_type cl_access ("unsafe" :: cl_modifiers) | _ :: meta -> get_class_modifiers meta cl_type cl_access cl_modifiers let rec get_fun_modifiers meta access modifiers = match meta with | [] -> access,modifiers | (Meta.Protected,[],_) :: meta -> get_fun_modifiers meta "protected" modifiers | (Meta.Internal,[],_) :: meta -> get_fun_modifiers meta "internal" modifiers | (Meta.ReadOnly,[],_) :: meta -> get_fun_modifiers meta access ("readonly" :: modifiers) | (Meta.Unsafe,[],_) :: meta -> get_fun_modifiers meta access ("unsafe" :: modifiers) | (Meta.Volatile,[],_) :: meta -> get_fun_modifiers meta access ("volatile" :: modifiers) | (Meta.Custom ("?prop_impl" | ":cs_event_impl"),[],_) :: meta -> get_fun_modifiers meta "private" modifiers | _ :: meta -> get_fun_modifiers meta access modifiers (* this was the way I found to pass the generator context to be accessible across all functions here *) (* so 'configure' is almost 'top-level' and will have all functions needed to make this work *) let configure gen = let native_arr_cl = get_cl ( get_type gen (["cs"], "NativeArray") ) in gen.gclasses.nativearray <- (fun t -> TInst(native_arr_cl,[t])); gen.gclasses.nativearray_type <- (function TInst(_,[t]) -> t | _ -> assert false); gen.gclasses.nativearray_len <- (fun e p -> mk_field_access gen e "Length" p); let basic = gen.gcon.basic in let erase_generics = Common.defined gen.gcon Define.EraseGenerics in let fn_cl = get_cl (get_type gen (["haxe";"lang"],"Function")) in let null_t = if erase_generics then null_class else (get_cl (get_type gen (["haxe";"lang"],"Null")) ) in let runtime_cl = get_cl (get_type gen (["haxe";"lang"],"Runtime")) in let no_root = Common.defined gen.gcon Define.NoRoot in let change_id name = try Hashtbl.find reserved name with | Not_found -> let ret = String.concat "." (String.nsplit name "#") in List.hd (String.nsplit ret "`") in let change_clname n = change_id n in let change_ns_params_root md ns params = let ns,params = List.fold_left (fun (ns,params) nspart -> try let part, nparams = String.split nspart "`" in let nparams = int_of_string nparams in let rec loop i needed params = if i = nparams then (List.rev needed,params) else loop (i+1) (List.hd params :: needed) (List.tl params) in let needed,params = loop 0 [] params in let part = change_id part in (part ^ "<" ^ (String.concat ", " needed) ^ ">")::ns, params with _ -> (* Invalid_string / int_of_string *) (change_id nspart)::ns, params ) ([],params) ns in List.rev ns,params in let change_ns_params md params ns = if no_root then match ns with | [] when is_hxgen md -> ["haxe";"root"], params | [s] when (t_infos md).mt_private && is_hxgen md -> ["haxe";"root";s], params | [] -> (match md with | TClassDecl { cl_path = ([],"Std" | [],"Math") } -> ["haxe";"root"], params | TClassDecl { cl_meta = m } when Meta.has Meta.Enum m -> ["haxe";"root"], params | _ -> [], params) | ns when params = [] -> List.map change_id ns, params | ns -> change_ns_params_root md ns params else if params = [] then List.map change_id ns, params else change_ns_params_root md ns params in let change_ns md ns = let ns, _ = change_ns_params md [] ns in ns in let change_field = change_id in let write_id w name = write w (change_id name) in let write_field w name = write w (change_field name) in let ptr = if Common.defined gen.gcon Define.Unsafe then get_abstract (get_type gen (["cs"],"Pointer")) else null_abstract in let is_hxgeneric md = TypeParams.RealTypeParams.is_hxgeneric md in let rec field_is_hxgeneric e = match e.eexpr with | TParenthesis e | TMeta(_,e) -> field_is_hxgeneric e | TField(_, (FStatic(cl,_) | FInstance(cl,_,_)) ) -> (* print_endline ("is_hxgeneric " ^ s_type_path cl.cl_path ^ " : " ^ string_of_bool (is_hxgeneric (TClassDecl cl))); *) is_hxgeneric (TClassDecl cl) | _ -> true in gen.gfollow#add ~name:"follow_basic" (fun t -> match t with | TAbstract ({ a_path = ([], "Bool") },[]) | TAbstract ({ a_path = ([], "Void") },[]) | TAbstract ({ a_path = ([],"Float") },[]) | TAbstract ({ a_path = ([],"Int") },[]) | TAbstract ({ a_path = [],"UInt" },[]) | TType ({ t_path = ["cs"], "Int64" },[]) | TAbstract ({ a_path = ["cs"], "Int64" },[]) | TType ({ t_path = ["cs"],"UInt64" },[]) | TAbstract ({ a_path = ["cs"],"UInt64" },[]) | TType ({ t_path = ["cs"],"UInt8" },[]) | TAbstract ({ a_path = ["cs"],"UInt8" },[]) | TType ({ t_path = ["cs"],"Int8" },[]) | TAbstract ({ a_path = ["cs"],"Int8" },[]) | TType ({ t_path = ["cs"],"Int16" },[]) | TAbstract ({ a_path = ["cs"],"Int16" },[]) | TType ({ t_path = ["cs"],"UInt16" },[]) | TAbstract ({ a_path = ["cs"],"UInt16" },[]) | TType ({ t_path = ["cs"],"Char16" },[]) | TAbstract ({ a_path = ["cs"],"Char16" },[]) | TType ({ t_path = ["cs"],"Ref" },_) | TAbstract ({ a_path = ["cs"],"Ref" },_) | TType ({ t_path = ["cs"],"Out" },_) | TAbstract ({ a_path = ["cs"],"Out" },_) | TType ({ t_path = [],"Single" },[]) | TAbstract ({ a_path = [],"Single" },[]) -> Some t | TType (({ t_path = [],"Null" } as tdef),[t2]) -> Some (TType(tdef,[follow (gen.gfollow#run_f t2)])) | TAbstract({ a_path = ["cs"],"PointerAccess" },[t]) -> Some (TAbstract(ptr,[t])) | TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) -> Some (gen.gfollow#run_f ( Abstract.get_underlying_type a pl) ) | TAbstract( { a_path = ([], "EnumValue") }, _ ) | TInst( { cl_path = ([], "EnumValue") }, _ ) -> Some t_dynamic | _ -> None); let module_s_params md params = let md = change_md md in let path = (t_infos md).mt_path in match path with | ([], "String") -> "string", params | ([], "Null") -> s_type_path (change_ns md ["haxe"; "lang"], change_clname "Null"), params | (ns,clname) -> let ns, params = change_ns_params md params ns in s_type_path (ns, change_clname clname), params in let module_s md = fst (module_s_params md []) in let ifaces = Hashtbl.create 1 in let ti64 = match ( get_type gen (["cs"], "Int64") ) with | TTypeDecl t -> TType(t,[]) | TAbstractDecl a -> TAbstract(a,[]) | _ -> assert false in let ttype = get_cl ( get_type gen (["System"], "Type") ) in let has_tdyn tl = List.exists (fun t -> match follow t with | TDynamic _ | TMono _ -> true | _ -> false ) tl in let rec real_type t = let t = gen.gfollow#run_f t in let ret = match t with | TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) -> real_type (Abstract.get_underlying_type a pl) | TAbstract ({ a_path = (["cs";"_Flags"], "EnumUnderlying") }, [t]) -> real_type t | TInst( { cl_path = (["cs";"system"], "String") }, [] ) -> gen.gcon.basic.tstring; | TInst( { cl_path = (["haxe"], "Int32") }, [] ) -> gen.gcon.basic.tint | TInst( { cl_path = (["haxe"], "Int64") }, [] ) -> ti64 | TAbstract( { a_path = [],"Class" }, _ ) | TAbstract( { a_path = [],"Enum" }, _ ) | TAbstract( { a_path = ["haxe";"extern"],"Rest" }, _ ) | TInst( { cl_path = ([], "Class") }, _ ) | TInst( { cl_path = ([], "Enum") }, _ ) -> TInst(ttype,[]) | TInst( ({ cl_kind = KTypeParameter _ } as cl), _ ) when erase_generics && not (Meta.has Meta.NativeGeneric cl.cl_meta) -> t_dynamic | TInst({ cl_kind = KExpr _ }, _) -> t_dynamic | TEnum(_, []) | TInst(_, []) -> t | TInst(cl, params) when has_tdyn params && Hashtbl.mem ifaces cl.cl_path -> TInst(Hashtbl.find ifaces cl.cl_path, []) | TEnum(e, params) -> TEnum(e, List.map (fun _ -> t_dynamic) params) | TInst(cl, params) when Meta.has Meta.Enum cl.cl_meta -> TInst(cl, List.map (fun _ -> t_dynamic) params) | TInst(cl, params) -> TInst(cl, change_param_type (TClassDecl cl) params) | TType({ t_path = ([], "Null") }, [t]) -> (* Null<> handling is a little tricky. It will only change to haxe.lang.Null<> when the actual type is non-nullable or a type parameter It works on cases such as Hash returning Null since cast_detect will invoke real_type at the original type, Null, which will then return the type haxe.lang.Null<> *) if erase_generics then if is_cs_basic_type t then t_dynamic else real_type t else (match real_type t with | TInst( { cl_kind = KTypeParameter _ }, _ ) -> TInst(null_t, [t]) | t when is_cs_basic_type t -> TInst(null_t, [t]) | _ -> real_type t) | TAbstract _ | TType _ -> t | TAnon (anon) when (match !(anon.a_status) with | Statics _ | EnumStatics _ | AbstractStatics _ -> true | _ -> false) -> t | TFun _ -> TInst(fn_cl,[]) | _ -> t_dynamic in ret and (* On hxcs, the only type parameters allowed to be declared are the basic c# types. That's made like this to avoid casting problems when type parameters in this case add nothing to performance, since the memory layout is always the same. To avoid confusion between Generic (which has a different meaning in hxcs AST), all those references are using dynamic_anon, which means Generic<{}> *) change_param_type md tl = let types = match md with | TClassDecl c -> c.cl_params | TEnumDecl e -> [] | TAbstractDecl a -> a.a_params | TTypeDecl t -> t.t_params in let is_hxgeneric = if types = [] then is_hxgen md else (TypeParams.RealTypeParams.is_hxgeneric md) in let ret t = let t_changed = real_type t in match is_hxgeneric, t_changed with | false, _ -> t (* Because Null<> types need a special compiler treatment for many operations (e.g. boxing/unboxing), Null<> type parameters will be transformed into Dynamic. *) | true, TInst ( { cl_path = (["haxe";"lang"], "Null") }, _ ) -> dynamic_anon | true, TInst ( { cl_kind = KTypeParameter _ }, _ ) -> t | true, TInst _ | true, TEnum _ | true, TAbstract _ when is_cs_basic_type t_changed -> t | true, TDynamic _ -> t | true, x -> dynamic_anon in if is_hxgeneric && (erase_generics || List.exists (fun t -> match follow t with | TDynamic _ -> true | _ -> false) tl) then List.map (fun _ -> t_dynamic) tl else List.map ret tl in let is_dynamic t = match real_type t with | TMono _ | TDynamic _ | TInst({ cl_kind = KTypeParameter _ }, _) -> true | TAnon anon -> (match !(anon.a_status) with | EnumStatics _ | Statics _ -> false | _ -> true ) | _ -> false in let rec t_s t = match real_type t with (* basic types *) | TAbstract ({ a_path = ([], "Bool") },[]) -> "bool" | TAbstract ({ a_path = ([], "Void") },[]) -> "object" | TAbstract ({ a_path = ([],"Float") },[]) -> "double" | TAbstract ({ a_path = ([],"Int") },[]) -> "int" | TAbstract ({ a_path = [],"UInt" },[]) -> "uint" | TType ({ t_path = ["cs"], "Int64" },[]) | TAbstract ({ a_path = ["cs"], "Int64" },[]) -> "long" | TType ({ t_path = ["cs"],"UInt64" },[]) | TAbstract ({ a_path = ["cs"],"UInt64" },[]) -> "ulong" | TType ({ t_path = ["cs"],"UInt8" },[]) | TAbstract ({ a_path = ["cs"],"UInt8" },[]) -> "byte" | TType ({ t_path = ["cs"],"Int8" },[]) | TAbstract ({ a_path = ["cs"],"Int8" },[]) -> "sbyte" | TType ({ t_path = ["cs"],"Int16" },[]) | TAbstract ({ a_path = ["cs"],"Int16" },[]) -> "short" | TType ({ t_path = ["cs"],"UInt16" },[]) | TAbstract ({ a_path = ["cs"],"UInt16" },[]) -> "ushort" | TType ({ t_path = ["cs"],"Char16" },[]) | TAbstract ({ a_path = ["cs"],"Char16" },[]) -> "char" | TType ({ t_path = [],"Single" },[]) | TAbstract ({ a_path = [],"Single" },[]) -> "float" | TInst ({ cl_path = ["haxe"],"Int32" },[]) | TAbstract ({ a_path = ["haxe"],"Int32" },[]) -> "int" | TInst ({ cl_path = ["haxe"],"Int64" },[]) | TAbstract ({ a_path = ["haxe"],"Int64" },[]) -> "long" | TInst ({ cl_path = ([], "Dynamic") },_) | TAbstract ({ a_path = ([], "Dynamic") },_) -> "object" | TType ({ t_path = ["cs"],"Out" },[t]) | TAbstract ({ a_path = ["cs"],"Out" },[t]) | TType ({ t_path = ["cs"],"Ref" },[t]) | TAbstract ({ a_path = ["cs"],"Ref" },[t]) -> t_s t | TInst({ cl_path = (["cs"], "NativeArray") }, [param]) -> let rec check_t_s t = match real_type t with | TInst({ cl_path = (["cs"], "NativeArray") }, [param]) -> (check_t_s param) ^ "[]" | _ -> t_s (run_follow gen t) in (check_t_s param) ^ "[]" | TInst({ cl_path = (["cs"], "Pointer") },[t]) | TAbstract({ a_path = (["cs"], "Pointer") },[t])-> let ret = t_s t in (if ret = "object" then "void" else ret) ^ "*" (* end of basic types *) | TInst ({ cl_kind = KTypeParameter _; cl_path=p }, []) -> snd p | TMono r -> (match !r with | None -> "object" | Some t -> t_s (run_follow gen t)) | TInst ({ cl_path = [], "String" }, []) -> "string" | TEnum (e, params) -> ("global::" ^ (module_s (TEnumDecl e))) | TInst (cl, _ :: _) when Meta.has Meta.Enum cl.cl_meta -> "global::" ^ module_s (TClassDecl cl) | TInst (({ cl_path = p } as cl), params) -> (path_param_s (TClassDecl cl) p params) | TType (({ t_path = p } as t), params) -> (path_param_s (TTypeDecl t) p params) | TAnon (anon) -> (match !(anon.a_status) with | Statics _ | EnumStatics _ -> "System.Type" | _ -> "object") | TDynamic _ -> "object" | TAbstract(a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> t_s (Abstract.get_underlying_type a pl) (* No Lazy type nor Function type made. That's because function types will be at this point be converted into other types *) | _ -> if !strict_mode then begin trace ("[ !TypeError " ^ (Type.s_type (Type.print_context()) t) ^ " ]"); assert false end else "[ !TypeError " ^ (Type.s_type (Type.print_context()) t) ^ " ]" and path_param_s md path params = match params with | [] -> "global::" ^ module_s md | _ when erase_generics && is_hxgeneric md -> "global::" ^ module_s md | _ -> let params = (List.map (fun t -> t_s t) (change_param_type md params)) in let str,params = module_s_params md params in if params = [] then "global::" ^ str else sprintf "global::%s<%s>" str (String.concat ", " params) in let rett_s t = match t with | TAbstract ({ a_path = ([], "Void") },[]) -> "void" | _ -> t_s t in let escape ichar b = match ichar with | 92 (* \ *) -> Buffer.add_string b "\\\\" | 39 (* ' *) -> Buffer.add_string b "\\\'" | 34 -> Buffer.add_string b "\\\"" | 13 (* \r *) -> Buffer.add_string b "\\r" | 10 (* \n *) -> Buffer.add_string b "\\n" | 9 (* \t *) -> Buffer.add_string b "\\t" | c when c < 32 || (c >= 127 && c <= 0xFFFF) -> Buffer.add_string b (Printf.sprintf "\\u%.4x" c) | c when c > 0xFFFF -> Buffer.add_string b (Printf.sprintf "\\U%.8x" c) | c -> Buffer.add_char b (Char.chr c) in let escape s = let b = Buffer.create 0 in (try UTF8.validate s; UTF8.iter (fun c -> escape (UChar.code c) b) s with UTF8.Malformed_code -> String.iter (fun c -> escape (Char.code c) b) s ); Buffer.contents b in let has_semicolon e = match e.eexpr with | TBlock _ | TFor _ | TSwitch _ | TTry _ | TIf _ -> false | TWhile (_,_,flag) when flag = Ast.NormalWhile -> false | _ -> true in let in_value = ref false in let rec md_s md = let md = follow_module (gen.gfollow#run_f) md in match md with | TClassDecl ({ cl_params = [] } as cl) -> t_s (TInst(cl,[])) | TClassDecl (cl) when not (is_hxgen md) -> t_s (TInst(cl,List.map (fun t -> t_dynamic) cl.cl_params)) | TEnumDecl ({ e_params = [] } as e) -> t_s (TEnum(e,[])) | TEnumDecl (e) when not (is_hxgen md) -> t_s (TEnum(e,List.map (fun t -> t_dynamic) e.e_params)) | TClassDecl cl -> t_s (TInst(cl,[])) | TEnumDecl e -> t_s (TEnum(e,[])) | TTypeDecl t -> t_s (TType(t, List.map (fun t -> t_dynamic) t.t_params)) | TAbstractDecl a -> t_s (TAbstract(a, List.map(fun t -> t_dynamic) a.a_params)) in let rec ensure_local e explain = match e.eexpr with | TLocal _ -> e | TCast(e,_) | TParenthesis e | TMeta(_,e) -> ensure_local e explain | _ -> gen.gcon.error ("This function argument " ^ explain ^ " must be a local variable.") e.epos; e in let rec ensure_refout e explain = match e.eexpr with | TField _ | TLocal _ -> e | TCast(e,_) | TParenthesis e | TMeta(_,e) -> ensure_refout e explain | _ -> gen.gcon.error ("This function argument " ^ explain ^ " must be a local variable.") e.epos; e in let last_line = ref (-1) in let begin_block w = write w "{"; push_indent w; newline w; last_line := -1 in let end_block w = pop_indent w; (if w.sw_has_content then newline w); write w "}"; newline w; last_line := -1 in let skip_line_directives = (not gen.gcon.debug && not (Common.defined gen.gcon Define.NoCompilation)) || Common.defined gen.gcon Define.RealPosition in let line_directive = if skip_line_directives then fun w p -> () else fun w p -> if p.pfile <> null_pos.pfile then (* Compiler Error CS1560 https://msdn.microsoft.com/en-us/library/z3t5e5sw(v=vs.90).aspx *) let cur_line = Lexer.get_error_line p in let file = Path.get_full_path p.pfile in if cur_line <> ((!last_line)+1) then let line = Ast.s_escape file in if String.length line <= 256 then begin print w "#line %d \"%s\"" cur_line line; newline w end else (* Compiler Error CS1560 https://msdn.microsoft.com/en-us/library/z3t5e5sw(v=vs.90).aspx *) begin print w "//line %d \"%s\"" cur_line line; newline w end; last_line := cur_line in let line_reset_directive = if skip_line_directives then fun w -> () else fun w -> print w "#line default" in let rec extract_tparams params el = match el with | ({ eexpr = TLocal({ v_name = "$type_param" }) } as tp) :: tl -> extract_tparams (tp.etype :: params) tl | _ -> (params, el) in let is_extern_prop t name = match follow (run_follow gen t), field_access gen t name with | TInst({ cl_interface = true; cl_extern = true } as cl, _), FNotFound -> not (is_hxgen (TClassDecl cl)) | _, FClassField(_,_,decl,v,_,t,_) -> Type.is_extern_field v && (Meta.has Meta.Property v.cf_meta || (decl.cl_extern && not (is_hxgen (TClassDecl decl)))) | _ -> false in let is_event t name = match follow (run_follow gen t), field_access gen t name with | TInst({ cl_interface = true; cl_extern = true } as cl, _), FNotFound -> not (is_hxgen (TClassDecl cl)) | _, FClassField(_,_,decl,v,_,_,_) -> Meta.has Meta.Event v.cf_meta | _ -> false in let extract_statements expr = let ret = ref [] in let rec loop expr = match expr.eexpr with | TCall ({ eexpr = TLocal { v_name = "__is__" | "__typeof__" | "__array__" | "__sizeof__" | "__delegate__" } }, el) -> List.iter loop el | TNew ({ cl_path = (["cs"], "NativeArray") }, params, [ size ]) -> () | TUnop (Ast.Increment, _, _) | TUnop (Ast.Decrement, _, _) | TBinop (Ast.OpAssign, _, _) | TBinop (Ast.OpAssignOp _, _, _) | TLocal { v_name = "__fallback__" } | TLocal { v_name = "__sbreak__" } -> ret := expr :: !ret | TConst _ | TLocal _ | TArray _ | TBinop _ | TField _ | TEnumParameter _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ | TCast _ | TMeta _ | TParenthesis _ | TUnop _ -> Type.iter loop expr | TFunction _ -> () (* do not extract parameters from inside of it *) | _ -> ret := expr :: !ret in loop expr; (* [expr] *) List.rev !ret in let expr_s w e = last_line := -1; in_value := false; let rec expr_s w e = let was_in_value = !in_value in in_value := true; (match e.eexpr with | TCall({ eexpr = TField(ef,f) }, (_ :: _ as args) ) when (field_name f) = "get_Item" -> expr_s w ef; write w "["; let first = ref true in List.iter (fun f -> if !first then first := false else write w ", "; expr_s w f ) args; write w "]" | TCall({ eexpr = TField(ef,f) }, (_ :: _ :: _ as args) ) when (field_name f) = "set_Item" -> expr_s w ef; write w "["; let args, value = match List.rev args with | v :: args -> List.rev args, v | _ -> assert false in let first = ref true in List.iter (fun f -> if !first then first := false else write w ", "; expr_s w f ) args; write w "] = "; expr_s w value | TCall( ({ eexpr = TField(ef,f) } as e), [ev] ) when String.starts_with (field_name f) "add_" -> let name = field_name f in let propname = String.sub name 4 (String.length name - 4) in if is_event (gen.greal_type ef.etype) propname then begin expr_s w ef; write w "."; write_field w propname; write w " += "; expr_s w ev end else do_call w e [ev] | TCall( ({ eexpr = TField(ef,f) } as e), [ev] ) when String.starts_with (field_name f) "remove_" -> let name = field_name f in let propname = String.sub name 7 (String.length name - 7) in if is_event (gen.greal_type ef.etype) propname then begin expr_s w ef; write w "."; write_field w propname; write w " -= "; expr_s w ev end else do_call w e [ev] | TCall( ({ eexpr = TField(ef,f) } as e), [] ) when String.starts_with (field_name f) "get_" -> let name = field_name f in let propname = String.sub name 4 (String.length name - 4) in if is_extern_prop (gen.greal_type ef.etype) propname then begin expr_s w ef; write w "."; write_field w propname end else do_call w e [] | TCall( ({ eexpr = TField(ef,f) } as e), [v] ) when String.starts_with (field_name f) "set_" -> let name = field_name f in let propname = String.sub name 4 (String.length name - 4) in if is_extern_prop (gen.greal_type ef.etype) propname then begin expr_s w ef; write w "."; write_field w propname; write w " = "; expr_s w v end else do_call w e [v] | TField (e, (FStatic(_, cf) | FInstance(_, _, cf))) when Meta.has Meta.Native cf.cf_meta -> let rec loop meta = match meta with | (Meta.Native, [EConst (String s), _],_) :: _ -> expr_s w e; write w "."; write_field w s | _ :: tl -> loop tl | [] -> expr_s w e; write w "."; write_field w (cf.cf_name) in loop cf.cf_meta | TConst c -> (match c with | TInt i32 -> write w (Int32.to_string i32); (* these suffixes won't work because of the cast detector which will set each constant to its expected type *) (*match real_type e.etype with | TType( { t_path = (["haxe";"_Int64"], "NativeInt64") }, [] ) -> write w "L"; | _ -> () *) | TFloat s -> write w s; (if String.get s (String.length s - 1) = '.' then write w "0"); (*match real_type e.etype with | TType( { t_path = ([], "Single") }, [] ) -> write w "f" | _ -> () *) | TString s -> write w "\""; write w (escape s); write w "\"" | TBool b -> write w (if b then "true" else "false") | TNull when is_cs_basic_type e.etype || is_tparam e.etype -> write w "default("; write w (t_s e.etype); write w ")" | TNull -> write w "null" | TThis -> write w "this" | TSuper -> write w "base") | TCast({ eexpr = TConst(TNull) }, _) -> write w "default("; write w (t_s e.etype); write w ")" | TLocal { v_name = "__sbreak__" } -> write w "break" | TLocal { v_name = "__undefined__" } -> write w (t_s (TInst(runtime_cl, List.map (fun _ -> t_dynamic) runtime_cl.cl_params))); write w ".undefined"; | TLocal { v_name = "__typeof__" } -> write w "typeof" | TLocal { v_name = "__sizeof__" } -> write w "sizeof" | TLocal var -> write_id w var.v_name | TField (_, FEnum(e, ef)) -> let s = ef.ef_name in print w "%s." ("global::" ^ module_s (TEnumDecl e)); write_field w s | TArray (e1, e2) -> expr_s w e1; write w "["; expr_s w e2; write w "]" | TBinop ((Ast.OpAssign as op), e1, e2) | TBinop ((Ast.OpAssignOp _ as op), e1, e2) -> expr_s w e1; write w ( " " ^ (Ast.s_binop op) ^ " " ); expr_s w e2 | TBinop (op, e1, e2) -> write w "( "; expr_s w e1; write w ( " " ^ (Ast.s_binop op) ^ " " ); expr_s w e2; write w " )" | TField ({ eexpr = TTypeExpr mt }, s) -> (match mt with | TClassDecl { cl_path = (["haxe"], "Int64") } -> write w ("global::" ^ module_s mt) | TClassDecl { cl_path = (["haxe"], "Int32") } -> write w ("global::" ^ module_s mt) | TClassDecl { cl_interface = true } -> write w ("global::" ^ module_s mt); write w "__Statics_"; | TClassDecl cl -> write w (t_s (TInst(cl, List.map (fun _ -> t_empty) cl.cl_params))) | TEnumDecl en -> write w (t_s (TEnum(en, List.map (fun _ -> t_empty) en.e_params))) | TTypeDecl td -> write w (t_s (gen.gfollow#run_f (TType(td, List.map (fun _ -> t_empty) td.t_params)))) | TAbstractDecl a -> write w (t_s (TAbstract(a, List.map (fun _ -> t_empty) a.a_params))) ); write w "."; write_field w (field_name s) | TField (e, s) when is_pointer gen e.etype -> (* take off the extra cast if possible *) let e = match e.eexpr with | TCast(e1,_) when CastDetect.type_iseq gen e.etype e1.etype -> e1 | _ -> e in expr_s w e; write w "->"; write_field w (field_name s) | TField (e, s) -> expr_s w e; write w "."; write_field w (field_name s) | TTypeExpr mt -> (match change_md mt with | TClassDecl { cl_path = (["haxe"], "Int64") } -> write w ("global::" ^ module_s mt) | TClassDecl { cl_path = (["haxe"], "Int32") } -> write w ("global::" ^ module_s mt) | TClassDecl cl -> write w (t_s (TInst(cl, List.map (fun _ -> t_empty) cl.cl_params))); | TEnumDecl en -> write w (t_s (TEnum(en, List.map (fun _ -> t_empty) en.e_params))) | TTypeDecl td -> write w (t_s (gen.gfollow#run_f (TType(td, List.map (fun _ -> t_empty) td.t_params)))) | TAbstractDecl a -> write w (t_s (TAbstract(a, List.map (fun _ -> t_empty) a.a_params))) ) | TParenthesis e -> write w "("; expr_s w e; write w ")" | TMeta (_,e) -> expr_s w e | TArrayDecl el | TCall ({ eexpr = TLocal { v_name = "__array__" } }, el) | TCall ({ eexpr = TField(_, FStatic({ cl_path = (["cs"],"NativeArray") }, { cf_name = "make" })) }, el) -> let _, el = extract_tparams [] el in print w "new %s" (t_s e.etype); write w "{"; ignore (List.fold_left (fun acc e -> (if acc <> 0 then write w ", "); expr_s w e; acc + 1 ) 0 el); write w "}" | TCall ({ eexpr = TLocal { v_name = "__delegate__" } }, [del]) -> expr_s w del | TCall ({ eexpr = TLocal( { v_name = "__is__" } ) }, [ expr; { eexpr = TTypeExpr(md) } ] ) -> write w "( "; expr_s w expr; write w " is "; write w (md_s md); write w " )" | TCall ({ eexpr = TLocal( { v_name = "__as__" } ) }, [ expr; { eexpr = TTypeExpr(md) } ] ) -> write w "( "; expr_s w expr; write w " as "; write w (md_s md); write w " )" | TCall ({ eexpr = TLocal( { v_name = "__as__" } ) }, expr :: _ ) -> write w "( "; expr_s w expr; write w " as "; write w (t_s e.etype); write w " )"; | TCall ({ eexpr = TLocal( { v_name = "__cs__" } ) }, [ { eexpr = TConst(TString(s)) } ] ) -> write w s | TCall ({ eexpr = TLocal( { v_name = "__cs__" } ) }, { eexpr = TConst(TString(s)) } :: tl ) -> Codegen.interpolate_code gen.gcon s tl (write w) (expr_s w) e.epos | TCall ({ eexpr = TLocal( { v_name = "__stackalloc__" } ) }, [ e ] ) -> write w "stackalloc byte["; expr_s w e; write w "]" | TCall ({ eexpr = TLocal( { v_name = "__unsafe__" } ) }, [ e ] ) -> write w "unsafe"; expr_s w (mk_block e) | TCall ({ eexpr = TLocal( { v_name = "__checked__" } ) }, [ e ] ) -> write w "checked"; expr_s w (mk_block e) | TCall ({ eexpr = TLocal( { v_name = "__lock__" } ) }, [ eobj; eblock ] ) -> write w "lock("; expr_s w eobj; write w ")"; expr_s w (mk_block eblock) | TCall ({ eexpr = TLocal( { v_name = "__fixed__" } ) }, [ e ] ) -> let fixeds = ref [] in let rec loop = function | ({ eexpr = TVar(v, Some(e) ) } as expr) :: tl when is_pointer gen v.v_type -> let e = match get_ptr e with | None -> e | Some e -> e in fixeds := (v,e,expr) :: !fixeds; loop tl; | el when !fixeds <> [] -> let rec loop fx acc = match fx with | (v,e,expr) :: tl -> write w "fixed("; let vf = mk_temp gen "fixed" v.v_type in expr_s w { expr with eexpr = TVar(vf, Some e) }; write w ") "; begin_block w; expr_s w { expr with eexpr = TVar(v, Some (mk_local vf expr.epos)) }; write w ";"; newline w; loop tl (acc + 1) | [] -> acc in let nblocks = loop (List.rev !fixeds) 0 in in_value := false; expr_s w { e with eexpr = TBlock el }; for i = 1 to nblocks do end_block w done | _ -> trace (debug_expr e); gen.gcon.error "Invalid 'fixed' keyword format" e.epos in (match e.eexpr with | TBlock bl -> loop bl | _ -> trace "not block"; trace (debug_expr e); gen.gcon.error "Invalid 'fixed' keyword format" e.epos ) | TCall ({ eexpr = TLocal( { v_name = "__addressOf__" } ) }, [ e ] ) -> let e = ensure_local e "for addressOf" in write w "&"; expr_s w e | TCall ({ eexpr = TLocal( { v_name = "__valueOf__" } ) }, [ e ] ) -> write w "*("; expr_s w e; write w ")" | TCall ({ eexpr = TLocal( { v_name = "__goto__" } ) }, [ { eexpr = TConst(TInt v) } ] ) -> print w "goto label%ld" v | TCall ({ eexpr = TLocal( { v_name = "__label__" } ) }, [ { eexpr = TConst(TInt v) } ] ) -> print w "label%ld: {}" v | TCall ({ eexpr = TLocal( { v_name = "__rethrow__" } ) }, _) -> write w "throw" (* operator overloading handling *) | TCall({ eexpr = TField(ef, FInstance(cl,_,{ cf_name = "__get" })) }, [idx]) when not (is_hxgen (TClassDecl cl)) -> expr_s w { e with eexpr = TArray(ef, idx) } | TCall({ eexpr = TField(ef, FInstance(cl,_,{ cf_name = "__set" })) }, [idx; v]) when not (is_hxgen (TClassDecl cl)) -> expr_s w { e with eexpr = TBinop(Ast.OpAssign, { e with eexpr = TArray(ef, idx) }, v) } | TCall({ eexpr = TField(ef, FStatic(_,cf)) }, el) when PMap.mem cf.cf_name binops_names -> let _, elr = extract_tparams [] el in (match elr with | [e1;e2] -> expr_s w { e with eexpr = TBinop(PMap.find cf.cf_name binops_names, e1, e2) } | _ -> do_call w e el) | TCall({ eexpr = TField(ef, FStatic(_,cf)) }, el) when PMap.mem cf.cf_name unops_names -> (match extract_tparams [] el with | _, [e1] -> expr_s w { e with eexpr = TUnop(PMap.find cf.cf_name unops_names, Ast.Prefix,e1) } | _ -> do_call w e el) | TCall (e, el) -> do_call w e el | TNew (({ cl_path = (["cs"], "NativeArray") } as cl), params, [ size ]) -> let rec check_t_s t times = match real_type t with | TInst({ cl_path = (["cs"], "NativeArray") }, [param]) -> (check_t_s param (times+1)) | _ -> print w "new %s[" (t_s (run_follow gen t)); expr_s w size; print w "]"; let rec loop i = if i <= 0 then () else (write w "[]"; loop (i-1)) in loop (times - 1) in check_t_s (TInst(cl, params)) 0 | TNew ({ cl_path = ([], "String") } as cl, [], el) -> write w "new "; write w (t_s (TInst(cl, []))); write w "("; ignore (List.fold_left (fun acc e -> (if acc <> 0 then write w ", "); expr_s w e; acc + 1 ) 0 el); write w ")" | TNew ({ cl_kind = KTypeParameter _ } as cl, params, el) -> print w "default(%s) /* This code should never be reached. It was produced by the use of @:generic on a new type parameter instance: %s */" (t_s (TInst(cl,params))) (path_param_s (TClassDecl cl) cl.cl_path params) | TNew (cl, params, el) -> write w "new "; write w (path_param_s (TClassDecl cl) cl.cl_path params); write w "("; ignore (List.fold_left (fun acc e -> (if acc <> 0 then write w ", "); expr_s w e; acc + 1 ) 0 el); write w ")" | TUnop ((Ast.Increment as op), flag, e) | TUnop ((Ast.Decrement as op), flag, e) -> (match flag with | Ast.Prefix -> write w ( " " ^ (Ast.s_unop op) ^ " " ); expr_s w e | Ast.Postfix -> expr_s w e; write w (Ast.s_unop op)) | TUnop (op, flag, e) -> (match flag with | Ast.Prefix -> write w ( " " ^ (Ast.s_unop op) ^ " (" ); expr_s w e; write w ") " | Ast.Postfix -> write w "("; expr_s w e; write w (") " ^ Ast.s_unop op)) | TVar (var, eopt) -> print w "%s " (t_s var.v_type); write_id w var.v_name; (match eopt with | None -> write w " = "; expr_s w (null var.v_type e.epos) | Some e -> write w " = "; expr_s w e ) | TBlock [e] when was_in_value -> expr_s w e | TBlock el -> begin_block w; List.iter (fun e -> List.iter (fun e -> line_directive w e.epos; in_value := false; expr_s w e; (if has_semicolon e then write w ";"); newline w ) (extract_statements e) ) el; end_block w | TIf (econd, e1, Some(eelse)) when was_in_value -> let base = t_s e.etype in write w "( "; expr_s w (mk_paren econd); write w " ? "; if t_s e1.etype <> base then expr_s w (mk_cast e.etype e1) else expr_s w (mk_paren e1); write w " : "; if t_s eelse.etype <> base then expr_s w (mk_cast e.etype eelse) else expr_s w (mk_paren eelse); write w " )"; | TIf (econd, e1, eelse) -> write w "if "; expr_s w (mk_paren econd); write w " "; in_value := false; expr_s w (mk_block e1); (match eelse with | None -> () | Some e -> write w "else "; in_value := false; let e = match e.eexpr with | TIf _ -> e | TBlock [{eexpr = TIf _} as e] -> e | _ -> mk_block e in expr_s w e ) | TWhile (econd, eblock, flag) -> (match flag with | Ast.NormalWhile -> write w "while "; expr_s w (mk_paren econd); write w " "; in_value := false; expr_s w (mk_block eblock) | Ast.DoWhile -> write w "do "; in_value := false; expr_s w (mk_block eblock); write w "while "; in_value := true; expr_s w (mk_paren econd); ) | TSwitch (econd, ele_l, default) -> write w "switch "; expr_s w (mk_paren econd); write w " "; begin_block w; List.iter (fun (el, e) -> List.iter (fun e -> write w "case "; in_value := true; expr_s w e; write w ":"; newline w; ) el; in_value := false; expr_s w (mk_block e); newline w; newline w ) ele_l; if is_some default then begin write w "default:"; newline w; in_value := false; expr_s w (get default); newline w; end; end_block w | TTry (tryexpr, ve_l) -> write w "try "; in_value := false; expr_s w (mk_block tryexpr); List.iter (fun (var, e) -> print w "catch (%s %s)" (t_s var.v_type) (var.v_name); in_value := false; expr_s w (mk_block e); newline w ) ve_l | TReturn eopt -> write w "return"; if is_some eopt then (write w " "; expr_s w (get eopt)) | TBreak -> write w "break" | TContinue -> write w "continue" | TThrow e -> write w "throw "; expr_s w e | TCast (e1,md_t) -> ((*match gen.gfollow#run_f e.etype with | TType({ t_path = ([], "UInt") }, []) -> write w "( unchecked ((uint) "; expr_s w e1; write w ") )" | _ ->*) (* FIXME I'm ignoring module type *) print w "((%s) (" (t_s e.etype); expr_s w e1; write w ") )" ) | TFor (_,_,content) -> write w "[ for not supported "; expr_s w content; write w " ]"; if !strict_mode then assert false | TObjectDecl _ -> write w "[ obj decl not supported ]"; if !strict_mode then assert false | TFunction _ -> write w "[ func decl not supported ]"; if !strict_mode then assert false | TEnumParameter _ -> write w "[ enum parameter not supported ]"; if !strict_mode then assert false ) and do_call w e el = let params, el = extract_tparams [] el in let params = List.rev params in expr_s w e; (match params with | _ :: _ when not (erase_generics && field_is_hxgeneric e) -> let md = match e.eexpr with | TField(ef, _) -> t_to_md (run_follow gen ef.etype) | _ -> assert false in write w "<"; ignore (List.fold_left (fun acc t -> (if acc <> 0 then write w ", "); write w (t_s t); acc + 1 ) 0 (change_param_type md params)); write w ">" | _ -> () ); let rec loop acc elist tlist = match elist, tlist with | e :: etl, (_,_,t) :: ttl -> (if acc <> 0 then write w ", "); (match real_type t with | TType({ t_path = (["cs"], "Ref") }, _) | TAbstract ({ a_path = (["cs"], "Ref") },_) -> let e = ensure_refout e "of type cs.Ref" in write w "ref "; expr_s w e | TType({ t_path = (["cs"], "Out") }, _) | TAbstract ({ a_path = (["cs"], "Out") },_) -> let e = ensure_refout e "of type cs.Out" in write w "out "; expr_s w e | _ -> expr_s w e ); loop (acc + 1) etl ttl | e :: etl, [] -> (if acc <> 0 then write w ", "); expr_s w e; loop (acc + 1) etl [] | _ -> () in write w "("; let ft = match follow e.etype with | TFun(args,_) -> args | _ -> [] in loop 0 el ft; write w ")" in expr_s w e in let rec gen_fpart_attrib w = function | EConst( Ident i ), _ -> write w i | EField( ef, f ), _ -> gen_fpart_attrib w ef; write w "."; write w f | _, p -> gen.gcon.error "Invalid expression inside @:meta metadata" p in let rec gen_spart w = function | EConst c, p -> (match c with | Int s | Float s | Ident s -> write w s | String s -> write w "\""; write w (escape s); write w "\"" | _ -> gen.gcon.error "Invalid expression inside @:meta metadata" p) | EField( ef, f ), _ -> gen_spart w ef; write w "."; write w f | EBinop( Ast.OpAssign, (EConst (Ident s), _), e2 ), _ -> write w s; write w " = "; gen_spart w e2 | EArrayDecl( el ), _ -> write w "new[] {"; let fst = ref true in List.iter (fun e -> if !fst then fst := false else write w ", "; gen_spart w e ) el; write w "}" | ECall(fpart,args), _ -> gen_fpart_attrib w fpart; write w "("; let fst = ref true in List.iter (fun e -> if !fst then fst := false else write w ", "; gen_spart w e ) args; write w ")" | _, p -> gen.gcon.error "Invalid expression inside @:meta metadata" p in let gen_attributes w metadata = List.iter (function | Meta.Meta, [EConst(String s), _], _ -> write w "["; write w s; write w "]"; newline w | Meta.Meta, [meta], _ -> write w "["; gen_spart w meta; write w "]"; newline w | _ -> () ) metadata in let gen_nocompletion w metadata = if Meta.has Meta.NoCompletion metadata then begin write w "[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]"; newline w end; in let argt_s t = let w = new_source_writer () in let rec run t = match t with | TType (tdef,p) -> gen_attributes w tdef.t_meta; run (follow_once t) | TMono r -> (match !r with | Some t -> run t | _ -> () (* avoid infinite loop / should be the same in this context *)) | TLazy f -> run (!f()) | _ -> () in run t; let ret = match run_follow gen t with | TType ({ t_path = (["cs"], "Ref") }, [t]) | TAbstract ({ a_path = (["cs"], "Ref") },[t]) -> "ref " ^ t_s t | TType ({ t_path = (["cs"], "Out") }, [t]) | TAbstract ({ a_path = (["cs"], "Out") },[t]) -> "out " ^ t_s t | t -> t_s t in let c = contents w in if c <> "" then c ^ " " ^ ret else ret in let get_string_params cl cl_params = let hxgen = is_hxgen (TClassDecl cl) in match cl_params with | (_ :: _) when not (erase_generics && is_hxgeneric (TClassDecl cl)) -> let get_param_name t = match follow t with TInst(cl, _) -> snd cl.cl_path | _ -> assert false in let params = sprintf "<%s>" (String.concat ", " (List.map (fun (_, tcl) -> get_param_name tcl) cl_params)) in let params_extends = if hxgen (* this is temprorary, see https://github.com/HaxeFoundation/haxe/issues/3526 *) || not (Meta.has (Meta.Custom ":nativeTypeConstraints") cl.cl_meta) then [""] else List.fold_left (fun acc (name, t) -> match run_follow gen t with | TInst({cl_kind = KTypeParameter constraints}, _) when constraints <> [] -> (* base class should come before interface constraints *) let base_class_constraints = ref [] in let other_constraints = List.fold_left (fun acc t -> match follow t with (* string is implicitly sealed, maybe haxe should have it final as well *) | TInst ({ cl_path=[],"String" }, []) -> acc (* non-sealed class *) | TInst ({ cl_interface = false; cl_meta = meta},_) when not (Meta.has Meta.Final meta) -> base_class_constraints := (t_s t) :: !base_class_constraints; acc; (* interface *) | TInst ({ cl_interface = true}, _) -> (t_s t) :: acc (* skip anything other *) | _ -> acc ) [] constraints in let s_constraints = (!base_class_constraints @ other_constraints) in if s_constraints <> [] then (sprintf " where %s : %s" (get_param_name t) (String.concat ", " s_constraints) :: acc) else acc; | _ -> acc ) [] cl_params in (params, String.concat " " params_extends) | _ -> ("","") in let gen_field_decl w visibility v_n modifiers t n = let parts = ref [] in if visibility <> "" then parts := visibility :: !parts; if v_n <> "" then parts := v_n :: !parts; if modifiers <> [] then parts := modifiers @ !parts; if t <> "" then parts := t :: !parts; parts := n :: !parts; write w (String.concat " " (List.rev !parts)); in let rec gen_event w is_static cl (event,t,custom,add,remove) = let is_interface = cl.cl_interface in let visibility = if is_interface then "" else "public" in let visibility, modifiers = get_fun_modifiers event.cf_meta visibility ["event"] in let v_n = if is_static then "static" else "" in gen_field_decl w visibility v_n modifiers (t_s (run_follow gen t)) (change_field event.cf_name); if custom && not is_interface then begin write w " "; begin_block w; print w "add { _add_%s(value); }" event.cf_name; newline w; print w "remove { _remove_%s(value); }" event.cf_name; newline w; end_block w; newline w; end else write w ";\n"; newline w; in let rec gen_prop w is_static cl is_final (prop,t,get,set) = gen_attributes w prop.cf_meta; let is_interface = cl.cl_interface in let fn_is_final = function | None -> true | Some ({ cf_kind = Method mkind } as m) -> (match mkind with | MethInline -> true | _ -> false) || Meta.has Meta.Final m.cf_meta | _ -> assert false in let is_virtual = not (is_interface || is_final || Meta.has Meta.Final prop.cf_meta || fn_is_final get || fn_is_final set) in let fn_is_override = function | Some cf -> List.memq cf cl.cl_overrides | None -> false in let is_override = fn_is_override get || fn_is_override set in let visibility = if is_interface then "" else "public" in let visibility, modifiers = get_fun_modifiers prop.cf_meta visibility [] in let v_n = if is_static then "static" else if is_override && not is_interface then "override" else if is_virtual then "virtual" else "" in gen_nocompletion w prop.cf_meta; gen_field_decl w visibility v_n modifiers (t_s (run_follow gen t)) (change_field prop.cf_name); let check cf = match cf with | Some ({ cf_overloads = o :: _ } as cf) -> gen.gcon.error "Property functions with more than one overload is currently unsupported" cf.cf_pos; gen.gcon.error "Property functions with more than one overload is currently unsupported" o.cf_pos | _ -> () in check get; check set; write w " "; if is_interface then begin write w "{ "; let s = ref "" in (match prop.cf_kind with Var { v_read = AccCall } -> write w "get;"; s := " "; | _ -> ()); (match prop.cf_kind with Var { v_write = AccCall } -> print w "%sset;" !s | _ -> ()); write w " }"; newline w; end else begin begin_block w; (match get with | Some cf -> print w "get { return _get_%s(); }" prop.cf_name; newline w; cf.cf_meta <- (Meta.Custom "?prop_impl", [], null_pos) :: cf.cf_meta; | None -> ()); (match set with | Some cf -> print w "set { _set_%s(value); }" prop.cf_name; newline w; cf.cf_meta <- (Meta.Custom "?prop_impl", [], null_pos) :: cf.cf_meta; | None -> ()); end_block w; newline w; newline w; end; in let needs_unchecked e = let rec loop e = match e.eexpr with (* a non-zero integer constant means that we want unchecked context *) | TConst (TInt i) when i <> Int32.zero -> raise Exit (* don't recurse into explicit checked blocks *) | TCall ({ eexpr = TLocal({ v_name = "__checked__" }) }, _) -> () (* skip reflection field hashes as they are safe *) | TNew ({ cl_path = (["haxe"; "lang"],"DynamicObject") }, [], [_; e1; _; e2]) -> loop e1; loop e2 | TNew ({ cl_path = (["haxe"; "lang"],"Closure") }, [], [eo; _; _]) -> loop eo | TCall ({ eexpr = TField (_, FStatic ({ cl_path = ["haxe"; "lang"],"Runtime" }, { cf_name = "getField" | "setField" | "getField_f" | "setField_f" | "callField" })) }, eo :: _ :: _ :: rest) -> loop eo; List.iter loop rest | _ -> Type.iter loop e in try (loop e; false) with Exit -> true in let rec gen_class_field w ?(is_overload=false) is_static cl is_final cf = gen_attributes w cf.cf_meta; let is_interface = cl.cl_interface in let name, is_new, is_explicit_iface = match cf.cf_name with | "new" -> snd cl.cl_path, true, false | name when String.contains name '.' -> let fn_name, path = parse_explicit_iface name in (s_type_path path) ^ "." ^ fn_name, false, true | name -> try let binop = PMap.find name binops_names in "operator " ^ s_binop binop, false, false with | Not_found -> try let unop = PMap.find name unops_names in "operator " ^ s_unop unop, false, false with | Not_found -> if Meta.has (Meta.Custom "?prop_impl") cf.cf_meta || Meta.has (Meta.Custom ":cs_event_impl") cf.cf_meta then "_" ^ name, false, false else name, false, false in let rec loop_static cl = match is_static, cl.cl_super with | false, _ -> [] | true, None -> [] | true, Some(cl,_) -> (try let cf2 = PMap.find cf.cf_name cl.cl_statics in CastDetect.type_eq gen EqStrict cf.cf_type cf2.cf_type; ["new"] with | Not_found | Unify_error _ -> loop_static cl ) in let modf = loop_static cl in (match cf.cf_kind with | Var _ | Method (MethDynamic) when not (Type.is_extern_field cf) -> (if is_overload || List.exists (fun cf -> cf.cf_expr <> None) cf.cf_overloads then gen.gcon.error "Only normal (non-dynamic) methods can be overloaded" cf.cf_pos); if not is_interface then begin let access, modifiers = get_fun_modifiers cf.cf_meta "public" [] in let modifiers = modifiers @ modf in gen_nocompletion w cf.cf_meta; gen_field_decl w access (if is_static then "static" else "") modifiers (t_s (run_follow gen cf.cf_type)) (change_field name); (match cf.cf_expr with | Some e -> write w " = "; expr_s w e; | None -> () ); write w ";" end (* TODO see how (get,set) variable handle when they are interfaces *) | Method _ when Type.is_extern_field cf || (match cl.cl_kind, cf.cf_expr with | KAbstractImpl _, None -> true | _ -> false) -> List.iter (fun cf -> if cl.cl_interface || cf.cf_expr <> None then gen_class_field w ~is_overload:true is_static cl (Meta.has Meta.Final cf.cf_meta) cf ) cf.cf_overloads | Var _ | Method MethDynamic -> () | Method mkind -> List.iter (fun cf -> if cl.cl_interface || cf.cf_expr <> None then gen_class_field w ~is_overload:true is_static cl (Meta.has Meta.Final cf.cf_meta) cf ) cf.cf_overloads; let is_virtual = not is_final && match mkind with | MethInline -> false | _ when not is_new -> true | _ -> false in let is_virtual = if not is_virtual || Meta.has Meta.Final cf.cf_meta then false else is_virtual in let is_override = List.memq cf cl.cl_overrides in let is_override = is_override || match cf.cf_name, follow cf.cf_type with | "Equals", TFun([_,_,targ], tret) -> (match follow targ, follow tret with | TDynamic _, TAbstract({ a_path = ([], "Bool") }, []) -> true | _ -> false) | "GetHashCode", TFun([],_) -> true | _ -> false in let is_override = if Meta.has (Meta.Custom "?prop_impl") cf.cf_meta then false else is_override in let is_virtual = is_virtual && not (Meta.has Meta.Final cl.cl_meta) && not (is_interface) in let visibility = if is_interface then "" else "public" in let visibility, modifiers = get_fun_modifiers cf.cf_meta visibility [] in let modifiers = modifiers @ modf in let visibility, is_virtual = if is_explicit_iface then "",false else if visibility = "private" then "private",false else visibility, is_virtual in let v_n = if is_static then "static" else if is_override && not is_interface then "override" else if is_virtual then "virtual" else "" in let cf_type = if is_override && not is_overload && not (Meta.has Meta.Overload cf.cf_meta) then match field_access gen (TInst(cl, List.map snd cl.cl_params)) cf.cf_name with | FClassField(_,_,_,_,_,actual_t,_) -> actual_t | _ -> assert false else cf.cf_type in let ret_type, args = match follow cf_type with | TFun (strbtl, t) -> (t, strbtl) | _ -> assert false in gen_nocompletion w cf.cf_meta; (* public static void funcName *) gen_field_decl w visibility v_n modifiers (if not is_new then (rett_s (run_follow gen ret_type)) else "") (change_field name); let params, params_ext = get_string_params cl cf.cf_params in (* (string arg1, object arg2) with T : object *) (match cf.cf_expr with | Some { eexpr = TFunction tf } -> print w "%s(%s)%s" (params) (String.concat ", " (List.map2 (fun (var, _) (_,_,t) -> sprintf "%s %s" (argt_s t) (change_id var.v_name)) tf.tf_args args)) (params_ext) | _ -> print w "%s(%s)%s" (params) (String.concat ", " (List.map (fun (name, _, t) -> sprintf "%s %s" (argt_s t) (change_id name)) args)) (params_ext) ); if is_interface then write w ";" else begin write w " "; let rec loop meta = match meta with | [] -> let expr = match cf.cf_expr with | None -> mk (TBlock([])) t_dynamic null_pos | Some s -> match s.eexpr with | TFunction tf -> mk_block (tf.tf_expr) | _ -> assert false (* FIXME *) in let write_method_expr e = match e.eexpr with | TBlock [] -> begin_block w; end_block w | TBlock _ -> let unchecked = needs_unchecked e in if unchecked then (begin_block w; write w "unchecked "); let t = Common.timer ["expression to string"] in expr_s w e; t(); line_reset_directive w; if unchecked then end_block w | _ -> assert false in (if is_new then begin let rec get_super_call el = match el with | ( { eexpr = TCall( { eexpr = TConst(TSuper) }, _) } as call) :: rest -> Some call, rest | ( { eexpr = TBlock(bl) } as block ) :: rest -> let ret, mapped = get_super_call bl in ret, ( { block with eexpr = TBlock(mapped) } :: rest ) | _ -> None, el in match expr.eexpr with | TBlock(bl) -> let super_call, rest = get_super_call bl in (match super_call with | None -> () | Some sc -> write w ": "; let t = Common.timer ["expression to string"] in expr_s w sc; write w " "; t() ); write_method_expr { expr with eexpr = TBlock(rest) } | _ -> assert false end else write_method_expr expr ) | (Meta.FunctionCode, [Ast.EConst (Ast.String contents),_],_) :: tl -> begin_block w; write w contents; end_block w | _ :: tl -> loop tl in loop cf.cf_meta end); newline w; newline w; in let check_special_behaviors w cl = match cl.cl_kind with | KAbstractImpl _ -> () | _ -> (* get/set pairs *) let pairs = ref PMap.empty in (try let get = PMap.find "__get" cl.cl_fields in List.iter (fun cf -> let args,ret = get_fun cf.cf_type in match args with | [_,_,idx] -> pairs := PMap.add (t_s idx) ( t_s ret, Some cf, None ) !pairs | _ -> gen.gcon.warning "The __get function must have exactly one argument (the index)" cf.cf_pos ) (get :: get.cf_overloads) with | Not_found -> ()); (try let set = PMap.find "__set" cl.cl_fields in List.iter (fun cf -> let args, ret = get_fun cf.cf_type in match args with | [_,_,idx; _,_,v] -> (try let vt, g, _ = PMap.find (t_s idx) !pairs in let tvt = t_s v in if vt <> tvt then gen.gcon.warning "The __get function of same index has a different type from this __set function" cf.cf_pos; pairs := PMap.add (t_s idx) (vt, g, Some cf) !pairs with | Not_found -> pairs := PMap.add (t_s idx) (t_s v, None, Some cf) !pairs) | _ -> gen.gcon.warning "The __set function must have exactly two arguments (index, value)" cf.cf_pos ) (set :: set.cf_overloads) with | Not_found -> ()); PMap.iter (fun idx (v, get, set) -> print w "public %s this[%s index]" v idx; begin_block w; (match get with | None -> () | Some _ -> write w "get"; begin_block w; write w "return this.__get(index);"; end_block w); (match set with | None -> () | Some _ -> write w "set"; begin_block w; write w "this.__set(index,value);"; end_block w); end_block w) !pairs; (if not (PMap.is_empty !pairs) then try let get = PMap.find "__get" cl.cl_fields in let idx_t, v_t = match follow get.cf_type with | TFun([_,_,arg_t],ret_t) -> t_s (run_follow gen arg_t), t_s (run_follow gen ret_t) | _ -> gen.gcon.error "The __get function must be a function with one argument. " get.cf_pos; assert false in List.iter (fun (cl,args) -> match cl.cl_array_access with | None -> () | Some t -> let changed_t = apply_params cl.cl_params (List.map (fun _ -> t_dynamic) cl.cl_params) t in let t_as_s = t_s (run_follow gen changed_t) in print w "%s %s.this[int key]" t_as_s (t_s (TInst(cl, args))); begin_block w; write w "get"; begin_block w; print w "return ((%s) this.__get(key));" t_as_s; end_block w; write w "set"; begin_block w; print w "this.__set(key, (%s) value);" v_t; end_block w; end_block w; newline w; newline w ) cl.cl_implements with | Not_found -> ()); if cl.cl_interface && is_hxgen (TClassDecl cl) && is_some cl.cl_array_access then begin let changed_t = apply_params cl.cl_params (List.map (fun _ -> t_dynamic) cl.cl_params) (get cl.cl_array_access) in print w "%s this[int key]" (t_s (run_follow gen changed_t)); begin_block w; write w "get;"; newline w; write w "set;"; newline w; end_block w; newline w; newline w end; (try if cl.cl_interface then raise Not_found; let cf = PMap.find "toString" cl.cl_fields in (if List.exists (fun c -> c.cf_name = "toString") cl.cl_overrides then raise Not_found); (match cf.cf_type with | TFun([], ret) -> (match real_type ret with | TInst( { cl_path = ([], "String") }, []) -> write w "public override string ToString()"; begin_block w; write w "return this.toString();"; end_block w; newline w; newline w | _ -> gen.gcon.error "A toString() function should return a String!" cf.cf_pos ) | _ -> () ) with | Not_found -> ()); (try if cl.cl_interface then raise Not_found; let cf = PMap.find "finalize" cl.cl_fields in (if List.exists (fun c -> c.cf_name = "finalize") cl.cl_overrides then raise Not_found); (match cf.cf_type with | TFun([], ret) -> (match real_type ret with | TAbstract( { a_path = ([], "Void") }, []) -> write w "~"; write w (snd cl.cl_path); write w "()"; begin_block w; write w "this.finalize();"; end_block w; newline w; newline w | _ -> gen.gcon.error "A finalize() function should be Void->Void!" cf.cf_pos ) | _ -> () ) with | Not_found -> ()); (* properties *) let handle_prop static f = match f.cf_kind with | Method _ -> () | Var v when not (Type.is_extern_field f) -> () | Var v -> let prop acc = match acc with | AccNo | AccNever | AccCall -> true | _ -> false in if prop v.v_read && prop v.v_write && (v.v_read = AccCall || v.v_write = AccCall) then begin let this = if static then ExprBuilder.make_static_this cl f.cf_pos else { eexpr = TConst TThis; etype = TInst(cl,List.map snd cl.cl_params); epos = f.cf_pos } in print w "public %s%s %s" (if static then "static " else "") (t_s f.cf_type) (netname_to_hx f.cf_name); begin_block w; (match v.v_read with | AccCall -> write w "get"; begin_block w; write w "return "; expr_s w this; print w ".get_%s();" f.cf_name; end_block w | _ -> ()); (match v.v_write with | AccCall -> write w "set"; begin_block w; expr_s w this; print w ".set_%s(value);" f.cf_name; end_block w | _ -> ()); end_block w; end in if Meta.has Meta.BridgeProperties cl.cl_meta then begin List.iter (handle_prop true) cl.cl_ordered_statics; List.iter (handle_prop false) cl.cl_ordered_fields; end in let gen_class w cl = write w "#pragma warning disable 109, 114, 219, 429, 168, 162"; newline w; let should_close = match change_ns (TClassDecl cl) (fst (cl.cl_path)) with | [] -> false | ns -> print w "namespace %s " (String.concat "." ns); begin_block w; true in (try let _,m,_ = Meta.get (Meta.Custom "generic_iface") cl.cl_meta in let rec loop i acc = if i == 0 then acc else "object" :: (loop (pred i) acc) in let tparams = loop (match m with [(EConst(Int s),_)] -> int_of_string s | _ -> assert false) [] in cl.cl_meta <- (Meta.Meta, [ EConst(String("global::haxe.lang.GenericInterface(typeof(global::" ^ module_s (TClassDecl cl) ^ "<" ^ String.concat ", " tparams ^ ">))") ), cl.cl_pos ], cl.cl_pos) :: cl.cl_meta with Not_found -> ()); gen_attributes w cl.cl_meta; let is_main = match gen.gcon.main_class with | Some ( (_,"Main") as path) when path = cl.cl_path && not cl.cl_interface -> (* for cases where the main class is called Main, there will be a problem with creating the entry point there. In this special case, a special entry point class will be created *) write w "public class EntryPoint__Main "; begin_block w; write w "public static void Main() "; begin_block w; (if Hashtbl.mem gen.gtypes (["cs"], "Boot") then write w "global::cs.Boot.init();"; newline w); (match gen.gcon.main with | None -> expr_s w { eexpr = TTypeExpr(TClassDecl cl); etype = t_dynamic; epos = null_pos }; write w ".main();" | Some expr -> expr_s w (mk_block expr)); end_block w; end_block w; newline w; false | Some path when path = cl.cl_path && not cl.cl_interface -> true | _ -> false in let clt, access, modifiers = get_class_modifiers cl.cl_meta (if cl.cl_interface then "interface" else "class") "public" [] in let is_final = clt = "struct" || Meta.has Meta.Final cl.cl_meta in let modifiers = [access] @ modifiers in print w "%s %s %s" (String.concat " " modifiers) clt (change_clname (snd cl.cl_path)); (* type parameters *) let params, params_ext = get_string_params cl cl.cl_params in let extends_implements = (match cl.cl_super with | None -> [] | Some (cl,p) -> [path_param_s (TClassDecl cl) cl.cl_path p]) @ (List.map (fun (cl,p) -> path_param_s (TClassDecl cl) cl.cl_path p) cl.cl_implements) in (match extends_implements with | [] -> print w "%s%s " params params_ext | _ -> print w "%s : %s%s " params (String.concat ", " extends_implements) params_ext); (* class head ok: *) (* public class Test : X, Y, Z where A : Y *) begin_block w; newline w; (* our constructor is expected to be a normal "new" function * if !strict_mode && is_some cl.cl_constructor then assert false;*) let rec loop meta = match meta with | [] -> () | (Meta.ClassCode, [Ast.EConst (Ast.String contents),_],_) :: tl -> write w contents | _ :: tl -> loop tl in loop cl.cl_meta; if is_main then begin write w "public static void Main()"; begin_block w; (if Hashtbl.mem gen.gtypes (["cs"], "Boot") then write w "global::cs.Boot.init();"; newline w); (match gen.gcon.main with | None -> write w "main();"; | Some expr -> expr_s w (mk_block expr)); end_block w end; (match cl.cl_init with | None -> () | Some init -> print w "static %s() " (snd cl.cl_path); if needs_unchecked init then begin begin_block w; write w "unchecked "; expr_s w (mk_block init); end_block w; end else expr_s w (mk_block init); line_reset_directive w; newline w; newline w ); (* collect properties and events *) let partition cf cflist = let events, props, nonprops = ref [], ref [], ref [] in List.iter (fun v -> match v.cf_kind with | Var { v_read = AccCall } | Var { v_write = AccCall } when Type.is_extern_field v && Meta.has Meta.Property v.cf_meta -> props := (v.cf_name, ref (v, v.cf_type, None, None)) :: !props; | Var { v_read = AccNormal; v_write = AccNormal } when Meta.has Meta.Event v.cf_meta -> events := (v.cf_name, ref (v, v.cf_type, false, None, None)) :: !events; | _ -> nonprops := v :: !nonprops; ) cflist; let events, nonprops = !events, !nonprops in let t = TInst(cl, List.map snd cl.cl_params) in let find_prop name = try List.assoc name !props with | Not_found -> match field_access gen t name with | FClassField (_,_,decl,v,_,t,_) when is_extern_prop (TInst(cl,List.map snd cl.cl_params)) name -> let ret = ref (v,t,None,None) in props := (name, ret) :: !props; ret | _ -> raise Not_found in let find_event name = List.assoc name events in let is_empty_function cf = match cf.cf_expr with | Some {eexpr = TFunction { tf_expr = {eexpr = TBlock []}}} -> true | _ -> false in let interf = cl.cl_interface in (* get all functions that are getters/setters *) let nonprops = List.filter (function | cf when String.starts_with cf.cf_name "get_" -> (try (* find the property *) let prop = find_prop (String.sub cf.cf_name 4 (String.length cf.cf_name - 4)) in let v, t, get, set = !prop in assert (get = None); prop := (v,t,Some cf,set); not interf with | Not_found -> true) | cf when String.starts_with cf.cf_name "set_" -> (try (* find the property *) let prop = find_prop (String.sub cf.cf_name 4 (String.length cf.cf_name - 4)) in let v, t, get, set = !prop in assert (set = None); prop := (v,t,get,Some cf); not interf with | Not_found -> true) | cf when String.starts_with cf.cf_name "add_" -> (try let event = find_event (String.sub cf.cf_name 4 (String.length cf.cf_name - 4)) in let v, t, _, add, remove = !event in assert (add = None); let custom = not (is_empty_function cf) in event := (v, t, custom, Some cf, remove); false with | Not_found -> true) | cf when String.starts_with cf.cf_name "remove_" -> (try let event = find_event (String.sub cf.cf_name 7 (String.length cf.cf_name - 7)) in let v, t, _, add, remove = !event in assert (remove = None); let custom = not (is_empty_function cf) in event := (v, t, custom, add, Some cf); false with | Not_found -> true) | _ -> true ) nonprops in let nonprops = ref nonprops in List.iter (fun (n,r) -> let ev, t, custom, add, remove = !r in match add, remove with | Some add, Some remove -> if custom && not cl.cl_interface then nonprops := add :: remove :: !nonprops | _ -> assert false (* shouldn't happen because Filters.check_cs_events makes sure methods are present *) ) events; let evts = List.map (fun(_,v) -> !v) events in let ret = List.map (fun (_,v) -> !v) !props in let ret = List.filter (function | (_,_,None,None) -> false | _ -> true) ret in evts, ret, List.rev !nonprops in let fevents, fprops, fnonprops = partition cl cl.cl_ordered_fields in let sevents, sprops, snonprops = partition cl cl.cl_ordered_statics in (if is_some cl.cl_constructor then gen_class_field w false cl is_final (get cl.cl_constructor)); if not cl.cl_interface then begin (* we don't want to generate properties for abstract implementation classes, because they don't have object to work with *) List.iter (gen_event w true cl) sevents; if (match cl.cl_kind with KAbstractImpl _ -> false | _ -> true) then List.iter (gen_prop w true cl is_final) sprops; List.iter (gen_class_field w true cl is_final) snonprops end; List.iter (gen_event w false cl) fevents; List.iter (gen_prop w false cl is_final) fprops; List.iter (gen_class_field w false cl is_final) fnonprops; check_special_behaviors w cl; end_block w; if cl.cl_interface && cl.cl_ordered_statics <> [] then begin print w "public class %s__Statics_" (snd cl.cl_path); begin_block w; List.iter (gen_class_field w true { cl with cl_interface = false } is_final) cl.cl_ordered_statics; end_block w end; if should_close then end_block w in let gen_enum w e = let should_close = match change_ns (TEnumDecl e) (fst e.e_path) with | [] -> false | ns -> print w "namespace %s" (String.concat "." ns); begin_block w; true in gen_attributes w e.e_meta; print w "public enum %s" (change_clname (snd e.e_path)); begin_block w; write w (String.concat ", " (List.map (change_id) e.e_names)); end_block w; if should_close then end_block w in let module_type_gen w md_tp = let file_start = len w = 0 in let requires_root = no_root && file_start in if file_start then Codegen.map_source_header gen.gcon (fun s -> print w "// %s\n" s); reset_temps(); match md_tp with | TClassDecl cl -> if not cl.cl_extern then begin (if requires_root then write w "using haxe.root;\n"; newline w;); gen_class w cl; newline w; newline w end; (not cl.cl_extern) | TEnumDecl e -> if not e.e_extern && not (Meta.has Meta.Class e.e_meta) then begin (if requires_root then write w "using haxe.root;\n"; newline w;); gen_enum w e; newline w; newline w end; (not e.e_extern) | TAbstractDecl _ | TTypeDecl _ -> false in (* generate source code *) init_ctx gen; Hashtbl.add gen.gspecial_vars "__rethrow__" true; Hashtbl.add gen.gspecial_vars "__typeof__" true; Hashtbl.add gen.gspecial_vars "__label__" true; Hashtbl.add gen.gspecial_vars "__goto__" true; Hashtbl.add gen.gspecial_vars "__is__" true; Hashtbl.add gen.gspecial_vars "__as__" true; Hashtbl.add gen.gspecial_vars "__cs__" true; Hashtbl.add gen.gspecial_vars "__checked__" true; Hashtbl.add gen.gspecial_vars "__lock__" true; Hashtbl.add gen.gspecial_vars "__fixed__" true; Hashtbl.add gen.gspecial_vars "__unsafe__" true; Hashtbl.add gen.gspecial_vars "__addressOf__" true; Hashtbl.add gen.gspecial_vars "__valueOf__" true; Hashtbl.add gen.gspecial_vars "__sizeof__" true; Hashtbl.add gen.gspecial_vars "__stackalloc__" true; Hashtbl.add gen.gspecial_vars "__delegate__" true; Hashtbl.add gen.gspecial_vars "__array__" true; Hashtbl.add gen.gspecial_vars "__ptr__" true; Hashtbl.add gen.gsupported_conversions (["haxe"; "lang"], "Null") (fun t1 t2 -> true); let last_needs_box = gen.gneeds_box in gen.gneeds_box <- (fun t -> match (gen.greal_type t) with | TAbstract( ( { a_path = ["cs"], "Pointer" }, _ ) ) | TInst( { cl_path = ["cs"], "Pointer" }, _ ) | TInst( { cl_path = (["haxe"; "lang"], "Null") }, _ ) -> true | _ -> last_needs_box t); gen.greal_type <- real_type; gen.greal_type_param <- change_param_type; SetHXGen.run_filter gen; (* before running the filters, follow all possible types *) (* this is needed so our module transformations don't break some core features *) (* like multitype selection *) let run_follow_gen = run_follow gen in let rec type_map e = Type.map_expr_type (fun e->type_map e) (run_follow_gen) (fun tvar-> tvar.v_type <- (run_follow_gen tvar.v_type); tvar) e in let super_map (cl,tl) = (cl, List.map run_follow_gen tl) in List.iter (function | TClassDecl cl -> let all_fields = (Option.map_default (fun cf -> [cf]) [] cl.cl_constructor) @ cl.cl_ordered_fields @ cl.cl_ordered_statics in List.iter (fun cf -> cf.cf_type <- run_follow_gen cf.cf_type; cf.cf_expr <- Option.map type_map cf.cf_expr; (* add @:skipReflection to @:event vars *) match cf.cf_kind with | Var _ when (Meta.has Meta.Event cf.cf_meta) && not (Meta.has Meta.SkipReflection cf.cf_meta) -> cf.cf_meta <- (Meta.SkipReflection, [], null_pos) :: cf.cf_meta; | _ -> () ) all_fields; cl.cl_dynamic <- Option.map run_follow_gen cl.cl_dynamic; cl.cl_array_access <- Option.map run_follow_gen cl.cl_array_access; cl.cl_init <- Option.map type_map cl.cl_init; cl.cl_super <- Option.map super_map cl.cl_super; cl.cl_implements <- List.map super_map cl.cl_implements | _ -> () ) gen.gtypes_list; let tp_v = alloc_var "$type_param" t_dynamic in let mk_tp t pos = { eexpr = TLocal(tp_v); etype = t; epos = pos } in gen.gparam_func_call <- (fun ecall efield params elist -> match efield.eexpr with | TField(_, FEnum _) -> { ecall with eexpr = TCall(efield, elist) } | _ -> { ecall with eexpr = TCall(efield, (List.map (fun t -> mk_tp t ecall.epos) params) @ elist) } ); if not erase_generics then HardNullableSynf.configure gen (fun e -> match e.eexpr, real_type e.etype with | TConst TThis, _ when gen.gcurrent_path = (["haxe";"lang"], "Null") -> e | _, TInst({ cl_path = (["haxe";"lang"], "Null") }, [t]) -> let e = { e with eexpr = TParenthesis(e) } in { (mk_field_access gen e "value" e.epos) with etype = t } | _ -> trace (debug_type e.etype); gen.gcon.error "This expression is not a Nullable expression" e.epos; assert false ) (fun v t has_value -> match has_value, real_type v.etype with | true, TDynamic _ | true, TAnon _ | true, TMono _ -> { eexpr = TCall(mk_static_field_access_infer null_t "ofDynamic" v.epos [t], [mk_tp t v.epos; v]); etype = TInst(null_t, [t]); epos = v.epos } | _ -> { eexpr = TNew(null_t, [t], [gen.ghandle_cast t v.etype v; { eexpr = TConst(TBool has_value); etype = gen.gcon.basic.tbool; epos = v.epos } ]); etype = TInst(null_t, [t]); epos = v.epos } ) (fun e -> { eexpr = TCall( { (mk_field_access gen { (mk_paren e) with etype = real_type e.etype } "toDynamic" e.epos) with etype = TFun([], t_dynamic) }, []); etype = t_dynamic; epos = e.epos } ) (fun e -> mk_field_access gen { e with etype = real_type e.etype } "hasValue" e.epos ) (fun e1 e2 -> mk (TCall(mk_field_access gen e1 "Equals" e1.epos, [e2])) basic.tbool e1.epos ); let explicit_fn_name c tl fname = path_param_s (TClassDecl c) c.cl_path tl ^ "." ^ fname in FixOverrides.configure ~explicit_fn_name:explicit_fn_name ~get_vmtype:real_type gen; Normalize.configure gen ~metas:(Hashtbl.create 0); AbstractImplementationFix.configure gen; IteratorsInterface.configure gen; let closure_t = ClosuresToClass.DoubleAndDynamicClosureImpl.get_ctx gen (get_cl (get_type gen (["haxe";"lang"],"Function"))) 6 in ClosuresToClass.configure gen closure_t; let enum_base = (get_cl (get_type gen (["haxe";"lang"],"Enum")) ) in let param_enum_base = (get_cl (get_type gen (["haxe";"lang"],"ParamEnum")) ) in EnumToClass.configure gen (Some (fun e -> mk_cast gen.gcon.basic.tint e)) true true enum_base param_enum_base; InterfaceVarsDeleteModf.configure gen; InterfaceProps.configure gen; let dynamic_object = (get_cl (get_type gen (["haxe";"lang"],"DynamicObject")) ) in let object_iface = get_cl (get_type gen (["haxe";"lang"],"IHxObject")) in let empty_en = match get_type gen (["haxe";"lang"], "EmptyObject") with TEnumDecl e -> e | _ -> assert false in let empty_ctor_type = TEnum(empty_en, []) in let empty_en_expr = mk (TTypeExpr (TEnumDecl empty_en)) (TAnon { a_fields = PMap.empty; a_status = ref (EnumStatics empty_en) }) null_pos in let empty_ctor_expr = mk (TField (empty_en_expr, FEnum(empty_en, PMap.find "EMPTY" empty_en.e_constrs))) empty_ctor_type null_pos in OverloadingConstructor.configure ~empty_ctor_type:empty_ctor_type ~empty_ctor_expr:empty_ctor_expr gen; let rcf_static_find = mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) "findHash" null_pos [] in let rcf_static_lookup = mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) "lookupHash" null_pos [] in let rcf_static_insert, rcf_static_remove = if erase_generics then begin let get_specialized_postfix t = match t with | TAbstract({a_path = [],("Float" | "Int" as name)}, _) -> name | TAnon _ | TDynamic _ -> "Dynamic" | _ -> print_endline (debug_type t); assert false in (fun t -> mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) ("insert" ^ get_specialized_postfix t) null_pos []), (fun t -> mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) ("remove" ^ get_specialized_postfix t) null_pos []) end else (fun t -> mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) "insert" null_pos [t]), (fun t -> mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) "remove" null_pos [t]) in let can_be_float = like_float in let rcf_on_getset_field main_expr field_expr field may_hash may_set is_unsafe = let is_float = can_be_float (real_type main_expr.etype) in let fn_name = if is_some may_set then "setField" else "getField" in let fn_name = if is_float then fn_name ^ "_f" else fn_name in let pos = field_expr.epos in let is_unsafe = { eexpr = TConst(TBool is_unsafe); etype = basic.tbool; epos = pos } in let should_cast = match main_expr.etype with | TAbstract({ a_path = ([], "Float") }, []) -> false | _ -> true in let infer = mk_static_field_access_infer runtime_cl fn_name field_expr.epos [] in let first_args = [ field_expr; { eexpr = TConst(TString field); etype = basic.tstring; epos = pos } ] @ if is_some may_hash then [ { eexpr = TConst(TInt (get may_hash)); etype = basic.tint; epos = pos } ] else [] in let args = first_args @ match is_float, may_set with | true, Some(set) -> [ if should_cast then mk_cast basic.tfloat set else set ] | false, Some(set) -> [ set ] | _ -> [ is_unsafe ] in let call = { main_expr with eexpr = TCall(infer,args) } in let call = if is_float && should_cast then mk_cast main_expr.etype call else call in call in let rcf_on_call_field ecall field_expr field may_hash args = let infer = mk_static_field_access_infer runtime_cl "callField" field_expr.epos [] in let hash_arg = match may_hash with | None -> [] | Some h -> [ { eexpr = TConst(TInt h); etype = basic.tint; epos = field_expr.epos } ] in let arr_call = if args <> [] then { eexpr = TArrayDecl args; etype = basic.tarray t_dynamic; epos = ecall.epos } else null (basic.tarray t_dynamic) ecall.epos in let call_args = [field_expr; { field_expr with eexpr = TConst(TString field); etype = basic.tstring } ] @ hash_arg @ [ arr_call ] in mk_cast ecall.etype { ecall with eexpr = TCall(infer, call_args) } in add_cast_handler gen; if not erase_generics then TypeParams.RealTypeParams.configure gen (fun e t -> gen.gcon.warning ("Cannot cast to " ^ (debug_type t)) e.epos; mk_cast t e) ifaces (get_cl (get_type gen (["haxe";"lang"], "IGenericObject"))) else TypeParams.RealTypeParams.RealTypeParamsModf.configure gen (TypeParams.RealTypeParams.RealTypeParamsModf.set_only_hxgeneric gen); let flookup_cl = get_cl (get_type gen (["haxe";"lang"], "FieldLookup")) in let rcf_ctx = ReflectionCFs.new_ctx gen closure_t object_iface true rcf_on_getset_field rcf_on_call_field (fun hash hash_array length -> { hash with eexpr = TCall(rcf_static_find, [hash; hash_array; length]); etype=basic.tint }) (fun hash -> { hash with eexpr = TCall(rcf_static_lookup, [hash]); etype = gen.gcon.basic.tstring }) (fun hash_array length pos value -> let ecall = mk (TCall(rcf_static_insert value.etype, [hash_array; length; pos; value])) (if erase_generics then hash_array.etype else basic.tvoid) hash_array.epos in if erase_generics then { ecall with eexpr = TBinop(OpAssign, hash_array, ecall) } else ecall ) (fun hash_array length pos -> let t = gen.gclasses.nativearray_type hash_array.etype in { hash_array with eexpr = TCall(rcf_static_remove t, [hash_array; length; pos]); etype = gen.gcon.basic.tvoid } ) ( let delete = mk_static_field_access_infer flookup_cl "deleteHashConflict" null_pos [] in let get = mk_static_field_access_infer flookup_cl "getHashConflict" null_pos [] in let set = mk_static_field_access_infer flookup_cl "setHashConflict" null_pos [] in let add = mk_static_field_access_infer flookup_cl "addHashConflictNames" null_pos [] in let conflict_t = TInst (get_cl (get_type gen (["haxe"; "lang"], "FieldHashConflict")), []) in Some { t = conflict_t; get_conflict = (fun ehead ehash ename -> mk (TCall (get, [ehead; ehash; ename])) conflict_t ehead.epos); set = (fun ehead ehash ename evalue -> mk (TCall (set, [ehead; ehash; ename; evalue])) basic.tvoid ehead.epos); delete = (fun ehead ehash ename -> mk (TCall (delete, [ehead; ehash; ename])) basic.tbool ehead.epos); add_names = (fun ehead earr -> mk (TCall (add, [ehead; earr])) basic.tvoid ehead.epos); } ) in ReflectionCFs.UniversalBaseClass.configure gen (get_cl (get_type gen (["haxe";"lang"],"HxObject")) ) object_iface dynamic_object; ReflectionCFs.configure_dynamic_field_access rcf_ctx; let closure_cl = get_cl (get_type gen (["haxe";"lang"],"Closure")) in let varargs_cl = get_cl (get_type gen (["haxe";"lang"],"VarArgsFunction")) in let dynamic_name = gen.gmk_internal_name "hx" "invokeDynamic" in List.iter (fun cl -> List.iter (fun cf -> if cf.cf_name = dynamic_name then cl.cl_overrides <- cf :: cl.cl_overrides ) cl.cl_ordered_fields ) [closure_cl; varargs_cl]; ReflectionCFs.implement_varargs_cl rcf_ctx ( get_cl (get_type gen (["haxe";"lang"], "VarArgsBase")) ); let slow_invoke = mk_static_field_access_infer (runtime_cl) "slowCallField" null_pos [] in ReflectionCFs.configure rcf_ctx ~slow_invoke:(fun ethis efield eargs -> { eexpr = TCall(slow_invoke, [ethis; efield; eargs]); etype = t_dynamic; epos = ethis.epos; } ) object_iface; ObjectDeclMap.configure gen (ReflectionCFs.implement_dynamic_object_ctor rcf_ctx dynamic_object); InitFunction.configure gen; TArrayTransform.configure gen ( fun e binop -> match e.eexpr with | TArray(e1, e2) -> (match follow e1.etype with | TDynamic _ | TAnon _ | TMono _ -> true | TInst({ cl_kind = KTypeParameter _ }, _) -> true | TInst(c,p) when erase_generics && is_hxgeneric (TClassDecl c) && is_hxgen (TClassDecl c) -> (match c.cl_path with | [],"String" | ["cs"],"NativeArray" -> false | _ -> true) | _ -> match binop, change_param_type (t_to_md e1.etype) [e.etype] with | Some(Ast.OpAssignOp _), ([TDynamic _] | [TAnon _]) -> true | _ -> false) | _ -> assert false ) "__get" "__set"; let field_is_dynamic t field = match field_access_esp gen (gen.greal_type t) field with | FEnumField _ -> false | FClassField (cl,p,_,_,_,t,_) -> if not erase_generics then false else let p = change_param_type (TClassDecl cl) p in is_dynamic (apply_params cl.cl_params p t) | _ -> true in let is_dynamic_expr e = is_dynamic e.etype || match e.eexpr with | TField(tf, f) -> field_is_dynamic tf.etype (f) | _ -> false in let may_nullable t = match gen.gfollow#run_f t with | TType({ t_path = ([], "Null") }, [t]) -> (match follow t with | TInst({ cl_path = ([], "String") }, []) | TAbstract ({ a_path = ([], "Float") },[]) | TInst({ cl_path = (["haxe"], "Int32")}, [] ) | TInst({ cl_path = (["haxe"], "Int64")}, [] ) | TAbstract ({ a_path = ([], "Int") },[]) | TAbstract ({ a_path = ([], "Bool") },[]) -> Some t | TAbstract _ when like_float t -> Some t | t when is_cs_basic_type t -> Some t | _ -> None ) | _ -> None in let is_double t = like_float t && not (like_int t) in let is_int t = like_int t in let is_null t = match real_type t with | TInst( { cl_path = (["haxe";"lang"], "Null") }, _ ) -> true | _ -> false in let is_null_expr e = is_null e.etype || match e.eexpr with | TField(tf, f) -> (match field_access_esp gen (real_type tf.etype) (f) with | FClassField(_,_,_,_,_,actual_t,_) -> is_null actual_t | _ -> false) | _ -> false in let should_handle_opeq t = match real_type t with | TDynamic _ | TAnon _ | TMono _ | TInst( { cl_kind = KTypeParameter _ }, _ ) | TInst( { cl_path = (["haxe";"lang"], "Null") }, _ ) -> true | _ -> false in let string_cl = match gen.gcon.basic.tstring with | TInst(c,[]) -> c | _ -> assert false in let is_undefined e = match e.eexpr with | TLocal { v_name = "__undefined__" } | TField(_,FStatic({cl_path=["haxe";"lang"],"Runtime"},{cf_name="undefined"})) -> true | _ -> false in DynamicOperators.configure gen (fun e -> match e.eexpr with | TBinop (Ast.OpEq, e1, e2) | TBinop (Ast.OpNotEq, e1, e2) -> ( (* dont touch (v == null) and (null == v) comparisons because they are handled by HardNullableSynf later *) match e1.eexpr, e2.eexpr with | TConst(TNull), _ when (not (is_tparam e2.etype) && is_dynamic e2.etype) || is_null_expr e2 -> false | _, TConst(TNull) when (not (is_tparam e1.etype) && is_dynamic e1.etype) || is_null_expr e1 -> false | _ when is_undefined e1 || is_undefined e2 -> false | _ -> should_handle_opeq e1.etype || should_handle_opeq e2.etype ) | TBinop (Ast.OpAssignOp Ast.OpAdd, e1, e2) -> is_dynamic_expr e1 || is_null_expr e1 || is_string e.etype | TBinop (Ast.OpAdd, e1, e2) -> is_dynamic e1.etype || is_dynamic e2.etype || is_tparam e1.etype || is_tparam e2.etype || is_string e1.etype || is_string e2.etype || is_string e.etype | TBinop (Ast.OpLt, e1, e2) | TBinop (Ast.OpLte, e1, e2) | TBinop (Ast.OpGte, e1, e2) | TBinop (Ast.OpGt, e1, e2) -> is_dynamic e.etype || is_dynamic_expr e1 || is_dynamic_expr e2 || is_string e1.etype || is_string e2.etype | TBinop (_, e1, e2) -> is_dynamic e.etype || is_dynamic_expr e1 || is_dynamic_expr e2 | TUnop (_, _, e1) -> is_dynamic_expr e1 || is_null_expr e1 (* we will see if the expression is Null also, as the unwrap from Unop will be the same *) | _ -> false) (fun e1 e2 -> let is_basic = is_cs_basic_type (follow e1.etype) || is_cs_basic_type (follow e2.etype) in let is_ref = if is_basic then false else match follow e1.etype, follow e2.etype with | TDynamic _, _ | _, TDynamic _ | TInst( { cl_path = ([], "String") }, [] ), _ | _, TInst( { cl_path = ([], "String") }, [] ) | TInst( { cl_kind = KTypeParameter _ }, [] ), _ | _, TInst( { cl_kind = KTypeParameter _ }, [] ) -> false | _, _ -> true in let static = mk_static_field_access_infer (runtime_cl) (if is_ref then "refEq" else "eq") e1.epos [] in { eexpr = TCall(static, [e1; e2]); etype = gen.gcon.basic.tbool; epos=e1.epos } ) (fun e e1 e2 -> match may_nullable e1.etype, may_nullable e2.etype with | Some t1, Some t2 -> let t1, t2 = if is_string t1 || is_string t2 then basic.tstring, basic.tstring else if is_double t1 || is_double t2 then basic.tfloat, basic.tfloat else if is_int t1 || is_int t2 then basic.tint, basic.tint else t1, t2 in { eexpr = TBinop(Ast.OpAdd, mk_cast t1 e1, mk_cast t2 e2); etype = e.etype; epos = e1.epos } | _ when is_string e.etype || is_string e1.etype || is_string e2.etype -> { eexpr = TCall( mk_static_field_access_infer runtime_cl "concat" e.epos [], [ e1; e2 ] ); etype = basic.tstring; epos = e.epos } | _ -> let static = mk_static_field_access_infer (runtime_cl) "plus" e1.epos [] in mk_cast e.etype { eexpr = TCall(static, [e1; e2]); etype = t_dynamic; epos=e1.epos }) (fun e1 e2 -> if is_string e1.etype then begin { e1 with eexpr = TCall(mk_static_field_access_infer string_cl "Compare" e1.epos [], [ e1; e2 ]); etype = gen.gcon.basic.tint } end else begin let static = mk_static_field_access_infer (runtime_cl) "compare" e1.epos [] in { eexpr = TCall(static, [e1; e2]); etype = gen.gcon.basic.tint; epos=e1.epos } end) ~handle_strings:false; FilterClosures.configure gen (fun e1 s -> true) (ReflectionCFs.get_closure_func rcf_ctx closure_cl); let base_exception = get_cl (get_type gen (["System"], "Exception")) in let base_exception_t = TInst(base_exception, []) in let hx_exception = get_cl (get_type gen (["haxe";"lang"], "HaxeException")) in let hx_exception_t = TInst(hx_exception, []) in let rec is_exception t = match follow t with | TInst(cl,_) -> if cl == base_exception then true else (match cl.cl_super with | None -> false | Some (cl,arg) -> is_exception (TInst(cl,arg))) | _ -> false in TryCatchWrapper.configure gen (fun t -> not (is_exception (real_type t))) (fun throwexpr expr -> let wrap_static = mk_static_field_access (hx_exception) "wrap" (TFun([("obj",false,t_dynamic)], base_exception_t)) expr.epos in { throwexpr with eexpr = TThrow { expr with eexpr = TCall(wrap_static, [expr]); etype = hx_exception_t }; etype = gen.gcon.basic.tvoid } ) (fun v_to_unwrap pos -> let local = mk_cast hx_exception_t { eexpr = TLocal(v_to_unwrap); etype = v_to_unwrap.v_type; epos = pos } in mk_field_access gen local "obj" pos ) (fun rethrow -> { rethrow with eexpr = TCall(mk_local (alloc_var "__rethrow__" t_dynamic) rethrow.epos, [rethrow]); etype = gen.gcon.basic.tvoid } ) (base_exception_t) (hx_exception_t) (fun v e -> let exc_cl = get_cl (get_type gen (["haxe";"lang"],"Exceptions")) in let exc_field = mk_static_field_access_infer exc_cl "exception" e.epos [] in let esetstack = mk (TBinop(Ast.OpAssign, exc_field, mk_local v e.epos)) v.v_type e.epos in Type.concat esetstack e; ); ClassInstance.configure gen (fun e _ -> { e with eexpr = TCall({ eexpr = TLocal(alloc_var "__typeof__" t_dynamic); etype = t_dynamic; epos = e.epos }, [e]) }); CastDetect.configure gen (Some empty_ctor_type) (not erase_generics) ~overloads_cast_to_base:true; SwitchToIf.configure gen (fun e -> match e.eexpr with | TSwitch(cond, cases, def) -> (match gen.gfollow#run_f cond.etype with | TAbstract ({ a_path = ([], "Int") },[]) | TInst({ cl_path = ([], "String") },[]) -> (List.exists (fun (c,_) -> List.exists (fun expr -> match expr.eexpr with | TConst _ -> false | _ -> true ) c ) cases) | _ -> true ) | _ -> assert false ); ExpressionUnwrap.configure gen (fun e -> Some { eexpr = TVar(mk_temp gen "expr" e.etype, Some e); etype = gen.gcon.basic.tvoid; epos = e.epos }); UnnecessaryCastsRemoval.configure gen; IntDivisionSynf.configure gen; UnreachableCodeEliminationSynf.configure gen false; ArrayDeclSynf.configure gen native_arr_cl; let goto_special = alloc_var "__goto__" t_dynamic in let label_special = alloc_var "__label__" t_dynamic in SwitchBreakSynf.configure gen (fun e_loop n api -> api ({ eexpr = TCall( mk_local label_special e_loop.epos, [ ExprBuilder.make_int gen.gcon n e_loop.epos ] ); etype = t_dynamic; epos = e_loop.epos }) false; e_loop ) (fun e_break n api -> { eexpr = TCall( mk_local goto_special e_break.epos, [ ExprBuilder.make_int gen.gcon n e_break.epos ] ); etype = t_dynamic; epos = e_break.epos } ); DefaultArguments.configure gen; InterfaceMetas.configure gen; CSharpSpecificSynf.configure gen runtime_cl; CSharpSpecificESynf.configure gen runtime_cl; let out_files = ref [] in (* copy resource files *) if Hashtbl.length gen.gcon.resources > 0 then begin let src = gen.gcon.file ^ "/src/Resources" in Hashtbl.iter (fun name v -> let name = Codegen.escape_res_name name true in let full_path = src ^ "/" ^ name in mkdir_from_path full_path; let f = open_out_bin full_path in output_string f v; close_out f; out_files := (Path.unique_full_path full_path) :: !out_files ) gen.gcon.resources; end; (* add resources array *) (try let res = get_cl (Hashtbl.find gen.gtypes (["haxe"], "Resource")) in let cf = PMap.find "content" res.cl_statics in let res = ref [] in Hashtbl.iter (fun name v -> res := { eexpr = TConst(TString name); etype = gen.gcon.basic.tstring; epos = null_pos } :: !res; ) gen.gcon.resources; cf.cf_expr <- Some ({ eexpr = TArrayDecl(!res); etype = gen.gcon.basic.tarray gen.gcon.basic.tstring; epos = null_pos }) with | Not_found -> ()); run_filters gen; (* after the filters have been run, add all hashed fields to FieldLookup *) let normalize_i i = let i = Int32.of_int (i) in if i < Int32.zero then Int32.logor (Int32.logand i (Int32.of_int 0x3FFFFFFF)) (Int32.shift_left Int32.one 30) else i in let nhash = ref 0 in let hashes = Hashtbl.fold (fun i s acc -> incr nhash; (normalize_i i,s) :: acc) rcf_ctx.rcf_hash_fields [] in let hashes = List.sort (fun (i,s) (i2,s2) -> compare i i2) hashes in let haxe_libs = List.filter (function (_,_,_,lookup) -> is_some (lookup (["haxe";"lang"], "DceNo"))) gen.gcon.net_libs in (try (* first let's see if we're adding a -net-lib that has already a haxe.lang.FieldLookup *) let name,_,_,_ = List.find (function (_,_,_,lookup) -> is_some (lookup (["haxe";"lang"], "FieldLookup"))) gen.gcon.net_libs in if not (Common.defined gen.gcon Define.DllImport) then begin gen.gcon.warning ("The -net-lib with path " ^ name ^ " contains a Haxe-generated assembly. Please define `-D dll_import` to handle Haxe-generated dll import correctly") null_pos; raise Not_found end; if not (List.exists (function (n,_,_,_) -> n = name) haxe_libs) then gen.gcon.warning ("The -net-lib with path " ^ name ^ " contains a Haxe-generated assembly, however it wasn't compiled with `-dce no`. Recompilation with `-dce no` is recommended") null_pos; (* it has; in this case, we need to add the used fields on each __init__ *) flookup_cl.cl_extern <- true; let hashs_by_path = Hashtbl.create !nhash in Hashtbl.iter (fun (path,i) s -> Hashtbl.add hashs_by_path path (i,s)) rcf_ctx.rcf_hash_paths; Hashtbl.iter (fun _ md -> match md with | TClassDecl ({ cl_extern = false; cl_interface = false } as c) -> (try let all = Hashtbl.find_all hashs_by_path c.cl_path in let all = List.map (fun (i,s) -> normalize_i i, s) all in let all = List.sort (fun (i,s) (i2,s2) -> compare i i2) all in if all <> [] then begin let add = mk_static_field_access_infer flookup_cl "addFields" c.cl_pos [] in let expr = { eexpr = TCall(add, [ mk_nativearray_decl gen basic.tint (List.map (fun (i,s) -> { eexpr = TConst(TInt (i)); etype = basic.tint; epos = c.cl_pos }) all) c.cl_pos; mk_nativearray_decl gen basic.tstring (List.map (fun (i,s) -> { eexpr = TConst(TString (s)); etype = basic.tstring; epos = c.cl_pos }) all) c.cl_pos; ]); etype = basic.tvoid; epos = c.cl_pos } in match c.cl_init with | None -> c.cl_init <- Some expr | Some e -> c.cl_init <- Some { eexpr = TBlock([expr;e]); etype = basic.tvoid; epos = e.epos } end with | Not_found -> ()) | _ -> ()) gen.gtypes; with | Not_found -> try let basic = gen.gcon.basic in let cl = flookup_cl in let field_ids = PMap.find "fieldIds" cl.cl_statics in let fields = PMap.find "fields" cl.cl_statics in field_ids.cf_expr <- Some (mk_nativearray_decl gen basic.tint (List.map (fun (i,s) -> { eexpr = TConst(TInt (i)); etype = basic.tint; epos = field_ids.cf_pos }) hashes) field_ids.cf_pos); fields.cf_expr <- Some (mk_nativearray_decl gen basic.tstring (List.map (fun (i,s) -> { eexpr = TConst(TString s); etype = basic.tstring; epos = fields.cf_pos }) hashes) fields.cf_pos); with | Not_found -> gen.gcon.error "Fields 'fieldIds' and 'fields' were not found in class haxe.lang.FieldLookup" flookup_cl.cl_pos ); if Common.defined gen.gcon Define.DllImport then begin Hashtbl.iter (fun _ md -> match md with | TClassDecl ({ cl_extern = false } as c) -> (try let extra = match c.cl_params with | _ :: _ when not erase_generics -> "_" ^ string_of_int (List.length c.cl_params) | _ -> "" in let pack = match c.cl_path with | ([], _) when no_root && is_hxgen (TClassDecl c) -> ["haxe";"root"] | (p,_) -> p in let path = (pack, snd c.cl_path ^ extra) in ignore (List.find (function (_,_,_,lookup) -> is_some (lookup path)) haxe_libs); c.cl_extern <- true; with | Not_found -> ()) | _ -> ()) gen.gtypes end; TypeParams.RenameTypeParameters.run gen; let parts = Str.split_delim (Str.regexp "[\\/]+") gen.gcon.file in mkdir_recursive "" parts; List.iter (fun md_def -> let source_dir = gen.gcon.file ^ "/src/" ^ (String.concat "/" (fst (path_of_md_def md_def))) in let w = SourceWriter.new_source_writer() in let should_write = List.fold_left (fun should md -> module_type_gen w md || should) false md_def.m_types in if should_write then begin let path = path_of_md_def md_def in write_file gen w source_dir path "cs" out_files end ) gen.gmodules; if not (Common.defined gen.gcon Define.KeepOldOutput) then clean_files (gen.gcon.file ^ "/src") !out_files gen.gcon.verbose; dump_descriptor gen ("hxcs_build.txt") s_type_path module_s; if ( not (Common.defined gen.gcon Define.NoCompilation) ) then begin let old_dir = Sys.getcwd() in Sys.chdir gen.gcon.file; let cmd = "haxelib run hxcs hxcs_build.txt --haxe-version " ^ (string_of_int gen.gcon.version) ^ " --feature-level 1" in print_endline cmd; if gen.gcon.run_command cmd <> 0 then failwith "Build failed"; Sys.chdir old_dir; end (* end of configure function *) let generate con = (try let gen = new_ctx con in let basic = con.basic in if Common.defined_value con Define.Dce = "no" then begin let m = { null_module with m_id = alloc_mid(); m_path = ["haxe";"lang"],"DceNo" } in let cl = mk_class m (["haxe";"lang"],"DceNo") null_pos in gen.gtypes_list <- (TClassDecl cl) :: gen.gtypes_list; Hashtbl.add gen.gtypes cl.cl_path (TClassDecl cl) end; (* make the basic functions in C# *) let type_cl = get_cl ( get_type gen (["System"], "Type")) in let basic_fns = [ mk_class_field "Equals" (TFun(["obj",false,t_dynamic], basic.tbool)) true null_pos (Method MethNormal) []; mk_class_field "ToString" (TFun([], basic.tstring)) true null_pos (Method MethNormal) []; mk_class_field "GetHashCode" (TFun([], basic.tint)) true null_pos (Method MethNormal) []; mk_class_field "GetType" (TFun([], TInst(type_cl, []))) true null_pos (Method MethNormal) []; ] in List.iter (fun cf -> gen.gbase_class_fields <- PMap.add cf.cf_name cf gen.gbase_class_fields) basic_fns; configure gen with | TypeNotFound path -> con.error ("Error. Module '" ^ (s_type_path path) ^ "' is required and was not included in build.") null_pos); debug_mode := false (* -net-lib implementation *) open IlData open IlMeta type net_lib_ctx = { nstd : bool; ncom : Common.context; nil : IlData.ilctx; } let is_haxe_keyword = function | "callback" | "cast" | "extern" | "function" | "in" | "typedef" | "using" | "var" | "untyped" | "inline" -> true | _ -> false let hxpath_to_net ctx path = try Hashtbl.find ctx.ncom.net_path_map path with | Not_found -> [],[],"Not_found" let add_cs = function | "haxe" :: ns -> "haxe" :: ns | "std" :: ns -> "std" :: ns | "cs" :: ns -> "cs" :: ns | "system" :: ns -> "cs" :: "system" :: ns | ns -> ns let escape_chars = String.replace_chars (fun chr -> if (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || chr = '_' then Char.escaped chr else "_x" ^ (string_of_int (Char.code chr)) ^ "_") let netcl_to_hx cl = let cl = if String.length cl > 0 && String.get cl 0 >= 'a' && String.get cl 0 <= 'z' then Char.escaped (Char.uppercase (String.get cl 0)) ^ (String.sub cl 1 (String.length cl - 1)) else cl in try let cl, nargs = String.split cl "`" in (escape_chars cl) ^ "_" ^ nargs with | Invalid_string -> escape_chars cl let netpath_to_hx std = function | [],[], cl -> [], netcl_to_hx cl | ns,[], cl -> let ns = (List.map (fun s -> String.lowercase (escape_chars s)) ns) in add_cs ns, netcl_to_hx cl | ns,(nhd :: ntl as nested), cl -> let nested = List.map (netcl_to_hx) nested in let ns = (List.map (fun s -> String.lowercase (escape_chars s)) ns) @ [nhd] in add_cs ns, String.concat "_" nested ^ "_" ^ netcl_to_hx cl let lookup_ilclass std com ilpath = let path = netpath_to_hx std ilpath in List.fold_right (fun (_,_,_,get_raw_class) acc -> match acc with | None -> get_raw_class path | Some p -> acc ) com.net_libs None let discard_nested = function | (ns,_),cl -> (ns,[]),cl let mk_type_path ctx path params = let pack, sub, name = match path with | ns,[], cl -> ns, None, netcl_to_hx cl | ns, (nhd :: ntl as nested), cl -> let nhd = netcl_to_hx nhd in let nested = List.map (netcl_to_hx) nested in ns, Some (String.concat "_" nested ^ "_" ^ netcl_to_hx cl), nhd in CTPath { tpackage = fst (netpath_to_hx ctx.nstd (pack,[],"")); Ast.tname = name; tparams = params; tsub = sub; } let raw_type_path ctx path params = { tpackage = fst path; Ast.tname = snd path; tparams = params; tsub = None; } let rec convert_signature ctx p = function | LVoid -> mk_type_path ctx ([],[],"Void") [] | LBool -> mk_type_path ctx ([],[],"Bool") [] | LChar -> mk_type_path ctx (["cs";"types"],[],"Char16") [] | LInt8 -> mk_type_path ctx (["cs";"types"],[],"Int8") [] | LUInt8 -> mk_type_path ctx (["cs";"types"],[],"UInt8") [] | LInt16 -> mk_type_path ctx (["cs";"types"],[],"Int16") [] | LUInt16 -> mk_type_path ctx (["cs";"types"],[],"UInt16") [] | LInt32 -> mk_type_path ctx ([],[],"Int") [] | LUInt32 -> mk_type_path ctx ([],[],"UInt") [] | LInt64 -> mk_type_path ctx (["haxe"],[],"Int64") [] | LUInt64 -> mk_type_path ctx (["cs";"types"],[],"UInt64") [] | LFloat32 -> mk_type_path ctx ([],[],"Single") [] | LFloat64 -> mk_type_path ctx ([],[],"Float") [] | LString -> mk_type_path ctx (["std"],[],"String") [] | LObject -> mk_type_path ctx ([],[],"Dynamic") [] | LPointer s | LManagedPointer s -> mk_type_path ctx (["cs"],[],"Pointer") [ TPType (convert_signature ctx p s,null_pos) ] | LTypedReference -> mk_type_path ctx (["cs";"system"],[],"TypedReference") [] | LIntPtr -> mk_type_path ctx (["cs";"system"],[],"IntPtr") [] | LUIntPtr -> mk_type_path ctx (["cs";"system"],[],"UIntPtr") [] | LValueType (s,args) | LClass (s,args) -> mk_type_path ctx s (List.map (fun s -> TPType (convert_signature ctx p s,null_pos)) args) | LTypeParam i -> mk_type_path ctx ([],[],"T" ^ string_of_int i) [] | LMethodTypeParam i -> mk_type_path ctx ([],[],"M" ^ string_of_int i) [] | LVector s -> mk_type_path ctx (["cs"],[],"NativeArray") [TPType (convert_signature ctx p s,null_pos)] (* | LArray of ilsig_norm * (int option * int option) array *) | LMethod (_,ret,args) -> CTFunction (List.map (fun v -> convert_signature ctx p v,null_pos) args, (convert_signature ctx p ret,null_pos)) | _ -> mk_type_path ctx ([],[], "Dynamic") [] let ilpath_s = function | ns,[], name -> s_type_path (ns,name) | [],nested,name -> String.concat "." nested ^ "." ^ name | ns, nested, name -> String.concat "." ns ^ "." ^ String.concat "." nested ^ "." ^ name let get_cls = function | _,_,c -> c (* TODO: When possible on Haxe, use this to detect flag enums, and make an abstract with @:op() *) (* that behaves like an enum, and with an enum as its underlying type *) let enum_is_flag ilcls = let check_flag name ns = name = "FlagsAttribute" && ns = ["System"] in List.exists (fun a -> match a.ca_type with | TypeRef r -> check_flag r.tr_name r.tr_namespace | TypeDef d -> check_flag d.td_name d.td_namespace | Method m -> (match m.m_declaring with | Some d -> check_flag d.td_name d.td_namespace | _ -> false) | MemberRef r -> (match r.memr_class with | TypeRef r -> check_flag r.tr_name r.tr_namespace | TypeDef d -> check_flag d.td_name d.td_namespace | _ -> false) | _ -> false ) ilcls.cattrs let convert_ilenum ctx p ?(is_flag=false) ilcls = let meta = ref [ Meta.Native, [EConst (String (ilpath_s ilcls.cpath) ), p], p; Meta.CsNative, [], p; ] in let data = ref [] in List.iter (fun f -> match f.fname with | "value__" -> () | _ when not (List.mem CStatic f.fflags.ff_contract) -> () | _ -> let meta, const = match f.fconstant with | Some IChar i | Some IByte i | Some IShort i -> [Meta.CsNative, [EConst (Int (string_of_int i) ), p], p ], Int64.of_int i | Some IInt i -> [Meta.CsNative, [EConst (Int (Int32.to_string i) ), p], p ], Int64.of_int32 i | Some IFloat32 f | Some IFloat64 f -> [], Int64.of_float f | Some IInt64 i -> [], i | _ -> [], Int64.zero in data := ( { ec_name = f.fname,null_pos; ec_doc = None; ec_meta = meta; ec_args = []; ec_pos = p; ec_params = []; ec_type = None; }, const) :: !data; ) ilcls.cfields; let data = List.stable_sort (fun (_,i1) (_,i2) -> Int64.compare i1 i2) (List.rev !data) in let _, c = netpath_to_hx ctx.nstd ilcls.cpath in let name = netname_to_hx c in EEnum { d_name = (if is_flag then name ^ "_FlagsEnum" else name),null_pos; d_doc = None; d_params = []; (* enums never have type parameters *) d_meta = !meta; d_flags = [EExtern]; d_data = List.map fst data; } let rec has_unmanaged = function | LPointer _ -> true | LManagedPointer s -> has_unmanaged s | LValueType (p,pl) -> List.exists (has_unmanaged) pl | LClass (p,pl) -> List.exists (has_unmanaged) pl | LVector s -> has_unmanaged s | LArray (s,a) -> has_unmanaged s | LMethod (c,r,args) -> has_unmanaged r || List.exists (has_unmanaged) args | _ -> false let convert_ilfield ctx p field = if not (Common.defined ctx.ncom Define.Unsafe) && has_unmanaged field.fsig.snorm then raise Exit; let p = { p with pfile = p.pfile ^" (" ^field.fname ^")" } in let cff_doc = None in let cff_pos = p in let cff_meta = ref [] in let cff_name = match field.fname with | name when String.length name > 5 -> (match String.sub name 0 5 with | "__hx_" -> raise Exit | _ -> name) | name -> name in let cff_access = match field.fflags.ff_access with | FAFamily | FAFamOrAssem -> APrivate | FAPublic -> APublic | _ -> raise Exit (* private instances aren't useful on externs *) in let readonly, acc = List.fold_left (fun (readonly,acc) -> function | CStatic -> readonly, AStatic :: acc | CInitOnly | CLiteral -> true, acc | _ -> readonly,acc ) (false,[cff_access]) field.fflags.ff_contract in if PMap.mem "net_loader_debug" ctx.ncom.defines then Printf.printf "\t%sfield %s : %s\n" (if List.mem AStatic acc then "static " else "") cff_name (IlMetaDebug.ilsig_s field.fsig.ssig); let kind = match readonly with | true -> cff_meta := (Meta.ReadOnly, [], cff_pos) :: !cff_meta; FProp (("default",null_pos), ("never",null_pos), Some (convert_signature ctx p field.fsig.snorm,null_pos), None) | false -> FVar (Some (convert_signature ctx p field.fsig.snorm,null_pos), None) in let cff_name, cff_meta = if String.get cff_name 0 = '%' then let name = (String.sub cff_name 1 (String.length cff_name - 1)) in "_" ^ name, (Meta.Native, [EConst (String (name) ), cff_pos], cff_pos) :: !cff_meta else cff_name, !cff_meta in { cff_name = cff_name,null_pos; cff_doc = cff_doc; cff_pos = cff_pos; cff_meta = cff_meta; cff_access = acc; cff_kind = kind; } let convert_ilevent ctx p ev = let p = { p with pfile = p.pfile ^" (" ^ev.ename ^")" } in let name = ev.ename in let kind = FVar (Some (convert_signature ctx p ev.esig.snorm,null_pos), None) in let meta = [Meta.Event, [], p; Meta.Keep,[],p; Meta.SkipReflection,[],p] in let acc = [APrivate] in let add_m acc m = match m with | None -> acc | Some (name,flags) -> if List.mem (CMStatic) flags.mf_contract then AStatic :: acc else acc in if PMap.mem "net_loader_debug" ctx.ncom.defines then Printf.printf "\tevent %s : %s\n" name (IlMetaDebug.ilsig_s ev.esig.ssig); let acc = add_m acc ev.eadd in let acc = add_m acc ev.eremove in let acc = add_m acc ev.eraise in { cff_name = name,null_pos; cff_doc = None; cff_pos = p; cff_meta = meta; cff_access = acc; cff_kind = kind; } let convert_ilmethod ctx p m is_explicit_impl = if not (Common.defined ctx.ncom Define.Unsafe) && has_unmanaged m.msig.snorm then raise Exit; let force_check = Common.defined ctx.ncom Define.ForceLibCheck in let p = { p with pfile = p.pfile ^" (" ^m.mname ^")" } in let cff_doc = None in let cff_pos = p in let cff_name = match m.mname with | ".ctor" -> "new" | ".cctor"-> raise Exit (* __init__ field *) | "Equals" | "GetHashCode" -> raise Exit | name when String.length name > 5 -> (match String.sub name 0 5 with | "__hx_" -> raise Exit | _ -> name) | name -> name in let acc = match m.mflags.mf_access with | FAFamily | FAFamOrAssem -> APrivate (* | FAPrivate -> APrivate *) | FAPublic when List.mem SGetter m.msemantics || List.mem SSetter m.msemantics -> APrivate | FAPublic -> APublic | _ -> if PMap.mem "net_loader_debug" ctx.ncom.defines then Printf.printf "\tmethod %s (skipped) : %s\n" cff_name (IlMetaDebug.ilsig_s m.msig.ssig); raise Exit in let is_static = ref false in let acc, is_final = List.fold_left (fun (acc,is_final) -> function | CMStatic when cff_name <> "new" -> is_static := true; AStatic :: acc, is_final | CMVirtual when is_final = None -> acc, Some false | CMFinal -> acc, Some true | _ -> acc, is_final ) ([acc],None) m.mflags.mf_contract in if PMap.mem "net_loader_debug" ctx.ncom.defines then Printf.printf "\t%smethod %s : %s\n" (if !is_static then "static " else "") cff_name (IlMetaDebug.ilsig_s m.msig.ssig); let meta = [Meta.Overload, [], p] in let meta = match is_final with | None | Some true when not force_check -> (Meta.Final,[],p) :: meta | _ -> meta in let meta = if is_explicit_impl then (Meta.NoCompletion,[],p) :: (Meta.SkipReflection,[],p) :: meta else meta in (* let meta = if List.mem OSynchronized m.mflags.mf_interop then *) (* (Meta.Synchronized,[],p) :: meta *) (* else *) (* meta *) (* in *) let rec change_sig = function | LManagedPointer s -> LManagedPointer (change_sig s) | LPointer s -> LPointer (change_sig s) | LValueType (p,pl) -> LValueType(p, List.map change_sig pl) | LClass (p,pl) -> LClass(p, List.map change_sig pl) | LTypeParam i -> LObject | LVector s -> LVector (change_sig s) | LArray (s,a) -> LArray (change_sig s, a) | LMethod (c,r,args) -> LMethod (c, change_sig r, List.map change_sig args) | p -> p in let change_sig = if !is_static then change_sig else (fun s -> s) in let ret = if String.length cff_name > 4 && String.sub cff_name 0 4 = "set_" then match m.mret.snorm, m.margs with | LVoid, [_,_,s] -> s.snorm | _ -> m.mret.snorm else m.mret.snorm in let kind = let args = List.map (fun (name,flag,s) -> let t = match s.snorm with | LManagedPointer s -> let is_out = List.mem POut flag.pf_io && not (List.mem PIn flag.pf_io) in let name = if is_out then "Out" else "Ref" in mk_type_path ctx (["cs"],[],name) [ TPType (convert_signature ctx p s,null_pos) ] | _ -> convert_signature ctx p (change_sig s.snorm) in (name,null_pos),false,[],Some (t,null_pos),None) m.margs in let ret = convert_signature ctx p (change_sig ret) in let types = List.map (fun t -> { tp_name = "M" ^ string_of_int t.tnumber,null_pos; tp_params = []; tp_constraints = []; tp_meta = []; } ) m.mtypes in FFun { f_params = types; f_args = args; f_type = Some (ret,null_pos); f_expr = None; } in let cff_name, cff_meta = if String.get cff_name 0 = '%' then let name = (String.sub cff_name 1 (String.length cff_name - 1)) in "_" ^ name, (Meta.Native, [EConst (String (name) ), cff_pos], cff_pos) :: meta else cff_name, meta in let acc = match m.moverride with | None -> acc | _ when cff_name = "new" -> acc | Some (path,s) -> match lookup_ilclass ctx.nstd ctx.ncom path with | Some ilcls when not (List.mem SInterface ilcls.cflags.tdf_semantics) -> AOverride :: acc | None when ctx.ncom.verbose -> prerr_endline ("(net-lib) A referenced assembly for path " ^ ilpath_s path ^ " was not found"); acc | _ -> acc in { cff_name = cff_name,null_pos; cff_doc = cff_doc; cff_pos = cff_pos; cff_meta = cff_meta; cff_access = acc; cff_kind = kind; } let convert_ilprop ctx p prop is_explicit_impl = if not (Common.defined ctx.ncom Define.Unsafe) && has_unmanaged prop.psig.snorm then raise Exit; let p = { p with pfile = p.pfile ^" (" ^prop.pname ^")" } in let pmflags = match prop.pget, prop.pset with | Some(_,fl1), _ -> Some fl1 | _, Some(_,fl2) -> Some fl2 | _ -> None in let cff_access = match pmflags with | Some { mf_access = FAFamily | FAFamOrAssem } -> APrivate | Some { mf_access = FAPublic } -> APublic | _ -> raise Exit (* non-public / protected fields don't interest us *) in let access acc = acc.mf_access in let cff_access = match pmflags with | Some m when List.mem CMStatic m.mf_contract -> [AStatic;cff_access] | _ -> [cff_access] in let get = match prop.pget with | None -> "never" | Some(s,_) when String.length s <= 4 || String.sub s 0 4 <> "get_" -> raise Exit (* special (?) getter; not used *) | Some(_,m) when access m <> FAPublic -> (match access m with | FAFamily | FAFamOrAssem -> "null" | _ -> "never") | Some _ -> "get" in let set = match prop.pset with | None -> "never" | Some(s,_) when String.length s <= 4 || String.sub s 0 4 <> "set_" -> raise Exit (* special (?) getter; not used *) | Some(_,m) when access m <> FAPublic -> (match access m with | FAFamily | FAFamOrAssem -> "never" | _ -> "never"); | Some _ -> "set" in if PMap.mem "net_loader_debug" ctx.ncom.defines then Printf.printf "\tproperty %s (%s,%s) : %s\n" prop.pname get set (IlMetaDebug.ilsig_s prop.psig.ssig); let ilsig = match prop.psig.snorm with | LMethod (_,ret,[]) -> ret | s -> raise Exit in let meta = if is_explicit_impl then [ Meta.NoCompletion,[],p; Meta.SkipReflection,[],p ] else [] in let kind = FProp ((get,null_pos), (set,null_pos), Some(convert_signature ctx p ilsig,null_pos), None) in { cff_name = prop.pname,null_pos; cff_doc = None; cff_pos = p; cff_meta = meta; cff_access = cff_access; cff_kind = kind; } let get_type_path ctx ct = match ct with | CTPath p -> p | _ -> assert false let is_explicit ctx ilcls i = let s = match i with | LClass(path,_) | LValueType(path,_) -> ilpath_s path | _ -> assert false in let len = String.length s in List.exists (fun m -> String.length m.mname > len && String.sub m.mname 0 len = s ) ilcls.cmethods let mke e p = (e,p) let mk_special_call name p args = mke (ECast( mke (EUntyped( mke (ECall( mke (EConst(Ident name)) p, args )) p )) p , None)) p let mk_this_call name p args = mke (ECall( mke (EField(mke (EConst(Ident "this")) p ,name)) p, args )) p let mk_metas metas p = List.map (fun m -> m,[],p) metas let mk_abstract_fun name p kind metas acc = let metas = mk_metas metas p in { cff_name = name,null_pos; cff_doc = None; cff_pos = p; cff_meta = metas; cff_access = acc; cff_kind = kind; } let convert_fun_arg ctx p = function | LManagedPointer s -> mk_type_path ctx (["cs"],[],"Ref") [ TPType (convert_signature ctx p s,null_pos) ],p | s -> convert_signature ctx p s,p let convert_fun ctx p ret args = let args = List.map (convert_fun_arg ctx p) args in CTFunction(args, (convert_signature ctx p ret,null_pos)) let get_clsname ctx cpath = match netpath_to_hx ctx.nstd cpath with | (_,n) -> n let convert_delegate ctx p ilcls = let p = { p with pfile = p.pfile ^" (abstract delegate)" } in (* will have the following methods: *) (* - new (haxeType:Func) *) (* - FromHaxeFunction(haxeType) *) (* - Invoke() *) (* - AsDelegate():Super *) (* - @:op(A+B) Add(d:absType) *) (* - @:op(A-B) Remove(d:absType) *) let abs_type = mk_type_path ctx (ilcls.cpath) (List.map (fun t -> TPType (mk_type_path ctx ([],[],"T" ^ string_of_int t.tnumber) [],null_pos)) ilcls.ctypes) in let invoke = List.find (fun m -> m.mname = "Invoke") ilcls.cmethods in let ret = invoke.mret.snorm in let args = List.map (fun (_,_,s) -> s.snorm) invoke.margs in let haxe_type = convert_fun ctx p ret args in let types = List.map (fun t -> { tp_name = ("T" ^ string_of_int t.tnumber),null_pos; tp_params = []; tp_constraints = []; tp_meta = []; } ) ilcls.ctypes in let mk_op_fn op name p = let fn_name = List.assoc op cs_binops in let clsname = match ilcls.cpath with | (ns,inner,n) -> get_clsname ctx (ns,inner,"Delegate_"^n) in let expr = (ECall( (EField( (EConst(Ident (clsname)),p), fn_name ),p), [(EConst(Ident"arg1"),p);(EConst(Ident"arg2"),p)]),p) in FFun { f_params = types; f_args = [("arg1",null_pos),false,[],Some (abs_type,null_pos),None;("arg2",null_pos),false,[],Some (abs_type,null_pos),None]; f_type = Some (abs_type,null_pos); f_expr = Some ( (EReturn (Some expr), p) ); } in let mk_op op name = let p = { p with pfile = p.pfile ^" (op " ^ name ^ ")" } in { cff_name = name,null_pos; cff_doc = None; cff_pos = p; cff_meta = [ Meta.Extern,[],p ; Meta.Op, [ (EBinop(op, (EConst(Ident"A"),p), (EConst(Ident"B"),p)),p) ], p ]; cff_access = [APublic;AInline;AStatic]; cff_kind = mk_op_fn op name p; } in let params = (List.map (fun s -> TPType (mk_type_path ctx ([],[],fst s.tp_name) [],null_pos) ) types) in let underlying_type = match ilcls.cpath with | ns,inner,name -> mk_type_path ctx (ns,inner,"Delegate_" ^ name) params in let fn_new = FFun { f_params = []; f_args = [("hxfunc",null_pos),false,[],Some (haxe_type,null_pos),None]; f_type = None; f_expr = Some ( EBinop(Ast.OpAssign, (EConst(Ident "this"),p), (mk_special_call "__delegate__" p [EConst(Ident "hxfunc"),p]) ), p ); } in let fn_from_hx = FFun { f_params = types; f_args = [("hxfunc",null_pos),false,[],Some (haxe_type,null_pos),None]; f_type = Some( mk_type_path ctx ilcls.cpath params,null_pos ); f_expr = Some( EReturn( Some (mk_special_call "__delegate__" p [EConst(Ident "hxfunc"),p] )), p); } in let fn_asdel = FFun { f_params = []; f_args = []; f_type = None; f_expr = Some( EReturn( Some ( EConst(Ident "this"), p ) ), p ); } in let fn_new = mk_abstract_fun "new" p fn_new [Meta.Extern] [APublic;AInline] in let fn_from_hx = mk_abstract_fun "FromHaxeFunction" p fn_from_hx [Meta.Extern;Meta.From] [APublic;AInline;AStatic] in let fn_asdel = mk_abstract_fun "AsDelegate" p fn_asdel [Meta.Extern] [APublic;AInline] in let _, c = netpath_to_hx ctx.nstd ilcls.cpath in EAbstract { d_name = netname_to_hx c,null_pos; d_doc = None; d_params = types; d_meta = mk_metas [Meta.Delegate; Meta.Forward] p; d_flags = [AIsType (underlying_type,null_pos)]; d_data = [fn_new;fn_from_hx;fn_asdel;mk_op Ast.OpAdd "Add";mk_op Ast.OpSub "Remove"]; } let convert_ilclass ctx p ?(delegate=false) ilcls = match ilcls.csuper with | Some { snorm = LClass ((["System"],[],"Enum"),[]) } -> convert_ilenum ctx p ilcls | _ -> let flags = ref [HExtern] in (* todo: instead of CsNative, use more specific definitions *) if PMap.mem "net_loader_debug" ctx.ncom.defines then begin let sup = match ilcls.csuper with | None -> [] | Some c -> [IlMetaDebug.ilsig_s c.ssig] in let sup = sup @ List.map (fun i -> IlMetaDebug.ilsig_s i.ssig) ilcls.cimplements in print_endline ("converting " ^ ilpath_s ilcls.cpath ^ " : " ^ (String.concat ", " sup)) end; let meta = ref [Meta.CsNative, [], p; Meta.Native, [EConst (String (ilpath_s ilcls.cpath) ), p], p] in let force_check = Common.defined ctx.ncom Define.ForceLibCheck in if not force_check then meta := (Meta.LibType,[],p) :: !meta; let is_interface = ref false in List.iter (fun f -> match f with | SSealed -> meta := (Meta.Final, [], p) :: !meta | SInterface -> is_interface := true; flags := HInterface :: !flags | SAbstract -> meta := (Meta.Abstract, [], p) :: !meta | _ -> () ) ilcls.cflags.tdf_semantics; (* (match ilcls.cflags.tdf_vis with *) (* | VPublic | VNestedFamOrAssem | VNestedFamily -> () *) (* | _ -> raise Exit); *) (match ilcls.csuper with | Some { snorm = LClass ( (["System"],[],"Object"), [] ) } -> () | Some ({ snorm = LClass ( (["System"],[],"ValueType"), [] ) } as s) -> flags := HExtends (get_type_path ctx (convert_signature ctx p s.snorm),null_pos) :: !flags; meta := (Meta.Struct,[],p) :: !meta | Some { snorm = LClass ( (["haxe";"lang"],[],"HxObject"), [] ) } -> meta := (Meta.HxGen,[],p) :: !meta | Some s -> flags := HExtends (get_type_path ctx (convert_signature ctx p s.snorm),null_pos) :: !flags | _ -> ()); let has_explicit_ifaces = ref false in List.iter (fun i -> match i.snorm with | LClass ( (["haxe";"lang"],[], "IHxObject"), _ ) -> meta := (Meta.HxGen,[],p) :: !meta (* | i when is_explicit ctx ilcls i -> () *) | i -> if is_explicit ctx ilcls i then has_explicit_ifaces := true; flags := if !is_interface then HExtends (get_type_path ctx (convert_signature ctx p i),null_pos) :: !flags else HImplements (get_type_path ctx (convert_signature ctx p i),null_pos) :: !flags ) ilcls.cimplements; (* this is needed because of explicit interfaces. see http://msdn.microsoft.com/en-us/library/aa288461(v=vs.71).aspx *) (* explicit interfaces can't be mapped into Haxe in any way - since their fields can't be accessed directly, but they still implement that interface *) if !has_explicit_ifaces && force_check then (* do not check on this specific case *) meta := (Meta.LibType,[],p) :: !meta; (* ArrayAccess *) ignore (List.exists (function | { psig = { snorm = LMethod(_,ret,[v]) } } -> flags := if !is_interface then (HExtends( raw_type_path ctx ([],"ArrayAccess") [ TPType (convert_signature ctx p ret,null_pos) ],null_pos) :: !flags) else (HImplements( raw_type_path ctx ([],"ArrayAccess") [ TPType (convert_signature ctx p ret,null_pos) ],null_pos) :: !flags); true | _ -> false) ilcls.cprops); let fields = ref [] in let run_fields fn f = List.iter (fun f -> try fields := fn f :: !fields with | Exit -> () ) f in let meths = if !is_interface then List.filter (fun m -> m.moverride = None) ilcls.cmethods else ilcls.cmethods in run_fields (fun m -> convert_ilmethod ctx p m (List.exists (fun m2 -> m != m2 && String.get m2.mname 0 <> '.' && String.ends_with m2.mname ("." ^ m.mname)) meths) ) meths; run_fields (convert_ilfield ctx p) ilcls.cfields; run_fields (fun prop -> convert_ilprop ctx p prop (List.exists (fun p2 -> prop != p2 && String.get p2.pname 0 <> '.' && String.ends_with p2.pname ("." ^ prop.pname)) ilcls.cprops) ) ilcls.cprops; run_fields (convert_ilevent ctx p) ilcls.cevents; let params = List.map (fun p -> { tp_name = "T" ^ string_of_int p.tnumber,null_pos; tp_params = []; tp_constraints = []; tp_meta = []; }) ilcls.ctypes in if delegate then begin (* add op_Addition and op_Subtraction *) let path = ilcls.cpath in let thist = mk_type_path ctx path (List.map (fun t -> TPType (mk_type_path ctx ([],[],"T" ^ string_of_int t.tnumber) [],null_pos)) ilcls.ctypes) in let op name = { cff_name = name,null_pos; cff_doc = None; cff_pos = p; cff_meta = []; cff_access = [APublic;AStatic]; cff_kind = FFun { f_params = params; f_args = [("arg1",null_pos),false,[],Some (thist,null_pos),None;("arg2",null_pos),false,[],Some (thist,null_pos),None]; f_type = Some (thist,null_pos); f_expr = None; }; } in fields := op "op_Addition" :: op "op_Subtraction" :: !fields; end; let path = match ilcls.cpath with | ns,inner,name when delegate -> ns,inner,"Delegate_"^name | _ -> ilcls.cpath in let _, c = netpath_to_hx ctx.nstd path in EClass { d_name = netname_to_hx c,null_pos; d_doc = None; d_params = params; d_meta = !meta; d_flags = !flags; d_data = !fields; } type il_any_field = | IlField of ilfield | IlMethod of ilmethod | IlProp of ilprop let get_fname = function | IlField f -> f.fname | IlMethod m -> m.mname | IlProp p -> p.pname let is_static = function | IlField f -> List.mem CStatic f.fflags.ff_contract | IlMethod m -> List.mem CMStatic m.mflags.mf_contract | IlProp p -> List.exists (function | None -> false | Some (_,m) -> List.mem CMStatic m.mf_contract ) [p.pget;p.pset] (* | _ -> false *) let change_name name = function | IlField f -> IlField { f with fname = name } | IlMethod m -> IlMethod { m with mname = name } | IlProp p -> IlProp { p with pname = name } let compatible_methods m1 m2 = match m1,m2 with | IlMethod { msig = { snorm = LMethod(_,ret1,args1) } }, IlMethod { msig = { snorm = LMethod(_,ret2,args2) } } -> ret1 = ret2 && args1 = args2 | _ -> false let ilcls_from_ilsig ctx ilsig = let path, params = match ilsig with | LClass(path, params) | LValueType(path, params) -> path, params | LObject -> (["System"],[],"Object"),[] | _ -> raise Not_found (* all other types won't appear as superclass *) in match lookup_ilclass ctx.nstd ctx.ncom path with | None -> raise Not_found | Some c -> c, params let rec ilapply_params params = function | LManagedPointer s -> LManagedPointer (ilapply_params params s) | LPointer s -> LPointer (ilapply_params params s) | LValueType (p,pl) -> LValueType(p, List.map (ilapply_params params) pl) | LClass (p,pl) -> LClass(p, List.map (ilapply_params params) pl) | LTypeParam i -> List.nth params i (* TODO: maybe i - 1? *) | LVector s -> LVector (ilapply_params params s) | LArray (s,a) -> LArray (ilapply_params params s, a) | LMethod (c,r,args) -> LMethod (c, ilapply_params params r, List.map (ilapply_params params) args) | p -> p let ilcls_with_params ctx cls params = match cls.ctypes with | [] -> cls | _ -> { cls with cfields = List.map (fun f -> { f with fsig = { f.fsig with snorm = ilapply_params params f.fsig.snorm } }) cls.cfields; cmethods = List.map (fun m -> { m with msig = { m.msig with snorm = ilapply_params params m.msig.snorm }; margs = List.map (fun (n,f,s) -> (n,f,{ s with snorm = ilapply_params params s.snorm })) m.margs; mret = { m.mret with snorm = ilapply_params params m.mret.snorm }; }) cls.cmethods; cprops = List.map (fun p -> { p with psig = { p.psig with snorm = ilapply_params params p.psig.snorm } }) cls.cprops; csuper = Option.map (fun s -> { s with snorm = ilapply_params params s.snorm } ) cls.csuper; cimplements = List.map (fun s -> { s with snorm = ilapply_params params s.snorm } ) cls.cimplements; } let rec compatible_params t1 t2 = match t1,t2 with | LManagedPointer(s1), LManagedPointer(s2) -> compatible_params s1 s2 | LManagedPointer(s1), s2 | s1, LManagedPointer(s2) -> compatible_params s1 s2 | _ -> t1 = t2 let compatible_methods m1 m2 = match m1, m2 with | LMethod(_,r1,a1), LMethod(_,r2,a2) -> (try List.for_all2 (fun a1 a2 -> compatible_params a1 a2) a1 a2 with | Invalid_argument _ -> false) | _ -> false let compatible_field f1 f2 = match f1, f2 with | IlMethod { msig = { snorm = LMethod(_,_,a1) } }, IlMethod { msig = { snorm = LMethod(_,_,a2) } } -> a1 = a2 | IlProp p1, IlProp p2 -> (* p1.psig.snorm = p2.psig.snorm *) true | IlField f1, IlField f2 -> (* f1.fsig.snorm = f2.fsig.snorm *) true | _ -> false let get_all_fields cls = let all_fields = List.map (fun f -> IlField f, cls.cpath, f.fname, List.mem CStatic f.fflags.ff_contract) cls.cfields in let all_fields = all_fields @ List.map (fun m -> IlMethod m, cls.cpath, m.mname, List.mem CMStatic m.mflags.mf_contract) cls.cmethods in let all_fields = all_fields @ List.map (fun p -> IlProp p, cls.cpath, p.pname, is_static (IlProp p)) cls.cprops in all_fields let normalize_ilcls ctx cls = let force_check = Common.defined ctx.ncom Define.ForceLibCheck in (* first filter out overloaded fields of same signature *) let rec loop acc = function | [] -> acc | m :: cmeths -> let static = List.mem CMStatic m.mflags.mf_contract in if List.exists (fun m2 -> m.mname = m2.mname && List.mem CMStatic m2.mflags.mf_contract = static && compatible_methods m.msig.snorm m2.msig.snorm) cmeths then loop acc cmeths else loop (m :: acc) cmeths in let meths = loop [] cls.cmethods in (* fix overrides *) (* get only the methods that aren't declared as override, but may be *) let meths = List.map (fun v -> ref v) meths in let no_overrides = List.filter (fun m -> let m = !m in not (List.mem CMStatic m.mflags.mf_contract) ) meths in let no_overrides = ref no_overrides in let all_fields = ref [] in let all_events_name = Hashtbl.create 0 in (* avoid naming collision between events and functions *) let add_cls_events_collision cls = List.iter (fun m -> if not (List.mem CMStatic m.mflags.mf_contract) then Hashtbl.replace all_events_name m.mname true) cls.cmethods; List.iter (fun p -> if not (is_static (IlProp p)) then Hashtbl.replace all_events_name p.pname true) cls.cprops; in let rec loop cls = try match cls.csuper with | Some { snorm = LClass((["System"],[],"Object"),_) } | Some { snorm = LObject } | None -> () | Some s -> let cls, params = ilcls_from_ilsig ctx s.snorm in let cls = ilcls_with_params ctx cls params in if force_check then no_overrides := List.filter (fun v -> let m = !v in let is_override_here = List.exists (fun m2 -> m2.mname = m.mname && not (List.mem CMStatic m2.mflags.mf_contract) && compatible_methods m.msig.snorm m2.msig.snorm ) cls.cmethods in if is_override_here then v := { m with moverride = Some(cls.cpath, m.mname) }; not is_override_here ) !no_overrides; all_fields := get_all_fields cls @ !all_fields; add_cls_events_collision cls; List.iter (fun ev -> Hashtbl.replace all_events_name ev.ename true) cls.cevents; loop cls with | Not_found -> () in loop cls; add_cls_events_collision cls; if force_check then List.iter (fun v -> v := { !v with moverride = None }) !no_overrides; let added = ref [] in let current_all = ref (get_all_fields cls @ !all_fields) in (* look for interfaces and add missing implementations (some methods' implementation is optional) *) let rec loop_interface cls iface = try match iface.snorm with | LClass((["System"],[],"Object"),_) | LObject -> () | LClass(path,_) when path = cls.cpath -> () | s -> let cif, params = ilcls_from_ilsig ctx s in let cif = ilcls_with_params ctx cif params in List.iter (function | (f,_,name,false) as ff -> (* look for compatible fields *) if not (List.exists (function | (f2,_,name2,false) when (name = name2 || String.ends_with name2 ("." ^ name)) -> (* consider explicit implementations as implementations *) compatible_field f f2 | _ -> false ) !current_all) then begin current_all := ff :: !current_all; added := ff :: !added end else (* ensure it's public *) List.iter (fun mref -> match !mref with | m when m.mname = name && compatible_field f (IlMethod m) -> mref := { m with mflags = { m.mflags with mf_access = FAPublic } } | _ -> () ) meths | _ -> () ) (get_all_fields cif); List.iter (loop_interface cif) cif.cimplements with | Not_found -> () in List.iter (loop_interface cls) cls.cimplements; let added = List.map (function | (IlMethod m,a,name,b) when m.mflags.mf_access <> FAPublic -> (IlMethod { m with mflags = { m.mflags with mf_access = FAPublic } },a,name,b) | (IlField f,a,name,b) when f.fflags.ff_access <> FAPublic -> (IlField { f with fflags = { f.fflags with ff_access = FAPublic } },a,name,b) | s -> s ) !added in (* filter out properties that were already declared *) let props = if force_check then List.filter (function | p -> let static = is_static (IlProp p) in let name = p.pname in not (List.exists (function (IlProp _,_,n,s) -> s = static && name = n | _ -> false) !all_fields) (* | _ -> false *) ) cls.cprops else cls.cprops in let cls = { cls with cmethods = List.map (fun v -> !v) meths; cprops = props } in let clsfields = (get_all_fields cls) @ added in let super_fields = !all_fields in all_fields := clsfields @ !all_fields; let refclsfields = (List.map (fun v -> ref v) clsfields) in (* search static / non-static name clash *) (* change field name to not collide with haxe keywords *) let fold_field acc v = let f, p, name, is_static = !v in let change, copy = match name with | _ when is_haxe_keyword name -> true, false | _ -> ((is_static && List.exists (function | (f,_,n,false) -> name = n | _ -> false) !all_fields) || (not is_static && match f with (* filter methods that have the same name as fields *) | IlMethod _ -> List.exists (function | ( (IlProp _ | IlField _),_,n,false) -> name = n | _ -> false) super_fields || List.exists (function | ( (IlProp _ | IlField _),_,n,s) -> name = n | _ -> false) clsfields | _ -> false)), true in if change then begin let name = "%" ^ name in let changed = change_name name f, p, name, is_static in if not copy then v := changed; if copy then v :: ref changed :: acc else v :: acc end else v :: acc in let refclsfields = List.fold_left fold_field [] refclsfields in let rec fold (fields,methods,props) f = match !f with | IlField f,_,_,_ -> f :: fields,methods,props | IlMethod m,_,_,_ -> fields,m :: methods,props | IlProp p,_,_,_ -> fields,methods,p :: props in let fields, methods, props = List.fold_left fold ([],[],[]) refclsfields in { cls with cfields = fields; cprops = props; cmethods = methods; cevents = List.filter (fun ev -> not (Hashtbl.mem all_events_name ev.ename)) cls.cevents; } let add_net_std com file = com.net_std <- file :: com.net_std let add_net_lib com file std = let ilctx = ref None in let netpath_to_hx = netpath_to_hx std in let real_file = ref file in let get_ctx () = match !ilctx with | Some c -> c | None -> let file = if Sys.file_exists file then file else try Common.find_file com file with | Not_found -> try Common.find_file com (file ^ ".dll") with | Not_found -> failwith (".NET lib " ^ file ^ " not found") in real_file := file; let r = PeReader.create_r (open_in_bin file) com.defines in let ctx = PeReader.read r in let clr_header = PeReader.read_clr_header ctx in let cache = IlMetaReader.create_cache () in let meta = IlMetaReader.read_meta_tables ctx clr_header cache in close_in (r.PeReader.ch); if PMap.mem "net_loader_debug" com.defines then print_endline ("for lib " ^ file); let il_typedefs = Hashtbl.copy meta.il_typedefs in Hashtbl.clear meta.il_typedefs; Hashtbl.iter (fun _ td -> let path = IlMetaTools.get_path (TypeDef td) in if PMap.mem "net_loader_debug" com.defines then Printf.printf "found %s\n" (s_type_path (netpath_to_hx path)); Hashtbl.replace com.net_path_map (netpath_to_hx path) path; Hashtbl.replace meta.il_typedefs path td ) il_typedefs; let meta = { nstd = std; ncom = com; nil = meta } in ilctx := Some meta; meta in let cache = Hashtbl.create 0 in let lookup path = try Hashtbl.find cache path with | Not_found -> try let ctx = get_ctx() in let ns, n, cl = hxpath_to_net ctx path in let cls = IlMetaTools.convert_class ctx.nil (ns,n,cl) in let cls = normalize_ilcls ctx cls in Hashtbl.add cache path (Some cls); Some cls with | Not_found -> Hashtbl.add cache path None; None in let all_files () = Hashtbl.fold (fun path _ acc -> match path with | _,_ :: _, _ -> acc | _ -> netpath_to_hx path :: acc) (get_ctx()).nil.il_typedefs [] in let build path = let p = { pfile = !real_file ^ " @ " ^ s_type_path path; pmin = 0; pmax = 0; } in let pack = match fst path with | ["haxe";"root"] -> [] | p -> p in let cp = ref [] in let rec build path = try if PMap.mem "net_loader_debug" com.defines then Printf.printf "looking up %s\n" (s_type_path path); match lookup path with | Some({csuper = Some{snorm = LClass( (["System"],[],("Delegate"|"MulticastDelegate")),_)}} as cls) when List.mem SSealed cls.cflags.tdf_semantics -> let ctx = get_ctx() in let hxcls = convert_ilclass ctx p ~delegate:true cls in let delegate = convert_delegate ctx p cls in cp := (hxcls,p) :: (delegate,p) :: !cp; List.iter (fun ilpath -> let path = netpath_to_hx ilpath in build path ) cls.cnested | Some cls -> let ctx = get_ctx() in let hxcls = convert_ilclass ctx p cls in cp := (hxcls,p) :: !cp; List.iter (fun ilpath -> let path = netpath_to_hx ilpath in build path ) cls.cnested | _ -> () with | Not_found | Exit -> () in build path; match !cp with | [] -> None | cp -> Some (!real_file, (pack,cp)) in let build path p = build path in com.load_extern_type <- com.load_extern_type @ [build]; com.net_libs <- (file, std, all_files, lookup) :: com.net_libs let before_generate com = (* net version *) let net_ver = try int_of_string (PMap.find "net_ver" com.defines) with | Not_found -> Common.define_value com Define.NetVer "20"; 20 in if net_ver < 20 then failwith ( ".NET version is defined to target .NET " ^ string_of_int net_ver ^ ", but the compiler can only output code to versions equal or superior to .NET 2.0 (defined as 20)" ); let rec loop = function | v :: acc when v <= net_ver -> Common.raw_define com ("NET_" ^ string_of_int v); loop acc | _ -> () in loop [20;21;30;35;40;45]; (* net target *) let net_target = try String.lowercase (PMap.find "net_target" com.defines) with | Not_found -> "net" in Common.define_value com Define.NetTarget net_target; Common.raw_define com net_target; (* std dirs *) let stds = match com.net_std with | [] -> ["netlib"] | s -> s in (* look for all dirs that have the digraph NET_TARGET-NET_VER *) let digraph = net_target ^ "-" ^ string_of_int net_ver in let matched = ref [] in List.iter (fun f -> try let f = Common.find_file com (f ^ "/" ^ digraph) in matched := (f, Unix.opendir f) :: !matched with | _ -> ()) stds; if !matched = [] then failwith ( "No .NET std lib directory with the pattern '" ^ digraph ^ "' was found in the -net-std search path. " ^ "Try updating the hxcs lib to the latest version, or specifying another -net-std path."); List.iter (fun (path,f) -> let rec loop () = try let f = Unix.readdir f in let finsens = String.lowercase f in if String.ends_with finsens ".dll" then add_net_lib com (path ^ "/" ^ f) true; loop() with | End_of_file -> Unix.closedir f in loop() ) !matched; (* now force all libraries to initialize *) List.iter (function (_,_,_,lookup) -> ignore (lookup ([],""))) com.net_libs haxe_3.4.4.orig/src/generators/genhl.ml0000664000175000017500000033600213166552354020007 0ustar andyandy00000000000000(* * Copyright (C)2005-2015 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 Unix open Globals open Ast open Type open Common open Hlcode (* compiler *) type ('a,'b) lookup = { arr : 'b DynArray.t; mutable map : ('a, int) PMap.t; } (* not mutable, might be be shared *) type method_capture = { c_map : (int, int) PMap.t; c_vars : tvar array; c_type : ttype; c_group : bool; } type allocator = { mutable a_all : int list; mutable a_hold : int list; } type lassign = (string index * int * int) type method_context = { mid : int; mregs : (int, ttype) lookup; mops : opcode DynArray.t; mret : ttype; mdebug : Globals.pos DynArray.t; mvars : (int, int) Hashtbl.t; mhasthis : bool; mutable mdeclared : int list; mutable mallocs : (ttype, allocator) PMap.t; mutable mcaptured : method_capture; mutable mcontinues : (int -> unit) list; mutable mbreaks : (int -> unit) list; mutable mtrys : int; mutable mloop_trys : int; mutable mcaptreg : int; mutable mcurpos : Globals.pos; mutable massign : lassign list; } type array_impl = { aall : tclass; abase : tclass; adyn : tclass; aobj : tclass; aui16 : tclass; ai32 : tclass; af32 : tclass; af64 : tclass; } type context = { com : Common.context; cglobals : (string, ttype) lookup; cstrings : (string, string) lookup; cfloats : (float, float) lookup; cints : (int32, int32) lookup; cnatives : (string, (string index * string index * ttype * functable index)) lookup; cfids : (string * path, unit) lookup; cfunctions : fundecl DynArray.t; optimize : bool; overrides : (string * path, bool) Hashtbl.t; defined_funs : (int,unit) Hashtbl.t; is_macro : bool; mutable dump_out : (unit IO.output) option; mutable cached_types : (path, ttype) PMap.t; mutable m : method_context; mutable anons_cache : (tanon * ttype) list; mutable method_wrappers : ((ttype * ttype), int) PMap.t; mutable rec_cache : (Type.t * ttype option ref) list; mutable cached_tuples : (ttype list, ttype) PMap.t; macro_typedefs : (string, ttype) Hashtbl.t; array_impl : array_impl; base_class : tclass; base_type : tclass; base_enum : tclass; core_type : tclass; core_enum : tclass; ref_abstract : tabstract; cdebug_files : (string, string) lookup; cdebug_locals : (string, string ) lookup; cdebug_assigns : (lassign array) DynArray.t; } (* --- *) type access = | ANone | AGlobal of global | ALocal of tvar * reg | AStaticVar of global * ttype * field index | AStaticFun of fundecl index | AInstanceFun of texpr * fundecl index | AInstanceProto of texpr * field index | AInstanceField of texpr * field index | AArray of reg * (ttype * ttype) * reg | AVirtualMethod of texpr * field index | ADynamic of texpr * string index | AEnum of tenum * field index | ACaptured of field index let is_to_string t = match follow t with | TFun([],r) -> (match follow r with TInst({ cl_path=[],"String" },[]) -> true | _ -> false) | _ -> false let is_extern_field f = Type.is_extern_field f || (match f.cf_kind with Method MethNormal -> List.exists (fun (m,_,_) -> m = Meta.Custom ":hlNative") f.cf_meta | _ -> false) || Meta.has Meta.Extern f.cf_meta let is_array_class name = match name with | "hl.types.ArrayDyn" | "hl.types.ArrayBytes_Int" | "hl.types.ArrayBytes_Float" | "hl.types.ArrayObj" | "hl.types.ArrayBytes_Single" | "hl.types.ArrayBytes_hl_UI16" -> true | _ -> false let is_array_type t = match t with | HObj p -> is_array_class p.pname | _ -> false let to_utf8 str p = let u8 = try UTF8.validate str; str; with UTF8.Malformed_code -> (* ISO to utf8 *) let b = UTF8.Buf.create 0 in String.iter (fun c -> UTF8.Buf.add_char b (UChar.of_char c)) str; UTF8.Buf.contents b in let ccount = ref 0 in UTF8.iter (fun c -> let c = UChar.code c in if (c >= 0xD800 && c <= 0xDFFF) || c >= 0x110000 then abort "Invalid unicode char" p; incr ccount; if c > 0x10000 then incr ccount; ) u8; u8, !ccount let tuple_type ctx tl = try PMap.find tl ctx.cached_tuples with Not_found -> let ct = HEnum { eglobal = None; ename = ""; eid = 0; efields = [|"",0,Array.of_list tl|]; } in ctx.cached_tuples <- PMap.add tl ct ctx.cached_tuples; ct let type_size_bits = function | HUI8 | HBool -> 0 | HUI16 -> 1 | HI32 | HF32 -> 2 | HF64 -> 3 | _ -> assert false let new_lookup() = { arr = DynArray.create(); map = PMap.empty; } let null_capture = { c_vars = [||]; c_map = PMap.empty; c_type = HVoid; c_group = false; } let lookup l v fb = try PMap.find v l.map with Not_found -> let id = DynArray.length l.arr in DynArray.add l.arr (Obj.magic 0); l.map <- PMap.add v id l.map; DynArray.set l.arr id (fb()); id let lookup_alloc l v = let id = DynArray.length l.arr in DynArray.add l.arr v; id let method_context id t captured hasthis = { mid = id; mregs = new_lookup(); mops = DynArray.create(); mvars = Hashtbl.create 0; mallocs = PMap.empty; mret = t; mbreaks = []; mdeclared = []; mcontinues = []; mhasthis = hasthis; mcaptured = captured; mtrys = 0; mloop_trys = 0; mcaptreg = 0; mdebug = DynArray.create(); mcurpos = Globals.null_pos; massign = []; } let field_name c f = s_type_path c.cl_path ^ ":" ^ f.cf_name let efield_name e f = s_type_path e.e_path ^ ":" ^ f.ef_name let global_type ctx g = DynArray.get ctx.cglobals.arr g let is_overriden ctx c f = ctx.is_macro || Hashtbl.mem ctx.overrides (f.cf_name,c.cl_path) let alloc_float ctx f = lookup ctx.cfloats f (fun() -> f) let alloc_i32 ctx i = lookup ctx.cints i (fun() -> i) let alloc_string ctx s = lookup ctx.cstrings s (fun() -> s) let array_class ctx t = match t with | HI32 -> ctx.array_impl.ai32 | HUI16 -> ctx.array_impl.aui16 | HF32 -> ctx.array_impl.af32 | HF64 -> ctx.array_impl.af64 | HDyn -> ctx.array_impl.adyn | _ -> ctx.array_impl.aobj let member_fun c t = match follow t with | TFun (args, ret) -> TFun (("this",false,TInst(c,[])) :: args, ret) | _ -> assert false let rec unsigned t = match follow t with | TAbstract ({ a_path = [],"UInt" },_) -> true | TAbstract (a,pl) -> unsigned (Abstract.get_underlying_type a pl) | _ -> false let unsigned_op e1 e2 = let is_unsigned e = match e.eexpr with | TConst (TInt _) -> true | _ -> unsigned e.etype in is_unsigned e1 && is_unsigned e2 let set_curpos ctx p = ctx.m.mcurpos <- p let make_debug ctx arr = let get_relative_path p = match Common.defined ctx.com Common.Define.AbsolutePath with | true -> if (Filename.is_relative p.pfile) then Filename.concat (Sys.getcwd()) p.pfile else p.pfile | false -> try (* lookup relative path *) let len = String.length p.pfile in let base = List.find (fun path -> let l = String.length path in len > l && String.sub p.pfile 0 l = path ) ctx.com.Common.class_path in let l = String.length base in String.sub p.pfile l (len - l) with Not_found -> p.pfile in let pos = ref (0,0) in let cur_file = ref 0 in let cur_line = ref 0 in let cur = ref Globals.null_pos in let out = Array.make (DynArray.length arr) !pos in for i = 0 to DynArray.length arr - 1 do let p = DynArray.unsafe_get arr i in if p != !cur then begin let file = if p.pfile == (!cur).pfile then !cur_file else lookup ctx.cdebug_files p.pfile (fun() -> if ctx.is_macro then p.pfile else get_relative_path p) in let line = if ctx.is_macro then p.pmin lor ((p.pmax - p.pmin) lsl 20) else Lexer.get_error_line p in if line <> !cur_line || file <> !cur_file then begin cur_file := file; cur_line := line; pos := (file,line); end; cur := p; end; Array.unsafe_set out i !pos done; out let rec to_type ?tref ctx t = match t with | TMono r -> (match !r with | None -> HDyn | Some t -> to_type ?tref ctx t) | TType (td,tl) -> let t = (try match !(List.assq t ctx.rec_cache) with | None -> abort "Unsupported recursive type" td.t_pos | Some t -> t with Not_found -> let tref = ref None in ctx.rec_cache <- (t,tref) :: ctx.rec_cache; let t = to_type ~tref ctx (apply_params td.t_params tl td.t_type) in ctx.rec_cache <- List.tl ctx.rec_cache; t ) in (match td.t_path with | [], "Null" when not (is_nullable t) -> HNull t | ["haxe";"macro"], name -> Hashtbl.replace ctx.macro_typedefs name t; t | _ -> t) | TLazy f -> to_type ?tref ctx (!f()) | TFun (args, ret) -> HFun (List.map (fun (_,o,t) -> let pt = to_type ctx t in if o && not (is_nullable pt) then HRef pt else pt ) args, to_type ctx ret) | TAnon a when (match !(a.a_status) with Statics _ | EnumStatics _ -> true | _ -> false) -> (match !(a.a_status) with | Statics c -> class_type ctx c (List.map snd c.cl_params) true | EnumStatics e -> enum_class ctx e | _ -> assert false) | TAnon a -> (try (* can't use physical comparison in PMap since addresses might change in GC compact, maybe add an uid to tanon if too slow ? *) List.assq a ctx.anons_cache with Not_found -> let vp = { vfields = [||]; vindex = PMap.empty; } in let t = HVirtual vp in (match tref with | None -> () | Some r -> r := Some t); ctx.anons_cache <- (a,t) :: ctx.anons_cache; let fields = PMap.fold (fun cf acc -> match cf.cf_kind with | Var _ when (match follow cf.cf_type with TAnon _ | TFun _ -> true | _ -> false) -> (* if it's another virtual or a method, it might not match our own (might be larger, or class) *) acc | Method _ -> acc | _ -> (cf.cf_name,alloc_string ctx cf.cf_name,to_type ctx cf.cf_type) :: acc ) a.a_fields [] in if fields = [] then let t = HDyn in ctx.anons_cache <- (a,t) :: List.tl ctx.anons_cache; t else let fields = List.sort (fun (n1,_,_) (n2,_,_) -> compare n1 n2) fields in vp.vfields <- Array.of_list fields; Array.iteri (fun i (n,_,_) -> vp.vindex <- PMap.add n i vp.vindex) vp.vfields; t ) | TDynamic _ -> HDyn | TEnum (e,_) -> enum_type ~tref ctx e | TInst ({ cl_path = ["hl"],"Abstract" },[TInst({ cl_kind = KExpr (EConst (String name),_) },_)]) -> HAbstract (name, alloc_string ctx name) | TInst (c,pl) -> (match c.cl_kind with | KTypeParameter tl -> let rec loop = function | [] -> HDyn | t :: tl -> match follow (apply_params c.cl_params pl t) with | TInst ({cl_interface=false},_) as t -> to_type ?tref ctx t | _ -> loop tl in loop tl | _ -> class_type ~tref ctx c pl false) | TAbstract (a,pl) -> if Meta.has Meta.CoreType a.a_meta then (match a.a_path with | [], "Void" -> HVoid | [], "Int" | [], "UInt" -> HI32 | [], "Float" -> HF64 | [], "Single" -> HF32 | [], "Bool" -> HBool | [], "Dynamic" -> HDyn | [], "Class" -> class_type ctx ctx.base_class [] false | [], "Enum" -> class_type ctx ctx.base_type [] false | [], "EnumValue" -> HDyn | ["hl"], "Ref" -> HRef (to_type ctx (List.hd pl)) | ["hl"], ("Bytes" | "BytesAccess") -> HBytes | ["hl"], "Type" -> HType | ["hl"], "UI16" -> HUI16 | ["hl"], "UI8" -> HUI8 | ["hl"], "NativeArray" -> HArray | ["haxe";"macro"], "Position" -> HAbstract ("macro_pos", alloc_string ctx "macro_pos") | _ -> failwith ("Unknown core type " ^ s_type_path a.a_path)) else to_type ?tref ctx (Abstract.get_underlying_type a pl) and resolve_class ctx c pl statics = let not_supported() = failwith ("Extern type not supported : " ^ s_type (print_context()) (TInst (c,pl))) in match c.cl_path, pl with | ([],"Array"), [t] -> if statics then ctx.array_impl.abase else array_class ctx (to_type ctx t) | ([],"Array"), [] -> assert false | _, _ when c.cl_extern -> not_supported() | _ -> c and field_type ctx f p = match f with | FInstance (c,pl,f) | FClosure (Some (c,pl),f) -> let creal = resolve_class ctx c pl false in let rec loop c = try PMap.find f.cf_name c.cl_fields with Not_found -> match c.cl_super with | Some (csup,_) -> loop csup | None -> abort (s_type_path creal.cl_path ^ " is missing field " ^ f.cf_name) p in (loop creal).cf_type | FStatic (_,f) | FAnon f | FClosure (_,f) -> f.cf_type | FDynamic _ -> t_dynamic | FEnum (_,f) -> f.ef_type and real_type ctx e = let rec loop e = match e.eexpr with | TField (_,f) -> let ft = field_type ctx f e.epos in (* Handle function variance: If we have type parameters which are function types, we need to keep the functions because we might need to insert a cast to coerce Void->Bool to Void->Dynamic for instance. *) (match ft, e.etype with | TFun (args,ret), TFun (args2,_) -> TFun (List.map2 (fun ((_,_,t) as a) ((_,_,t2) as a2) -> match t, t2 with TInst ({cl_kind=KTypeParameter _},_), TFun _ -> a2 | _ -> a) args args2, ret) | _ -> ft) | TLocal v -> v.v_type | TParenthesis e -> loop e | _ -> e.etype in to_type ctx (loop e) and class_type ?(tref=None) ctx c pl statics = let c = if c.cl_extern then resolve_class ctx c pl statics else c in let key_path = (if statics then fst c.cl_path, "$" ^ snd c.cl_path else c.cl_path) in try PMap.find key_path ctx.cached_types with Not_found when c.cl_interface && not statics -> let vp = { vfields = [||]; vindex = PMap.empty; } in let t = HVirtual vp in ctx.cached_types <- PMap.add c.cl_path t ctx.cached_types; let rec loop c = let fields = List.fold_left (fun acc (i,_) -> loop i @ acc) [] c.cl_implements in PMap.fold (fun cf acc -> (cf.cf_name,alloc_string ctx cf.cf_name,to_type ctx cf.cf_type) :: acc) c.cl_fields fields in let fields = loop c in vp.vfields <- Array.of_list fields; Array.iteri (fun i (n,_,_) -> vp.vindex <- PMap.add n i vp.vindex) vp.vfields; t | Not_found -> let pname = s_type_path key_path in let p = { pname = pname; pid = alloc_string ctx pname; psuper = None; pclassglobal = None; pproto = [||]; pfields = [||]; pindex = PMap.empty; pvirtuals = [||]; pfunctions = PMap.empty; pnfields = -1; pinterfaces = PMap.empty; pbindings = []; } in let t = HObj p in (match tref with | None -> () | Some r -> r := Some t); ctx.cached_types <- PMap.add key_path t ctx.cached_types; if c.cl_path = ([],"Array") then assert false; if c == ctx.base_class then begin if statics then assert false; p.pnfields <- 1; end; let tsup = (match c.cl_super with | Some (csup,pl) when not statics -> Some (class_type ctx csup [] statics) | _ -> if statics then Some (class_type ctx ctx.base_class [] false) else None ) in let start_field, virtuals = (match tsup with | None -> 0, [||] | Some (HObj psup) -> if psup.pnfields < 0 then assert false; p.psuper <- Some psup; p.pfunctions <- psup.pfunctions; p.pinterfaces <- psup.pinterfaces; psup.pnfields, psup.pvirtuals | _ -> assert false ) in let fa = DynArray.create() and pa = DynArray.create() and virtuals = DynArray.of_array virtuals in let todo = ref [] in List.iter (fun f -> if is_extern_field f || (statics && f.cf_name = "__meta__") then () else let fid = (match f.cf_kind with | Method m when m <> MethDynamic && not statics -> let g = alloc_fid ctx c f in p.pfunctions <- PMap.add f.cf_name g p.pfunctions; let virt = if List.exists (fun ff -> ff.cf_name = f.cf_name) c.cl_overrides then let vid = (try -(fst (get_index f.cf_name p))-1 with Not_found -> assert false) in DynArray.set virtuals vid g; Some vid else if is_overriden ctx c f then begin let vid = DynArray.length virtuals in DynArray.add virtuals g; p.pindex <- PMap.add f.cf_name (-vid-1,HVoid) p.pindex; Some vid end else None in DynArray.add pa { fname = f.cf_name; fid = alloc_string ctx f.cf_name; fmethod = g; fvirtual = virt; }; None | Method MethDynamic when List.exists (fun ff -> ff.cf_name = f.cf_name) c.cl_overrides -> Some (try fst (get_index f.cf_name p) with Not_found -> assert false) | _ -> let fid = DynArray.length fa in p.pindex <- PMap.add f.cf_name (fid + start_field, t) p.pindex; DynArray.add fa (f.cf_name, alloc_string ctx f.cf_name, HVoid); todo := (fun() -> let t = to_type ctx f.cf_type in p.pindex <- PMap.add f.cf_name (fid + start_field, t) p.pindex; Array.set p.pfields fid (f.cf_name, alloc_string ctx f.cf_name, t) ) :: !todo; Some (fid + start_field) ) in match f.cf_kind, fid with | Method _, Some fid -> p.pbindings <- (fid, alloc_fun_path ctx c.cl_path f.cf_name) :: p.pbindings | _ -> () ) (if statics then c.cl_ordered_statics else c.cl_ordered_fields); if not statics then begin (* add interfaces *) List.iter (fun (i,pl) -> let fid = DynArray.length fa in let t = to_type ctx (TInst (i,pl)) in p.pinterfaces <- PMap.add t (fid + start_field) p.pinterfaces; DynArray.add fa ("", 0, t); ) c.cl_implements; (* check toString *) (try let cf = PMap.find "toString" c.cl_fields in if List.memq cf c.cl_overrides || PMap.mem "__string" c.cl_fields || not (is_to_string cf.cf_type) then raise Not_found; DynArray.add pa { fname = "__string"; fid = alloc_string ctx "__string"; fmethod = alloc_fun_path ctx c.cl_path "__string"; fvirtual = None; } with Not_found -> ()); end else begin (match c.cl_constructor with | Some f when not (is_extern_field f) -> p.pbindings <- ((try fst (get_index "__constructor__" p) with Not_found -> assert false),alloc_fid ctx c f) :: p.pbindings | _ -> ()); end; p.pnfields <- DynArray.length fa + start_field; p.pfields <- DynArray.to_array fa; p.pproto <- DynArray.to_array pa; p.pvirtuals <- DynArray.to_array virtuals; List.iter (fun f -> f()) !todo; if not statics && c != ctx.core_type && c != ctx.core_enum then p.pclassglobal <- Some (fst (class_global ctx (if statics then ctx.base_class else c))); t and enum_type ?(tref=None) ctx e = try PMap.find e.e_path ctx.cached_types with Not_found -> let ename = s_type_path e.e_path in let et = { eglobal = None; ename = ename; eid = alloc_string ctx ename; efields = [||]; } in let t = HEnum et in (match tref with | None -> () | Some r -> r := Some t); ctx.cached_types <- PMap.add e.e_path t ctx.cached_types; et.efields <- Array.of_list (List.map (fun f -> let f = PMap.find f e.e_constrs in let args = (match f.ef_type with | TFun (args,_) -> Array.of_list (List.map (fun (_,_,t) -> to_type ctx t) args) | _ -> [||] ) in (f.ef_name, alloc_string ctx f.ef_name, args) ) e.e_names); let ct = enum_class ctx e in et.eglobal <- Some (alloc_global ctx (match ct with HObj o -> o.pname | _ -> assert false) ct); t and enum_class ctx e = let cpath = (fst e.e_path,"$" ^ snd e.e_path) in try PMap.find cpath ctx.cached_types with Not_found -> let pname = s_type_path cpath in let p = { pname = pname; pid = alloc_string ctx pname; psuper = None; pclassglobal = None; pproto = [||]; pfields = [||]; pindex = PMap.empty; pvirtuals = [||]; pfunctions = PMap.empty; pnfields = -1; pinterfaces = PMap.empty; pbindings = []; } in let t = HObj p in ctx.cached_types <- PMap.add cpath t ctx.cached_types; p.psuper <- Some (match class_type ctx ctx.base_enum [] false with HObj o -> o | _ -> assert false); t and alloc_fun_path ctx path name = lookup ctx.cfids (name, path) (fun() -> ()) and alloc_fid ctx c f = match f.cf_kind with | Var _ -> assert false | _ -> alloc_fun_path ctx c.cl_path f.cf_name and alloc_eid ctx e f = alloc_fun_path ctx e.e_path f.ef_name and alloc_function_name ctx f = alloc_fun_path ctx ([],"") f and alloc_global ctx name t = lookup ctx.cglobals name (fun() -> t) and class_global ?(resolve=true) ctx c = let static = c != ctx.base_class in let c = if resolve && is_array_type (HObj { null_proto with pname = s_type_path c.cl_path }) then ctx.array_impl.abase else c in let c = resolve_class ctx c (List.map snd c.cl_params) static in let t = class_type ctx c [] static in alloc_global ctx ("$" ^ s_type_path c.cl_path) t, t let resolve_class_global ctx cpath = lookup ctx.cglobals ("$" ^ cpath) (fun() -> assert false) let resolve_type ctx path = PMap.find path ctx.cached_types let alloc_std ctx name args ret = let lib = "std" in (* different from :hlNative to prevent mismatch *) let nid = lookup ctx.cnatives ("$" ^ name ^ "@" ^ lib) (fun() -> let fid = alloc_fun_path ctx ([],"std") name in Hashtbl.add ctx.defined_funs fid (); (alloc_string ctx lib, alloc_string ctx name,HFun (args,ret),fid) ) in let _,_,_,fid = DynArray.get ctx.cnatives.arr nid in fid let alloc_fresh ctx t = let rid = DynArray.length ctx.m.mregs.arr in DynArray.add ctx.m.mregs.arr t; rid let alloc_tmp ctx t = if not ctx.optimize then alloc_fresh ctx t else let a = try PMap.find t ctx.m.mallocs with Not_found -> let a = { a_all = []; a_hold = []; } in ctx.m.mallocs <- PMap.add t a ctx.m.mallocs; a in match a.a_all with | [] -> let r = alloc_fresh ctx t in a.a_all <- [r]; r | r :: _ -> r let current_pos ctx = DynArray.length ctx.m.mops let rtype ctx r = DynArray.get ctx.m.mregs.arr r let hold ctx r = if not ctx.optimize || Hashtbl.mem ctx.m.mvars r then () else let t = rtype ctx r in let a = PMap.find t ctx.m.mallocs in let rec loop l = match l with | [] -> if List.mem r a.a_hold then [] else assert false | n :: l when n = r -> l | n :: l -> n :: loop l in a.a_all <- loop a.a_all; a.a_hold <- r :: a.a_hold let free ctx r = if not ctx.optimize || Hashtbl.mem ctx.m.mvars r then () else let t = rtype ctx r in let a = PMap.find t ctx.m.mallocs in let last = ref true in let rec loop l = match l with | [] -> assert false | n :: l when n = r -> if List.mem r l then last := false; l | n :: l -> n :: loop l in a.a_hold <- loop a.a_hold; (* insert sorted *) let rec loop l = match l with | [] -> [r] | n :: _ when n > r -> r :: l | n :: l -> n :: loop l in if !last then a.a_all <- loop a.a_all let decl_var ctx v = ctx.m.mdeclared <- v.v_id :: ctx.m.mdeclared let alloc_var ctx v new_var = if new_var then decl_var ctx v; try Hashtbl.find ctx.m.mvars v.v_id with Not_found -> let r = alloc_tmp ctx (to_type ctx v.v_type) in hold ctx r; Hashtbl.add ctx.m.mvars v.v_id r; r let op ctx o = match o with | OMov (a,b) when a = b -> () | _ -> DynArray.add ctx.m.mdebug ctx.m.mcurpos; DynArray.add ctx.m.mops o let jump ctx f = let pos = current_pos ctx in op ctx (OJAlways (-1)); (* loop *) (fun() -> DynArray.set ctx.m.mops pos (f (current_pos ctx - pos - 1))) let jump_back ctx = let pos = current_pos ctx in op ctx (OLabel 0); (fun() -> op ctx (OJAlways (pos - current_pos ctx - 1))) let reg_int ctx v = let r = alloc_tmp ctx HI32 in op ctx (OInt (r,alloc_i32 ctx (Int32.of_int v))); r let shl ctx idx v = if v = 0 then idx else begin hold ctx idx; let rv = reg_int ctx v in let idx2 = alloc_tmp ctx HI32 in op ctx (OShl (idx2, idx, rv)); free ctx idx; idx2; end let set_default ctx r = match rtype ctx r with | HUI8 | HUI16 | HI32 -> op ctx (OInt (r,alloc_i32 ctx 0l)) | HF32 | HF64 -> op ctx (OFloat (r,alloc_float ctx 0.)) | HBool -> op ctx (OBool (r, false)) | HType -> op ctx (OType (r, HVoid)) | _ -> op ctx (ONull r) let read_mem ctx rdst bytes index t = match t with | HUI8 -> op ctx (OGetUI8 (rdst,bytes,index)) | HUI16 -> op ctx (OGetUI16 (rdst,bytes,index)) | HI32 -> op ctx (OGetI32 (rdst,bytes,index)) | HF32 -> op ctx (OGetF32 (rdst,bytes,index)) | HF64 -> op ctx (OGetF64 (rdst,bytes,index)) | _ -> assert false let write_mem ctx bytes index t r = match t with | HUI8 -> op ctx (OSetUI8 (bytes,index,r)) | HUI16 -> op ctx (OSetUI16 (bytes,index,r)) | HI32 -> op ctx (OSetI32 (bytes,index,r)) | HF32 -> op ctx (OSetF32 (bytes,index,r)) | HF64 -> op ctx (OSetF64 (bytes,index,r)) | _ -> assert false let common_type ctx e1 e2 for_eq p = let t1 = to_type ctx e1.etype in let t2 = to_type ctx e2.etype in let rec loop t1 t2 = if t1 == t2 then t1 else match t1, t2 with | HUI8, (HUI16 | HI32 | HF32 | HF64) -> t2 | HUI16, (HI32 | HF32 | HF64) -> t2 | HI32, HF32 -> t2 (* possible loss of precision *) | (HI32 | HF32), HF64 -> t2 | (HUI8|HUI16|HI32|HF32|HF64), (HUI8|HUI16|HI32|HF32|HF64) -> t1 | (HUI8|HUI16|HI32|HF32|HF64), (HNull t2) -> if for_eq then HNull (loop t1 t2) else loop t1 t2 | (HNull t1), (HUI8|HUI16|HI32|HF32|HF64) -> if for_eq then HNull (loop t1 t2) else loop t1 t2 | (HNull t1), (HNull t2) -> if for_eq then HNull (loop t1 t2) else loop t1 t2 | HDyn, (HUI8|HUI16|HI32|HF32|HF64) -> HF64 | (HUI8|HUI16|HI32|HF32|HF64), HDyn -> HF64 | HDyn, _ -> HDyn | _, HDyn -> HDyn | _ when for_eq && safe_cast t1 t2 -> t2 | _ when for_eq && safe_cast t2 t1 -> t1 | HBool, HNull HBool when for_eq -> t2 | HNull HBool, HBool when for_eq -> t1 | HObj _, HVirtual _ | HVirtual _, HObj _ -> HDyn | _ -> abort ("Don't know how to compare " ^ tstr t1 ^ " and " ^ tstr t2) p in loop t1 t2 let captured_index ctx v = if not v.v_capture then None else try Some (PMap.find v.v_id ctx.m.mcaptured.c_map) with Not_found -> None let real_name v = let rec loop = function | [] -> v.v_name | (Meta.RealPath,[EConst (String name),_],_) :: _ -> name | _ :: l -> loop l in loop v.v_meta let add_assign ctx v r = let name = real_name v in ctx.m.massign <- (lookup ctx.cdebug_locals name (fun() -> name), DynArray.length ctx.m.mops, r) :: ctx.m.massign let add_capture ctx r = Array.iter (fun v -> let name = real_name v in ctx.m.massign <- (lookup ctx.cdebug_locals name (fun() -> name), -1, r) :: ctx.m.massign ) ctx.m.mcaptured.c_vars let before_return ctx = let rec loop i = if i > 0 then begin op ctx (OEndTrap false); loop (i - 1) end in loop ctx.m.mtrys let before_break_continue ctx = let rec loop i = if i > 0 then begin op ctx (OEndTrap false); loop (i - 1) end in loop (ctx.m.mtrys - ctx.m.mloop_trys) let type_value ctx t p = match t with | TClassDecl c -> let g, t = class_global ctx c in let r = alloc_tmp ctx t in op ctx (OGetGlobal (r, g)); r | TAbstractDecl a -> let r = alloc_tmp ctx (class_type ctx ctx.base_type [] false) in (match a.a_path with | [], "Int" -> op ctx (OGetGlobal (r, alloc_global ctx "$Int" (rtype ctx r))) | [], "Float" -> op ctx (OGetGlobal (r, alloc_global ctx "$Float" (rtype ctx r))) | [], "Bool" -> op ctx (OGetGlobal (r, alloc_global ctx "$Bool" (rtype ctx r))) | [], "Class" -> op ctx (OGetGlobal (r, fst (class_global ctx ctx.base_class))) | [], "Enum" -> op ctx (OGetGlobal (r, fst (class_global ctx ctx.base_enum))) | [], "Dynamic" -> op ctx (OGetGlobal (r, alloc_global ctx "$Dynamic" (rtype ctx r))) | _ -> abort ("Unsupported type value " ^ s_type_path (t_path t)) p); r | TEnumDecl e -> let r = alloc_tmp ctx (enum_class ctx e) in let rt = rtype ctx r in op ctx (OGetGlobal (r, alloc_global ctx (match rt with HObj o -> o.pname | _ -> assert false) rt)); r | TTypeDecl _ -> assert false let rec eval_to ctx e (t:ttype) = let r = eval_expr ctx e in cast_to ctx r t e.epos and cast_to ?(force=false) ctx (r:reg) (t:ttype) p = let rt = rtype ctx r in if safe_cast rt t then r else match rt, t with | _, HVoid -> alloc_tmp ctx HVoid | HVirtual _, HVirtual _ -> let tmp = alloc_tmp ctx HDyn in op ctx (OMov (tmp,r)); cast_to ctx tmp t p | (HUI8 | HUI16 | HI32 | HF32 | HF64), (HF32 | HF64) -> let tmp = alloc_tmp ctx t in op ctx (OToSFloat (tmp, r)); tmp | (HUI8 | HUI16 | HI32 | HF32 | HF64), (HUI8 | HUI16 | HI32) -> let tmp = alloc_tmp ctx t in op ctx (OToInt (tmp, r)); tmp | (HUI8 | HUI16 | HI32), HObj { pname = "String" } -> let len = alloc_tmp ctx HI32 in hold ctx len; let lref = alloc_tmp ctx (HRef HI32) in let bytes = alloc_tmp ctx HBytes in op ctx (ORef (lref,len)); op ctx (OCall2 (bytes,alloc_std ctx "itos" [HI32;HRef HI32] HBytes,cast_to ctx r HI32 p,lref)); let out = alloc_tmp ctx t in op ctx (OCall2 (out,alloc_fun_path ctx ([],"String") "__alloc__",bytes,len)); free ctx len; out | (HF32 | HF64), HObj { pname = "String" } -> let len = alloc_tmp ctx HI32 in let lref = alloc_tmp ctx (HRef HI32) in let bytes = alloc_tmp ctx HBytes in op ctx (ORef (lref,len)); op ctx (OCall2 (bytes,alloc_std ctx "ftos" [HF64;HRef HI32] HBytes,cast_to ctx r HF64 p,lref)); let out = alloc_tmp ctx t in op ctx (OCall2 (out,alloc_fun_path ctx ([],"String") "__alloc__",bytes,len)); out | _, HObj { pname = "String" } -> let r = cast_to ctx r HDyn p in let out = alloc_tmp ctx t in op ctx (OJNotNull (r,2)); op ctx (ONull out); op ctx (OJAlways 1); op ctx (OCall1 (out,alloc_fun_path ctx ([],"Std") "string",r)); out | HObj o, HVirtual _ -> let out = alloc_tmp ctx t in (try let fid = PMap.find t o.pinterfaces in (* memoisation *) let need_null_check r = not (r = 0 && ctx.m.mhasthis) in let jend = if need_null_check r then let jnull = jump ctx (fun d -> OJNotNull (r,d)) in op ctx (ONull out); let jend = jump ctx (fun d -> OJAlways d) in jnull(); jend else (fun() -> ()) in op ctx (OField (out, r, fid)); let j = jump ctx (fun d -> OJNotNull (out,d)) in op ctx (OToVirtual (out,r)); op ctx (OSetField (r, fid, out)); jend(); j(); with Not_found -> (* not an interface *) op ctx (OToVirtual (out,r))); out | (HDynObj | HDyn) , HVirtual _ -> let out = alloc_tmp ctx t in op ctx (OToVirtual (out,r)); out | HDyn, _ -> let out = alloc_tmp ctx t in op ctx (OSafeCast (out, r)); out | HNull rt, _ when t = rt -> let out = alloc_tmp ctx t in op ctx (OSafeCast (out, r)); out | HVoid, HDyn -> let tmp = alloc_tmp ctx HDyn in op ctx (ONull tmp); tmp | _ , HDyn -> let tmp = alloc_tmp ctx HDyn in op ctx (OToDyn (tmp, r)); tmp | _, HNull t when rt == t -> let tmp = alloc_tmp ctx (HNull t) in op ctx (OToDyn (tmp, r)); tmp | HNull t1, HNull t2 -> let j = jump ctx (fun n -> OJNull (r,n)) in let rtmp = alloc_tmp ctx t1 in op ctx (OSafeCast (rtmp,r)); let out = cast_to ctx rtmp t p in op ctx (OJAlways 1); j(); op ctx (ONull out); out | (HUI8 | HUI16 | HI32 | HF32 | HF64), HNull ((HF32 | HF64) as t) -> let tmp = alloc_tmp ctx t in op ctx (OToSFloat (tmp, r)); let r = alloc_tmp ctx (HNull t) in op ctx (OToDyn (r,tmp)); r | (HUI8 | HUI16 | HI32 | HF32 | HF64), HNull ((HUI8 | HUI16 | HI32) as t) -> let tmp = alloc_tmp ctx t in op ctx (OToInt (tmp, r)); let r = alloc_tmp ctx (HNull t) in op ctx (OToDyn (r,tmp)); r | HNull ((HUI8 | HUI16 | HI32) as it), (HF32 | HF64) -> let i = alloc_tmp ctx it in op ctx (OSafeCast (i,r)); let tmp = alloc_tmp ctx t in op ctx (OToSFloat (tmp, i)); tmp | HNull ((HF32 | HF64) as it), (HUI8 | HUI16 | HI32) -> let i = alloc_tmp ctx it in op ctx (OSafeCast (i,r)); let tmp = alloc_tmp ctx t in op ctx (OToInt (tmp, i)); tmp | HFun (args1,ret1), HFun (args2, ret2) when List.length args1 = List.length args2 -> let fid = gen_method_wrapper ctx rt t p in let fr = alloc_tmp ctx t in op ctx (OJNotNull (r,2)); op ctx (ONull fr); op ctx (OJAlways 1); op ctx (OInstanceClosure (fr,fid,r)); fr | HObj _, HObj _ when is_array_type rt && is_array_type t -> let out = alloc_tmp ctx t in op ctx (OSafeCast (out, r)); out | _, HRef t2 -> let r = cast_to ctx r t2 p in let r2 = alloc_tmp ctx t2 in op ctx (OMov (r2, r)); hold ctx r2; (* retain *) let out = alloc_tmp ctx t in op ctx (ORef (out,r2)); out | _ -> if force then let out = alloc_tmp ctx t in op ctx (OSafeCast (out, r)); out else abort ("Don't know how to cast " ^ tstr rt ^ " to " ^ tstr t) p and unsafe_cast_to ctx (r:reg) (t:ttype) p = let rt = rtype ctx r in if safe_cast rt t then r else match rt with | HFun _ -> cast_to ctx r t p | HDyn when is_array_type t -> cast_to ctx r t p | (HDyn | HObj _) when (match t with HVirtual _ -> true | _ -> false) -> cast_to ctx r t p | HObj _ when is_array_type rt && is_array_type t -> cast_to ctx r t p | HVirtual _ when (match t with HObj _ | HVirtual _ -> true | _ -> false) -> cast_to ~force:true ctx r t p | _ -> if is_dynamic (rtype ctx r) && is_dynamic t then let r2 = alloc_tmp ctx t in op ctx (OUnsafeCast (r2,r)); r2 else cast_to ~force:true ctx r t p and object_access ctx eobj t f = match t with | HObj p -> (try let fid = fst (get_index f.cf_name p) in if f.cf_kind = Method MethNormal then AInstanceProto (eobj, -fid-1) else AInstanceField (eobj, fid) with Not_found -> ADynamic (eobj, alloc_string ctx f.cf_name)) | HVirtual v -> (try let fid = PMap.find f.cf_name v.vindex in if f.cf_kind = Method MethNormal then AVirtualMethod (eobj, fid) else AInstanceField (eobj, fid) with Not_found -> ADynamic (eobj, alloc_string ctx f.cf_name)) | HDyn -> ADynamic (eobj, alloc_string ctx f.cf_name) | _ -> abort ("Unsupported field access " ^ tstr t) eobj.epos and direct_method_call ctx c f ethis = if (match f.cf_kind with Method m -> m = MethDynamic | Var _ -> true) then false else if c.cl_interface then false else if (match c.cl_kind with KTypeParameter _ -> true | _ -> false) then false else if is_overriden ctx c f && ethis.eexpr <> TConst(TSuper) then false else true and get_access ctx e = match e.eexpr with | TField (ethis, a) -> (match a, follow ethis.etype with | FStatic (c,({ cf_kind = Var _ | Method MethDynamic } as f)), _ -> let g, t = class_global ctx c in AStaticVar (g, t, (match t with HObj o -> (try fst (get_index f.cf_name o) with Not_found -> assert false) | _ -> assert false)) | FStatic (c,({ cf_kind = Method _ } as f)), _ -> AStaticFun (alloc_fid ctx c f) | FClosure (Some (cdef,pl), f), TInst (c,_) | FInstance (cdef,pl,f), TInst (c,_) when direct_method_call ctx c f ethis -> (* cdef is the original definition, we want the last redefinition *) let rec loop c = if PMap.mem f.cf_name c.cl_fields then c else (match c.cl_super with None -> cdef | Some (c,_) -> loop c) in let last_def = loop c in AInstanceFun (ethis, alloc_fid ctx (resolve_class ctx last_def pl false) f) | (FInstance (cdef,pl,f) | FClosure (Some (cdef,pl), f)), _ -> let rec loop t = match follow t with | TInst (c,pl) -> c, pl | TAbstract (a,pl) -> loop (Abstract.get_underlying_type a pl) | _ -> abort (s_type (print_context()) ethis.etype ^ " hl type should be interface") ethis.epos in let cdef, pl = if cdef.cl_interface then loop ethis.etype else cdef,pl in object_access ctx ethis (class_type ctx cdef pl false) f | (FAnon f | FClosure(None,f)), _ -> object_access ctx ethis (to_type ctx ethis.etype) f | FDynamic name, _ -> ADynamic (ethis, alloc_string ctx name) | FEnum (e,ef), _ -> (match follow ef.ef_type with | TFun _ -> AEnum (e,ef.ef_index) | t -> AGlobal (alloc_global ctx (efield_name e ef) (to_type ctx t)))) | TLocal v -> (match captured_index ctx v with | None -> ALocal (v, alloc_var ctx v false) | Some idx -> ACaptured idx) | TParenthesis e -> get_access ctx e | TArray (a,i) -> let rec loop t = match follow t with | TInst({ cl_path = [],"Array" },[t]) -> let a = eval_null_check ctx a in hold ctx a; let i = eval_to ctx i HI32 in free ctx a; let t = to_type ctx t in AArray (a,(t,t),i) | TAbstract (a,pl) -> loop (Abstract.get_underlying_type a pl) | _ -> let a = eval_to ctx a (class_type ctx ctx.array_impl.adyn [] false) in op ctx (ONullCheck a); hold ctx a; let i = eval_to ctx i HI32 in free ctx a; AArray (a,(HDyn,to_type ctx e.etype),i) in loop a.etype | _ -> ANone and array_read ctx ra (at,vt) ridx p = match at with | HUI8 | HUI16 | HI32 | HF32 | HF64 -> (* check bounds *) hold ctx ridx; let length = alloc_tmp ctx HI32 in free ctx ridx; op ctx (OField (length, ra, 0)); let j = jump ctx (fun i -> OJULt (ridx,length,i)) in let r = alloc_tmp ctx (match at with HUI8 | HUI16 -> HI32 | _ -> at) in (match at with | HUI8 | HUI16 | HI32 -> op ctx (OInt (r,alloc_i32 ctx 0l)); | HF32 | HF64 -> op ctx (OFloat (r,alloc_float ctx 0.)); | _ -> assert false); let jend = jump ctx (fun i -> OJAlways i) in j(); let hbytes = alloc_tmp ctx HBytes in op ctx (OField (hbytes, ra, 1)); read_mem ctx r hbytes (shl ctx ridx (type_size_bits at)) at; jend(); cast_to ctx r vt p | HDyn -> (* call getDyn *) let r = alloc_tmp ctx HDyn in op ctx (OCallMethod (r,0,[ra;ridx])); unsafe_cast_to ctx r vt p | _ -> (* check bounds *) hold ctx ridx; let length = alloc_tmp ctx HI32 in free ctx ridx; op ctx (OField (length,ra,0)); let j = jump ctx (fun i -> OJULt (ridx,length,i)) in let r = alloc_tmp ctx vt in set_default ctx r; let jend = jump ctx (fun i -> OJAlways i) in j(); let tmp = alloc_tmp ctx HDyn in let harr = alloc_tmp ctx HArray in op ctx (OField (harr,ra,1)); op ctx (OGetArray (tmp,harr,ridx)); op ctx (OMov (r,unsafe_cast_to ctx tmp vt p)); jend(); r and jump_expr ctx e jcond = match e.eexpr with | TParenthesis e -> jump_expr ctx e jcond | TUnop (Not,_,e) -> jump_expr ctx e (not jcond) | TBinop (OpEq,{ eexpr = TConst(TNull) },e) | TBinop (OpEq,e,{ eexpr = TConst(TNull) }) -> let r = eval_expr ctx e in jump ctx (fun i -> if jcond then OJNull (r,i) else OJNotNull (r,i)) | TBinop (OpNotEq,{ eexpr = TConst(TNull) },e) | TBinop (OpNotEq,e,{ eexpr = TConst(TNull) }) -> let r = eval_expr ctx e in jump ctx (fun i -> if jcond then OJNotNull (r,i) else OJNull (r,i)) | TBinop (OpEq | OpNotEq | OpGt | OpGte | OpLt | OpLte as jop, e1, e2) -> let t = common_type ctx e1 e2 (match jop with OpEq | OpNotEq -> true | _ -> false) e.epos in let r1 = eval_to ctx e1 t in hold ctx r1; let r2 = eval_to ctx e2 t in free ctx r1; let unsigned = unsigned_op e1 e2 in jump ctx (fun i -> let lt a b = if unsigned then OJULt (a,b,i) else OJSLt (a,b,i) in let gte a b = if unsigned then OJUGte (a,b,i) else OJSGte (a,b,i) in match jop with | OpEq -> if jcond then OJEq (r1,r2,i) else OJNotEq (r1,r2,i) | OpNotEq -> if jcond then OJNotEq (r1,r2,i) else OJEq (r1,r2,i) | OpGt -> if jcond then lt r2 r1 else gte r2 r1 | OpGte -> if jcond then gte r1 r2 else lt r1 r2 | OpLt -> if jcond then lt r1 r2 else gte r1 r2 | OpLte -> if jcond then gte r2 r1 else lt r2 r1 | _ -> assert false ) | TBinop (OpBoolAnd, e1, e2) -> let j = jump_expr ctx e1 false in let j2 = jump_expr ctx e2 jcond in if jcond then j(); (fun() -> if not jcond then j(); j2()); | TBinop (OpBoolOr, e1, e2) -> let j = jump_expr ctx e1 true in let j2 = jump_expr ctx e2 jcond in if not jcond then j(); (fun() -> if jcond then j(); j2()); | _ -> let r = eval_to ctx e HBool in jump ctx (fun i -> if jcond then OJTrue (r,i) else OJFalse (r,i)) and eval_args ctx el t p = let rl = List.map2 (fun e t -> let r = (match e.eexpr, t with | TConst TNull, HRef _ -> let r = alloc_tmp ctx t in op ctx (ONull r); r | _ -> eval_to ctx e t ) in hold ctx r; r ) el (match t with HFun (args,_) -> args | HDyn -> List.map (fun _ -> HDyn) el | _ -> assert false) in List.iter (free ctx) rl; set_curpos ctx p; rl and eval_null_check ctx e = let r = eval_expr ctx e in (match e.eexpr with | TConst TThis | TConst TSuper -> () | _ -> op ctx (ONullCheck r)); r and make_string ctx s p = let str, len = to_utf8 s p in let r = alloc_tmp ctx HBytes in let s = alloc_tmp ctx (to_type ctx ctx.com.basic.tstring) in op ctx (ONew s); op ctx (OString (r,alloc_string ctx str)); op ctx (OSetField (s,0,r)); op ctx (OSetField (s,1,reg_int ctx len)); s and eval_var ctx v = match captured_index ctx v with | None -> alloc_var ctx v false | Some idx -> let r = alloc_tmp ctx (to_type ctx v.v_type) in op ctx (OEnumField (r,ctx.m.mcaptreg,0,idx)); r and eval_expr ctx e = set_curpos ctx e.epos; match e.eexpr with | TConst c -> (match c with | TInt i -> let r = alloc_tmp ctx HI32 in op ctx (OInt (r,alloc_i32 ctx i)); r | TFloat f -> let r = alloc_tmp ctx HF64 in op ctx (OFloat (r,alloc_float ctx (float_of_string f))); r | TBool b -> let r = alloc_tmp ctx HBool in op ctx (OBool (r,b)); r | TString s -> make_string ctx s e.epos | TThis | TSuper -> 0 (* first reg *) | TNull -> let r = alloc_tmp ctx (to_type ctx e.etype) in op ctx (ONull r); r) | TVar (v,e) -> (match e with | None -> if captured_index ctx v = None then decl_var ctx v | Some e -> let ri = eval_to ctx e (to_type ctx v.v_type) in match captured_index ctx v with | None -> let r = alloc_var ctx v true in op ctx (OMov (r,ri)); add_assign ctx v r; | Some idx -> op ctx (OSetEnumField (ctx.m.mcaptreg, idx, ri)); ); alloc_tmp ctx HVoid | TLocal v -> cast_to ctx (match captured_index ctx v with | None -> (* we need to make a copy for cases such as (a - a++) *) let r = alloc_var ctx v false in let r2 = alloc_tmp ctx (rtype ctx r) in op ctx (OMov (r2, r)); r2 | Some idx -> let r = alloc_tmp ctx (to_type ctx v.v_type) in op ctx (OEnumField (r, ctx.m.mcaptreg, 0, idx)); r) (to_type ctx e.etype) e.epos | TReturn None -> before_return ctx; let r = alloc_tmp ctx HVoid in op ctx (ORet r); alloc_tmp ctx HDyn | TReturn (Some e) -> let r = eval_to ctx e ctx.m.mret in before_return ctx; op ctx (ORet r); alloc_tmp ctx HDyn | TParenthesis e -> eval_expr ctx e | TBlock el -> let rec loop = function | [e] -> eval_expr ctx e | [] -> alloc_tmp ctx HVoid | e :: l -> ignore(eval_expr ctx e); loop l in let old = ctx.m.mdeclared in ctx.m.mdeclared <- []; let r = loop el in List.iter (fun vid -> let r = try Hashtbl.find ctx.m.mvars vid with Not_found -> -1 in if r >= 0 then begin Hashtbl.remove ctx.m.mvars vid; free ctx r; end ) ctx.m.mdeclared; ctx.m.mdeclared <- old; r | TCall ({ eexpr = TConst TSuper } as s, el) -> (match follow s.etype with | TInst (csup,_) -> (match csup.cl_constructor with | None -> assert false | Some f -> let r = alloc_tmp ctx HVoid in let el = eval_args ctx el (to_type ctx f.cf_type) e.epos in op ctx (OCallN (r, alloc_fid ctx csup f, 0 :: el)); r ) | _ -> assert false); | TCall ({ eexpr = TLocal v }, el) when v.v_name.[0] = '$' -> let invalid() = abort "Invalid native call" e.epos in (match v.v_name, el with | "$new", [{ eexpr = TTypeExpr (TClassDecl _) }] -> (match follow e.etype with | TInst (c,pl) -> let r = alloc_tmp ctx (class_type ctx c pl false) in op ctx (ONew r); r | _ -> invalid()) | "$int", [{ eexpr = TBinop (OpDiv, e1, e2) }] when is_int (to_type ctx e1.etype) && is_int (to_type ctx e2.etype) -> let tmp = alloc_tmp ctx HI32 in let r1 = eval_to ctx e1 HI32 in hold ctx r1; let r2 = eval_to ctx e2 HI32 in free ctx r1; op ctx (if unsigned_op e1 e2 then OUDiv (tmp,r1,r2) else OSDiv (tmp, r1, r2)); tmp | "$int", [e] -> let tmp = alloc_tmp ctx HI32 in op ctx (OToInt (tmp, eval_expr ctx e)); tmp | "$bsetui8", [b;pos;v] -> let b = eval_to ctx b HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in hold ctx pos; let r = eval_to ctx v HI32 in free ctx pos; free ctx b; op ctx (OSetUI8 (b, pos, r)); r | "$bsetui16", [b;pos;v] -> let b = eval_to ctx b HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in hold ctx pos; let r = eval_to ctx v HI32 in free ctx pos; free ctx b; op ctx (OSetUI16 (b, pos, r)); r | "$bseti32", [b;pos;v] -> let b = eval_to ctx b HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in hold ctx pos; let r = eval_to ctx v HI32 in free ctx pos; free ctx b; op ctx (OSetI32 (b, pos, r)); r | "$bsetf32", [b;pos;v] -> let b = eval_to ctx b HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in hold ctx pos; let r = eval_to ctx v HF32 in free ctx pos; free ctx b; op ctx (OSetF32 (b, pos, r)); r | "$bsetf64", [b;pos;v] -> let b = eval_to ctx b HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in hold ctx pos; let r = eval_to ctx v HF64 in free ctx pos; free ctx b; op ctx (OSetF64 (b, pos, r)); r | "$bytes_sizebits", [eb] -> (match follow eb.etype with | TAbstract({a_path = ["hl"],"BytesAccess"},[t]) -> reg_int ctx (match to_type ctx t with | HUI8 -> 0 | HUI16 -> 1 | HI32 -> 2 | HF32 -> 2 | HF64 -> 3 | t -> abort ("Unsupported basic type " ^ tstr t) e.epos) | _ -> abort "Invalid BytesAccess" eb.epos); | "$bytes_nullvalue", [eb] -> (match follow eb.etype with | TAbstract({a_path = ["hl"],"BytesAccess"},[t]) -> let t = to_type ctx t in let r = alloc_tmp ctx t in (match t with | HUI8 | HUI16 | HI32 -> op ctx (OInt (r,alloc_i32 ctx 0l)) | HF32 | HF64 -> op ctx (OFloat (r, alloc_float ctx 0.)) | t -> abort ("Unsupported basic type " ^ tstr t) e.epos); r | _ -> abort "Invalid BytesAccess" eb.epos); | "$bget", [eb;pos] -> (match follow eb.etype with | TAbstract({a_path = ["hl"],"BytesAccess"},[t]) -> let b = eval_to ctx eb HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in free ctx b; let t = to_type ctx t in (match t with | HUI8 -> let r = alloc_tmp ctx HI32 in op ctx (OGetUI8 (r, b, pos)); r | HUI16 -> let r = alloc_tmp ctx HI32 in op ctx (OGetUI16 (r, b, shl ctx pos 1)); r | HI32 -> let r = alloc_tmp ctx HI32 in op ctx (OGetI32 (r, b, shl ctx pos 2)); r | HF32 -> let r = alloc_tmp ctx HF32 in op ctx (OGetF32 (r, b, shl ctx pos 2)); r | HF64 -> let r = alloc_tmp ctx HF64 in op ctx (OGetF64 (r, b, shl ctx pos 3)); r | _ -> abort ("Unsupported basic type " ^ tstr t) e.epos) | _ -> abort "Invalid BytesAccess" eb.epos); | "$bset", [eb;pos;value] -> (match follow eb.etype with | TAbstract({a_path = ["hl"],"BytesAccess"},[t]) -> let b = eval_to ctx eb HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in hold ctx pos; let t = to_type ctx t in let v = (match t with | HUI8 -> let v = eval_to ctx value HI32 in op ctx (OSetUI8 (b, pos, v)); v | HUI16 -> let v = eval_to ctx value HI32 in hold ctx v; op ctx (OSetUI16 (b, shl ctx pos 1, v)); free ctx v; v | HI32 -> let v = eval_to ctx value HI32 in hold ctx v; op ctx (OSetI32 (b, shl ctx pos 2, v)); free ctx v; v | HF32 -> let v = eval_to ctx value HF32 in hold ctx v; op ctx (OSetF32 (b, shl ctx pos 2, v)); free ctx v; v | HF64 -> let v = eval_to ctx value HF64 in hold ctx v; op ctx (OSetF64 (b, shl ctx pos 3, v)); free ctx v; v | _ -> abort ("Unsupported basic type " ^ tstr t) e.epos ) in free ctx b; free ctx pos; v | _ -> abort "Invalid BytesAccess" eb.epos); | "$bgetui8", [b;pos] -> let b = eval_to ctx b HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in free ctx b; let r = alloc_tmp ctx HI32 in op ctx (OGetUI8 (r, b, pos)); r | "$bgetui16", [b;pos] -> let b = eval_to ctx b HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in free ctx b; let r = alloc_tmp ctx HI32 in op ctx (OGetUI16 (r, b, pos)); r | "$bgeti32", [b;pos] -> let b = eval_to ctx b HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in free ctx b; let r = alloc_tmp ctx HI32 in op ctx (OGetI32 (r, b, pos)); r | "$bgetf32", [b;pos] -> let b = eval_to ctx b HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in free ctx b; let r = alloc_tmp ctx HF32 in op ctx (OGetF32 (r, b, pos)); r | "$bgetf64", [b;pos] -> let b = eval_to ctx b HBytes in hold ctx b; let pos = eval_to ctx pos HI32 in free ctx b; let r = alloc_tmp ctx HF64 in op ctx (OGetF64 (r, b, pos)); r | "$asize", [e] -> let r = alloc_tmp ctx HI32 in op ctx (OArraySize (r, eval_to ctx e HArray)); r | "$aalloc", [esize] -> let et = (match follow e.etype with TAbstract ({ a_path = ["hl"],"NativeArray" },[t]) -> to_type ctx t | _ -> invalid()) in let size = eval_to ctx esize HI32 in let a = alloc_tmp ctx HArray in let rt = alloc_tmp ctx HType in op ctx (OType (rt,et)); op ctx (OCall2 (a,alloc_std ctx "alloc_array" [HType;HI32] HArray,rt,size)); a | "$aget", [a; pos] -> (* read/write on arrays are unsafe : the type of NativeArray needs to be correcly set. *) let at = (match follow a.etype with TAbstract ({ a_path = ["hl"],"NativeArray" },[t]) -> to_type ctx t | _ -> invalid()) in let arr = eval_to ctx a HArray in hold ctx arr; let pos = eval_to ctx pos HI32 in free ctx arr; let r = alloc_tmp ctx at in op ctx (OGetArray (r, arr, pos)); cast_to ctx r (to_type ctx e.etype) e.epos | "$aset", [a; pos; value] -> let et = (match follow a.etype with TAbstract ({ a_path = ["hl"],"NativeArray" },[t]) -> to_type ctx t | _ -> invalid()) in let arr = eval_to ctx a HArray in let pos = eval_to ctx pos HI32 in let r = eval_to ctx value et in op ctx (OSetArray (arr, pos, r)); r | "$abytes", [a] -> (match follow a.etype with | TInst ({ cl_path = [], "Array" },[t]) when is_number (to_type ctx t) -> let a = eval_expr ctx a in let r = alloc_tmp ctx HBytes in op ctx (ONullCheck a); op ctx (OField (r,a,1)); r | t -> abort ("Invalid array type " ^ s_type (print_context()) t) a.epos) | "$ref", [v] -> (match v.eexpr with | TLocal v -> let r = alloc_tmp ctx (to_type ctx e.etype) in let rv = (match rtype ctx r with HRef t -> alloc_var ctx v false | _ -> invalid()) in hold ctx rv; (* infinite hold *) op ctx (ORef (r,rv)); r | _ -> abort "Ref should be a local variable" v.epos) | "$setref", [e1;e2] -> let rec loop e = match e.eexpr with | TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) -> loop e1 | TLocal v -> v | _ -> invalid() in let v = loop e1 in let r = alloc_var ctx v false in let rv = eval_to ctx e2 (match rtype ctx r with HRef t -> t | _ -> invalid()) in op ctx (OSetref (r,rv)); r | "$unref", [e1] -> let rec loop e = match e.eexpr with | TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) -> loop e1 | TLocal v -> v | _ -> invalid() in let v = loop e1 in let r = alloc_var ctx v false in let out = alloc_tmp ctx (match rtype ctx r with HRef t -> t | _ -> invalid()) in op ctx (OUnref (out,r)); out | "$ttype", [v] -> let r = alloc_tmp ctx HType in op ctx (OType (r,to_type ctx v.etype)); r | "$tdyntype", [v] -> let r = alloc_tmp ctx HType in op ctx (OGetType (r,eval_to ctx v HDyn)); r | "$tkind", [v] -> let r = alloc_tmp ctx HI32 in op ctx (OGetTID (r,eval_to ctx v HType)); r | "$resources", [] -> let tdef = (try List.find (fun t -> (t_infos t).mt_path = (["haxe";"_Resource"],"ResourceContent")) ctx.com.types with Not_found -> assert false) in let t = class_type ctx (match tdef with TClassDecl c -> c | _ -> assert false) [] false in let arr = alloc_tmp ctx HArray in let rt = alloc_tmp ctx HType in op ctx (OType (rt,t)); let res = Hashtbl.fold (fun k v acc -> (k,v) :: acc) ctx.com.resources [] in let size = reg_int ctx (List.length res) in op ctx (OCall2 (arr,alloc_std ctx "alloc_array" [HType;HI32] HArray,rt,size)); let ro = alloc_tmp ctx t in let rb = alloc_tmp ctx HBytes in let ridx = reg_int ctx 0 in hold ctx ridx; let has_len = (match t with HObj p -> PMap.mem "dataLen" p.pindex | _ -> assert false) in list_iteri (fun i (k,v) -> op ctx (ONew ro); op ctx (OString (rb,alloc_string ctx k)); op ctx (OSetField (ro,0,rb)); op ctx (OBytes (rb,alloc_string ctx (v ^ "\x00"))); (* add a \x00 to prevent clashing with existing string *) op ctx (OSetField (ro,1,rb)); if has_len then op ctx (OSetField (ro,2,reg_int ctx (String.length v))); op ctx (OSetArray (arr,ridx,ro)); op ctx (OIncr ridx); ) res; free ctx ridx; arr | "$rethrow", [v] -> let r = alloc_tmp ctx HVoid in op ctx (ORethrow (eval_to ctx v HDyn)); r | "$allTypes", [] -> let r = alloc_tmp ctx (to_type ctx e.etype) in op ctx (OGetGlobal (r, alloc_global ctx "__types__" (rtype ctx r))); r | "$allTypes", [v] -> let v = eval_expr ctx v in op ctx (OSetGlobal (alloc_global ctx "__types__" (rtype ctx v), v)); v | "$hash", [v] -> (match v.eexpr with | TConst (TString str) -> let r = alloc_tmp ctx HI32 in op ctx (OInt (r,alloc_i32 ctx (hl_hash str))); r | _ -> abort "Constant string required" v.epos) | "$enumIndex", [v] -> let r = alloc_tmp ctx HI32 in let re = eval_expr ctx v in op ctx (ONullCheck re); op ctx (OEnumIndex (r,re)); r | "$__mk_pos__", [{ eexpr = TConst (TString file) };min;max] -> (* macros only - generated by reification *) let rt = HAbstract ("macro_pos",alloc_string ctx "macro_pos") in let r = alloc_tmp ctx rt in let rfile = alloc_tmp ctx HBytes in op ctx (OBytes (rfile, alloc_string ctx file)); hold ctx rfile; let min = eval_expr ctx min in hold ctx min; let max = eval_expr ctx max in op ctx (OCall3 (r,alloc_std ctx "make_macro_pos" [HBytes;HI32;HI32] rt,rfile,min,max)); free ctx rfile; free ctx min; r | _ -> abort ("Unknown native call " ^ v.v_name) e.epos) | TCall (ec,args) -> let tfun = real_type ctx ec in let el() = eval_args ctx args tfun e.epos in let ret = alloc_tmp ctx (match tfun with HFun (_,r) -> r | _ -> HDyn) in let def_ret = ref None in (match get_access ctx ec with | AStaticFun f -> (match el() with | [] -> op ctx (OCall0 (ret, f)) | [a] -> op ctx (OCall1 (ret, f, a)) | [a;b] -> op ctx (OCall2 (ret, f, a, b)) | [a;b;c] -> op ctx (OCall3 (ret, f, a, b, c)) | [a;b;c;d] -> op ctx (OCall4 (ret, f, a, b, c, d)) | el -> op ctx (OCallN (ret, f, el))); | AInstanceFun (ethis, f) -> let r = eval_null_check ctx ethis in hold ctx r; let el = r :: el() in free ctx r; (match el with | [a] -> op ctx (OCall1 (ret, f, a)) | [a;b] -> op ctx (OCall2 (ret, f, a, b)) | [a;b;c] -> op ctx (OCall3 (ret, f, a, b, c)) | [a;b;c;d] -> op ctx (OCall4 (ret, f, a, b, c, d)) | _ -> op ctx (OCallN (ret, f, el))); | AInstanceProto ({ eexpr = TConst TThis }, fid) -> op ctx (OCallThis (ret, fid, el())) | AInstanceProto (ethis, fid) | AVirtualMethod (ethis, fid) -> let r = eval_null_check ctx ethis in hold ctx r; let el = r :: el() in free ctx r; op ctx (OCallMethod (ret, fid, el)) | AEnum (_,index) -> op ctx (OMakeEnum (ret, index, el())) | AArray (a,t,idx) -> let r = array_read ctx a t idx ec.epos in hold ctx r; op ctx (ONullCheck r); op ctx (OCallClosure (ret, r, el())); (* if it's a value, it's a closure *) free ctx r; | _ -> (* don't use real_type here *) let tfun = to_type ctx ec.etype in let r = eval_null_check ctx ec in hold ctx r; let el = eval_args ctx args tfun e.epos in free ctx r; let ret = alloc_tmp ctx (match tfun with HFun (_,r) -> r | _ -> HDyn) in op ctx (OCallClosure (ret, r, el)); (* if it's a value, it's a closure *) def_ret := Some (cast_to ~force:true ctx ret (to_type ctx e.etype) e.epos); ); (match !def_ret with None -> cast_to ~force:true ctx ret (to_type ctx e.etype) e.epos | Some r -> r) | TField (ec,FInstance({ cl_path = [],"Array" },[t],{ cf_name = "length" })) when to_type ctx t = HDyn -> let r = alloc_tmp ctx HI32 in op ctx (OCall1 (r,alloc_fun_path ctx (["hl";"types"],"ArrayDyn") "get_length", eval_null_check ctx ec)); r | TField (ec,a) -> let r = alloc_tmp ctx (to_type ctx (field_type ctx a e.epos)) in (match get_access ctx e with | AGlobal g -> op ctx (OGetGlobal (r,g)); | AStaticVar (g,t,fid) -> let o = alloc_tmp ctx t in op ctx (OGetGlobal (o,g)); op ctx (OField (r,o,fid)); | AStaticFun f -> op ctx (OStaticClosure (r,f)); | AInstanceFun (ethis, f) -> op ctx (OInstanceClosure (r, f, eval_null_check ctx ethis)) | AInstanceField (ethis,fid) -> let robj = eval_null_check ctx ethis in op ctx (match ethis.eexpr with TConst TThis -> OGetThis (r,fid) | _ -> OField (r,robj,fid)); | AInstanceProto (ethis,fid) | AVirtualMethod (ethis, fid) -> let robj = eval_null_check ctx ethis in op ctx (OVirtualClosure (r,robj,fid)); | ADynamic (ethis, f) -> let robj = eval_null_check ctx ethis in op ctx (ODynGet (r,robj,f)) | AEnum (en,index) -> let cur_fid = DynArray.length ctx.cfids.arr in let name = List.nth en.e_names index in let fid = alloc_fun_path ctx en.e_path name in if fid = cur_fid then begin let ef = PMap.find name en.e_constrs in let eargs, et = (match follow ef.ef_type with TFun (args,ret) -> args, ret | _ -> assert false) in let ct = ctx.com.basic in let p = ef.ef_pos in let eargs = List.map (fun (n,o,t) -> Type.alloc_var n t en.e_pos, if o then Some TNull else None) eargs in let ecall = mk (TCall (e,List.map (fun (v,_) -> mk (TLocal v) v.v_type p) eargs)) et p in let f = { tf_args = eargs; tf_type = et; tf_expr = mk (TReturn (Some ecall)) ct.tvoid p; } in ignore(make_fun ctx ("","") fid f None None); end; op ctx (OStaticClosure (r,fid)); | ANone | ALocal _ | AArray _ | ACaptured _ -> abort "Invalid access" e.epos); unsafe_cast_to ctx r (to_type ctx e.etype) e.epos | TObjectDecl fl -> (match to_type ctx e.etype with | HVirtual vp as t when Array.length vp.vfields = List.length fl && not (List.exists (fun (s,e) -> s = "toString" && is_to_string e.etype) fl) -> let r = alloc_tmp ctx t in op ctx (ONew r); hold ctx r; List.iter (fun (s,ev) -> let fidx = (try PMap.find s vp.vindex with Not_found -> assert false) in let _, _, ft = vp.vfields.(fidx) in let v = eval_to ctx ev ft in op ctx (OSetField (r,fidx,v)); ) fl; free ctx r; r | _ -> let r = alloc_tmp ctx HDynObj in op ctx (ONew r); hold ctx r; let a = (match follow e.etype with TAnon a -> Some a | t -> if t == t_dynamic then None else assert false) in List.iter (fun (s,ev) -> let ft = (try (match a with None -> raise Not_found | Some a -> PMap.find s a.a_fields).cf_type with Not_found -> ev.etype) in let v = eval_to ctx ev (to_type ctx ft) in op ctx (ODynSet (r,alloc_string ctx s,v)); if s = "toString" && is_to_string ev.etype then begin let f = alloc_tmp ctx (HFun ([],HBytes)) in op ctx (OInstanceClosure (f, alloc_fun_path ctx ([],"String") "call_toString", r)); op ctx (ODynSet (r,alloc_string ctx "__string",f)); end; ) fl; free ctx r; cast_to ctx r (to_type ctx e.etype) e.epos) | TNew (c,pl,el) -> let c = resolve_class ctx c pl false in let r = alloc_tmp ctx (class_type ctx c pl false) in op ctx (ONew r); hold ctx r; (match c.cl_constructor with | None -> if c.cl_implements <> [] then assert false | Some { cf_expr = None } -> abort (s_type_path c.cl_path ^ " does not have a constructor") e.epos | Some ({ cf_expr = Some cexpr } as constr) -> let rl = eval_args ctx el (to_type ctx cexpr.etype) e.epos in let ret = alloc_tmp ctx HVoid in let g = alloc_fid ctx c constr in op ctx (match rl with | [] -> OCall1 (ret,g,r) | [a] -> OCall2 (ret,g,r,a) | [a;b] -> OCall3 (ret,g,r,a,b) | [a;b;c] -> OCall4 (ret,g,r,a,b,c) | _ -> OCallN (ret,g,r :: rl)); ); free ctx r; r | TIf (cond,eif,eelse) -> let t = to_type ctx e.etype in let out = alloc_tmp ctx t in let j = jump_expr ctx cond false in if t = HVoid then ignore(eval_expr ctx eif) else op ctx (OMov (out,eval_to ctx eif t)); (match eelse with | None -> j() | Some e -> let jexit = jump ctx (fun i -> OJAlways i) in j(); if t = HVoid then ignore(eval_expr ctx e) else op ctx (OMov (out,eval_to ctx e t)); jexit()); out | TBinop (bop, e1, e2) -> let is_unsigned() = unsigned_op e1 e2 in let boolop r f = let j = jump ctx f in op ctx (OBool (r,false)); op ctx (OJAlways 1); j(); op ctx (OBool (r, true)); in let binop r a b = let rec loop bop = match bop with | OpLte -> boolop r (fun d -> if is_unsigned() then OJUGte (b,a,d) else OJSLte (a,b,d)) | OpGt -> boolop r (fun d -> if is_unsigned() then OJULt (b,a,d) else OJSGt (a,b,d)) | OpGte -> boolop r (fun d -> if is_unsigned() then OJUGte (a,b,d) else OJSGte (a,b,d)) | OpLt -> boolop r (fun d -> if is_unsigned() then OJULt (a,b,d) else OJSLt (a,b,d)) | OpEq -> boolop r (fun d -> OJEq (a,b,d)) | OpNotEq -> boolop r (fun d -> OJNotEq (a,b,d)) | OpAdd -> (match rtype ctx r with | HUI8 | HUI16 | HI32 | HF32 | HF64 -> op ctx (OAdd (r,a,b)) | HObj { pname = "String" } -> op ctx (OCall2 (r,alloc_fun_path ctx ([],"String") "__add__",a,b)) | HDyn -> op ctx (OCall2 (r,alloc_fun_path ctx ([],"Std") "__add__",a,b)) | t -> abort ("Cannot add " ^ tstr t) e.epos) | OpSub | OpMult | OpMod | OpDiv -> (match rtype ctx r with | HUI8 | HUI16 | HI32 | HF32 | HF64 -> (match bop with | OpSub -> op ctx (OSub (r,a,b)) | OpMult -> op ctx (OMul (r,a,b)) | OpMod -> op ctx (if unsigned e1.etype then OUMod (r,a,b) else OSMod (r,a,b)) | OpDiv -> op ctx (OSDiv (r,a,b)) (* don't use UDiv since both operands are float already *) | _ -> assert false) | _ -> assert false) | OpShl | OpShr | OpUShr | OpAnd | OpOr | OpXor -> (match rtype ctx r with | HUI8 | HUI16 | HI32 -> (match bop with | OpShl -> op ctx (OShl (r,a,b)) | OpShr -> op ctx (if unsigned e1.etype then OUShr (r,a,b) else OSShr (r,a,b)) | OpUShr -> op ctx (OUShr (r,a,b)) | OpAnd -> op ctx (OAnd (r,a,b)) | OpOr -> op ctx (OOr (r,a,b)) | OpXor -> op ctx (OXor (r,a,b)) | _ -> ()) | _ -> assert false) | OpAssignOp bop -> loop bop | _ -> assert false in loop bop in (match bop with | OpLte | OpGt | OpGte | OpLt -> let r = alloc_tmp ctx HBool in let t = common_type ctx e1 e2 false e.epos in let a = eval_to ctx e1 t in hold ctx a; let b = eval_to ctx e2 t in free ctx a; binop r a b; r | OpEq | OpNotEq -> let r = alloc_tmp ctx HBool in let t = common_type ctx e1 e2 true e.epos in let a = eval_to ctx e1 t in hold ctx a; let b = eval_to ctx e2 t in free ctx a; binop r a b; r | OpAdd | OpSub | OpMult | OpDiv | OpMod | OpShl | OpShr | OpUShr | OpAnd | OpOr | OpXor -> let t = (match to_type ctx e.etype with HNull t -> t | t -> t) in let r = alloc_tmp ctx t in let a = eval_to ctx e1 t in hold ctx a; let b = eval_to ctx e2 t in free ctx a; binop r a b; r | OpAssign -> let value() = eval_to ctx e2 (real_type ctx e1) in (match get_access ctx e1 with | AGlobal g -> let r = value() in op ctx (OSetGlobal (g,r)); r | AStaticVar (g,t,fid) -> let r = value() in hold ctx r; let o = alloc_tmp ctx t in free ctx r; op ctx (OGetGlobal (o, g)); op ctx (OSetField (o, fid, r)); r | AInstanceField ({ eexpr = TConst TThis }, fid) -> let r = value() in op ctx (OSetThis (fid,r)); r | AInstanceField (ethis, fid) -> let rthis = eval_null_check ctx ethis in hold ctx rthis; let r = value() in free ctx rthis; op ctx (OSetField (rthis, fid, r)); r | ALocal (v,l) -> let r = value() in op ctx (OMov (l, r)); add_assign ctx v l; r | AArray (ra,(at,vt),ridx) -> hold ctx ra; hold ctx ridx; let v = cast_to ctx (value()) (match at with HUI16 | HUI8 -> HI32 | _ -> at) e.epos in hold ctx v; (* bounds check against length *) (match at with | HDyn -> (* call setDyn() *) op ctx (OCallMethod (alloc_tmp ctx HVoid,1,[ra;ridx;cast_to ctx v (if is_dynamic at then at else HDyn) e.epos])); | _ -> let len = alloc_tmp ctx HI32 in op ctx (OField (len,ra,0)); (* length *) let j = jump ctx (fun i -> OJULt (ridx,len,i)) in op ctx (OCall2 (alloc_tmp ctx HVoid, alloc_fun_path ctx (array_class ctx at).cl_path "__expand", ra, ridx)); j(); match at with | HI32 | HF64 | HUI16 | HF32 -> let b = alloc_tmp ctx HBytes in op ctx (OField (b,ra,1)); write_mem ctx b (shl ctx ridx (type_size_bits at)) at v | _ -> let arr = alloc_tmp ctx HArray in op ctx (OField (arr,ra,1)); op ctx (OSetArray (arr,ridx,cast_to ctx v (if is_dynamic at then at else HDyn) e.epos)) ); free ctx v; free ctx ra; free ctx ridx; v | ADynamic (ethis,f) -> let obj = eval_null_check ctx ethis in hold ctx obj; let r = eval_expr ctx e2 in free ctx obj; op ctx (ODynSet (obj,f,r)); r | ACaptured index -> let r = value() in op ctx (OSetEnumField (ctx.m.mcaptreg,index,r)); r | AEnum _ | ANone | AInstanceFun _ | AInstanceProto _ | AStaticFun _ | AVirtualMethod _ -> assert false) | OpBoolOr -> let r = alloc_tmp ctx HBool in let j = jump_expr ctx e1 true in let j2 = jump_expr ctx e2 true in op ctx (OBool (r,false)); let jend = jump ctx (fun b -> OJAlways b) in j(); j2(); op ctx (OBool (r,true)); jend(); r | OpBoolAnd -> let r = alloc_tmp ctx HBool in let j = jump_expr ctx e1 false in let j2 = jump_expr ctx e2 false in op ctx (OBool (r,true)); let jend = jump ctx (fun b -> OJAlways b) in j(); j2(); op ctx (OBool (r,false)); jend(); r | OpAssignOp bop -> (match get_access ctx e1 with | ALocal (v,l) -> let r = eval_to ctx { e with eexpr = TBinop (bop,e1,e2) } (to_type ctx e1.etype) in op ctx (OMov (l, r)); add_assign ctx v l; r | acc -> gen_assign_op ctx acc e1 (fun r -> hold ctx r; let b = eval_to ctx e2 (rtype ctx r) in free ctx r; binop r r b; r)) | OpInterval | OpArrow -> assert false) | TUnop (Not,_,v) -> let tmp = alloc_tmp ctx HBool in let r = eval_to ctx v HBool in op ctx (ONot (tmp,r)); tmp | TUnop (Neg,_,v) -> let t = to_type ctx e.etype in let tmp = alloc_tmp ctx t in let r = eval_to ctx v t in op ctx (ONeg (tmp,r)); tmp | TUnop (NegBits,_,v) -> let t = to_type ctx e.etype in let tmp = alloc_tmp ctx t in let r = eval_to ctx v t in let mask = (match t with | HUI8 -> 0xFFl | HUI16 -> 0xFFFFl | HI32 -> 0xFFFFFFFFl | _ -> abort (tstr t) e.epos ) in hold ctx r; let r2 = alloc_tmp ctx t in free ctx r; op ctx (OInt (r2,alloc_i32 ctx mask)); op ctx (OXor (tmp,r,r2)); tmp | TUnop (Increment|Decrement as uop,fix,v) -> let rec unop r = match rtype ctx r with | HUI8 | HUI16 | HI32 -> if uop = Increment then op ctx (OIncr r) else op ctx (ODecr r) | HF32 | HF64 as t -> hold ctx r; let tmp = alloc_tmp ctx t in free ctx r; op ctx (OFloat (tmp,alloc_float ctx 1.)); if uop = Increment then op ctx (OAdd (r,r,tmp)) else op ctx (OSub (r,r,tmp)) | HNull (HUI8 | HUI16 | HI32 | HF32 | HF64 as t) -> hold ctx r; let tmp = alloc_tmp ctx t in free ctx r; op ctx (OSafeCast (tmp,r)); unop tmp; op ctx (OToDyn (r,tmp)); | _ -> assert false in (match get_access ctx v, fix with | ALocal (v,r), Prefix -> unop r; add_assign ctx v r; r | ALocal (v,r), Postfix -> let r2 = alloc_tmp ctx (rtype ctx r) in op ctx (OMov (r2,r)); unop r; add_assign ctx v r; r2 | acc, _ -> let ret = ref 0 in (match acc with AArray (a,_,idx) -> hold ctx a; hold ctx idx | _ -> ()); ignore(gen_assign_op ctx acc v (fun r -> if fix = Prefix then ret := r else begin hold ctx r; let tmp = alloc_tmp ctx (rtype ctx r) in free ctx r; op ctx (OMov (tmp, r)); ret := tmp; end; hold ctx !ret; unop r; r) ); free ctx !ret; (match acc with AArray (a,_,idx) -> free ctx a; free ctx idx | _ -> ()); !ret) | TFunction f -> let fid = alloc_function_name ctx ("function#" ^ string_of_int (DynArray.length ctx.cfids.arr)) in let capt = make_fun ctx ("","") fid f None (Some ctx.m.mcaptured) in let r = alloc_tmp ctx (to_type ctx e.etype) in if capt == ctx.m.mcaptured then op ctx (OInstanceClosure (r, fid, ctx.m.mcaptreg)) else (match Array.length capt.c_vars with | 0 -> op ctx (OStaticClosure (r, fid)) | 1 when not capt.c_group -> op ctx (OInstanceClosure (r, fid, eval_var ctx capt.c_vars.(0))) | _ -> let env = alloc_tmp ctx capt.c_type in op ctx (OEnumAlloc (env,0)); hold ctx env; Array.iteri (fun i v -> op ctx (OSetEnumField (env,i,eval_var ctx v))) capt.c_vars; free ctx env; op ctx (OInstanceClosure (r, fid, env))); r | TThrow v -> op ctx (OThrow (eval_to ctx v HDyn)); alloc_tmp ctx HDyn | TWhile (cond,eloop,NormalWhile) -> let oldb = ctx.m.mbreaks and oldc = ctx.m.mcontinues and oldtrys = ctx.m.mloop_trys in ctx.m.mbreaks <- []; ctx.m.mcontinues <- []; ctx.m.mloop_trys <- ctx.m.mtrys; let continue_pos = current_pos ctx in let ret = jump_back ctx in let j = jump_expr ctx cond false in ignore(eval_expr ctx eloop); ret(); j(); List.iter (fun f -> f (current_pos ctx)) ctx.m.mbreaks; List.iter (fun f -> f continue_pos) ctx.m.mcontinues; ctx.m.mbreaks <- oldb; ctx.m.mcontinues <- oldc; ctx.m.mloop_trys <- oldtrys; alloc_tmp ctx HVoid | TWhile (cond,eloop,DoWhile) -> let oldb = ctx.m.mbreaks and oldc = ctx.m.mcontinues and oldtrys = ctx.m.mloop_trys in ctx.m.mbreaks <- []; ctx.m.mcontinues <- []; ctx.m.mloop_trys <- ctx.m.mtrys; let start = jump ctx (fun p -> OJAlways p) in let continue_pos = current_pos ctx in let ret = jump_back ctx in let j = jump_expr ctx cond false in start(); ignore(eval_expr ctx eloop); ret(); j(); List.iter (fun f -> f (current_pos ctx)) ctx.m.mbreaks; List.iter (fun f -> f continue_pos) ctx.m.mcontinues; ctx.m.mbreaks <- oldb; ctx.m.mcontinues <- oldc; ctx.m.mloop_trys <- oldtrys; alloc_tmp ctx HVoid | TCast (v,None) -> let t = to_type ctx e.etype in let rv = eval_expr ctx v in (match t with | HF32 | HF64 when unsigned v.etype -> let r = alloc_tmp ctx t in op ctx (OToUFloat (r,rv)); r | HDyn when (match rtype ctx rv with HFun _ -> true | _ -> false) -> (* if called, a HDyn method will return HDyn, not its usual return type *) let r = alloc_tmp ctx t in op ctx (OMov (r,rv)); r | _ -> cast_to ~force:true ctx rv t e.epos) | TArrayDecl el -> let r = alloc_tmp ctx (to_type ctx e.etype) in let et = (match follow e.etype with TInst (_,[t]) -> to_type ctx t | _ -> assert false) in let array_bytes bits t tname get_op = let b = alloc_tmp ctx HBytes in let size = reg_int ctx ((List.length el) lsl bits) in op ctx (OCall1 (b,alloc_std ctx "alloc_bytes" [HI32] HBytes,size)); let idx = reg_int ctx 0 in hold ctx idx; hold ctx b; list_iteri (fun i e -> let r = eval_to ctx e t in hold ctx r; op ctx (get_op b (shl ctx idx bits) r); free ctx r; op ctx (OIncr idx); ) el; free ctx b; free ctx idx; op ctx (OCall2 (r, alloc_fun_path ctx (["hl";"types"],"ArrayBase") ("alloc" ^ tname), b, reg_int ctx (List.length el))); in (match et with | HI32 -> array_bytes 2 HI32 "I32" (fun b i r -> OSetI32 (b,i,r)) | HUI16 -> array_bytes 1 HI32 "UI16" (fun b i r -> OSetUI16 (b,i,r)) | HF32 -> array_bytes 2 HF32 "F32" (fun b i r -> OSetF32 (b,i,r)) | HF64 -> array_bytes 3 HF64 "F64" (fun b i r -> OSetF64 (b,i,r)) | _ -> let at = if is_dynamic et then et else HDyn in let a = alloc_tmp ctx HArray in let rt = alloc_tmp ctx HType in op ctx (OType (rt,at)); let size = reg_int ctx (List.length el) in op ctx (OCall2 (a,alloc_std ctx "alloc_array" [HType;HI32] HArray,rt,size)); hold ctx a; list_iteri (fun i e -> let r = eval_to ctx e at in op ctx (OSetArray (a,reg_int ctx i,r)); ) el; free ctx a; let tmp = if et = HDyn then alloc_tmp ctx (class_type ctx ctx.array_impl.aobj [] false) else r in op ctx (OCall1 (tmp, alloc_fun_path ctx (["hl";"types"],"ArrayObj") "alloc", a)); if tmp <> r then begin let re = alloc_tmp ctx HBool in op ctx (OBool (re,true)); let ren = alloc_tmp ctx (HRef HBool) in op ctx (ORef (ren, re)); op ctx (OCall2 (r, alloc_fun_path ctx (["hl";"types"],"ArrayDyn") "alloc", tmp, ren)); end; ); r | TArray _ -> (match get_access ctx e with | AArray (a,at,idx) -> array_read ctx a at idx e.epos | _ -> assert false) | TMeta (_,e) -> eval_expr ctx e | TFor (v,it,loop) -> eval_expr ctx (Codegen.for_remap ctx.com v it loop e.epos) | TSwitch (en,cases,def) -> let rt = to_type ctx e.etype in let r = alloc_tmp ctx rt in (try let max = ref (-1) in let rec get_int e = match e.eexpr with | TConst (TInt i) -> let v = Int32.to_int i in if Int32.of_int v <> i then raise Exit; v | _ -> raise Exit in List.iter (fun (values,_) -> List.iter (fun v -> let i = get_int v in if i < 0 then raise Exit; if i > !max then max := i; ) values; ) cases; if !max > 255 || cases = [] then raise Exit; let ridx = eval_to ctx en HI32 in let indexes = Array.make (!max + 1) 0 in op ctx (OSwitch (ridx,indexes,0)); let switch_pos = current_pos ctx in (match def with | None -> if rt <> HVoid then set_default ctx r; | Some e -> let re = eval_to ctx e rt in if rt <> HVoid then op ctx (OMov (r,re))); let jends = ref [jump ctx (fun i -> OJAlways i)] in List.iter (fun (values,ecase) -> List.iter (fun v -> Array.set indexes (get_int v) (current_pos ctx - switch_pos) ) values; let re = eval_to ctx ecase rt in if rt <> HVoid then op ctx (OMov (r,re)); jends := jump ctx (fun i -> OJAlways i) :: !jends ) cases; DynArray.set ctx.m.mops (switch_pos - 1) (OSwitch (ridx,indexes,current_pos ctx - switch_pos)); List.iter (fun j -> j()) (!jends); with Exit -> let jends = ref [] in let rvalue = eval_expr ctx en in let loop (cases,e) = let ok = List.map (fun c -> hold ctx rvalue; let r = eval_to ctx c (common_type ctx en c true c.epos) in free ctx rvalue; jump ctx (fun n -> OJEq (r,rvalue,n)) ) cases in (fun() -> List.iter (fun f -> f()) ok; let re = eval_to ctx e rt in if rt <> HVoid then op ctx (OMov (r,re)); jends := jump ctx (fun n -> OJAlways n) :: !jends) in let all = List.map loop cases in (match def with | None -> if rt <> HVoid then op ctx (ONull r) | Some e -> let rdef = eval_to ctx e rt in if rt <> HVoid then op ctx (OMov (r,rdef))); jends := jump ctx (fun n -> OJAlways n) :: !jends; List.iter (fun f -> f()) all; List.iter (fun j -> j()) (!jends); ); r | TEnumParameter (ec,f,index) -> let r = alloc_tmp ctx (match to_type ctx ec.etype with HEnum e -> let _,_,args = e.efields.(f.ef_index) in args.(index) | _ -> assert false) in op ctx (OEnumField (r,eval_expr ctx ec,f.ef_index,index)); cast_to ctx r (to_type ctx e.etype) e.epos | TContinue -> before_break_continue ctx; let pos = current_pos ctx in op ctx (OJAlways (-1)); (* loop *) ctx.m.mcontinues <- (fun target -> DynArray.set ctx.m.mops pos (OJAlways (target - (pos + 1)))) :: ctx.m.mcontinues; alloc_tmp ctx HVoid | TBreak -> before_break_continue ctx; let pos = current_pos ctx in op ctx (OJAlways (-1)); (* loop *) ctx.m.mbreaks <- (fun target -> DynArray.set ctx.m.mops pos (OJAlways (target - (pos + 1)))) :: ctx.m.mbreaks; alloc_tmp ctx HVoid | TTry (etry,catches) -> let pos = current_pos ctx in let rtrap = alloc_tmp ctx HDyn in op ctx (OTrap (rtrap,-1)); (* loop *) ctx.m.mtrys <- ctx.m.mtrys + 1; let tret = to_type ctx e.etype in let result = alloc_tmp ctx tret in let r = eval_expr ctx etry in if tret <> HVoid then op ctx (OMov (result,cast_to ctx r tret etry.epos)); ctx.m.mtrys <- ctx.m.mtrys - 1; op ctx (OEndTrap true); let j = jump ctx (fun n -> OJAlways n) in DynArray.set ctx.m.mops pos (OTrap (rtrap, current_pos ctx - (pos + 1))); let rec loop l = match l with | [] -> op ctx (ORethrow rtrap); [] | (v,ec) :: next -> let rv = alloc_var ctx v true in let jnext = if v.v_type == t_dynamic then begin op ctx (OMov (rv, rtrap)); (fun() -> ()) end else let ct = (match follow v.v_type with | TInst (c,_) -> TClassDecl c | TAbstract (a,_) -> TAbstractDecl a | TEnum (e,_) -> TEnumDecl e | _ -> assert false ) in hold ctx rtrap; let r = type_value ctx ct ec.epos in free ctx rtrap; let rb = alloc_tmp ctx HBool in op ctx (OCall2 (rb, alloc_fun_path ctx (["hl"],"BaseType") "check",r,rtrap)); let jnext = jump ctx (fun n -> OJFalse (rb,n)) in op ctx (OMov (rv, unsafe_cast_to ctx rtrap (to_type ctx v.v_type) ec.epos)); jnext in let r = eval_expr ctx ec in if tret <> HVoid then op ctx (OMov (result,cast_to ctx r tret ec.epos)); if v.v_type == t_dynamic then [] else let jend = jump ctx (fun n -> OJAlways n) in jnext(); jend :: loop next in List.iter (fun j -> j()) (loop catches); j(); result | TTypeExpr t -> type_value ctx t e.epos | TCast (ev,Some _) -> let t = to_type ctx e.etype in let re = eval_expr ctx ev in let r = alloc_tmp ctx t in if safe_cast (rtype ctx re) t then op ctx (OMov (r,re)) else op ctx (OSafeCast (r,re)); r and gen_assign_op ctx acc e1 f = let f r = match rtype ctx r with | HNull t -> let r2 = alloc_tmp ctx t in op ctx (OSafeCast (r2,r)); let r3 = alloc_tmp ctx (HNull t) in op ctx (OToDyn (r3,f r2)); r3 | _ -> f r in match acc with | AInstanceField (eobj, findex) -> let robj = eval_null_check ctx eobj in hold ctx robj; let t = real_type ctx e1 in let r = alloc_tmp ctx t in op ctx (OField (r,robj,findex)); let r = cast_to ctx r (to_type ctx e1.etype) e1.epos in let r = f r in free ctx robj; op ctx (OSetField (robj,findex,cast_to ctx r t e1.epos)); r | AStaticVar (g,t,fid) -> let o = alloc_tmp ctx t in op ctx (OGetGlobal (o,g)); let r = alloc_tmp ctx (to_type ctx e1.etype) in op ctx (OField (r,o,fid)); hold ctx o; let r = f r in free ctx o; op ctx (OSetField (o,fid,r)); r | AGlobal g -> let r = alloc_tmp ctx (to_type ctx e1.etype) in op ctx (OGetGlobal (r,g)); let r = f r in op ctx (OSetGlobal (g,r)); r | ACaptured idx -> let r = alloc_tmp ctx (to_type ctx e1.etype) in op ctx (OEnumField (r, ctx.m.mcaptreg, 0, idx)); let r = f r in op ctx (OSetEnumField (ctx.m.mcaptreg,idx,r)); r | AArray (ra,(at,_),ridx) -> hold ctx ra; hold ctx ridx; let r = (match at with | HDyn -> (* call getDyn() *) let r = alloc_tmp ctx HDyn in op ctx (OCallMethod (r,0,[ra;ridx])); let r = f r in (* call setDyn() *) op ctx (OCallMethod (alloc_tmp ctx HVoid,1,[ra;ridx;r])); r | _ -> (* bounds check against length *) let len = alloc_tmp ctx HI32 in op ctx (OField (len,ra,0)); (* length *) let j = jump ctx (fun i -> OJULt (ridx,len,i)) in op ctx (OCall2 (alloc_tmp ctx HVoid, alloc_fun_path ctx (array_class ctx at).cl_path "__expand", ra, ridx)); j(); match at with | HUI8 | HUI16 | HI32 | HF32 | HF64 -> let hbytes = alloc_tmp ctx HBytes in op ctx (OField (hbytes, ra, 1)); let ridx = shl ctx ridx (type_size_bits at) in hold ctx ridx; hold ctx hbytes; let r = alloc_tmp ctx at in read_mem ctx r hbytes ridx at; let r = f r in write_mem ctx hbytes ridx at r; free ctx ridx; free ctx hbytes; r | _ -> let arr = alloc_tmp ctx HArray in op ctx (OField (arr,ra,1)); let r = alloc_tmp ctx at in op ctx (OGetArray (r,arr,ridx)); hold ctx arr; let r = f r in free ctx arr; op ctx (OSetArray (arr,ridx,r)); r ) in free ctx ra; free ctx ridx; r | ADynamic (eobj, fid) -> let robj = eval_null_check ctx eobj in let t = real_type ctx e1 in let r = alloc_tmp ctx t in op ctx (ODynGet (r,robj,fid)); hold ctx robj; let r = cast_to ctx r (to_type ctx e1.etype) e1.epos in let r = f r in free ctx robj; op ctx (ODynSet (robj,fid,cast_to ctx r t e1.epos)); r | ANone | ALocal _ | AStaticFun _ | AInstanceFun _ | AInstanceProto _ | AVirtualMethod _ | AEnum _ -> assert false and build_capture_vars ctx f = let ignored_vars = ref PMap.empty in let used_vars = ref PMap.empty in (* get all captured vars in scope, ignore vars that are declared *) let decl_var v = if v.v_capture then ignored_vars := PMap.add v.v_id () !ignored_vars in let use_var v = if v.v_capture then used_vars := PMap.add v.v_id v !used_vars in let rec loop e = (match e.eexpr with | TLocal v -> use_var v; | TVar (v,_) -> decl_var v | TTry (_,catches) -> List.iter (fun (v,_) -> decl_var v) catches | TFunction f -> List.iter (fun (v,_) -> decl_var v) f.tf_args; | _ -> () ); Type.iter loop e in List.iter (fun (v,_) -> decl_var v) f.tf_args; loop f.tf_expr; let cvars = Array.of_list (PMap.fold (fun v acc -> if PMap.mem v.v_id !ignored_vars then acc else v :: acc) !used_vars []) in Array.sort (fun v1 v2 -> v1.v_id - v2.v_id) cvars; let indexes = ref PMap.empty in let v0t = (if Array.length cvars = 1 then to_type ctx cvars.(0).v_type else HDyn) in let ct, group = (match Array.length cvars with | 0 -> HVoid, false | 1 when is_nullable v0t -> v0t, false | _ -> Array.iteri (fun i v -> indexes := PMap.add v.v_id i !indexes) cvars; let ctypes = Array.map (fun v -> to_type ctx v.v_type) cvars in let ct = tuple_type ctx (Array.to_list ctypes) in ct, true ) in { c_map = !indexes; c_vars = cvars; c_type = ct; c_group = group; } and gen_method_wrapper ctx rt t p = try PMap.find (rt,t) ctx.method_wrappers with Not_found -> let fid = lookup_alloc ctx.cfids () in ctx.method_wrappers <- PMap.add (rt,t) fid ctx.method_wrappers; let old = ctx.m in let targs, tret = (match t with HFun (args, ret) -> args, ret | _ -> assert false) in let iargs, iret = (match rt with HFun (args, ret) -> args, ret | _ -> assert false) in ctx.m <- method_context fid HDyn null_capture false; let rfun = alloc_tmp ctx rt in let rargs = List.map (fun t -> let r = alloc_tmp ctx t in hold ctx r; r ) targs in let casts = List.map2 (fun r t -> let r2 = cast_to ctx r t p in hold ctx r2; free ctx r; r2) rargs iargs in List.iter (free ctx) casts; let rret = alloc_tmp ctx iret in op ctx (OCallClosure (rret,rfun,casts)); op ctx (ORet (cast_to ctx rret tret p)); let f = { fpath = "",""; findex = fid; ftype = HFun (rt :: targs, tret); regs = DynArray.to_array ctx.m.mregs.arr; code = DynArray.to_array ctx.m.mops; debug = make_debug ctx ctx.m.mdebug; } in ctx.m <- old; DynArray.add ctx.cfunctions f; DynArray.add ctx.cdebug_assigns [||]; fid and make_fun ?gen_content ctx name fidx f cthis cparent = let old = ctx.m in let capt = build_capture_vars ctx f in let has_captured_vars = Array.length capt.c_vars > 0 in let capt, use_parent_capture = (match cparent with | Some cparent when has_captured_vars && List.for_all (fun v -> PMap.mem v.v_id cparent.c_map) (Array.to_list capt.c_vars) -> cparent, true | _ -> capt, false ) in ctx.m <- method_context fidx (to_type ctx f.tf_type) capt (cthis <> None); set_curpos ctx f.tf_expr.epos; let tthis = (match cthis with | None -> None | Some c -> let t = to_type ctx (TInst (c,[])) in hold ctx (alloc_tmp ctx t); (* index 0 *) Some t ) in let rcapt = match has_captured_vars && cparent <> None with | true when capt.c_group -> let r = alloc_tmp ctx capt.c_type in hold ctx r; Some r | true -> Some (alloc_var ctx capt.c_vars.(0) true) | false -> None in let args = List.map (fun (v,o) -> let t = to_type ctx v.v_type in let r = alloc_var ctx (if o = None then v else { v with v_type = if not (is_nullable t) then TAbstract(ctx.ref_abstract,[v.v_type]) else v.v_type }) true in add_assign ctx v r; rtype ctx r ) f.tf_args in if has_captured_vars then ctx.m.mcaptreg <- (match rcapt with | None when not capt.c_group -> -1 | None -> let r = alloc_tmp ctx capt.c_type in hold ctx r; op ctx (OEnumAlloc (r,0)); add_capture ctx r; r | Some r -> add_capture ctx r; r ); List.iter (fun (v, o) -> let r = alloc_var ctx v false in let vt = to_type ctx v.v_type in let capt = captured_index ctx v in (match o with | None | Some TNull -> () | Some c when not (is_nullable vt) -> (* if optional but not null, turn into a not nullable here *) let j = jump ctx (fun n -> OJNotNull (r,n)) in let t = alloc_tmp ctx vt in (match vt with | HUI8 | HUI16 | HI32 -> (match c with | TInt i -> op ctx (OInt (t,alloc_i32 ctx i)) | TFloat s -> op ctx (OInt (t,alloc_i32 ctx (Int32.of_float (float_of_string s)))) | _ -> assert false) | HF32 | HF64 -> (match c with | TInt i -> op ctx (OFloat (t,alloc_float ctx (Int32.to_float i))) | TFloat s -> op ctx (OFloat (t,alloc_float ctx (float_of_string s))) | _ -> assert false) | HBool -> (match c with | TBool b -> op ctx (OBool (t,b)) | _ -> assert false) | _ -> assert false); if capt = None then add_assign ctx v t; let jend = jump ctx (fun n -> OJAlways n) in j(); op ctx (OUnref (t,r)); if capt = None then add_assign ctx v t; jend(); Hashtbl.replace ctx.m.mvars v.v_id t; free ctx r; hold ctx t | Some c -> let j = jump ctx (fun n -> OJNotNull (r,n)) in (match c with | TNull | TThis | TSuper -> assert false | TInt i when (match to_type ctx (follow v.v_type) with HUI8 | HUI16 | HI32 | HDyn -> true | _ -> false) -> let tmp = alloc_tmp ctx HI32 in op ctx (OInt (tmp, alloc_i32 ctx i)); op ctx (OToDyn (r, tmp)); | TFloat s when (match to_type ctx (follow v.v_type) with HUI8 | HUI16 | HI32 -> true | _ -> false) -> let tmp = alloc_tmp ctx HI32 in op ctx (OInt (tmp, alloc_i32 ctx (Int32.of_float (float_of_string s)))); op ctx (OToDyn (r, tmp)); | TInt i -> let tmp = alloc_tmp ctx HF64 in op ctx (OFloat (tmp, alloc_float ctx (Int32.to_float i))); op ctx (OToDyn (r, tmp)); | TFloat s -> let tmp = alloc_tmp ctx HF64 in op ctx (OFloat (tmp, alloc_float ctx (float_of_string s))); op ctx (OToDyn (r, tmp)); | TBool b -> let tmp = alloc_tmp ctx HBool in op ctx (OBool (tmp, b)); op ctx (OToDyn (r, tmp)); | TString s -> op ctx (OMov (r, make_string ctx s f.tf_expr.epos)) ); if capt = None then add_assign ctx v r; j(); ); (match capt with | None -> () | Some index -> op ctx (OSetEnumField (ctx.m.mcaptreg, index, alloc_var ctx v false))); ) f.tf_args; (match gen_content with | None -> () | Some f -> f()); ignore(eval_expr ctx f.tf_expr); let tret = to_type ctx f.tf_type in let rec has_final_jump e = (* prevents a jump outside function bounds error *) match e.eexpr with | TBlock el -> (match List.rev el with e :: _ -> has_final_jump e | [] -> false) | TParenthesis e -> has_final_jump e | TReturn _ -> false | _ -> true in if tret = HVoid then op ctx (ORet (alloc_tmp ctx HVoid)) else if has_final_jump f.tf_expr then begin let r = alloc_tmp ctx tret in (match tret with | HI32 | HUI8 | HUI16 -> op ctx (OInt (r,alloc_i32 ctx 0l)) | HF32 | HF64 -> op ctx (OFloat (r,alloc_float ctx 0.)) | HBool -> op ctx (OBool (r,false)) | _ -> op ctx (ONull r)); op ctx (ORet r) end; let fargs = (match tthis with None -> [] | Some t -> [t]) @ (match rcapt with None -> [] | Some r -> [rtype ctx r]) @ args in let f = { fpath = name; findex = fidx; ftype = HFun (fargs, tret); regs = DynArray.to_array ctx.m.mregs.arr; code = DynArray.to_array ctx.m.mops; debug = make_debug ctx ctx.m.mdebug; } in let assigns = Array.of_list (List.rev ctx.m.massign) in ctx.m <- old; Hashtbl.add ctx.defined_funs fidx (); let f = if ctx.optimize then Hlopt.optimize ctx.dump_out f else f in DynArray.add ctx.cfunctions f; DynArray.add ctx.cdebug_assigns assigns; capt let generate_static ctx c f = match f.cf_kind with | Var _ -> () | Method _ when Meta.has Meta.Extern f.cf_meta -> () | Method m -> let add_native lib name = ignore(lookup ctx.cnatives (name ^ "@" ^ lib) (fun() -> let fid = alloc_fid ctx c f in Hashtbl.add ctx.defined_funs fid (); (alloc_string ctx lib, alloc_string ctx name,to_type ctx f.cf_type,fid) )); in let rec loop = function | (Meta.Custom ":hlNative",[(EConst(String(lib)),_);(EConst(String(name)),_)] ,_ ) :: _ -> add_native lib name | (Meta.Custom ":hlNative",[(EConst(String(lib)),_)] ,_ ) :: _ -> add_native lib f.cf_name | (Meta.Custom ":hlNative",[] ,_ ) :: _ -> add_native "std" f.cf_name | (Meta.Custom ":hlNative",_ ,p) :: _ -> abort "Invalid @:hlNative decl" p | [] -> ignore(make_fun ctx (s_type_path c.cl_path,f.cf_name) (alloc_fid ctx c f) (match f.cf_expr with Some { eexpr = TFunction f } -> f | _ -> abort "Missing function body" f.cf_pos) None None) | _ :: l -> loop l in loop f.cf_meta let rec generate_member ctx c f = match f.cf_kind with | Var _ -> () | _ when is_extern_field f -> () | Method m -> let gen_content = if f.cf_name <> "new" then None else Some (fun() -> let o = (match class_type ctx c (List.map snd c.cl_params) false with | HObj o -> o | _ -> assert false ) in (* init dynamic functions *) List.iter (fun f -> match f.cf_kind with | Method MethDynamic -> let r = alloc_tmp ctx (to_type ctx f.cf_type) in let fid = (try fst (get_index f.cf_name o) with Not_found -> assert false) in op ctx (OGetThis (r,fid)); op ctx (OJNotNull (r,2)); op ctx (OInstanceClosure (r,alloc_fid ctx c f,0)); op ctx (OSetThis (fid,r)); | _ -> () ) c.cl_ordered_fields; ) in ignore(make_fun ?gen_content ctx (s_type_path c.cl_path,f.cf_name) (alloc_fid ctx c f) (match f.cf_expr with Some { eexpr = TFunction f } -> f | _ -> abort "Missing function body" f.cf_pos) (Some c) None); if f.cf_name = "toString" && not (List.memq f c.cl_overrides) && not (PMap.mem "__string" c.cl_fields) && is_to_string f.cf_type then begin let p = f.cf_pos in (* function __string() return this.toString().bytes *) let ethis = mk (TConst TThis) (TInst (c,List.map snd c.cl_params)) p in let tstr = mk (TCall (mk (TField (ethis,FInstance(c,List.map snd c.cl_params,f))) f.cf_type p,[])) ctx.com.basic.tstring p in let cstr, cf_bytes = (try (match ctx.com.basic.tstring with TInst(c,_) -> c, PMap.find "bytes" c.cl_fields | _ -> assert false) with Not_found -> assert false) in let estr = mk (TReturn (Some (mk (TField (tstr,FInstance (cstr,[],cf_bytes))) cf_bytes.cf_type p))) ctx.com.basic.tvoid p in ignore(make_fun ctx (s_type_path c.cl_path,"__string") (alloc_fun_path ctx c.cl_path "__string") { tf_expr = estr; tf_args = []; tf_type = cf_bytes.cf_type; } (Some c) None) end let generate_type ctx t = match t with | TClassDecl { cl_interface = true }-> () | TClassDecl c when c.cl_extern -> List.iter (fun f -> List.iter (fun (name,args,pos) -> match name with | Meta.Custom ":hlNative" -> generate_static ctx c f | _ -> () ) f.cf_meta ) c.cl_ordered_statics | TClassDecl c -> List.iter (generate_static ctx c) c.cl_ordered_statics; (match c.cl_constructor with | None -> () | Some f -> generate_member ctx c f); List.iter (generate_member ctx c) c.cl_ordered_fields; | TEnumDecl _ | TTypeDecl _ | TAbstractDecl _ -> () let generate_static_init ctx types main = let exprs = ref [] in let t_void = ctx.com.basic.tvoid in let gen_content() = op ctx (OCall0 (alloc_tmp ctx HVoid, alloc_fun_path ctx ([],"Type") "init")); (* init class values *) List.iter (fun t -> match t with | TClassDecl c when not c.cl_extern && not (is_array_class (s_type_path c.cl_path) && snd c.cl_path <> "ArrayDyn") && c != ctx.core_type && c != ctx.core_enum -> let path = if c == ctx.array_impl.abase then [],"Array" else if c == ctx.base_class then [],"Class" else c.cl_path in let g, ct = class_global ~resolve:false ctx c in let ctype = if c == ctx.array_impl.abase then ctx.array_impl.aall else c in let t = class_type ctx ctype (List.map snd ctype.cl_params) false in let index name = match ct with | HObj o -> fst (try get_index name o with Not_found -> assert false) | _ -> assert false in let rc = (match t with | HObj o when (match o.pclassglobal with None -> -1 | Some i -> i) <> g -> (* manual registration for objects with prototype tricks (Array) *) let rc = alloc_tmp ctx ct in op ctx (ONew rc); op ctx (OSetGlobal (g,rc)); hold ctx rc; let rt = alloc_tmp ctx HType in op ctx (OType (rt, t)); op ctx (OSetField (rc,index "__type__",rt)); op ctx (OSetField (rc,index "__name__",eval_expr ctx { eexpr = TConst (TString (s_type_path path)); epos = c.cl_pos; etype = ctx.com.basic.tstring })); let rname = alloc_tmp ctx HBytes in op ctx (OString (rname, alloc_string ctx (s_type_path path))); op ctx (OCall2 (alloc_tmp ctx HVoid, alloc_fun_path ctx ([],"Type") "register",rname,rc)); rc | _ -> let rct = alloc_tmp ctx HType in op ctx (OType (rct, ct)); hold ctx rct; let rt = alloc_tmp ctx HType in op ctx (OType (rt, t)); let rname = alloc_tmp ctx HBytes in op ctx (OString (rname, alloc_string ctx (s_type_path path))); let rc = alloc_tmp ctx (class_type ctx ctx.base_class [] false) in op ctx (OCall3 (rc, alloc_fun_path ctx ([],"Type") "initClass", rct, rt, rname)); hold ctx rc; free ctx rct; rc ) in let gather_implements() = let classes = ref [] in let rec lookup cv = List.exists (fun (i,_) -> i == c || lookup i) cv.cl_implements in let check = function | TClassDecl c when c.cl_interface = false && not c.cl_extern -> if lookup c then classes := c :: !classes | _ -> () in List.iter check ctx.com.types; !classes in if c.cl_interface then begin let l = gather_implements() in let ra = alloc_tmp ctx HArray in let rt = alloc_tmp ctx HType in op ctx (OType (rt, HType)); op ctx (OCall2 (ra, alloc_std ctx "alloc_array" [HType;HI32] HArray, rt, reg_int ctx (List.length l))); list_iteri (fun i intf -> op ctx (OType (rt, to_type ctx (TInst (intf,[])))); op ctx (OSetArray (ra, reg_int ctx i, rt)); ) l; op ctx (OSetField (rc,index "__implementedBy__",ra)); (* TODO : use a plain class for interface object since we don't allow statics *) let rt = alloc_tmp ctx ct in op ctx (OSafeCast (rt, rc)); op ctx (OSetGlobal (g, rt)); end; (match Codegen.build_metadata ctx.com (TClassDecl c) with | None -> () | Some e -> let r = eval_to ctx e HDyn in op ctx (OSetField (rc,index "__meta__",r))); free ctx rc; | TEnumDecl e when not e.e_extern -> let et = enum_class ctx e in let t = enum_type ctx e in let ret = alloc_tmp ctx HType in op ctx (OType (ret, et)); hold ctx ret; let rt = alloc_tmp ctx HType in op ctx (OType (rt, t)); let r = alloc_tmp ctx (class_type ctx ctx.base_enum [] false) in op ctx (OCall2 (r, alloc_fun_path ctx ([],"Type") "initEnum", ret, rt)); free ctx ret; let index name = match et with | HObj o -> fst (try get_index name o with Not_found -> assert false) | _ -> assert false in let avalues = alloc_tmp ctx HArray in op ctx (OField (avalues, r, index "__evalues__")); List.iter (fun n -> let f = PMap.find n e.e_constrs in match follow f.ef_type with | TFun _ -> () | _ -> let g = alloc_global ctx (efield_name e f) t in let r = alloc_tmp ctx t in let rd = alloc_tmp ctx HDyn in op ctx (OGetArray (rd,avalues, reg_int ctx f.ef_index)); op ctx (OSafeCast (r, rd)); op ctx (OSetGlobal (g,r)); ) e.e_names; (match Codegen.build_metadata ctx.com (TEnumDecl e) with | None -> () | Some e -> op ctx (OSetField (r,index "__meta__",eval_to ctx e HDyn))); | TAbstractDecl { a_path = [], name; a_pos = pos } -> (match name with | "Int" | "Float" | "Dynamic" | "Bool" -> let is_bool = name = "Bool" in let t = class_type ctx (if is_bool then ctx.core_enum else ctx.core_type) [] false in let index name = match t with | HObj o -> fst (try get_index name o with Not_found -> assert false) | _ -> assert false in let g = alloc_global ctx ("$" ^ name) t in let r = alloc_tmp ctx t in let rt = alloc_tmp ctx HType in op ctx (ONew r); op ctx (OType (rt,(match name with "Int" -> HI32 | "Float" -> HF64 | "Dynamic" -> HDyn | "Bool" -> HBool | _ -> assert false))); op ctx (OSetField (r,index "__type__",rt)); op ctx (OSetField (r,index (if is_bool then "__ename__" else "__name__"),make_string ctx name pos)); op ctx (OSetGlobal (g,r)); let bytes = alloc_tmp ctx HBytes in op ctx (OString (bytes, alloc_string ctx name)); op ctx (OCall2 (alloc_tmp ctx HVoid, alloc_fun_path ctx ([],"Type") "register",bytes,r)); | _ -> ()) | _ -> () ) types; in (* init class statics *) List.iter (fun t -> match t with | TClassDecl c when not c.cl_extern -> (match c.cl_init with None -> () | Some e -> exprs := e :: !exprs); List.iter (fun f -> match f.cf_kind, f.cf_expr with | Var _, Some e -> let p = e.epos in let e = mk (TBinop (OpAssign,(mk (TField (mk (TTypeExpr t) t_dynamic p,FStatic (c,f))) f.cf_type p), e)) f.cf_type p in exprs := e :: !exprs; | _ -> () ) c.cl_ordered_statics; | _ -> () ) types; (* call main() *) (match main with | None -> () | Some e -> exprs := e :: !exprs); let fid = lookup_alloc ctx.cfids () in ignore(make_fun ~gen_content ctx ("","") fid { tf_expr = mk (TBlock (List.rev !exprs)) t_void null_pos; tf_args = []; tf_type = t_void } None None); fid (* --------------------------------------------------------------------------------------------------------------------- *) (* WRITE *) (* from -500M to +500M 0[7] = 0-127 10[+/-][5] [8] = -x2000/+x2000 11[+/-][5] [24] = -x20000000/+x20000000 *) let write_index_gen b i = if i < 0 then let i = -i in if i < 0x2000 then begin b ((i lsr 8) lor 0xA0); b (i land 0xFF); end else if i >= 0x20000000 then assert false else begin b ((i lsr 24) lor 0xE0); b ((i lsr 16) land 0xFF); b ((i lsr 8) land 0xFF); b (i land 0xFF); end else if i < 0x80 then b i else if i < 0x2000 then begin b ((i lsr 8) lor 0x80); b (i land 0xFF); end else if i >= 0x20000000 then assert false else begin b ((i lsr 24) lor 0xC0); b ((i lsr 16) land 0xFF); b ((i lsr 8) land 0xFF); b (i land 0xFF); end let write_code ch code debug = let all_types, htypes = gather_types code in let byte = IO.write_byte ch in let write_index = write_index_gen byte in let rec write_type t = write_index (try PMap.find t htypes with Not_found -> assert false) in let write_op op = let o = Obj.repr op in let oid = Obj.tag o in match op with | OLabel _ | ONop _ -> byte oid | OCall2 (r,g,a,b) -> byte oid; write_index r; write_index g; write_index a; write_index b; | OCall3 (r,g,a,b,c) -> byte oid; write_index r; write_index g; write_index a; write_index b; write_index c; | OCall4 (r,g,a,b,c,d) -> byte oid; write_index r; write_index g; write_index a; write_index b; write_index c; write_index d; | OCallN (r,f,rl) | OCallClosure (r,f,rl) | OCallMethod (r,f,rl) | OCallThis (r,f,rl) | OMakeEnum (r,f,rl) -> byte oid; write_index r; write_index f; let n = List.length rl in if n > 0xFF then assert false; byte n; List.iter write_index rl | OType (r,t) -> byte oid; write_index r; write_type t | OSwitch (r,pl,eend) -> byte oid; write_index r; write_index (Array.length pl); Array.iter write_index pl; write_index eend | OEnumField (r,e,i,idx) -> byte oid; write_index r; write_index e; write_index i; write_index idx; | _ -> let field n = (Obj.magic (Obj.field o n) : int) in match Obj.size o with | 1 -> let a = field 0 in byte oid; write_index a; | 2 -> let a = field 0 in let b = field 1 in byte oid; write_index a; write_index b; | 3 -> let a = field 0 in let b = field 1 in let c = field 2 in byte oid; write_index a; write_index b; write_index c; | _ -> assert false in IO.nwrite ch "HLB"; byte code.version; let flags = ref 0 in if debug then flags := !flags lor 1; byte !flags; write_index (Array.length code.ints); write_index (Array.length code.floats); write_index (Array.length code.strings); write_index (Array.length all_types); write_index (Array.length code.globals); write_index (Array.length code.natives); write_index (Array.length code.functions); write_index code.entrypoint; Array.iter (IO.write_real_i32 ch) code.ints; Array.iter (IO.write_double ch) code.floats; let write_strings strings = let str_length = ref 0 in Array.iter (fun str -> str_length := !str_length + String.length str + 1) strings; IO.write_i32 ch !str_length; Array.iter (IO.write_string ch) strings; Array.iter (fun str -> write_index (String.length str)) strings; in write_strings code.strings; if debug then begin write_index (Array.length code.debugfiles); write_strings code.debugfiles; end; Array.iter (fun t -> match t with | HVoid -> byte 0 | HUI8 -> byte 1 | HUI16 -> byte 2 | HI32 -> byte 3 | HF32 -> byte 4 | HF64 -> byte 5 | HBool -> byte 6 | HBytes -> byte 7 | HDyn -> byte 8 | HFun (args,ret) -> let n = List.length args in if n > 0xFF then assert false; byte 9; byte n; List.iter write_type args; write_type ret | HObj p -> byte 10; write_index p.pid; (match p.psuper with | None -> write_index (-1) | Some t -> write_type (HObj t)); (match p.pclassglobal with | None -> write_index 0 | Some g -> write_index (g + 1)); write_index (Array.length p.pfields); write_index (Array.length p.pproto); write_index (List.length p.pbindings); Array.iter (fun (_,n,t) -> write_index n; write_type t) p.pfields; Array.iter (fun f -> write_index f.fid; write_index f.fmethod; write_index (match f.fvirtual with None -> -1 | Some i -> i)) p.pproto; List.iter (fun (fid,fidx) -> write_index fid; write_index fidx) p.pbindings; | HArray -> byte 11 | HType -> byte 12 | HRef t -> byte 13; write_type t | HVirtual v -> byte 14; write_index (Array.length v.vfields); Array.iter (fun (_,sid,t) -> write_index sid; write_type t) v.vfields | HDynObj -> byte 15 | HAbstract (_,i) -> byte 16; write_index i | HEnum e -> byte 17; write_index e.eid; (match e.eglobal with | None -> write_index 0 | Some g -> write_index (g + 1)); write_index (Array.length e.efields); Array.iter (fun (_,nid,tl) -> write_index nid; if Array.length tl > 0xFF then assert false; byte (Array.length tl); Array.iter write_type tl; ) e.efields | HNull t -> byte 18; write_type t ) all_types; let write_debug_infos debug = let curfile = ref (-1) in let curpos = ref 0 in let rcount = ref 0 in let rec flush_repeat p = if !rcount > 0 then begin if !rcount > 15 then begin byte ((15 lsl 2) lor 2); rcount := !rcount - 15; flush_repeat(p) end else begin let delta = p - !curpos in let delta = (if delta > 0 && delta < 4 then delta else 0) in byte ((delta lsl 6) lor (!rcount lsl 2) lor 2); rcount := 0; curpos := !curpos + delta; end end in Array.iter (fun (f,p) -> if f <> !curfile then begin flush_repeat(p); curfile := f; byte ((f lsr 7) lor 1); byte (f land 0xFF); end; if p <> !curpos then flush_repeat(p); if p = !curpos then rcount := !rcount + 1 else let delta = p - !curpos in if delta > 0 && delta < 32 then byte ((delta lsl 3) lor 4) else begin byte (p lsl 3); byte (p lsr 5); byte (p lsr 13); end; curpos := p; ) debug; flush_repeat(!curpos) in Array.iter write_type code.globals; Array.iter (fun (lib_index, name_index,ttype,findex) -> write_index lib_index; write_index name_index; write_type ttype; write_index findex; ) code.natives; Array.iter (fun f -> write_type f.ftype; write_index f.findex; write_index (Array.length f.regs); write_index (Array.length f.code); Array.iter write_type f.regs; Array.iter write_op f.code; if debug then write_debug_infos f.debug; ) code.functions (* --------------------------------------------------------------------------------------------------------------------- *) let create_context com is_macro dump = let get_type name = try List.find (fun t -> (t_infos t).mt_path = (["hl"],name)) com.types with Not_found -> try List.find (fun t -> (t_infos t).mt_path = (["hl";"types"],name)) com.types with Not_found -> failwith ("hl type " ^ name ^ " not found") in let get_class name = match get_type name with | TClassDecl c -> c | _ -> assert false in let get_abstract name = match get_type name with | TAbstractDecl a -> a | _ -> assert false in let ctx = { com = com; is_macro = is_macro; optimize = not (Common.raw_defined com "hl-no-opt"); dump_out = if dump then Some (IO.output_channel (open_out_bin "dump/hlopt.txt")) else None; m = method_context 0 HVoid null_capture false; cints = new_lookup(); cstrings = new_lookup(); cfloats = new_lookup(); cglobals = new_lookup(); cnatives = new_lookup(); cfunctions = DynArray.create(); overrides = Hashtbl.create 0; cached_types = PMap.empty; cached_tuples = PMap.empty; cfids = new_lookup(); defined_funs = Hashtbl.create 0; array_impl = { aall = get_class "ArrayAccess"; abase = get_class "ArrayBase"; adyn = get_class "ArrayDyn"; aobj = get_class "ArrayObj"; aui16 = get_class "ArrayBytes_hl_UI16"; ai32 = get_class "ArrayBytes_Int"; af32 = get_class "ArrayBytes_Single"; af64 = get_class "ArrayBytes_Float"; }; base_class = get_class "Class"; base_enum = get_class "Enum"; base_type = get_class "BaseType"; core_type = get_class "CoreType"; core_enum = get_class "CoreEnum"; ref_abstract = get_abstract "Ref"; anons_cache = []; rec_cache = []; method_wrappers = PMap.empty; cdebug_files = new_lookup(); macro_typedefs = Hashtbl.create 0; cdebug_locals = new_lookup(); cdebug_assigns = DynArray.create(); } in ignore(alloc_string ctx ""); ignore(class_type ctx ctx.base_class [] false); ctx let add_types ctx types = List.iter (fun t -> match t with | TClassDecl ({ cl_path = ["hl";"types"], ("BytesIterator"|"ArrayBytes") } as c) -> c.cl_extern <- true | TClassDecl c -> let rec loop p f = match p with | Some (p,_) when PMap.mem f.cf_name p.cl_fields || loop p.cl_super f -> Hashtbl.replace ctx.overrides (f.cf_name,p.cl_path) true; true | _ -> false in if not ctx.is_macro then List.iter (fun f -> ignore(loop c.cl_super f)) c.cl_overrides; List.iter (fun (m,args,p) -> if m = Meta.Custom ":hlNative" then let lib, prefix = (match args with | [(EConst (String lib),_)] -> lib, "" | [(EConst (String lib),_);(EConst (String p),_)] -> lib, p | _ -> abort "hlNative on class requires library name" p ) in (* adds :hlNative for all empty methods *) List.iter (fun f -> match f.cf_kind with | Method MethNormal when not (List.exists (fun (m,_,_) -> m = Meta.Custom ":hlNative") f.cf_meta) -> (match f.cf_expr with | Some { eexpr = TFunction { tf_expr = { eexpr = TBlock ([] | [{ eexpr = TReturn (Some { eexpr = TConst _ })}]) } } } | None -> let name = prefix ^ String.lowercase (Str.global_replace (Str.regexp "[A-Z]+") "_\\0" f.cf_name) in f.cf_meta <- (Meta.Custom ":hlNative", [(EConst (String lib),p);(EConst (String name),p)], p) :: f.cf_meta; | _ -> ()) | _ -> () ) c.cl_ordered_statics ) c.cl_meta; | _ -> () ) types; List.iter (generate_type ctx) types let build_code ctx types main = let ep = generate_static_init ctx types main in { version = 1; entrypoint = ep; strings = DynArray.to_array ctx.cstrings.arr; ints = DynArray.to_array ctx.cints.arr; floats = DynArray.to_array ctx.cfloats.arr; globals = DynArray.to_array ctx.cglobals.arr; natives = DynArray.to_array ctx.cnatives.arr; functions = DynArray.to_array ctx.cfunctions; debugfiles = DynArray.to_array ctx.cdebug_files.arr; } let check ctx = PMap.iter (fun (s,p) fid -> if not (Hashtbl.mem ctx.defined_funs fid) then failwith (Printf.sprintf "Unresolved method %s:%s(@%d)" (s_type_path p) s fid) ) ctx.cfids.map let generate com = let dump = Common.defined com Define.Dump in let ctx = create_context com false dump in add_types ctx com.types; let code = build_code ctx com.types com.main in Array.sort (fun (lib1,_,_,_) (lib2,_,_,_) -> lib1 - lib2) code.natives; if dump then begin (match ctx.dump_out with None -> () | Some ch -> IO.close_out ch); let ch = open_out_bin "dump/hlcode.txt" in Hlcode.dump (fun s -> output_string ch (s ^ "\n")) code; close_out ch; end; if Common.raw_defined com "hl-dump-spec" then begin let ch = open_out_bin "dump/hlspec.txt" in let write s = output_string ch (s ^ "\n") in Array.iter (fun f -> write (fundecl_name f); let spec = Hlinterp.make_spec code f in List.iter (fun s -> write ("\t" ^ Hlinterp.spec_string s)) spec; write ""; ) code.functions; close_out ch; end; if Common.raw_defined com "hl-check" then begin check ctx; Hlinterp.check code false; end; let t = Common.timer ["write";"hl"] in let escape_command s = let b = Buffer.create 0 in String.iter (fun ch -> if (ch=='"' || ch=='\\' ) then Buffer.add_string b "\\"; Buffer.add_char b ch) s; "\"" ^ Buffer.contents b ^ "\"" in if file_extension com.file = "c" then begin Hl2c.write_c com com.file code; let t = Common.timer ["nativecompile";"hl"] in if not (Common.defined com Define.NoCompilation) && com.run_command ("haxelib run hashlink build " ^ escape_command com.file) <> 0 then failwith "Build failed"; t(); end else begin let ch = IO.output_string() in write_code ch code true; let str = IO.close_out ch in let ch = open_out_bin com.file in output_string ch str; close_out ch; (* let ch = IO.output_string() in let byte = IO.write_byte ch in let write_index = write_index_gen byte in write_index (DynArray.length ctx.cdebug_locals.arr); DynArray.iter (fun s -> write_index (String.length s); IO.write_string ch s; ) ctx.cdebug_locals.arr; write_index (DynArray.length ctx.cdebug_assigns); DynArray.iter (fun a -> write_index (Array.length a); Array.iter (fun (i,p,r) -> write_index i; write_index p; write_index r; ) a; ) ctx.cdebug_assigns; let str = IO.close_out ch in let dbg = open_out_bin (com.file ^ "d") in output_string dbg str; close_out dbg; *) end; t(); if Common.raw_defined com "run" then begin if com.run_command ("haxelib run hashlink run " ^ escape_command com.file) <> 0 then failwith "Failed to run HL"; end; if Common.defined com Define.Interp then try let ctx = Hlinterp.create true in Hlinterp.add_code ctx code; with Failure msg -> abort msg null_pos haxe_3.4.4.orig/src/generators/genjava.ml0000664000175000017500000041602413166552354020330 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open JData open Unix open Ast open Common open Type open Gencommon open Gencommon.SourceWriter open Printf open Option open ExtString module SS = Set.Make(String) let is_boxed_type t = match follow t with | TInst ({ cl_path = (["java";"lang"], "Boolean") }, []) | TInst ({ cl_path = (["java";"lang"], "Double") }, []) | TInst ({ cl_path = (["java";"lang"], "Integer") }, []) | TInst ({ cl_path = (["java";"lang"], "Byte") }, []) | TInst ({ cl_path = (["java";"lang"], "Short") }, []) | TInst ({ cl_path = (["java";"lang"], "Character") }, []) | TInst ({ cl_path = (["java";"lang"], "Float") }, []) -> true | TAbstract ({ a_path = (["java";"lang"], "Boolean") }, []) | TAbstract ({ a_path = (["java";"lang"], "Double") }, []) | TAbstract ({ a_path = (["java";"lang"], "Integer") }, []) | TAbstract ({ a_path = (["java";"lang"], "Byte") }, []) | TAbstract ({ a_path = (["java";"lang"], "Short") }, []) | TAbstract ({ a_path = (["java";"lang"], "Character") }, []) | TAbstract ({ a_path = (["java";"lang"], "Float") }, []) -> true | _ -> false let unboxed_type gen t tbyte tshort tchar tfloat = match follow t with | TInst ({ cl_path = (["java";"lang"], "Boolean") }, []) -> gen.gcon.basic.tbool | TInst ({ cl_path = (["java";"lang"], "Double") }, []) -> gen.gcon.basic.tfloat | TInst ({ cl_path = (["java";"lang"], "Integer") }, []) -> gen.gcon.basic.tint | TInst ({ cl_path = (["java";"lang"], "Byte") }, []) -> tbyte | TInst ({ cl_path = (["java";"lang"], "Short") }, []) -> tshort | TInst ({ cl_path = (["java";"lang"], "Character") }, []) -> tchar | TInst ({ cl_path = (["java";"lang"], "Float") }, []) -> tfloat | TAbstract ({ a_path = (["java";"lang"], "Boolean") }, []) -> gen.gcon.basic.tbool | TAbstract ({ a_path = (["java";"lang"], "Double") }, []) -> gen.gcon.basic.tfloat | TAbstract ({ a_path = (["java";"lang"], "Integer") }, []) -> gen.gcon.basic.tint | TAbstract ({ a_path = (["java";"lang"], "Byte") }, []) -> tbyte | TAbstract ({ a_path = (["java";"lang"], "Short") }, []) -> tshort | TAbstract ({ a_path = (["java";"lang"], "Character") }, []) -> tchar | TAbstract ({ a_path = (["java";"lang"], "Float") }, []) -> tfloat | _ -> assert false let rec t_has_type_param t = match follow t with | TInst({ cl_kind = KTypeParameter _ }, []) -> true | TEnum(_, params) | TAbstract(_, params) | TInst(_, params) -> List.exists t_has_type_param params | TFun(f,ret) -> t_has_type_param ret || List.exists (fun (_,_,t) -> t_has_type_param t) f | _ -> false let is_dynamic gen t = match follow (gen.greal_type t) with | TDynamic _ -> true | _ -> false let is_type_param t = match follow t with | TInst({ cl_kind = KTypeParameter _ }, _) -> true | _ -> false let rec t_has_type_param_shallow last t = match follow t with | TInst({ cl_kind = KTypeParameter _ }, []) -> true | TEnum(_, params) | TAbstract(_, params) | TInst(_, params) when not last -> List.exists (t_has_type_param_shallow true) params | TFun(f,ret) when not last -> t_has_type_param_shallow true ret || List.exists (fun (_,_,t) -> t_has_type_param_shallow true t) f | _ -> false let rec replace_type_param t = match follow t with | TInst({ cl_kind = KTypeParameter _ }, []) -> t_dynamic | TEnum(e, params) -> TEnum(e, List.map replace_type_param params) | TAbstract(a, params) -> TAbstract(a, List.map replace_type_param params) | TInst(cl, params) -> TInst(cl, List.map replace_type_param params) | _ -> t let is_java_basic_type t = match follow t with | TInst( { cl_path = (["haxe"], "Int32") }, [] ) | TInst( { cl_path = (["haxe"], "Int64") }, [] ) | TAbstract( { a_path = ([], "Single") }, [] ) | TAbstract( { a_path = (["java"], ("Int8" | "Int16" | "Char16" | "Int64")) }, [] ) | TAbstract( { a_path = ([], "Int") }, [] ) | TAbstract( { a_path = ([], "Float") }, [] ) | TAbstract( { a_path = ([], "Bool") }, [] ) -> true | _ -> false let is_bool t = match follow t with | TAbstract ({ a_path = ([], "Bool") },[]) -> true | _ -> false let like_bool t = match follow t with | TAbstract ({ a_path = ([], "Bool") },[]) | TAbstract ({ a_path = (["java";"lang"],"Boolean") },[]) | TInst ({ cl_path = (["java";"lang"],"Boolean") },[]) -> true | _ -> false let is_int_float gen t = match follow (gen.greal_type t) with | TInst( { cl_path = (["haxe"], "Int32") }, [] ) | TAbstract( { a_path = ([], "Int") }, [] ) | TAbstract( { a_path = ([], "Float") }, [] ) -> true | (TAbstract _ as t) when like_float t && not (like_i64 t)-> true | _ -> false let parse_explicit_iface = let regex = Str.regexp "\\." in let parse_explicit_iface str = let split = Str.split regex str in let rec get_iface split pack = match split with | clname :: fn_name :: [] -> fn_name, (List.rev pack, clname) | pack_piece :: tl -> get_iface tl (pack_piece :: pack) | _ -> assert false in get_iface split [] in parse_explicit_iface let is_string t = match follow t with | TInst( { cl_path = ([], "String") }, [] ) -> true | _ -> false let is_cl t = match follow t with | TInst({ cl_path = ["java";"lang"],"Class" },_) | TAbstract({ a_path = [], ("Class"|"Enum") },_) -> true | TAnon(a) when is_some (anon_class t) -> true | _ -> false (* ******************************************* *) (* JavaSpecificESynf *) (* ******************************************* *) (* Some Java-specific syntax filters that must run before ExpressionUnwrap dependencies: It must run before ExprUnwrap, as it may not return valid Expr/Statement expressions It must run before ClassInstance, as it will detect expressions that need unchanged TTypeExpr It must run after CastDetect, as it changes casts It must run after TryCatchWrapper, to change Std.is() calls inside there *) module JavaSpecificESynf = struct let name = "java_specific_e" let priority = solve_deps name [ DBefore ExpressionUnwrap.priority; DBefore ClassInstance.priority; DAfter CastDetect.priority; DAfter TryCatchWrapper.priority ] let get_cl_from_t t = match follow t with | TInst(cl,_) -> cl | _ -> assert false let configure gen runtime_cl = let basic = gen.gcon.basic in let float_cl = get_cl ( get_type gen (["java";"lang"], "Double")) in let i8_md = ( get_type gen (["java";"lang"], "Byte")) in let i16_md = ( get_type gen (["java";"lang"], "Short")) in let i64_md = ( get_type gen (["java";"lang"], "Long")) in let c16_md = ( get_type gen (["java";"lang"], "Character")) in let f_md = ( get_type gen (["java";"lang"], "Float")) in let bool_md = get_type gen (["java";"lang"], "Boolean") in let is_var = alloc_var "__is__" t_dynamic in let rec run e = match e.eexpr with (* Math changes *) | TField( _, FStatic({ cl_path = (["java";"lang"], "Math") }, { cf_name = "NaN" }) ) -> mk_static_field_access_infer float_cl "NaN" e.epos [] | TField( _, FStatic({ cl_path = (["java";"lang"], "Math") }, { cf_name = "NEGATIVE_INFINITY" }) ) -> mk_static_field_access_infer float_cl "NEGATIVE_INFINITY" e.epos [] | TField( _, FStatic({ cl_path = (["java";"lang"], "Math") }, { cf_name = "POSITIVE_INFINITY" }) ) -> mk_static_field_access_infer float_cl "POSITIVE_INFINITY" e.epos [] | TField( _, FStatic({ cl_path = (["java";"lang"], "Math") }, { cf_name = "isNaN"}) ) -> mk_static_field_access_infer float_cl "isNaN" e.epos [] | TCall( ({ eexpr = TField( (_ as ef), FStatic({ cl_path = (["java";"lang"], "Math") }, { cf_name = ("ffloor" as f) }) ) } as fe), p) | TCall( ({ eexpr = TField( (_ as ef), FStatic({ cl_path = (["java";"lang"], "Math") }, { cf_name = ("fceil" as f) }) ) } as fe), p) -> Type.map_expr run { e with eexpr = TCall({ fe with eexpr = TField(ef, FDynamic (String.sub f 1 (String.length f - 1))) }, p) } | TCall( { eexpr = TField( _, FStatic({ cl_path = (["java";"lang"], "Math") }, { cf_name = "floor" }) ) }, _) | TCall( { eexpr = TField( _, FStatic({ cl_path = (["java";"lang"], "Math") }, { cf_name = "round" }) ) }, _) | TCall( { eexpr = TField( _, FStatic({ cl_path = (["java";"lang"], "Math") }, { cf_name = "ceil" }) ) }, _) -> mk_cast basic.tint (Type.map_expr run { e with etype = basic.tfloat }) | TCall( ( { eexpr = TField( _, FStatic({ cl_path = (["java";"lang"], "Math") }, { cf_name = "isFinite" }) ) } as efield ), [v]) -> { e with eexpr = TCall( mk_static_field_access_infer runtime_cl "isFinite" efield.epos [], [run v] ) } (* end of math changes *) (* Std.is() *) | TCall( { eexpr = TField( _, FStatic({ cl_path = ([], "Std") }, { cf_name = "is" })) }, [ obj; { eexpr = TTypeExpr(md) } ] ) -> let mk_is is_basic obj md = let obj = if is_basic then mk_cast t_dynamic obj else obj in { e with eexpr = TCall( { eexpr = TLocal is_var; etype = t_dynamic; epos = e.epos }, [ run obj; { eexpr = TTypeExpr md; etype = t_dynamic (* this is after all a syntax filter *); epos = e.epos } ] ) } in (match follow_module follow md with | TAbstractDecl({ a_path = ([], "Float") }) -> { eexpr = TCall( mk_static_field_access_infer runtime_cl "isDouble" e.epos [], [ run obj ] ); etype = basic.tbool; epos = e.epos } | TAbstractDecl{ a_path = ([], "Int") } -> { eexpr = TCall( mk_static_field_access_infer runtime_cl "isInt" e.epos [], [ run obj ] ); etype = basic.tbool; epos = e.epos } | TAbstractDecl{ a_path = ([], "Bool") } -> mk_is true obj bool_md | TAbstractDecl{ a_path = ([], "Single") } -> mk_is true obj f_md | TAbstractDecl{ a_path = (["java"], "Int8") } -> mk_is true obj i8_md | TAbstractDecl{ a_path = (["java"], "Int16") } -> mk_is true obj i16_md | TAbstractDecl{ a_path = (["java"], "Char16") } -> mk_is true obj c16_md | TAbstractDecl{ a_path = (["java"], "Int64") } -> mk_is true obj i64_md | TClassDecl{ cl_path = (["haxe"], "Int64") } -> mk_is true obj i64_md | TAbstractDecl{ a_path = ([], "Dynamic") } | TClassDecl{ cl_path = ([], "Dynamic") } -> (match obj.eexpr with | TLocal _ | TConst _ -> { e with eexpr = TConst(TBool true) } | _ -> { e with eexpr = TBlock([run obj; { e with eexpr = TConst(TBool true) }]) } ) | _ -> mk_is false obj md ) (* end Std.is() *) | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* JavaSpecificSynf *) (* ******************************************* *) (* Some Java-specific syntax filters that can run after ExprUnwrap dependencies: Runs after ExprUnwarp *) module JavaSpecificSynf = struct let name = "java_specific" let priority = solve_deps name [ DAfter ExpressionUnwrap.priority; DAfter ObjectDeclMap.priority; DAfter ArrayDeclSynf.priority; DBefore IntDivisionSynf.priority ] let java_hash s = let high_surrogate c = (c lsr 10) + 0xD7C0 in let low_surrogate c = (c land 0x3FF) lor 0xDC00 in let h = ref Int32.zero in let thirtyone = Int32.of_int 31 in (try UTF8.validate s; UTF8.iter (fun c -> let c = (UChar.code c) in if c > 0xFFFF then (h := Int32.add (Int32.mul thirtyone !h) (Int32.of_int (high_surrogate c)); h := Int32.add (Int32.mul thirtyone !h) (Int32.of_int (low_surrogate c))) else h := Int32.add (Int32.mul thirtyone !h) (Int32.of_int c) ) s with UTF8.Malformed_code -> String.iter (fun c -> h := Int32.add (Int32.mul thirtyone !h) (Int32.of_int (Char.code c))) s ); !h let rec is_final_return_expr is_switch e = let is_final_return_expr = is_final_return_expr is_switch in match e.eexpr with | TReturn _ | TThrow _ -> true (* this is hack to not use 'break' on switch cases *) | TLocal { v_name = "__fallback__" } when is_switch -> true | TCall( { eexpr = TLocal { v_name = "__goto__" } }, _ ) -> true | TParenthesis p | TMeta (_,p) -> is_final_return_expr p | TBlock bl -> is_final_return_block is_switch bl | TSwitch (_, el_e_l, edef) -> List.for_all (fun (_,e) -> is_final_return_expr e) el_e_l && Option.map_default is_final_return_expr false edef | TIf (_,eif, Some eelse) -> is_final_return_expr eif && is_final_return_expr eelse | TFor (_,_,e) -> is_final_return_expr e | TWhile (_,e,_) -> is_final_return_expr e | TFunction tf -> is_final_return_expr tf.tf_expr | TTry (e, ve_l) -> is_final_return_expr e && List.for_all (fun (_,e) -> is_final_return_expr e) ve_l | _ -> false and is_final_return_block is_switch el = match el with | [] -> false | final :: [] -> is_final_return_expr is_switch final | hd :: tl -> is_final_return_block is_switch tl let is_null e = match e.eexpr with | TConst(TNull) -> true | _ -> false let rec is_equatable gen t = match follow t with | TInst(cl,_) -> if cl.cl_path = (["haxe";"lang"], "IEquatable") then true else List.exists (fun (cl,p) -> is_equatable gen (TInst(cl,p))) cl.cl_implements || (match cl.cl_super with | Some(cl,p) -> is_equatable gen (TInst(cl,p)) | None -> false) | _ -> false (* Changing string switch will take an expression like switch(str) { case "a": case "b": } and modify it to: { var execute_def = true; switch(str.hashCode()) { case (hashcode of a): if (str == "a") { execute_def = false; ..code here } //else if (str == otherVariableWithSameHashCode) { ... } ... } if (execute_def) { ..default code } } this might actually be slower in some cases than a if/else approach, but it scales well and as a bonus, hashCode in java are cached, so we only have the performance hit once to cache it. *) let change_string_switch gen eswitch e1 ecases edefault = let basic = gen.gcon.basic in let is_final_ret = is_final_return_expr false eswitch in let has_default = is_some edefault in let block = ref [] in let local = match e1.eexpr with | TLocal _ -> e1 | _ -> let var = mk_temp gen "svar" e1.etype in let added = { e1 with eexpr = TVar(var, Some(e1)); etype = basic.tvoid } in let local = mk_local var e1.epos in block := added :: !block; local in let execute_def_var = mk_temp gen "executeDef" gen.gcon.basic.tbool in let execute_def = mk_local execute_def_var e1.epos in let execute_def_set = { eexpr = TBinop(Ast.OpAssign, execute_def, { eexpr = TConst(TBool false); etype = basic.tbool; epos = e1.epos }); etype = basic.tbool; epos = e1.epos } in let hash_cache = ref None in let local_hashcode = ref { local with eexpr = TCall({ local with eexpr = TField(local, FDynamic "hashCode"); etype = TFun([], basic.tint); }, []); etype = basic.tint } in let get_hash_cache () = match !hash_cache with | Some c -> c | None -> let var = mk_temp gen "hash" basic.tint in let cond = !local_hashcode in block := { eexpr = TVar(var, Some cond); etype = basic.tvoid; epos = local.epos } :: !block; let local = mk_local var local.epos in local_hashcode := local; hash_cache := Some local; local in let has_case = ref false in (* first we need to reorder all cases so all collisions are close to each other *) let get_str e = match e.eexpr with | TConst(TString s) -> s | _ -> assert false in let has_conflict = ref false in let rec reorder_cases unordered ordered = match unordered with | [] -> ordered | (el, e) :: tl -> let current = Hashtbl.create 1 in List.iter (fun e -> let str = get_str e in let hash = java_hash str in Hashtbl.add current hash true ) el; let rec extract_fields cases found_cases ret_cases = match cases with | [] -> found_cases, ret_cases | (el, e) :: tl -> if List.exists (fun e -> Hashtbl.mem current (java_hash (get_str e)) ) el then begin has_conflict := true; List.iter (fun e -> Hashtbl.add current (java_hash (get_str e)) true) el; extract_fields tl ( (el, e) :: found_cases ) ret_cases end else extract_fields tl found_cases ( (el, e) :: ret_cases ) in let found, remaining = extract_fields tl [] [] in let ret = if found <> [] then let ret = List.sort (fun (e1,_) (e2,_) -> compare (List.length e2) (List.length e1) ) ( (el, e) :: found ) in let rec loop ret acc = match ret with | (el, e) :: ( (_,_) :: _ as tl ) -> loop tl ( (true, el, e) :: acc ) | (el, e) :: [] -> ( (false, el, e) :: acc ) | _ -> assert false in List.rev (loop ret []) else (false, el, e) :: [] in reorder_cases remaining (ordered @ ret) in let already_in_cases = Hashtbl.create 0 in let change_case (has_fallback, el, e) = let conds, el = List.fold_left (fun (conds,el) e -> has_case := true; match e.eexpr with | TConst(TString s) -> let hashed = java_hash s in let equals_test = { eexpr = TCall({ e with eexpr = TField(local, FDynamic "equals"); etype = TFun(["obj",false,t_dynamic],basic.tbool) }, [ e ]); etype = basic.tbool; epos = e.epos } in let hashed_expr = { eexpr = TConst(TInt hashed); etype = basic.tint; epos = e.epos } in let hashed_exprs = if !has_conflict then begin if Hashtbl.mem already_in_cases hashed then el else begin Hashtbl.add already_in_cases hashed true; hashed_expr :: el end end else hashed_expr :: el in let conds = match conds with | None -> equals_test | Some c -> (* if there is more than one case, we should test first if hash equals to the one specified. This way we can save a heavier string compare *) let equals_test = mk_paren { eexpr = TBinop(Ast.OpBoolAnd, { eexpr = TBinop(Ast.OpEq, get_hash_cache(), hashed_expr); etype = basic.tbool; epos = e.epos }, equals_test); etype = basic.tbool; epos = e.epos; } in { eexpr = TBinop(Ast.OpBoolOr, equals_test, c); etype = basic.tbool; epos = e1.epos } in Some conds, hashed_exprs | _ -> assert false ) (None,[]) el in let e = if has_default then Type.concat execute_def_set e else e in let e = if !has_conflict then Type.concat e { e with eexpr = TBreak; etype = basic.tvoid } else e in let e = { eexpr = TIf(get conds, e, None); etype = basic.tvoid; epos = e.epos } in let e = if has_fallback then { e with eexpr = TBlock([ e; mk_local (alloc_var "__fallback__" t_dynamic) e.epos]) } else e in (el, e) in let switch = { eswitch with eexpr = TSwitch(!local_hashcode, List.map change_case (reorder_cases ecases []), None); } in (if !has_case then begin (if has_default then block := { e1 with eexpr = TVar(execute_def_var, Some({ e1 with eexpr = TConst(TBool true); etype = basic.tbool })); etype = basic.tvoid } :: !block); block := switch :: !block end); (match edefault with | None -> () | Some edef when not !has_case -> block := edef :: !block | Some edef -> let eelse = if is_final_ret then Some { eexpr = TThrow { eexpr = TConst(TNull); etype = t_dynamic; epos = edef.epos }; etype = basic.tvoid; epos = edef.epos } else None in block := { edef with eexpr = TIf(execute_def, edef, eelse); etype = basic.tvoid } :: !block ); { eswitch with eexpr = TBlock(List.rev !block) } let get_cl_from_t t = match follow t with | TInst(cl,_) -> cl | _ -> assert false let configure gen runtime_cl = (if java_hash "Testing string hashCode implementation from haXe" <> (Int32.of_int 545883604) then assert false); let basic = gen.gcon.basic in (* let tchar = mt_to_t_dyn ( get_type gen (["java"], "Char16") ) in *) (* let tbyte = mt_to_t_dyn ( get_type gen (["java"], "Int8") ) in *) (* let tshort = mt_to_t_dyn ( get_type gen (["java"], "Int16") ) in *) (* let tsingle = mt_to_t_dyn ( get_type gen ([], "Single") ) in *) let ti64 = mt_to_t_dyn ( get_type gen (["java"], "Int64") ) in let string_ext = get_cl ( get_type gen (["haxe";"lang"], "StringExt")) in let fast_cast = Common.defined gen.gcon Define.FastCast in let is_string t = match follow t with | TInst({ cl_path = ([], "String") }, []) -> true | _ -> false in let rec run e = match e.eexpr with (* for new NativeArray issues *) | TNew(({ cl_path = (["java"], "NativeArray") } as cl), [t], el) when is_type_param t -> mk_cast (TInst(cl,[t])) (mk_cast t_dynamic ({ e with eexpr = TNew(cl, [t_empty], List.map run el) })) (* Std.int() *) | TCall( { eexpr = TField( _, FStatic({ cl_path = ([], "Std") }, { cf_name = "int" })) }, [obj] ) -> run (mk_cast basic.tint obj) (* end Std.int() *) | TField( ef, FInstance({ cl_path = ([], "String") }, _, { cf_name = "length" }) ) -> { e with eexpr = TCall(Type.map_expr run e, []) } | TField( ef, field ) when field_name field = "length" && is_string ef.etype -> { e with eexpr = TCall(Type.map_expr run e, []) } | TCall( ( { eexpr = TField(ef, field) } as efield ), args ) when is_string ef.etype && String.get (field_name field) 0 = '_' -> let field = field_name field in { e with eexpr = TCall({ efield with eexpr = TField(run ef, FDynamic (String.sub field 1 ( (String.length field) - 1)) )}, List.map run args) } | TCall( ( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, field )) } as efield ), args ) -> let field = field.cf_name in (match field with | "charAt" | "charCodeAt" | "split" | "indexOf" | "lastIndexOf" | "substring" | "substr" -> { e with eexpr = TCall(mk_static_field_access_infer string_ext field e.epos [], [run ef] @ (List.map run args)) } | _ -> { e with eexpr = TCall(run efield, List.map run args) } ) (* | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("toString") })) }, [] ) -> run ef *) (* | TCast(expr, m) when is_boxed_type e.etype -> *) (* (* let unboxed_type gen t tbyte tshort tchar tfloat = match follow t with *) *) (* run { e with etype = unboxed_type gen e.etype tbyte tshort tchar tsingle } *) | TCast(expr, _) when is_bool e.etype && is_dynamic gen expr.etype -> { eexpr = TCall( mk_static_field_access_infer runtime_cl "toBool" expr.epos [], [ run expr ] ); etype = basic.tbool; epos = e.epos } | TCast(expr, _) when is_int_float gen e.etype && is_dynamic gen expr.etype -> let needs_cast = match gen.gfollow#run_f e.etype with | TInst _ -> false | _ -> true in let fun_name = if like_int e.etype then "toInt" else "toDouble" in let ret = { eexpr = TCall( mk_static_field_access_infer runtime_cl fun_name expr.epos [], [ run expr ] ); etype = if fun_name = "toDouble" then basic.tfloat else basic.tint; epos = expr.epos } in if needs_cast then mk_cast e.etype ret else ret (*| TCast(expr, c) when is_int_float gen e.etype -> (* cases when float x = (float) (java.lang.Double val); *) (* FIXME: this fix is broken since it will fail on cases where float x = (float) (java.lang.Float val) or similar. FIX THIS *) let need_second_cast = match gen.gfollow#run_f e.etype with | TInst _ -> false | _ -> true in if need_second_cast then { e with eexpr = TCast(mk_cast (follow e.etype) (run expr), c) } else Type.map_expr run e*) | TCast(expr, _) when like_i64 e.etype && is_dynamic gen expr.etype -> { eexpr = TCall( mk_static_field_access_infer runtime_cl "toLong" expr.epos [], [ run expr ] ); etype = ti64; epos = expr.epos } | TCast(expr, Some(TClassDecl cls)) when fast_cast && cls == null_class -> { e with eexpr = TCast(run expr, Some(TClassDecl null_class)) } | TBinop( (Ast.OpAssignOp OpAdd as op), e1, e2) | TBinop( (Ast.OpAdd as op), e1, e2) when not fast_cast && (is_string e.etype || is_string e1.etype || is_string e2.etype) -> let is_assign = match op with Ast.OpAssignOp _ -> true | _ -> false in let mk_to_string e = { e with eexpr = TCall( mk_static_field_access_infer runtime_cl "toString" e.epos [], [run e] ); etype = gen.gcon.basic.tstring } in let check_cast e = match gen.greal_type e.etype with | TDynamic _ | TAbstract({ a_path = ([], "Float") }, []) | TAbstract({ a_path = ([], "Single") }, []) -> mk_to_string e | _ -> run e in { e with eexpr = TBinop(op, (if is_assign then run e1 else check_cast e1), check_cast e2) } | TCast(expr, _) when is_string e.etype -> { e with eexpr = TCall( mk_static_field_access_infer runtime_cl "toString" expr.epos [], [run expr] ) } | TSwitch(cond, ecases, edefault) when is_string cond.etype -> (*let change_string_switch gen eswitch e1 ecases edefault =*) change_string_switch gen e (run cond) (List.map (fun (el,e) -> (el, run e)) ecases) (Option.map run edefault) | TBinop( (Ast.OpNotEq as op), e1, e2) | TBinop( (Ast.OpEq as op), e1, e2) when not (is_null e2 || is_null e1) && (is_string e1.etype || is_string e2.etype || is_equatable gen e1.etype || is_equatable gen e2.etype) -> let static = mk_static_field_access_infer (runtime_cl) "valEq" e1.epos [] in let eret = { eexpr = TCall(static, [run e1; run e2]); etype = gen.gcon.basic.tbool; epos=e.epos } in if op = Ast.OpNotEq then { eret with eexpr = TUnop(Ast.Not, Ast.Prefix, eret) } else eret | TBinop( (Ast.OpNotEq | Ast.OpEq as op), e1, e2) when is_cl e1.etype && is_cl e2.etype -> { e with eexpr = TBinop(op, mk_cast t_empty (run e1), mk_cast t_empty (run e2)) } | _ -> Type.map_expr run e in let map e = Some(run e) in gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map end;; (* ******************************************* *) (* handle @:throws *) (* ******************************************* *) let rec is_checked_exc cl = match cl.cl_path with | ["java";"lang"],"RuntimeException" -> false | ["java";"lang"],"Throwable" -> true | _ -> match cl.cl_super with | None -> false | Some(c,_) -> is_checked_exc c let rec cls_any_super cl supers = PMap.mem cl.cl_path supers || match cl.cl_super with | None -> false | Some(c,_) -> cls_any_super c supers let rec handle_throws gen cf = List.iter (handle_throws gen) cf.cf_overloads; match cf.cf_expr with | Some ({ eexpr = TFunction(tf) } as e) -> let rec collect_throws acc = function | (Meta.Throws, [Ast.EConst (Ast.String path), _],_) :: meta -> (try collect_throws (get_cl ( get_type gen (parse_path path)) :: acc) meta with | Not_found | TypeNotFound _ -> collect_throws acc meta) | [] -> acc | _ :: meta -> collect_throws acc meta in let cf_throws = collect_throws [] cf.cf_meta in let throws = ref (List.fold_left (fun map cl -> PMap.add cl.cl_path cl map ) PMap.empty cf_throws) in let rec iter e = match e.eexpr with | TTry(etry,ecatches) -> let old = !throws in let needs_check_block = ref true in List.iter (fun (v,e) -> Type.iter iter e; match follow (run_follow gen v.v_type) with | TInst({ cl_path = ["java";"lang"],"Throwable" },_) | TDynamic _ -> needs_check_block := false | TInst(c,_) when is_checked_exc c -> throws := PMap.add c.cl_path c !throws | _ ->() ) ecatches; if !needs_check_block then Type.iter iter etry; throws := old | TField(e, (FInstance(_,_,f) | FStatic(_,f) | FClosure(_,f))) -> let tdefs = collect_throws [] f.cf_meta in if tdefs <> [] && not (List.for_all (fun c -> cls_any_super c !throws) tdefs) then raise Exit; Type.iter iter e | TThrow e -> (match follow (run_follow gen e.etype) with | TInst(c,_) when is_checked_exc c && not (cls_any_super c !throws) -> raise Exit | _ -> iter e) | _ -> Type.iter iter e in (try Type.iter iter e with | Exit -> (* needs typed exception to be caught *) let throwable = get_cl (get_type gen (["java";"lang"],"Throwable")) in let catch_var = alloc_var "typedException" (TInst(throwable,[])) in let rethrow = mk_local catch_var e.epos in let hx_exception = get_cl (get_type gen (["haxe";"lang"], "HaxeException")) in let wrap_static = mk_static_field_access (hx_exception) "wrap" (TFun([("obj",false,t_dynamic)], t_dynamic)) rethrow.epos in let wrapped = { rethrow with eexpr = TThrow { rethrow with eexpr = TCall(wrap_static, [rethrow]) }; } in let map_throws cl = let var = alloc_var "typedException" (TInst(cl,List.map (fun _ -> t_dynamic) cl.cl_params)) in var, { tf.tf_expr with eexpr = TThrow (mk_local var e.epos) } in cf.cf_expr <- Some { e with eexpr = TFunction({ tf with tf_expr = mk_block { tf.tf_expr with eexpr = TTry(tf.tf_expr, List.map (map_throws) cf_throws @ [catch_var, wrapped]) } }) }) | _ -> () let connecting_string = "?" (* ? see list here http://www.fileformat.info/info/unicode/category/index.htm and here for C# http://msdn.microsoft.com/en-us/library/aa664670.aspx *) let default_package = "java" let strict_mode = ref false (* strict mode is so we can check for unexpected information *) (* reserved java words *) let reserved = let res = Hashtbl.create 120 in List.iter (fun lst -> Hashtbl.add res lst ("_" ^ lst)) ["abstract"; "assert"; "boolean"; "break"; "byte"; "case"; "catch"; "char"; "class"; "const"; "continue"; "default"; "do"; "double"; "else"; "enum"; "extends"; "final"; "false"; "finally"; "float"; "for"; "goto"; "if"; "implements"; "import"; "instanceof"; "int"; "interface"; "long"; "native"; "new"; "null"; "package"; "private"; "protected"; "public"; "return"; "short"; "static"; "strictfp"; "super"; "switch"; "synchronized"; "this"; "throw"; "throws"; "transient"; "true"; "try"; "void"; "volatile"; "while"; ]; res let dynamic_anon = TAnon( { a_fields = PMap.empty; a_status = ref Closed } ) let rec get_class_modifiers meta cl_type cl_access cl_modifiers = match meta with | [] -> cl_type,cl_access,cl_modifiers (*| (Meta.Struct,[],_) :: meta -> get_class_modifiers meta "struct" cl_access cl_modifiers*) | (Meta.Protected,[],_) :: meta -> get_class_modifiers meta cl_type "protected" cl_modifiers | (Meta.Internal,[],_) :: meta -> get_class_modifiers meta cl_type "" cl_modifiers (* no abstract for now | (":abstract",[],_) :: meta -> get_class_modifiers meta cl_type cl_access ("abstract" :: cl_modifiers) | (Meta.Static,[],_) :: meta -> get_class_modifiers meta cl_type cl_access ("static" :: cl_modifiers) TODO: support those types *) | (Meta.Final,[],_) :: meta -> get_class_modifiers meta cl_type cl_access ("final" :: cl_modifiers) | _ :: meta -> get_class_modifiers meta cl_type cl_access cl_modifiers let rec get_fun_modifiers meta access modifiers = match meta with | [] -> access,modifiers | (Meta.Protected,[],_) :: meta -> get_fun_modifiers meta "protected" modifiers | (Meta.Internal,[],_) :: meta -> get_fun_modifiers meta "" modifiers | (Meta.ReadOnly,[],_) :: meta -> get_fun_modifiers meta access ("final" :: modifiers) (*| (Meta.Unsafe,[],_) :: meta -> get_fun_modifiers meta access ("unsafe" :: modifiers)*) | (Meta.Volatile,[],_) :: meta -> get_fun_modifiers meta access ("volatile" :: modifiers) | (Meta.Transient,[],_) :: meta -> get_fun_modifiers meta access ("transient" :: modifiers) | (Meta.Native,[],_) :: meta -> get_fun_modifiers meta access ("native" :: modifiers) | _ :: meta -> get_fun_modifiers meta access modifiers (* this was the way I found to pass the generator context to be accessible across all functions here *) (* so 'configure' is almost 'top-level' and will have all functions needed to make this work *) let configure gen = let native_arr_cl = get_cl ( get_type gen (["java"], "NativeArray") ) in gen.gclasses.nativearray <- (fun t -> TInst(native_arr_cl,[t])); gen.gclasses.nativearray_type <- (function TInst(_,[t]) -> t | _ -> assert false); gen.gclasses.nativearray_len <- (fun e p -> mk_field_access gen e "length" p); let basic = gen.gcon.basic in let fn_cl = get_cl (get_type gen (["haxe";"lang"],"Function")) in let runtime_cl = get_cl (get_type gen (["haxe";"lang"],"Runtime")) in let nulltdef = get_tdef (get_type gen ([],"Null")) in (*let string_ref = get_cl ( get_type gen (["haxe";"lang"], "StringRefl")) in*) let ti64 = match ( get_type gen (["java"], "Int64") ) with | TAbstractDecl a -> TAbstract(a,[]) | _ -> assert false in let has_tdynamic params = List.exists (fun e -> match run_follow gen e with | TDynamic _ -> true | _ -> false) params in (* The type parameters always need to be changed to their boxed counterparts *) let change_param_type md params = match md with | TClassDecl( { cl_path = (["java"], "NativeArray") } ) -> params | TAbstractDecl { a_path=[],("Class" | "Enum") } | TClassDecl { cl_path = (["java";"lang"],("Class"|"Enum")) } -> List.map (fun _ -> t_dynamic) params | _ -> match params with | [] -> [] | _ -> if has_tdynamic params then List.map (fun _ -> t_dynamic) params else List.map (fun t -> let f_t = gen.gfollow#run_f t in match f_t with | TAbstract ({ a_path = ([], "Bool") },[]) | TAbstract ({ a_path = ([],"Float") },[]) | TInst ({ cl_path = ["haxe"],"Int32" },[]) | TInst ({ cl_path = ["haxe"],"Int64" },[]) | TAbstract ({ a_path = ([],"Int") },[]) | TType ({ t_path = ["java"], "Int64" },[]) | TAbstract ({ a_path = ["java"], "Int64" },[]) | TType ({ t_path = ["java"],"Int8" },[]) | TAbstract ({ a_path = ["java"],"Int8" },[]) | TType ({ t_path = ["java"],"Int16" },[]) | TAbstract ({ a_path = ["java"],"Int16" },[]) | TType ({ t_path = ["java"],"Char16" },[]) | TAbstract ({ a_path = ["java"],"Char16" },[]) | TType ({ t_path = [],"Single" },[]) | TAbstract ({ a_path = [],"Single" },[]) -> TType(nulltdef, [f_t]) (*| TType ({ t_path = [], "Null"*) | TInst (cl, ((_ :: _) as p)) when cl.cl_path <> (["java"],"NativeArray") -> (* TInst(cl, List.map (fun _ -> t_dynamic) p) *) TInst(cl,p) | TEnum (e, ((_ :: _) as p)) -> TEnum(e, List.map (fun _ -> t_dynamic) p) | _ -> t ) params in let change_clname name = String.map (function | '$' -> '.' | c -> c) name in let change_id name = try Hashtbl.find reserved name with | Not_found -> name in let rec change_ns ns = match ns with | [] -> ["haxe"; "root"] | _ -> List.map change_id ns in let change_field = change_id in let write_id w name = write w (change_id name) in let write_field w name = write w (change_field name) in gen.gfollow#add ~name:"follow_basic" (fun t -> match t with | TAbstract ({ a_path = ([], "Bool") },[]) | TAbstract ({ a_path = ([], "Void") },[]) | TAbstract ({ a_path = ([],"Float") },[]) | TAbstract ({ a_path = ([],"Int") },[]) | TInst( { cl_path = (["haxe"], "Int32") }, [] ) | TInst( { cl_path = (["haxe"], "Int64") }, [] ) | TType ({ t_path = ["java"], "Int64" },[]) | TAbstract ({ a_path = ["java"], "Int64" },[]) | TType ({ t_path = ["java"],"Int8" },[]) | TAbstract ({ a_path = ["java"],"Int8" },[]) | TType ({ t_path = ["java"],"Int16" },[]) | TAbstract ({ a_path = ["java"],"Int16" },[]) | TType ({ t_path = ["java"],"Char16" },[]) | TAbstract ({ a_path = ["java"],"Char16" },[]) | TType ({ t_path = [],"Single" },[]) | TAbstract ({ a_path = [],"Single" },[]) -> Some t | TType (({ t_path = [],"Null" } as tdef),[t2]) -> Some (TType(tdef,[gen.gfollow#run_f t2])) | TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) -> Some (gen.gfollow#run_f ( Abstract.get_underlying_type a pl) ) | TAbstract( { a_path = ([], "EnumValue") }, _ ) | TInst( { cl_path = ([], "EnumValue") }, _ ) -> Some t_dynamic | _ -> None); let change_path path = (change_ns (fst path), change_clname (snd path)) in let path_s path meta = try match Meta.get Meta.JavaCanonical meta with | (Meta.JavaCanonical, [EConst(String pack), _; EConst(String name), _], _) -> if pack = "" then name else pack ^ "." ^ name | _ -> raise Not_found with Not_found -> match path with | (ns,clname) -> s_type_path (change_ns ns, change_clname clname) in let cl_cl = get_cl (get_type gen (["java";"lang"],"Class")) in let rec real_type t = let t = gen.gfollow#run_f t in match t with | TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) -> real_type (Abstract.get_underlying_type a pl) | TInst( { cl_path = (["haxe"], "Int32") }, [] ) -> gen.gcon.basic.tint | TInst( { cl_path = (["haxe"], "Int64") }, [] ) -> ti64 | TAbstract( { a_path = ([], "Class") }, p ) | TAbstract( { a_path = ([], "Enum") }, p ) | TInst( { cl_path = ([], "Class") }, p ) | TInst( { cl_path = ([], "Enum") }, p ) -> TInst(cl_cl,[t_dynamic]) | TEnum(e,params) -> TEnum(e, List.map (fun _ -> t_dynamic) params) | TInst(c,params) when Meta.has Meta.Enum c.cl_meta -> TInst(c, List.map (fun _ -> t_dynamic) params) | TInst({ cl_kind = KExpr _ }, _) -> t_dynamic | TInst _ -> t | TType({ t_path = ([], "Null") }, [t]) when is_java_basic_type (gen.gfollow#run_f t) -> t_dynamic | TType({ t_path = ([], "Null") }, [t]) -> (match follow t with | TInst( { cl_kind = KTypeParameter _ }, []) -> t_dynamic (* real_type t *) | _ -> real_type t ) | TType _ | TAbstract _ -> t | TAnon (anon) -> (match !(anon.a_status) with | Statics _ | EnumStatics _ | AbstractStatics _ -> t | _ -> t_dynamic) | TFun _ -> TInst(fn_cl,[]) | _ -> t_dynamic in let scope = ref PMap.empty in let imports = ref [] in let clear_scope () = scope := PMap.empty; imports := []; in let add_scope name = scope := PMap.add name () !scope in let add_import pos path meta = let name = snd path in let rec loop = function | (pack, n) :: _ when name = n -> if path <> (pack,n) then gen.gcon.error ("This expression cannot be generated because " ^ path_s path meta ^ " is shadowed by the current scope and ") pos | _ :: tl -> loop tl | [] -> (* add import *) imports := path :: !imports in loop !imports in let path_s_import pos path meta = match path with | [], name when PMap.mem name !scope -> gen.gcon.error ("This expression cannot be generated because " ^ name ^ " is shadowed by the current scope") pos; name | pack1 :: _, name when PMap.mem pack1 !scope -> (* exists in scope *) add_import pos path meta; (* check if name exists in scope *) if PMap.mem name !scope then gen.gcon.error ("This expression cannot be generated because " ^ pack1 ^ " and " ^ name ^ " are both shadowed by the current scope") pos; name | _ -> path_s path meta in let is_dynamic t = match real_type t with | TMono _ | TDynamic _ | TInst({ cl_kind = KTypeParameter _ }, _) -> true | TAnon anon -> (match !(anon.a_status) with | EnumStatics _ | Statics _ | AbstractStatics _ -> false | _ -> true ) | _ -> false in let rec t_s pos t = match real_type t with (* basic types *) | TAbstract ({ a_path = ([], "Bool") },[]) -> "boolean" | TAbstract ({ a_path = ([], "Void") },[]) -> path_s_import pos (["java";"lang"], "Object") [] | TAbstract ({ a_path = ([],"Float") },[]) -> "double" | TAbstract ({ a_path = ([],"Int") },[]) -> "int" | TType ({ t_path = ["java"], "Int64" },[]) | TAbstract ({ a_path = ["java"], "Int64" },[]) -> "long" | TType ({ t_path = ["java"],"Int8" },[]) | TAbstract ({ a_path = ["java"],"Int8" },[]) -> "byte" | TType ({ t_path = ["java"],"Int16" },[]) | TAbstract ({ a_path = ["java"],"Int16" },[]) -> "short" | TType ({ t_path = ["java"],"Char16" },[]) | TAbstract ({ a_path = ["java"],"Char16" },[]) -> "char" | TType ({ t_path = [],"Single" },[]) | TAbstract ({ a_path = [],"Single" },[]) -> "float" | TInst ({ cl_path = ["haxe"],"Int32" },[]) | TAbstract ({ a_path = ["haxe"],"Int32" },[]) -> "int" | TInst ({ cl_path = ["haxe"],"Int64" },[]) | TAbstract ({ a_path = ["haxe"],"Int64" },[]) -> "long" | TInst({ cl_path = (["java"], "NativeArray") }, [param]) -> let rec check_t_s t = match real_type t with | TInst({ cl_path = (["java"], "NativeArray") }, [param]) -> (check_t_s param) ^ "[]" | _ -> t_s pos (run_follow gen t) in (check_t_s param) ^ "[]" (* end of basic types *) | TInst ({ cl_kind = KTypeParameter _; cl_path=p }, []) -> snd p | TAbstract ({ a_path = [], "Dynamic" },[]) -> path_s_import pos (["java";"lang"], "Object") [] | TMono r -> (match !r with | None -> "java.lang.Object" | Some t -> t_s pos (run_follow gen t)) | TInst ({ cl_path = [], "String" }, []) -> path_s_import pos (["java";"lang"], "String") [] | TAbstract ({ a_path = [], "Class" }, [p]) | TAbstract ({ a_path = [], "Enum" }, [p]) | TInst ({ cl_path = [], "Class" }, [p]) | TInst ({ cl_path = [], "Enum" }, [p]) -> path_param_s pos (TClassDecl cl_cl) (["java";"lang"], "Class") [p] [] | TAbstract ({ a_path = [], "Class" }, _) | TAbstract ({ a_path = [], "Enum" }, _) | TInst ({ cl_path = [], "Class" }, _) | TInst ({ cl_path = [], "Enum" }, _) -> path_s_import pos (["java";"lang"], "Class") [] | TEnum ({e_path = p; e_meta = meta}, _) -> path_s_import pos p meta | TInst (({cl_path = p; cl_meta = meta} as cl), _) when Meta.has Meta.Enum cl.cl_meta -> path_s_import pos p meta | TInst (({cl_path = p; cl_meta = meta} as cl), params) -> (path_param_s pos (TClassDecl cl) p params meta) | TType (({t_path = p; t_meta = meta} as t), params) -> (path_param_s pos (TTypeDecl t) p params meta) | TAnon (anon) -> (match !(anon.a_status) with | Statics _ | EnumStatics _ | AbstractStatics _ -> path_s_import pos (["java";"lang"], "Class") [] | _ -> path_s_import pos (["java";"lang"], "Object") []) | TDynamic _ -> path_s_import pos (["java";"lang"], "Object") [] (* No Lazy type nor Function type made. That's because function types will be at this point be converted into other types *) | _ -> if !strict_mode then begin trace ("[ !TypeError " ^ (Type.s_type (Type.print_context()) t) ^ " ]"); assert false end else "[ !TypeError " ^ (Type.s_type (Type.print_context()) t) ^ " ]" and param_t_s pos t = match run_follow gen t with | TAbstract ({ a_path = ([], "Bool") },[]) -> path_s_import pos (["java";"lang"], "Boolean") [] | TAbstract ({ a_path = ([],"Float") },[]) -> path_s_import pos (["java";"lang"], "Double") [] | TAbstract ({ a_path = ([],"Int") },[]) -> path_s_import pos (["java";"lang"], "Integer") [] | TType ({ t_path = ["java"], "Int64" },[]) | TAbstract ({ a_path = ["java"], "Int64" },[]) -> path_s_import pos (["java";"lang"], "Long") [] | TInst ({ cl_path = ["haxe"],"Int64" },[]) | TAbstract ({ a_path = ["haxe"],"Int64" },[]) -> path_s_import pos (["java";"lang"], "Long") [] | TInst ({ cl_path = ["haxe"],"Int32" },[]) | TAbstract ({ a_path = ["haxe"],"Int32" },[]) -> path_s_import pos (["java";"lang"], "Integer") [] | TType ({ t_path = ["java"],"Int8" },[]) | TAbstract ({ a_path = ["java"],"Int8" },[]) -> path_s_import pos (["java";"lang"], "Byte") [] | TType ({ t_path = ["java"],"Int16" },[]) | TAbstract ({ a_path = ["java"],"Int16" },[]) -> path_s_import pos (["java";"lang"], "Short") [] | TType ({ t_path = ["java"],"Char16" },[]) | TAbstract ({ a_path = ["java"],"Char16" },[]) -> path_s_import pos (["java";"lang"], "Character") [] | TType ({ t_path = [],"Single" },[]) | TAbstract ({ a_path = [],"Single" },[]) -> path_s_import pos (["java";"lang"], "Float") [] | TDynamic _ -> "?" | TInst (cl, params) -> t_s pos (TInst(cl, change_param_type (TClassDecl cl) params)) | TType (cl, params) -> t_s pos (TType(cl, change_param_type (TTypeDecl cl) params)) | TEnum (e, params) -> t_s pos (TEnum(e, change_param_type (TEnumDecl e) params)) | _ -> t_s pos t and path_param_s pos md path params meta = match params with | [] -> path_s_import pos path meta | _ when has_tdynamic (change_param_type md params) -> path_s_import pos path meta | _ -> sprintf "%s<%s>" (path_s_import pos path meta) (String.concat ", " (List.map (fun t -> param_t_s pos t) (change_param_type md params))) in let rett_s pos t = match t with | TAbstract ({ a_path = ([], "Void") },[]) -> "void" | _ -> t_s pos t in let high_surrogate c = (c lsr 10) + 0xD7C0 in let low_surrogate c = (c land 0x3FF) lor 0xDC00 in let escape ichar b = match ichar with | 92 (* \ *) -> Buffer.add_string b "\\\\" | 39 (* ' *) -> Buffer.add_string b "\\\'" | 34 -> Buffer.add_string b "\\\"" | 13 (* \r *) -> Buffer.add_string b "\\r" | 10 (* \n *) -> Buffer.add_string b "\\n" | 9 (* \t *) -> Buffer.add_string b "\\t" | c when c < 32 || (c >= 127 && c <= 0xFFFF) -> Buffer.add_string b (Printf.sprintf "\\u%.4x" c) | c when c > 0xFFFF -> Buffer.add_string b (Printf.sprintf "\\u%.4x\\u%.4x" (high_surrogate c) (low_surrogate c)) | c -> Buffer.add_char b (Char.chr c) in let escape s = let b = Buffer.create 0 in (try UTF8.validate s; UTF8.iter (fun c -> escape (UChar.code c) b) s with UTF8.Malformed_code -> String.iter (fun c -> escape (Char.code c) b) s ); Buffer.contents b in let has_semicolon e = match e.eexpr with | TLocal { v_name = "__fallback__" } | TCall ({ eexpr = TLocal( { v_name = "__label__" } ) }, [ { eexpr = TConst(TInt _) } ] ) -> false | TCall ({ eexpr = TLocal( { v_name = "__lock__" } ) }, _ ) -> false | TBlock _ | TFor _ | TSwitch _ | TTry _ | TIf _ -> false | TWhile (_,_,flag) when flag = Ast.NormalWhile -> false | _ -> true in let in_value = ref false in let rec md_s pos md = let md = follow_module (gen.gfollow#run_f) md in match md with | TClassDecl (cl) -> t_s pos (TInst(cl,[])) | TEnumDecl (e) -> t_s pos (TEnum(e,[])) | TTypeDecl t -> t_s pos (TType(t, [])) | TAbstractDecl a -> t_s pos (TAbstract(a, [])) in (* it seems that Java doesn't like when you create a new array with the type parameter defined so we'll just ignore all type parameters, and hope for the best! *) let rec transform_nativearray_t t = match real_type t with | TInst( ({ cl_path = (["java"], "NativeArray") } as narr), [t]) -> TInst(narr, [transform_nativearray_t t]) | TInst(cl, params) -> TInst(cl, List.map (fun _ -> t_dynamic) params) | TEnum(e, params) -> TEnum(e, List.map (fun _ -> t_dynamic) params) | TType(t, params) -> TType(t, List.map (fun _ -> t_dynamic) params) | _ -> t in let rec extract_tparams params el = match el with | ({ eexpr = TLocal({ v_name = "$type_param" }) } as tp) :: tl -> extract_tparams (tp.etype :: params) tl | _ -> (params, el) in let line_directive = if Common.defined gen.gcon Define.RealPosition then fun w p -> () else fun w p -> let cur_line = Lexer.get_error_line p in let file = Path.get_full_path p.pfile in print w "//line %d \"%s\"" cur_line (Ast.s_escape file); newline w in let extract_statements expr = let ret = ref [] in let rec loop expr = match expr.eexpr with | TCall ({ eexpr = TLocal { v_name = "__is__" | "__typeof__" | "__array__" } }, el) -> List.iter loop el | TNew ({ cl_path = (["java"], "NativeArray") }, params, [ size ]) -> () | TUnop (Ast.Increment, _, _) | TUnop (Ast.Decrement, _, _) | TBinop (Ast.OpAssign, _, _) | TBinop (Ast.OpAssignOp _, _, _) | TLocal { v_name = "__fallback__" } | TLocal { v_name = "__sbreak__" } -> ret := expr :: !ret | TConst _ | TLocal _ | TArray _ | TBinop _ | TField _ | TEnumParameter _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ | TCast _ | TMeta _ | TParenthesis _ | TUnop _ -> Type.iter loop expr | TFunction _ -> () (* do not extract parameters from inside of it *) | _ -> ret := expr :: !ret in loop expr; (* [expr] *) List.rev !ret in let expr_s w e = in_value := false; let rec expr_s w e = let was_in_value = !in_value in in_value := true; match e.eexpr with | TConst c -> (match c with | TInt i32 -> print w "%ld" i32; | TFloat s -> write w s; (* fix for Int notation, which only fit in a Float *) (if not (String.contains s '.' || String.contains s 'e' || String.contains s 'E') then write w ".0"); | TString s -> print w "\"%s\"" (escape s) | TBool b -> write w (if b then "true" else "false") | TNull -> (match real_type e.etype with | TAbstract( { a_path = (["java"], "Int64") }, [] ) | TInst( { cl_path = (["haxe"], "Int64") }, [] ) -> write w "0L" | TInst( { cl_path = (["haxe"], "Int32") }, [] ) | TAbstract ({ a_path = ([], "Int") },[]) -> expr_s w ({ e with eexpr = TConst(TInt Int32.zero) }) | TAbstract ({ a_path = ([], "Float") },[]) -> expr_s w ({ e with eexpr = TConst(TFloat "0.0") }) | TAbstract ({ a_path = ([], "Bool") },[]) -> write w "false" | TAbstract _ when like_int e.etype -> expr_s w (mk_cast e.etype { e with eexpr = TConst(TInt Int32.zero) }) | TAbstract _ when like_float e.etype -> expr_s w (mk_cast e.etype { e with eexpr = TConst(TFloat "0.0") } ) | t -> write w ("null") ) | TThis -> write w "this" | TSuper -> write w "super") | TLocal { v_name = "__fallback__" } -> () | TLocal { v_name = "__sbreak__" } -> write w "break" | TLocal { v_name = "__undefined__" } -> write w (t_s e.epos (TInst(runtime_cl, List.map (fun _ -> t_dynamic) runtime_cl.cl_params))); write w ".undefined"; | TLocal var -> write_id w var.v_name | TField(_, FEnum(en,ef)) -> let s = ef.ef_name in print w "%s." (path_s_import e.epos en.e_path en.e_meta); write_field w s | TArray (e1, e2) -> expr_s w e1; write w "["; expr_s w e2; write w "]" | TBinop ((Ast.OpAssign as op), e1, e2) | TBinop ((Ast.OpAssignOp _ as op), e1, e2) -> expr_s w e1; write w ( " " ^ (Ast.s_binop op) ^ " " ); expr_s w e2 | TBinop (op, e1, e2) -> write w "( "; expr_s w e1; write w ( " " ^ (Ast.s_binop op) ^ " " ); expr_s w e2; write w " )" | TField (e, FStatic(_, cf)) when Meta.has Meta.Native cf.cf_meta -> let rec loop meta = match meta with | (Meta.Native, [EConst (String s), _],_) :: _ -> expr_s w e; write w "."; write_field w s | _ :: tl -> loop tl | [] -> expr_s w e; write w "."; write_field w (cf.cf_name) in loop cf.cf_meta | TField (e, s) -> expr_s w e; write w "."; write_field w (field_name s) | TTypeExpr (TClassDecl { cl_path = (["haxe"], "Int32") }) -> write w (path_s_import e.epos (["haxe"], "Int32") []) | TTypeExpr (TClassDecl { cl_path = (["haxe"], "Int64") }) -> write w (path_s_import e.epos (["haxe"], "Int64") []) | TTypeExpr mt -> write w (md_s e.epos mt) | TParenthesis e -> write w "("; expr_s w e; write w ")" | TMeta (_,e) -> expr_s w e | TCall ({ eexpr = TLocal { v_name = "__array__" } }, el) | TCall ({ eexpr = TField(_, FStatic({ cl_path = (["java"],"NativeArray") }, { cf_name = "make" })) }, el) | TArrayDecl el when t_has_type_param e.etype -> let _, el = extract_tparams [] el in print w "( (%s) (new %s " (t_s e.epos e.etype) (t_s e.epos (replace_type_param e.etype)); write w "{"; ignore (List.fold_left (fun acc e -> (if acc <> 0 then write w ", "); expr_s w e; acc + 1 ) 0 el); write w "}) )" | TCall ({ eexpr = TLocal { v_name = "__array__" } }, el) | TCall ({ eexpr = TField(_, FStatic({ cl_path = (["java"],"NativeArray") }, { cf_name = "make" })) }, el) | TArrayDecl el -> let _, el = extract_tparams [] el in print w "new %s" (param_t_s e.epos (transform_nativearray_t e.etype)); let is_double = match follow e.etype with | TInst(_,[ t ]) -> if like_float t && not (like_int t) then Some t else None | _ -> None in write w "{"; ignore (List.fold_left (fun acc e -> (if acc <> 0 then write w ", "); (* this is a hack so we are able to convert ints to boxed Double / Float when needed *) let e = if is_some is_double then mk_cast (get is_double) e else e in expr_s w e; acc + 1 ) 0 el); write w "}" | TCall( ( { eexpr = TField(_, FStatic({ cl_path = ([], "String") }, { cf_name = "fromCharCode" })) } ), [cc] ) -> write w "Character.toString((char) "; expr_s w cc; write w ")" | TCall ({ eexpr = TLocal( { v_name = "__is__" } ) }, [ expr; { eexpr = TTypeExpr(md) } ] ) -> write w "( "; expr_s w expr; write w " instanceof "; write w (md_s e.epos md); write w " )" | TCall ({ eexpr = TLocal( { v_name = "__java__" } ) }, [ { eexpr = TConst(TString(s)) } ] ) -> write w s | TCall ({ eexpr = TLocal( { v_name = "__java__" } ) }, { eexpr = TConst(TString(s)) } :: tl ) -> Codegen.interpolate_code gen.gcon s tl (write w) (expr_s w) e.epos | TCall ({ eexpr = TLocal( { v_name = "__lock__" } ) }, [ eobj; eblock ] ) -> write w "synchronized("; let rec loop eobj = match eobj.eexpr with | TTypeExpr md -> expr_s w eobj; write w ".class" | TMeta(_,e) | TParenthesis(e) -> loop e | _ -> expr_s w eobj in loop eobj; write w ")"; (match eblock.eexpr with | TBlock(_ :: _) -> expr_s w eblock | _ -> begin_block w; expr_s w eblock; if has_semicolon eblock then write w ";"; end_block w; ) | TCall ({ eexpr = TLocal( { v_name = "__goto__" } ) }, [ { eexpr = TConst(TInt v) } ] ) -> print w "break label%ld" v | TCall ({ eexpr = TLocal( { v_name = "__label__" } ) }, [ { eexpr = TConst(TInt v) } ] ) -> print w "label%ld:" v | TCall ({ eexpr = TLocal( { v_name = "__typeof__" } ) }, [ { eexpr = TTypeExpr md } as expr ] ) -> expr_s w expr; write w ".class" | TCall (e, el) -> let params, el = extract_tparams [] el in expr_s w e; (*(match params with | [] -> () | params -> let md = match e.eexpr with | TField(ef, _) -> t_to_md (run_follow gen ef.etype) | _ -> assert false in write w "<"; ignore (List.fold_left (fun acc t -> (if acc <> 0 then write w ", "); write w (param_t_s (change_param_type md t)); acc + 1 ) 0 params); write w ">" );*) write w "("; ignore (List.fold_left (fun acc e -> (if acc <> 0 then write w ", "); expr_s w e; acc + 1 ) 0 el); write w ")" | TNew (({ cl_path = (["java"], "NativeArray") } as cl), params, [ size ]) -> let rec check_t_s t times = match real_type t with | TInst({ cl_path = (["java"], "NativeArray") }, [param]) -> (check_t_s param (times+1)) | _ -> print w "new %s[" (t_s e.epos (transform_nativearray_t t)); expr_s w size; print w "]"; let rec loop i = if i <= 0 then () else (write w "[]"; loop (i-1)) in loop (times - 1) in check_t_s (TInst(cl, params)) 0 | TNew ({ cl_path = ([], "String") } as cl, [], el) -> write w "new "; write w (t_s e.epos (TInst(cl, []))); write w "("; ignore (List.fold_left (fun acc e -> (if acc <> 0 then write w ", "); expr_s w e; acc + 1 ) 0 el); write w ")" | TNew ({ cl_kind = KTypeParameter _ } as cl, params, el) -> print w "null /* This code should never be reached. It was produced by the use of @:generic on a new type parameter instance: %s */" (path_param_s e.epos (TClassDecl cl) cl.cl_path params cl.cl_meta) | TNew (cl, params, el) -> write w "new "; write w (path_param_s e.epos (TClassDecl cl) cl.cl_path params cl.cl_meta); write w "("; ignore (List.fold_left (fun acc e -> (if acc <> 0 then write w ", "); expr_s w e; acc + 1 ) 0 el); write w ")" | TUnop ((Ast.Increment as op), flag, e) | TUnop ((Ast.Decrement as op), flag, e) -> (match flag with | Ast.Prefix -> write w ( " " ^ (Ast.s_unop op) ^ " " ); expr_s w e | Ast.Postfix -> expr_s w e; write w (Ast.s_unop op)) | TUnop (op, flag, e) -> (match flag with | Ast.Prefix -> write w ( " " ^ (Ast.s_unop op) ^ " (" ); expr_s w e; write w ") " | Ast.Postfix -> write w "("; expr_s w e; write w (") " ^ Ast.s_unop op)) | TVar (var, eopt) -> print w "%s " (t_s e.epos var.v_type); write_id w var.v_name; (match eopt with | None -> write w " = "; expr_s w (null var.v_type e.epos) | Some e -> write w " = "; expr_s w e ) | TBlock [e] when was_in_value -> expr_s w e | TBlock el -> begin_block w; List.iter (fun e -> List.iter (fun e -> in_value := false; line_directive w e.epos; expr_s w e; if has_semicolon e then write w ";"; newline w; ) (extract_statements e) ) el; end_block w | TIf (econd, e1, Some(eelse)) when was_in_value -> write w "( "; expr_s w (mk_paren econd); write w " ? "; expr_s w (mk_paren e1); write w " : "; expr_s w (mk_paren eelse); write w " )"; | TIf (econd, e1, eelse) -> write w "if "; expr_s w (mk_paren econd); write w " "; in_value := false; expr_s w (mk_block e1); (match eelse with | None -> () | Some e -> write w "else"; in_value := false; expr_s w (mk_block e) ) | TWhile (econd, eblock, flag) -> (match flag with | Ast.NormalWhile -> write w "while "; expr_s w (mk_paren econd); write w ""; in_value := false; expr_s w (mk_block eblock) | Ast.DoWhile -> write w "do "; in_value := false; expr_s w (mk_block eblock); write w "while "; in_value := true; expr_s w (mk_paren econd); ) | TSwitch (econd, ele_l, default) -> write w "switch "; expr_s w (mk_paren econd); begin_block w; List.iter (fun (el, e) -> List.iter (fun e -> write w "case "; in_value := true; (match e.eexpr with | TField(_, FEnum(e, ef)) -> let changed_name = change_id ef.ef_name in write w changed_name | _ -> expr_s w e); write w ":"; newline w; ) el; in_value := false; expr_s w (mk_block e); newline w; newline w ) ele_l; if is_some default then begin write w "default:"; newline w; in_value := false; expr_s w (get default); newline w; end; end_block w | TTry (tryexpr, ve_l) -> write w "try "; in_value := false; expr_s w (mk_block tryexpr); let pos = e.epos in List.iter (fun (var, e) -> print w "catch (%s %s)" (t_s pos var.v_type) (var.v_name); in_value := false; expr_s w (mk_block e); newline w ) ve_l | TReturn eopt -> write w "return "; if is_some eopt then expr_s w (get eopt) | TBreak -> write w "break" | TContinue -> write w "continue" | TThrow e -> write w "throw "; expr_s w e | TCast (e1,md_t) -> ((*match gen.gfollow#run_f e.etype with | TType({ t_path = ([], "UInt") }, []) -> write w "( unchecked ((uint) "; expr_s w e1; write w ") )" | _ ->*) (* FIXME I'm ignoring module type *) print w "((%s) (" (t_s e.epos e.etype); expr_s w e1; write w ") )" ) | TFor (_,_,content) -> write w "[ for not supported "; expr_s w content; write w " ]"; if !strict_mode then assert false | TObjectDecl _ -> write w "[ obj decl not supported ]"; if !strict_mode then assert false | TFunction _ -> write w "[ func decl not supported ]"; if !strict_mode then assert false | TEnumParameter _ -> write w "[ enum parameter not supported ]"; if !strict_mode then assert false in expr_s w e in let rec gen_fpart_attrib w = function | EConst( Ident i ), _ -> write w i | EField( ef, f ), _ -> gen_fpart_attrib w ef; write w "."; write w f | _, p -> gen.gcon.error "Invalid expression inside @:meta metadata" p in let rec gen_spart w = function | EConst c, p -> (match c with | Int s | Float s | Ident s -> write w s | String s -> write w "\""; write w (escape s); write w "\"" | _ -> gen.gcon.error "Invalid expression inside @:meta metadata" p) | EField( ef, f ), _ -> gen_spart w ef; write w "."; write w f | EBinop( Ast.OpAssign, (EConst (Ident s), _), e2 ), _ -> write w s; write w " = "; gen_spart w e2 | EArrayDecl( el ), _ -> write w "{"; let fst = ref true in List.iter (fun e -> if !fst then fst := false else write w ", "; gen_spart w e ) el; write w "}" | ECall(fpart,args), _ -> gen_fpart_attrib w fpart; write w "("; let fst = ref true in List.iter (fun e -> if !fst then fst := false else write w ", "; gen_spart w e ) args; write w ")" | _, p -> gen.gcon.error "Invalid expression inside @:meta metadata" p in let gen_annotations w ?(add_newline=true) metadata = List.iter (function | Meta.Meta, [meta], _ -> write w "@"; gen_spart w meta; if add_newline then newline w else write w " "; | _ -> () ) metadata in let argt_s p t = let w = new_source_writer () in let rec run t = match t with | TType (tdef,p) -> gen_annotations w ~add_newline:false tdef.t_meta; run (follow_once t) | TMono r -> (match !r with | Some t -> run t | _ -> () (* avoid infinite loop / should be the same in this context *)) | TLazy f -> run (!f()) | _ -> () in run t; let ret = t_s p t in let c = contents w in if c <> "" then c ^ " " ^ ret else ret in let get_string_params cl_params = match cl_params with | [] -> ("","") | _ -> let params = sprintf "<%s>" (String.concat ", " (List.map (fun (_, tcl) -> match follow tcl with | TInst(cl, _) -> snd cl.cl_path | _ -> assert false) cl_params)) in let params_extends = List.fold_left (fun acc (name, t) -> match run_follow gen t with | TInst (cl, p) -> (match cl.cl_implements with | [] -> acc | _ -> acc) (* TODO | _ -> (sprintf " where %s : %s" name (String.concat ", " (List.map (fun (cl,p) -> path_param_s (TClassDecl cl) cl.cl_path p) cl.cl_implements))) :: acc ) *) | _ -> trace (t_s null_pos t); assert false (* FIXME it seems that a cl_params will never be anything other than cl.cl_params. I'll take the risk and fail if not, just to see if that confirms *) ) [] cl_params in (params, String.concat " " params_extends) in let write_parts w parts = let parts = List.filter (fun s -> s <> "") parts in write w (String.concat " " parts) in let rec gen_class_field w ?(is_overload=false) is_static cl is_final cf = let is_interface = cl.cl_interface in let name, is_new, is_explicit_iface = match cf.cf_name with | "new" -> snd cl.cl_path, true, false | name when String.contains name '.' -> let fn_name, path = parse_explicit_iface name in (path_s path cl.cl_meta) ^ "." ^ fn_name, false, true | name -> name, false, false in (match cf.cf_kind with | Var _ | Method (MethDynamic) when not (Type.is_extern_field cf) -> (if is_overload || List.exists (fun cf -> cf.cf_expr <> None) cf.cf_overloads then gen.gcon.error "Only normal (non-dynamic) methods can be overloaded" cf.cf_pos); if not is_interface then begin let access, modifiers = get_fun_modifiers cf.cf_meta "public" [] in write_parts w (access :: (if is_static then "static" else "") :: modifiers @ [(t_s cf.cf_pos (run_follow gen cf.cf_type)); (change_field name)]); (match cf.cf_expr with | Some e -> write w " = "; expr_s w e; write w ";" | None -> write w ";" ) end (* TODO see how (get,set) variable handle when they are interfaces *) | Method _ when Type.is_extern_field cf || (match cl.cl_kind, cf.cf_expr with | KAbstractImpl _, None -> true | _ -> false) -> List.iter (fun cf -> if cl.cl_interface || cf.cf_expr <> None then gen_class_field w ~is_overload:true is_static cl (Meta.has Meta.Final cf.cf_meta) cf ) cf.cf_overloads | Var _ | Method MethDynamic -> () | Method mkind -> List.iter (fun cf -> if cl.cl_interface || cf.cf_expr <> None then gen_class_field w ~is_overload:true is_static cl (Meta.has Meta.Final cf.cf_meta) cf ) cf.cf_overloads; let is_virtual = is_new || (not is_final && match mkind with | MethInline -> false | _ when not is_new -> true | _ -> false) in let is_override = match cf.cf_name with | "equals" when not is_static -> (match cf.cf_type with | TFun([_,_,t], ret) -> (match (real_type t, real_type ret) with | TDynamic _, TAbstract ({ a_path = ([], "Bool") },[]) | TAnon _, TAbstract ({ a_path = ([], "Bool") },[]) -> true | _ -> List.memq cf cl.cl_overrides ) | _ -> List.memq cf cl.cl_overrides) | "toString" when not is_static -> (match cf.cf_type with | TFun([], ret) -> (match real_type ret with | TInst( { cl_path = ([], "String") }, []) -> true | _ -> gen.gcon.error "A toString() function should return a String!" cf.cf_pos; false ) | _ -> List.memq cf cl.cl_overrides ) | "hashCode" when not is_static -> (match cf.cf_type with | TFun([], ret) -> (match real_type ret with | TAbstract ({ a_path = ([], "Int") },[]) -> true | _ -> gen.gcon.error "A hashCode() function should return an Int!" cf.cf_pos; false ) | _ -> List.memq cf cl.cl_overrides ) | _ -> List.memq cf cl.cl_overrides in let visibility = if is_interface then "" else "public" in let visibility, modifiers = get_fun_modifiers cf.cf_meta visibility [] in let visibility, is_virtual = if is_explicit_iface then "",false else visibility, is_virtual in let v_n = if is_static then "static" else if is_override && not is_interface then "" else if not is_virtual then "final" else "" in let cf_type = if is_override && not is_overload && not (Meta.has Meta.Overload cf.cf_meta) then match field_access gen (TInst(cl, List.map snd cl.cl_params)) cf.cf_name with | FClassField(_,_,_,_,_,actual_t,_) -> actual_t | _ -> assert false else cf.cf_type in let params = List.map snd cl.cl_params in let ret_type, args = match follow cf_type, follow cf.cf_type with | TFun (strbtl, t), TFun(rargs, _) -> (apply_params cl.cl_params params (real_type t), List.map2 (fun(_,_,t) (n,o,_) -> (n,o,apply_params cl.cl_params params (real_type t))) strbtl rargs) | _ -> assert false in (if is_override && not is_interface then write w "@Override "); gen_annotations w cf.cf_meta; (* public static void funcName *) let params, _ = get_string_params cf.cf_params in write_parts w (visibility :: v_n :: modifiers @ [params; (if is_new then "" else rett_s cf.cf_pos (run_follow gen ret_type)); (change_field name)]); (* (string arg1, object arg2) with T : object *) (match cf.cf_expr with | Some { eexpr = TFunction tf } -> print w "(%s)" (String.concat ", " (List.map2 (fun (var,_) (_,_,t) -> sprintf "%s %s" (argt_s cf.cf_pos (run_follow gen t)) (change_id var.v_name)) tf.tf_args args)) | _ -> print w "(%s)" (String.concat ", " (List.map (fun (name, _, t) -> sprintf "%s %s" (argt_s cf.cf_pos (run_follow gen t)) (change_id name)) args)) ); if is_interface || List.mem "native" modifiers then write w ";" else begin let rec loop meta = match meta with | [] -> let expr = match cf.cf_expr with | None -> mk (TBlock([])) t_dynamic null_pos | Some s -> match s.eexpr with | TFunction tf -> mk_block (tf.tf_expr) | _ -> assert false (* FIXME *) in (if is_new then begin (*let rec get_super_call el = match el with | ( { eexpr = TCall( { eexpr = TConst(TSuper) }, _) } as call) :: rest -> Some call, rest | ( { eexpr = TBlock(bl) } as block ) :: rest -> let ret, mapped = get_super_call bl in ret, ( { block with eexpr = TBlock(mapped) } :: rest ) | _ -> None, el in*) expr_s w expr end else begin expr_s w expr; end) | (Meta.Throws, [Ast.EConst (Ast.String t), _], _) :: tl -> print w " throws %s" t; loop tl | (Meta.FunctionCode, [Ast.EConst (Ast.String contents),_],_) :: tl -> begin_block w; write w contents; end_block w | _ :: tl -> loop tl in loop cf.cf_meta end); newline w; newline w in let gen_class w cl = let cf_filters = [ handle_throws ] in List.iter (fun f -> List.iter (f gen) cl.cl_ordered_fields) cf_filters; List.iter (fun f -> List.iter (f gen) cl.cl_ordered_statics) cf_filters; let should_close = match change_ns (fst cl.cl_path) with | [] -> false | ns -> print w "package %s;" (String.concat "." (change_ns ns)); newline w; newline w; false in let rec loop_meta meta acc = match meta with | (Meta.SuppressWarnings, [Ast.EConst (Ast.String w),_],_) :: meta -> loop_meta meta (w :: acc) | _ :: meta -> loop_meta meta acc | _ -> acc in let suppress_warnings = loop_meta cl.cl_meta [ "rawtypes"; "unchecked" ] in write w "import haxe.root.*;"; newline w; let w_header = w in let w = new_source_writer () in clear_scope(); (* add all haxe.root.* to imports *) List.iter (function | TClassDecl { cl_path = ([],c) } -> imports := ([],c) :: !imports | TEnumDecl { e_path = ([],c) } -> imports := ([],c) :: !imports | TAbstractDecl { a_path = ([],c) } -> imports := ([],c) :: !imports | _ -> () ) gen.gtypes_list; newline w; write w "@SuppressWarnings(value={"; let first = ref true in List.iter (fun s -> (if !first then first := false else write w ", "); print w "\"%s\"" (escape s) ) suppress_warnings; write w "})"; newline w; gen_annotations w cl.cl_meta; let clt, access, modifiers = get_class_modifiers cl.cl_meta (if cl.cl_interface then "interface" else "class") "public" [] in let is_final = Meta.has Meta.Final cl.cl_meta in write_parts w (access :: modifiers @ [clt; (change_clname (snd cl.cl_path))]); (* type parameters *) let params, _ = get_string_params cl.cl_params in let cl_p_to_string (c,p) = let p = List.map (fun t -> match follow t with | TMono _ | TDynamic _ -> t_empty | _ -> t) p in path_param_s cl.cl_pos (TClassDecl c) c.cl_path p c.cl_meta in print w "%s" params; (if is_some cl.cl_super then print w " extends %s" (cl_p_to_string (get cl.cl_super))); (match cl.cl_implements with | [] -> () | _ -> print w " %s %s" (if cl.cl_interface then "extends" else "implements") (String.concat ", " (List.map cl_p_to_string cl.cl_implements)) ); (* class head ok: *) (* public class Test : X, Y, Z where A : Y *) begin_block w; (* our constructor is expected to be a normal "new" function * if !strict_mode && is_some cl.cl_constructor then assert false;*) let rec loop cl = List.iter (fun cf -> add_scope cf.cf_name) cl.cl_ordered_fields; List.iter (fun cf -> add_scope cf.cf_name) cl.cl_ordered_statics; match cl.cl_super with | Some(c,_) -> loop c | None -> () in loop cl; let rec loop meta = match meta with | [] -> () | (Meta.ClassCode, [Ast.EConst (Ast.String contents),_],_) :: tl -> write w contents | _ :: tl -> loop tl in loop cl.cl_meta; (match gen.gcon.main_class with | Some path when path = cl.cl_path -> write w "public static void main(String[] args)"; begin_block w; (try let t = Hashtbl.find gen.gtypes ([], "Sys") in match t with | TClassDecl(cl) when PMap.mem "_args" cl.cl_statics -> write w "Sys._args = args;"; newline w | _ -> () with | Not_found -> () ); (match gen.gcon.main with | Some(expr) -> expr_s w (mk_block expr) | None -> write w "main();"); end_block w; newline w | _ -> () ); (match cl.cl_init with | None -> () | Some init -> write w "static"; expr_s w (mk_block init); newline w ); (if is_some cl.cl_constructor then gen_class_field w false cl is_final (get cl.cl_constructor)); (if not cl.cl_interface then List.iter (gen_class_field w true cl is_final) cl.cl_ordered_statics); List.iter (gen_class_field w false cl is_final) cl.cl_ordered_fields; end_block w; if should_close then end_block w; (* add imports *) List.iter (function | ["haxe";"root"], _ | [], _ -> () | path -> write w_header "import "; write w_header (path_s path []); write w_header ";\n" ) !imports; add_writer w w_header in let gen_enum w e = let should_close = match change_ns (fst e.e_path) with | [] -> false | ns -> print w "package %s;" (String.concat "." (change_ns ns)); newline w; newline w; false in gen_annotations w e.e_meta; print w "public enum %s" (change_clname (snd e.e_path)); begin_block w; write w (String.concat ", " (List.map (change_id) e.e_names)); end_block w; if should_close then end_block w in let module_type_gen w md_tp = Codegen.map_source_header gen.gcon (fun s -> print w "// %s\n" s); match md_tp with | TClassDecl cl -> if not cl.cl_extern then begin gen_class w cl; newline w; newline w end; (not cl.cl_extern) | TEnumDecl e -> if not e.e_extern && not (Meta.has Meta.Class e.e_meta) then begin gen_enum w e; newline w; newline w end; (not e.e_extern) | TTypeDecl e -> false | TAbstractDecl a -> false in (* generate source code *) init_ctx gen; Hashtbl.add gen.gspecial_vars "__label__" true; Hashtbl.add gen.gspecial_vars "__goto__" true; Hashtbl.add gen.gspecial_vars "__is__" true; Hashtbl.add gen.gspecial_vars "__typeof__" true; Hashtbl.add gen.gspecial_vars "__java__" true; Hashtbl.add gen.gspecial_vars "__lock__" true; Hashtbl.add gen.gspecial_vars "__array__" true; gen.greal_type <- real_type; gen.greal_type_param <- change_param_type; SetHXGen.run_filter gen; (* before running the filters, follow all possible types *) (* this is needed so our module transformations don't break some core features *) (* like multitype selection *) let run_follow_gen = run_follow gen in let rec type_map e = Type.map_expr_type (fun e->type_map e) (run_follow_gen) (fun tvar-> tvar.v_type <- (run_follow_gen tvar.v_type); tvar) e in let super_map (cl,tl) = (cl, List.map run_follow_gen tl) in List.iter (function | TClassDecl cl -> let all_fields = (Option.map_default (fun cf -> [cf]) [] cl.cl_constructor) @ cl.cl_ordered_fields @ cl.cl_ordered_statics in List.iter (fun cf -> cf.cf_type <- run_follow_gen cf.cf_type; cf.cf_expr <- Option.map type_map cf.cf_expr ) all_fields; cl.cl_dynamic <- Option.map run_follow_gen cl.cl_dynamic; cl.cl_array_access <- Option.map run_follow_gen cl.cl_array_access; cl.cl_init <- Option.map type_map cl.cl_init; cl.cl_super <- Option.map super_map cl.cl_super; cl.cl_implements <- List.map super_map cl.cl_implements | _ -> () ) gen.gtypes_list; let get_vmtype t = match real_type t with | TInst({ cl_path = ["java"],"NativeArray" }, tl) -> t | TInst(c,tl) -> TInst(c,List.map (fun _ -> t_dynamic) tl) | TEnum(e,tl) -> TEnum(e, List.map (fun _ -> t_dynamic) tl) | TType(t,tl) -> TType(t, List.map (fun _ -> t_dynamic) tl) | TAbstract(a,tl) -> TAbstract(a, List.map (fun _ -> t_dynamic) tl) | t -> t in FixOverrides.configure ~get_vmtype gen; Normalize.configure gen ~metas:(Hashtbl.create 0); AbstractImplementationFix.configure gen; IteratorsInterface.configure gen; let closure_t = ClosuresToClass.DoubleAndDynamicClosureImpl.get_ctx gen (get_cl (get_type gen (["haxe";"lang"],"Function"))) 6 in ClosuresToClass.configure gen closure_t; let enum_base = (get_cl (get_type gen (["haxe";"lang"],"Enum")) ) in let param_enum_base = (get_cl (get_type gen (["haxe";"lang"],"ParamEnum")) ) in EnumToClass.configure gen (None) false true enum_base param_enum_base; InterfaceVarsDeleteModf.configure gen; let dynamic_object = (get_cl (get_type gen (["haxe";"lang"],"DynamicObject")) ) in let object_iface = get_cl (get_type gen (["haxe";"lang"],"IHxObject")) in let empty_en = match get_type gen (["haxe";"lang"], "EmptyObject") with TEnumDecl e -> e | _ -> assert false in let empty_ctor_type = TEnum(empty_en, []) in let empty_en_expr = mk (TTypeExpr (TEnumDecl empty_en)) (TAnon { a_fields = PMap.empty; a_status = ref (EnumStatics empty_en) }) null_pos in let empty_ctor_expr = mk (TField (empty_en_expr, FEnum(empty_en, PMap.find "EMPTY" empty_en.e_constrs))) empty_ctor_type null_pos in OverloadingConstructor.configure ~empty_ctor_type:empty_ctor_type ~empty_ctor_expr:empty_ctor_expr gen; let rcf_static_find = mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) "findHash" null_pos [] in (*let rcf_static_lookup = mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) "lookupHash" null_pos [] in*) let get_specialized_postfix t = match t with | TAbstract({a_path = [],"Float"}, _) -> "Float" | TInst({cl_path = [],"String"},_) -> "String" | TAnon _ | TDynamic _ -> "Dynamic" | _ -> print_endline (debug_type t); assert false in let rcf_static_insert t = mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) ("insert" ^ get_specialized_postfix t) null_pos [] in let rcf_static_remove t = mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) ("remove" ^ get_specialized_postfix t) null_pos [] in let can_be_float t = like_float (real_type t) in let rcf_on_getset_field main_expr field_expr field may_hash may_set is_unsafe = let is_float = can_be_float (if is_none may_set then main_expr.etype else (get may_set).etype) in let fn_name = if is_some may_set then "setField" else "getField" in let fn_name = if is_float then fn_name ^ "_f" else fn_name in let pos = field_expr.epos in let is_unsafe = { eexpr = TConst(TBool is_unsafe); etype = basic.tbool; epos = pos } in let should_cast = match main_expr.etype with | TAbstract({ a_path = ([], "Float") }, []) -> false | _ -> true in let infer = mk_static_field_access_infer runtime_cl fn_name field_expr.epos [] in let first_args = [ field_expr; { eexpr = TConst(TString field); etype = basic.tstring; epos = pos } ] @ if is_some may_hash then [ { eexpr = TConst(TInt (get may_hash)); etype = basic.tint; epos = pos } ] else [] in let args = first_args @ match is_float, may_set with | true, Some(set) -> [ if should_cast then mk_cast basic.tfloat set else set ] | false, Some(set) -> [ set ] | _ -> [ is_unsafe ] in let call = { main_expr with eexpr = TCall(infer,args) } in let call = if is_float && should_cast then mk_cast main_expr.etype call else call in call in let rcf_on_call_field ecall field_expr field may_hash args = let infer = mk_static_field_access_infer runtime_cl "callField" field_expr.epos [] in let hash_arg = match may_hash with | None -> [] | Some h -> [ { eexpr = TConst(TInt h); etype = basic.tint; epos = field_expr.epos } ] in let arr_call = if args <> [] then { eexpr = TArrayDecl args; etype = basic.tarray t_dynamic; epos = ecall.epos } else null (basic.tarray t_dynamic) ecall.epos in let call_args = [field_expr; { field_expr with eexpr = TConst(TString field); etype = basic.tstring } ] @ hash_arg @ [ arr_call ] in mk_cast ecall.etype { ecall with eexpr = TCall(infer, call_args); etype = t_dynamic } in let rcf_ctx = ReflectionCFs.new_ctx gen closure_t object_iface false rcf_on_getset_field rcf_on_call_field (fun hash hash_array length -> { hash with eexpr = TCall(rcf_static_find, [hash; hash_array; length]); etype=basic.tint }) (fun hash -> hash) (fun hash_array length pos value -> { hash_array with eexpr = TBinop(OpAssign, hash_array, mk (TCall(rcf_static_insert value.etype, [hash_array; length; pos; value])) hash_array.etype hash_array.epos) }) (fun hash_array length pos -> let t = gen.gclasses.nativearray_type hash_array.etype in { hash_array with eexpr = TCall(rcf_static_remove t, [hash_array; length; pos]); etype = gen.gcon.basic.tvoid } ) None in ReflectionCFs.UniversalBaseClass.configure gen (get_cl (get_type gen (["haxe";"lang"],"HxObject")) ) object_iface dynamic_object; ReflectionCFs.configure_dynamic_field_access rcf_ctx; ReflectionCFs.implement_varargs_cl rcf_ctx ( get_cl (get_type gen (["haxe";"lang"], "VarArgsBase")) ); let slow_invoke = mk_static_field_access_infer (runtime_cl) "slowCallField" null_pos [] in ReflectionCFs.configure rcf_ctx ~slow_invoke:(fun ethis efield eargs -> { eexpr = TCall(slow_invoke, [ethis; efield; eargs]); etype = t_dynamic; epos = ethis.epos; } ) object_iface; ObjectDeclMap.configure gen (ReflectionCFs.implement_dynamic_object_ctor rcf_ctx dynamic_object); InitFunction.configure gen; TArrayTransform.configure gen ( fun e _ -> match e.eexpr with | TArray ({ eexpr = TLocal { v_extra = Some( _ :: _, _) } }, _) -> (* captured transformation *) false | TArray(e1, e2) -> ( match run_follow gen (follow e1.etype) with | TInst({ cl_path = (["java"], "NativeArray") }, _) -> false | _ -> true ) | _ -> assert false ) "__get" "__set"; let field_is_dynamic t field = match field_access_esp gen (gen.greal_type t) field with | FClassField (cl,p,_,_,_,t,_) -> let p = change_param_type (TClassDecl cl) p in is_dynamic (apply_params cl.cl_params p t) | FEnumField _ -> false | _ -> true in let is_type_param e = match follow e with | TInst( { cl_kind = KTypeParameter _ },[]) -> true | _ -> false in let is_dynamic_expr e = is_dynamic e.etype || match e.eexpr with | TField(tf, f) -> field_is_dynamic tf.etype f | _ -> false in let may_nullable t = match gen.gfollow#run_f t with | TType({ t_path = ([], "Null") }, [t]) -> (match follow t with | TInst({ cl_path = ([], "String") }, []) | TAbstract ({ a_path = ([], "Float") },[]) | TInst({ cl_path = (["haxe"], "Int32")}, [] ) | TInst({ cl_path = (["haxe"], "Int64")}, [] ) | TAbstract ({ a_path = ([], "Int") },[]) | TAbstract ({ a_path = ([], "Bool") },[]) -> Some t | t when is_java_basic_type t -> Some t | _ -> None ) | _ -> None in let is_double t = like_float t && not (like_int t) in let is_int t = like_int t in DynamicOperators.configure gen (fun e -> match e.eexpr with | TBinop (Ast.OpEq, e1, e2) -> is_dynamic e1.etype || is_dynamic e2.etype || is_type_param e1.etype || is_type_param e2.etype | TBinop (Ast.OpAdd, e1, e2) | TBinop (Ast.OpNotEq, e1, e2) -> is_dynamic e1.etype || is_dynamic e2.etype || is_type_param e1.etype || is_type_param e2.etype | TBinop (Ast.OpLt, e1, e2) | TBinop (Ast.OpLte, e1, e2) | TBinop (Ast.OpGte, e1, e2) | TBinop (Ast.OpGt, e1, e2) -> is_dynamic e.etype || is_dynamic_expr e1 || is_dynamic_expr e2 || is_string e1.etype || is_string e2.etype | TBinop (_, e1, e2) -> is_dynamic e.etype || is_dynamic_expr e1 || is_dynamic_expr e2 | TUnop (_, _, e1) -> is_dynamic_expr e1 | _ -> false) (fun e1 e2 -> let is_null e = match e.eexpr with | TConst(TNull) | TLocal({ v_name = "__undefined__" }) -> true | _ -> false in match e1.eexpr, e2.eexpr with | TConst c1, TConst c2 when is_null e1 || is_null e2 -> { e1 with eexpr = TConst(TBool (c1 = c2)); etype = basic.tbool } | _ when is_null e1 || is_null e2 && not (is_java_basic_type e1.etype || is_java_basic_type e2.etype) -> { e1 with eexpr = TBinop(Ast.OpEq, e1, e2); etype = basic.tbool } | _ -> let is_ref = match follow e1.etype, follow e2.etype with | TDynamic _, _ | _, TDynamic _ | TAbstract ({ a_path = ([], "Float") },[]) , _ | TInst( { cl_path = (["haxe"], "Int32") }, [] ), _ | TInst( { cl_path = (["haxe"], "Int64") }, [] ), _ | TAbstract ({ a_path = ([], "Int") },[]) , _ | TAbstract ({ a_path = ([], "Bool") },[]) , _ | _, TAbstract ({ a_path = ([], "Float") },[]) | _, TAbstract ({ a_path = ([], "Int") },[]) | _, TInst( { cl_path = (["haxe"], "Int32") }, [] ) | _, TInst( { cl_path = (["haxe"], "Int64") }, [] ) | _, TAbstract ({ a_path = ([], "Bool") },[]) | TInst( { cl_kind = KTypeParameter _ }, [] ), _ | _, TInst( { cl_kind = KTypeParameter _ }, [] ) -> false | _, _ -> true in let static = mk_static_field_access_infer (runtime_cl) (if is_ref then "refEq" else "eq") e1.epos [] in { eexpr = TCall(static, [e1; e2]); etype = gen.gcon.basic.tbool; epos=e1.epos } ) (fun e e1 e2 -> match may_nullable e1.etype, may_nullable e2.etype with | Some t1, Some t2 -> let t1, t2 = if is_string t1 || is_string t2 then basic.tstring, basic.tstring else if is_double t1 || is_double t2 then basic.tfloat, basic.tfloat else if is_int t1 || is_int t2 then basic.tint, basic.tint else t1, t2 in { eexpr = TBinop(Ast.OpAdd, mk_cast t1 e1, mk_cast t2 e2); etype = e.etype; epos = e1.epos } | _ -> let static = mk_static_field_access_infer (runtime_cl) "plus" e1.epos [] in mk_cast e.etype { eexpr = TCall(static, [e1; e2]); etype = t_dynamic; epos=e1.epos }) (fun e1 e2 -> if is_string e1.etype then begin { e1 with eexpr = TCall(mk_field_access gen e1 "compareTo" e1.epos, [ e2 ]); etype = gen.gcon.basic.tint } end else begin let static = mk_static_field_access_infer (runtime_cl) "compare" e1.epos [] in { eexpr = TCall(static, [e1; e2]); etype = gen.gcon.basic.tint; epos=e1.epos } end); let closure_cl = get_cl (get_type gen (["haxe";"lang"],"Closure")) in FilterClosures.configure gen (fun e1 s -> true) (ReflectionCFs.get_closure_func rcf_ctx closure_cl); let base_exception = get_cl (get_type gen (["java"; "lang"], "Throwable")) in let base_exception_t = TInst(base_exception, []) in let hx_exception = get_cl (get_type gen (["haxe";"lang"], "HaxeException")) in let hx_exception_t = TInst(hx_exception, []) in let rec is_exception t = match follow t with | TInst(cl,_) -> if cl == base_exception then true else (match cl.cl_super with | None -> false | Some (cl,arg) -> is_exception (TInst(cl,arg))) | _ -> false in TryCatchWrapper.configure gen (fun t -> not (is_exception (real_type t))) (fun throwexpr expr -> let wrap_static = mk_static_field_access (hx_exception) "wrap" (TFun([("obj",false,t_dynamic)], hx_exception_t)) expr.epos in { throwexpr with eexpr = TThrow { expr with eexpr = TCall(wrap_static, [expr]); etype = hx_exception_t }; etype = gen.gcon.basic.tvoid } ) (fun v_to_unwrap pos -> let local = mk_cast hx_exception_t { eexpr = TLocal(v_to_unwrap); etype = v_to_unwrap.v_type; epos = pos } in mk_field_access gen local "obj" pos ) (fun rethrow -> let wrap_static = mk_static_field_access (hx_exception) "wrap" (TFun([("obj",false,t_dynamic)], hx_exception_t)) rethrow.epos in { rethrow with eexpr = TThrow { rethrow with eexpr = TCall(wrap_static, [rethrow]); etype = hx_exception_t }; } ) (base_exception_t) (hx_exception_t) (fun v e -> let exc_cl = get_cl (get_type gen (["haxe";"lang"],"Exceptions")) in let exc_field = mk_static_field_access_infer exc_cl "setException" e.epos [] in let esetstack = { eexpr = TCall(exc_field,[mk_local v e.epos]); etype = gen.gcon.basic.tvoid; epos = e.epos } in Type.concat esetstack e; ); ClassInstance.configure gen (fun e _ -> { e with eexpr = TCall({ eexpr = TLocal(alloc_var "__typeof__" t_dynamic); etype = t_dynamic; epos = e.epos }, [e]) }); CastDetect.configure gen (Some empty_ctor_type) false; SwitchToIf.configure gen (fun e -> match e.eexpr with | TSwitch(cond, cases, def) -> (match gen.gfollow#run_f cond.etype with | TInst( { cl_path = (["haxe"], "Int32") }, [] ) | TAbstract ({ a_path = ([], "Int") },[]) | TInst({ cl_path = ([], "String") },[]) -> (List.exists (fun (c,_) -> List.exists (fun expr -> match expr.eexpr with | TConst _ -> false | _ -> true ) c ) cases) | _ -> true ) | _ -> assert false ); ExpressionUnwrap.configure gen (fun e -> Some { eexpr = TVar(mk_temp gen "expr" e.etype, Some e); etype = gen.gcon.basic.tvoid; epos = e.epos }); UnnecessaryCastsRemoval.configure gen; IntDivisionSynf.configure gen; UnreachableCodeEliminationSynf.configure gen true; ArrayDeclSynf.configure gen native_arr_cl; let goto_special = alloc_var "__goto__" t_dynamic in let label_special = alloc_var "__label__" t_dynamic in SwitchBreakSynf.configure gen (fun e_loop n api -> { e_loop with eexpr = TBlock( { eexpr = TCall( mk_local label_special e_loop.epos, [ Codegen.ExprBuilder.make_int gen.gcon n e_loop.epos ] ); etype = t_dynamic; epos = e_loop.epos } :: [e_loop] ) }; ) (fun e_break n api -> { eexpr = TCall( mk_local goto_special e_break.epos, [ Codegen.ExprBuilder.make_int gen.gcon n e_break.epos ] ); etype = t_dynamic; epos = e_break.epos } ); DefaultArguments.configure gen; InterfaceMetas.configure gen; JavaSpecificSynf.configure gen runtime_cl; JavaSpecificESynf.configure gen runtime_cl; (* add native String as a String superclass *) let str_cl = match gen.gcon.basic.tstring with | TInst(cl,_) -> cl | _ -> assert false in str_cl.cl_super <- Some (get_cl (get_type gen (["haxe";"lang"], "NativeString")), []); let mkdir dir = if not (Sys.file_exists dir) then Unix.mkdir dir 0o755 in mkdir gen.gcon.file; mkdir (gen.gcon.file ^ "/src"); let out_files = ref [] in (* add resources array *) let res = ref [] in Hashtbl.iter (fun name v -> res := { eexpr = TConst(TString name); etype = gen.gcon.basic.tstring; epos = null_pos } :: !res; let name = Codegen.escape_res_name name true in let full_path = gen.gcon.file ^ "/src/" ^ name in mkdir_from_path full_path; let f = open_out_bin full_path in output_string f v; close_out f; out_files := (Path.unique_full_path full_path) :: !out_files ) gen.gcon.resources; (try let c = get_cl (Hashtbl.find gen.gtypes (["haxe"], "Resource")) in let cf = PMap.find "content" c.cl_statics in cf.cf_expr <- Some ({ eexpr = TArrayDecl(!res); etype = gen.gcon.basic.tarray gen.gcon.basic.tstring; epos = null_pos }) with | Not_found -> ()); run_filters gen; TypeParams.RenameTypeParameters.run gen; let parts = Str.split_delim (Str.regexp "[\\/]+") gen.gcon.file in mkdir_recursive "" parts; let source_dir = gen.gcon.file ^ "/src" in List.iter (fun md -> let w = SourceWriter.new_source_writer () in let should_write = module_type_gen w md in if should_write then begin let path = change_path (t_path md) in write_file gen w (source_dir ^ "/" ^ (String.concat "/" (fst path))) path "java" out_files; end ) gen.gtypes_list; if not (Common.defined gen.gcon Define.KeepOldOutput) then clean_files (gen.gcon.file ^ "/src") !out_files gen.gcon.verbose; let path_s_desc path = path_s path [] in dump_descriptor gen ("hxjava_build.txt") path_s_desc (fun md -> path_s_desc (t_infos md).mt_path); if ( not (Common.defined gen.gcon Define.NoCompilation) ) then begin let old_dir = Sys.getcwd() in Sys.chdir gen.gcon.file; let cmd = "haxelib run hxjava hxjava_build.txt --haxe-version " ^ (string_of_int gen.gcon.version) ^ " --feature-level 1" in print_endline cmd; if gen.gcon.run_command cmd <> 0 then failwith "Build failed"; Sys.chdir old_dir; end (* end of configure function *) let before_generate con = let java_ver = try int_of_string (PMap.find "java_ver" con.defines) with | Not_found -> Common.define_value con Define.JavaVer "7"; 7 in if java_ver < 5 then failwith ("Java version is defined to target Java " ^ string_of_int java_ver ^ ", but the compiler can only output code to versions equal or superior to Java 5"); let rec loop i = Common.raw_define con ("java" ^ (string_of_int i)); if i > 0 then loop (i - 1) in loop java_ver; () let generate con = let exists = ref false in con.java_libs <- List.map (fun (file,std,close,la,gr) -> if String.ends_with file "hxjava-std.jar" then begin exists := true; (file,true,close,la,gr) end else (file,std,close,la,gr)) con.java_libs; if not !exists then failwith "Your version of hxjava is outdated. Please update it by running: `haxelib update hxjava`"; let gen = new_ctx con in gen.gallow_tp_dynamic_conversion <- true; let basic = con.basic in (* make the basic functions in java *) let cl_cl = get_cl (get_type gen (["java";"lang"],"Class")) in let basic_fns = [ mk_class_field "equals" (TFun(["obj",false,t_dynamic], basic.tbool)) true null_pos (Method MethNormal) []; mk_class_field "toString" (TFun([], basic.tstring)) true null_pos (Method MethNormal) []; mk_class_field "hashCode" (TFun([], basic.tint)) true null_pos (Method MethNormal) []; mk_class_field "getClass" (TFun([], (TInst(cl_cl,[t_dynamic])))) true null_pos (Method MethNormal) []; mk_class_field "wait" (TFun([], basic.tvoid)) true null_pos (Method MethNormal) []; mk_class_field "notify" (TFun([], basic.tvoid)) true null_pos (Method MethNormal) []; mk_class_field "notifyAll" (TFun([], basic.tvoid)) true null_pos (Method MethNormal) []; ] in List.iter (fun cf -> gen.gbase_class_fields <- PMap.add cf.cf_name cf gen.gbase_class_fields) basic_fns; (try configure gen with | TypeNotFound path -> con.error ("Error. Module '" ^ (s_type_path path) ^ "' is required and was not included in build.") null_pos); debug_mode := false (** Java lib *) open JData type java_lib_ctx = { jcom : Common.context; (* current tparams context *) mutable jtparams : jtypes list; } exception ConversionError of string * pos let error s p = raise (ConversionError (s, p)) let is_haxe_keyword = function | "callback" | "cast" | "extern" | "function" | "in" | "typedef" | "using" | "var" | "untyped" | "inline" -> true | _ -> false let jname_to_hx name = let name = if name <> "" && (String.get name 0 < 'A' || String.get name 0 > 'Z') then Char.escaped (Char.uppercase (String.get name 0)) ^ String.sub name 1 (String.length name - 1) else name in let name = String.concat "__" (String.nsplit name "_") in String.map (function | '$' -> '_' | c -> c) name let normalize_pack pack = List.map (function | "" -> "" | str when String.get str 0 >= 'A' && String.get str 0 <= 'Z' -> String.lowercase str | str -> str ) pack let jpath_to_hx (pack,name) = match pack, name with | ["haxe";"root"], name -> [], name | "com" :: ("oracle" | "sun") :: _, _ | "javax" :: _, _ | "org" :: ("ietf" | "jcp" | "omg" | "w3c" | "xml") :: _, _ | "sun" :: _, _ | "sunw" :: _, _ -> "java" :: normalize_pack pack, jname_to_hx name | pack, name -> normalize_pack pack, jname_to_hx name let real_java_path ctx (pack,name) = s_type_path (pack, name) let lookup_jclass com path = let path = jpath_to_hx path in List.fold_right (fun (_,_,_,_,get_raw_class) acc -> match acc with | None -> get_raw_class path | Some p -> Some p ) com.java_libs None let mk_type_path ctx path params = let name, sub = try let p, _ = String.split (snd path) "$" in jname_to_hx p, Some (jname_to_hx (snd path)) with | Invalid_string -> jname_to_hx (snd path), None in let pack = fst (jpath_to_hx path) in let pack, sub, name = match path with | [], ("Float" as c) | [], ("Int" as c) | [], ("Single" as c) | [], ("Bool" as c) | [], ("Dynamic" as c) | [], ("Iterator" as c) | [], ("ArrayAccess" as c) | [], ("Iterable" as c) -> [], Some c, "StdTypes" | [], ("String" as c) -> ["std"], None, c | _ -> pack, sub, name in CTPath { tpackage = pack; tname = name; tparams = params; tsub = sub; } let has_tparam name params = List.exists(fun (n,_,_) -> n = name) params let rec convert_arg ctx p arg = match arg with | TAny | TType (WSuper, _) -> TPType (mk_type_path ctx ([], "Dynamic") [],null_pos) | TType (_, jsig) -> TPType (convert_signature ctx p jsig,null_pos) and convert_signature ctx p jsig = match jsig with | TByte -> mk_type_path ctx (["java"; "types"], "Int8") [] | TChar -> mk_type_path ctx (["java"; "types"], "Char16") [] | TDouble -> mk_type_path ctx ([], "Float") [] | TFloat -> mk_type_path ctx ([], "Single") [] | TInt -> mk_type_path ctx ([], "Int") [] | TLong -> mk_type_path ctx (["haxe"], "Int64") [] | TShort -> mk_type_path ctx (["java"; "types"], "Int16") [] | TBool -> mk_type_path ctx ([], "Bool") [] | TObject ( (["haxe";"root"], name), args ) -> mk_type_path ctx ([], name) (List.map (convert_arg ctx p) args) (** nullable types *) (* replaced from Null to the actual abstract type to fix #2738 *) (* | TObject ( (["java";"lang"], "Integer"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx ([], "Int") []) ] *) (* | TObject ( (["java";"lang"], "Double"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx ([], "Float") []) ] *) (* | TObject ( (["java";"lang"], "Float"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx ([], "Single") []) ] *) (* | TObject ( (["java";"lang"], "Boolean"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx ([], "Bool") []) ] *) (* | TObject ( (["java";"lang"], "Byte"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx (["java";"types"], "Int8") []) ] *) (* | TObject ( (["java";"lang"], "Character"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx (["java";"types"], "Char16") []) ] *) (* | TObject ( (["java";"lang"], "Short"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx (["java";"types"], "Int16") []) ] *) (* | TObject ( (["java";"lang"], "Long"), [] ) -> mk_type_path ctx ([], "Null") [ TPType (mk_type_path ctx (["haxe"], "Int64") []) ] *) (** other std types *) | TObject ( (["java";"lang"], "Object"), [] ) -> mk_type_path ctx ([], "Dynamic") [] | TObject ( (["java";"lang"], "String"), [] ) -> mk_type_path ctx ([], "String") [] | TObject ( (["java";"lang"], "Enum"), [_] ) -> mk_type_path ctx ([], "EnumValue") [] (** other types *) | TObject ( path, [] ) -> (match lookup_jclass ctx.jcom path with | Some (jcl, _, _) -> mk_type_path ctx path (List.map (fun _ -> convert_arg ctx p TAny) jcl.ctypes) | None -> mk_type_path ctx path []) | TObject ( path, args ) -> mk_type_path ctx path (List.map (convert_arg ctx p) args) | TObjectInner (pack, (name, params) :: inners) -> let actual_param = match List.rev inners with | (_, p) :: _ -> p | _ -> assert false in mk_type_path ctx (pack, name ^ "$" ^ String.concat "$" (List.map fst inners)) (List.map (fun param -> convert_arg ctx p param) actual_param) | TObjectInner (pack, inners) -> assert false | TArray (jsig, _) -> mk_type_path ctx (["java"], "NativeArray") [ TPType (convert_signature ctx p jsig,null_pos) ] | TMethod _ -> JReader.error "TMethod cannot be converted directly into Complex Type" | TTypeParameter s -> (match ctx.jtparams with | cur :: others -> if has_tparam s cur then mk_type_path ctx ([], s) [] else begin if ctx.jcom.verbose && not(List.exists (has_tparam s) others) then print_endline ("Type parameter " ^ s ^ " was not found while building type!"); mk_type_path ctx ([], "Dynamic") [] end | _ -> if ctx.jcom.verbose then print_endline ("Empty type parameter stack!"); mk_type_path ctx ([], "Dynamic") []) let convert_constant ctx p const = Option.map_default (function | ConstString s -> Some (EConst (String s), p) | ConstInt i -> Some (EConst (Int (Printf.sprintf "%ld" i)), p) | ConstFloat f | ConstDouble f -> Some (EConst (Float (Printf.sprintf "%E" f)), p) | _ -> None) None const let rec same_sig parent jsig = match jsig with | TObject (p,targs) -> parent = p || List.exists (function | TType (_,s) -> same_sig parent s | _ -> false) targs | TObjectInner(p, ntargs) -> parent = (p, String.concat "$" (List.map fst ntargs)) || List.exists (fun (_,targs) -> List.exists (function | TType(_,s) -> same_sig parent s | _ -> false) targs) ntargs | TArray(s,_) -> same_sig parent s | _ -> false let convert_param ctx p parent param = let name, constraints = match param with | (name, Some extends_sig, implem_sig) -> name, extends_sig :: implem_sig | (name, None, implemem_sig) -> name, implemem_sig in let constraints = List.map (fun s -> if same_sig parent s then (TObject( (["java";"lang"], "Object"), [])) else s) constraints in { tp_name = name,null_pos; tp_params = []; tp_constraints = List.map (fun t -> convert_signature ctx p t,null_pos) constraints; tp_meta = []; } let get_type_path ctx ct = match ct with | CTPath p -> p | _ -> assert false let is_override field = List.exists (function | AttrVisibleAnnotations [{ ann_type = TObject( (["java";"lang"], "Override"), _ ) }] -> true | _ -> false) field.jf_attributes let mk_override field = { field with jf_attributes = ((AttrVisibleAnnotations [{ ann_type = TObject( (["java";"lang"], "Override"), [] ); ann_elements = [] }]) :: field.jf_attributes) } let del_override field = { field with jf_attributes = List.filter (fun a -> not (is_override_attrib a)) field.jf_attributes } let get_canonical ctx p pack name = (Meta.JavaCanonical, [EConst (String (String.concat "." pack)), p; EConst (String name), p], p) let convert_java_enum ctx p pe = let meta = ref (get_canonical ctx p (fst pe.cpath) (snd pe.cpath) :: [Meta.Native, [EConst (String (real_java_path ctx pe.cpath) ), p], p ]) in let data = ref [] in List.iter (fun f -> (* if List.mem JEnum f.jf_flags then *) match f.jf_vmsignature with | TObject( path, [] ) when path = pe.cpath && List.mem JStatic f.jf_flags && List.mem JFinal f.jf_flags -> data := { ec_name = f.jf_name,null_pos; ec_doc = None; ec_meta = []; ec_args = []; ec_pos = p; ec_params = []; ec_type = None; } :: !data; | _ -> () ) pe.cfields; EEnum { d_name = jname_to_hx (snd pe.cpath),null_pos; d_doc = None; d_params = []; (* enums never have type parameters *) d_meta = !meta; d_flags = [EExtern]; d_data = List.rev !data; } let convert_java_field ctx p jc field = let p = { p with pfile = p.pfile ^" (" ^field.jf_name ^")" } in let cff_doc = None in let cff_pos = p in let cff_meta = ref [] in let cff_access = ref [] in let cff_name = match field.jf_name with | "" -> "new" | ""-> raise Exit (* __init__ field *) | name when String.length name > 5 -> (match String.sub name 0 5 with | "__hx_" | "this$" -> raise Exit | _ -> name) | name -> name in let jf_constant = ref field.jf_constant in let readonly = ref false in List.iter (function | JPublic -> cff_access := APublic :: !cff_access | JPrivate -> raise Exit (* private instances aren't useful on externs *) | JProtected -> cff_access := APrivate :: !cff_access | JStatic -> cff_access := AStatic :: !cff_access | JFinal -> cff_meta := (Meta.Final, [], p) :: !cff_meta; (match field.jf_kind, field.jf_vmsignature, field.jf_constant with | JKField, TObject _, _ -> jf_constant := None | JKField, _, Some _ -> readonly := true; jf_constant := None; | _ -> jf_constant := None) (* | JSynchronized -> cff_meta := (Meta.Synchronized, [], p) :: !cff_meta *) | JVolatile -> cff_meta := (Meta.Volatile, [], p) :: !cff_meta | JTransient -> cff_meta := (Meta.Transient, [], p) :: !cff_meta (* | JVarArgs -> cff_meta := (Meta.VarArgs, [], p) :: !cff_meta *) | _ -> () ) field.jf_flags; List.iter (function | AttrDeprecated when jc.cpath <> (["java";"util"],"Date") -> cff_meta := (Meta.Deprecated, [], p) :: !cff_meta (* TODO: pass anotations as @:meta *) | AttrVisibleAnnotations ann -> List.iter (function | { ann_type = TObject( (["java";"lang"], "Override"), [] ) } -> cff_access := AOverride :: !cff_access | _ -> () ) ann | _ -> () ) field.jf_attributes; List.iter (fun jsig -> match convert_signature ctx p jsig with | CTPath path -> cff_meta := (Meta.Throws, [Ast.EConst (Ast.String (s_type_path (path.tpackage,path.tname))), p],p) :: !cff_meta | _ -> () ) field.jf_throws; let kind = match field.jf_kind with | JKField when !readonly -> FProp (("default",null_pos), ("null",null_pos), Some (convert_signature ctx p field.jf_signature,null_pos), None) | JKField -> FVar (Some (convert_signature ctx p field.jf_signature,null_pos), None) | JKMethod -> match field.jf_signature with | TMethod (args, ret) -> let old_types = ctx.jtparams in (match ctx.jtparams with | c :: others -> ctx.jtparams <- (c @ field.jf_types) :: others | [] -> ctx.jtparams <- field.jf_types :: []); let i = ref 0 in let args = List.map (fun s -> incr i; ("param" ^ string_of_int !i,null_pos), false, [], Some(convert_signature ctx p s,null_pos), None ) args in let t = Option.map_default (convert_signature ctx p) (mk_type_path ctx ([], "Void") []) ret in cff_meta := (Meta.Overload, [], p) :: !cff_meta; let types = List.map (function | (name, Some ext, impl) -> { tp_name = name,null_pos; tp_params = []; tp_constraints = List.map (fun t -> convert_signature ctx p t,null_pos) (ext :: impl); tp_meta = []; } | (name, None, impl) -> { tp_name = name,null_pos; tp_params = []; tp_constraints = List.map (fun t -> convert_signature ctx p t,null_pos) (impl); tp_meta = []; } ) field.jf_types in ctx.jtparams <- old_types; FFun ({ f_params = types; f_args = args; f_type = Some (t,null_pos); f_expr = None }) | _ -> error "Method signature was expected" p in let cff_name, cff_meta = match String.get cff_name 0 with | '%' -> let name = (String.sub cff_name 1 (String.length cff_name - 1)) in if not (is_haxe_keyword name) then cff_meta := (Meta.Deprecated, [EConst(String( "This static field `_" ^ name ^ "` is deprecated and will be removed in later versions. Please use `" ^ name ^ "` instead") ),p], p) :: !cff_meta; "_" ^ name, (Meta.Native, [EConst (String (name) ), cff_pos], cff_pos) :: !cff_meta | _ -> match String.nsplit cff_name "$" with | [ no_dollar ] -> cff_name, !cff_meta | parts -> String.concat "_" parts, (Meta.Native, [EConst (String (cff_name) ), cff_pos], cff_pos) :: !cff_meta in if PMap.mem "java_loader_debug" ctx.jcom.defines then Printf.printf "\t%s%sfield %s : %s\n" (if List.mem AStatic !cff_access then "static " else "") (if List.mem AOverride !cff_access then "override " else "") cff_name (s_sig field.jf_signature); { cff_name = cff_name,null_pos; cff_doc = cff_doc; cff_pos = cff_pos; cff_meta = cff_meta; cff_access = !cff_access; cff_kind = kind } let rec japply_params params jsig = match params with | [] -> jsig | _ -> match jsig with | TTypeParameter s -> (try List.assoc s params with | Not_found -> jsig) | TObject(p,tl) -> TObject(p, args params tl) | TObjectInner(sl, stll) -> TObjectInner(sl, List.map (fun (s,tl) -> (s, args params tl)) stll) | TArray(s,io) -> TArray(japply_params params s, io) | TMethod(sl, sopt) -> TMethod(List.map (japply_params params) sl, Option.map (japply_params params) sopt) | _ -> jsig and args params tl = match params with | [] -> tl | _ -> List.map (function | TAny -> TAny | TType(w,s) -> TType(w,japply_params params s)) tl let mk_params jtypes = List.map (fun (s,_,_) -> (s,TTypeParameter s)) jtypes let convert_java_class ctx p jc = match List.mem JEnum jc.cflags with | true -> (* is enum *) [convert_java_enum ctx p jc] | false -> let flags = ref [HExtern] in if PMap.mem "java_loader_debug" ctx.jcom.defines then begin let sup = jc.csuper :: jc.cinterfaces in print_endline ("converting " ^ (if List.mem JAbstract jc.cflags then "abstract " else "") ^ JData.path_s jc.cpath ^ " : " ^ (String.concat ", " (List.map s_sig sup))); end; (* todo: instead of JavaNative, use more specific definitions *) let meta = ref [Meta.JavaNative, [], p; Meta.Native, [EConst (String (real_java_path ctx jc.cpath) ), p], p; get_canonical ctx p (fst jc.cpath) (snd jc.cpath)] in let force_check = Common.defined ctx.jcom Define.ForceLibCheck in if not force_check then meta := (Meta.LibType,[],p) :: !meta; let is_interface = ref false in List.iter (fun f -> match f with | JFinal -> meta := (Meta.Final, [], p) :: !meta | JInterface -> is_interface := true; flags := HInterface :: !flags | JAbstract -> meta := (Meta.Abstract, [], p) :: !meta | JAnnotation -> meta := (Meta.Annotation, [], p) :: !meta | _ -> () ) jc.cflags; (match jc.csuper with | TObject( (["java";"lang"], "Object"), _ ) -> () | TObject( (["haxe";"lang"], "HxObject"), _ ) -> meta := (Meta.HxGen,[],p) :: !meta | _ -> flags := HExtends (get_type_path ctx (convert_signature ctx p jc.csuper),null_pos) :: !flags ); List.iter (fun i -> match i with | TObject ( (["haxe";"lang"], "IHxObject"), _ ) -> meta := (Meta.HxGen,[],p) :: !meta | _ -> flags := if !is_interface then HExtends (get_type_path ctx (convert_signature ctx p i),null_pos) :: !flags else HImplements (get_type_path ctx (convert_signature ctx p i),null_pos) :: !flags ) jc.cinterfaces; let fields = ref [] in let jfields = ref [] in if jc.cpath <> (["java";"lang"], "CharSequence") then List.iter (fun f -> try if !is_interface && List.mem JStatic f.jf_flags then () else begin fields := convert_java_field ctx p jc f :: !fields; jfields := f :: !jfields end with | Exit -> () ) (jc.cfields @ jc.cmethods); (* make sure the throws types are imported correctly *) let imports = List.concat (List.map (fun f -> List.map (fun jsig -> match convert_signature ctx p jsig with | CTPath path -> let pos = { p with pfile = p.pfile ^ " (" ^ f.jf_name ^" @:throws)" } in EImport( List.map (fun s -> s,pos) (path.tpackage @ [path.tname]), INormal ) | _ -> assert false ) f.jf_throws ) jc.cmethods) in (EClass { d_name = jname_to_hx (snd jc.cpath),null_pos; d_doc = None; d_params = List.map (convert_param ctx p jc.cpath) jc.ctypes; d_meta = !meta; d_flags = !flags; d_data = !fields; }) :: imports let create_ctx com = { jcom = com; jtparams = []; } let rec has_type_param = function | TTypeParameter _ -> true | TMethod (lst, opt) -> List.exists has_type_param lst || Option.map_default has_type_param false opt | TArray (s,_) -> has_type_param s | TObjectInner (_, stpl) -> List.exists (fun (_,sigs) -> List.exists has_type_param_arg sigs) stpl | TObject(_, pl) -> List.exists has_type_param_arg pl | _ -> false and has_type_param_arg = function | TType(_,s) -> has_type_param s | _ -> false let rec japply_params jparams jsig = match jparams with | [] -> jsig | _ -> match jsig with | TObject(path,p) -> TObject(path, List.map (japply_params_tp jparams ) p) | TObjectInner(sl,stargl) -> TObjectInner(sl,List.map (fun (s,targ) -> (s, List.map (japply_params_tp jparams) targ)) stargl) | TArray(jsig,io) -> TArray(japply_params jparams jsig,io) | TMethod(args,ret) -> TMethod(List.map (japply_params jparams ) args, Option.map (japply_params jparams ) ret) | TTypeParameter s -> (try List.assoc s jparams with | Not_found -> jsig) | _ -> jsig and japply_params_tp jparams jtype_argument = match jtype_argument with | TAny -> TAny | TType(w,jsig) -> TType(w,japply_params jparams jsig) let mk_jparams jtypes params = match jtypes, params with | [], [] -> [] | _, [] -> List.map (fun (s,_,_) -> s, TObject( (["java";"lang"], "Object"), [] ) ) jtypes | _ -> List.map2 (fun (s,_,_) jt -> match jt with | TAny -> s, TObject((["java";"lang"],"Object"),[]) | TType(_,jsig) -> s, jsig) jtypes params let rec compatible_signature_arg ?arg_test f1 f2 = let arg_test = match arg_test with | None -> (fun _ _ -> true) | Some a -> a in if f1 = f2 then true else match f1, f2 with | TObject(p,a), TObject(p2,a2) -> p = p2 && arg_test a a2 | TObjectInner(sl, stal), TObjectInner(sl2, stal2) -> sl = sl2 && List.map fst stal = List.map fst stal2 | TArray(s,_) , TArray(s2,_) -> compatible_signature_arg s s2 | TTypeParameter t1 , TTypeParameter t2 -> t1 = t2 | _ -> false let rec compatible_param p1 p2 = match p1, p2 with | TType (_,s1), TType(_,s2) -> compatible_signature_arg ~arg_test:compatible_tparams s1 s2 | TAny, TType(_, TObject( (["java";"lang"],"Object"), _ )) -> true | TType(_, TObject( (["java";"lang"],"Object"), _ )), TAny -> true | _ -> false and compatible_tparams p1 p2 = try match p1, p2 with | [], [] -> true | _, [] -> let p2 = List.map (fun _ -> TAny) p1 in List.for_all2 compatible_param p1 p2 | [], _ -> let p1 = List.map (fun _ -> TAny) p2 in List.for_all2 compatible_param p1 p2 | _, _ -> List.for_all2 compatible_param p1 p2 with | Invalid_argument("List.for_all2") -> false let get_adapted_sig f f2 = match f.jf_types with | [] -> f.jf_signature | _ -> let jparams = mk_jparams f.jf_types (List.map (fun (s,_,_) -> TType(WNone, TTypeParameter s)) f2.jf_types) in japply_params jparams f.jf_signature let compatible_methods f1 f2 = if List.length f1.jf_types <> List.length f2.jf_types then false else match (get_adapted_sig f1 f2), f2.jf_signature with | TMethod(a1,_), TMethod(a2,_) when List.length a1 = List.length a2 -> List.for_all2 compatible_signature_arg a1 a2 | _ -> false let jcl_from_jsig com jsig = let path, params = match jsig with | TObject(path, params) -> path,params | TObjectInner(sl, stll) -> let last_params = ref [] in let real_path = sl, String.concat "$" (List.map (fun (s,p) -> last_params := p; s) stll) in real_path, !last_params | _ -> raise Not_found in match lookup_jclass com path with | None -> raise Not_found | Some(c,_,_) -> c,params let jclass_with_params com cls params = try match cls.ctypes with | [] -> cls | _ -> let jparams = mk_jparams cls.ctypes params in { cls with cfields = List.map (fun f -> { f with jf_signature = japply_params jparams f.jf_signature }) cls.cfields; cmethods = List.map (fun f -> { f with jf_signature = japply_params jparams f.jf_signature }) cls.cmethods; csuper = japply_params jparams cls.csuper; cinterfaces = List.map (japply_params jparams) cls.cinterfaces; } with Invalid_argument("List.map2") -> if com.verbose then prerr_endline ("Differing parameters for class: " ^ s_type_path cls.cpath); cls let is_object = function | TObject( (["java";"lang"], "Object"), [] ) -> true | _ -> false let is_tobject = function | TObject _ | TObjectInner _ -> true | _ -> false let simplify_args args = if List.for_all (function | TAny -> true | _ -> false) args then [] else args let compare_type com s1 s2 = if s1 = s2 then 0 else if not (is_tobject s1) then if is_tobject s2 then (* Dynamic *) 1 else if compatible_signature_arg s1 s2 then 0 else raise Exit else if not (is_tobject s2) then -1 else begin let rec loop ?(first_error=true) s1 s2 : bool = if is_object s1 then s1 = s2 else if compatible_signature_arg s1 s2 then begin let p1, p2 = match s1, s2 with | TObject(_, p1), TObject(_,p2) -> p1, p2 | TObjectInner(_, npl1), TObjectInner(_, npl2) -> snd (List.hd (List.rev npl1)), snd (List.hd (List.rev npl2)) | _ -> assert false (* not tobject *) in let p1, p2 = simplify_args p1, simplify_args p2 in let lp1 = List.length p1 in let lp2 = List.length p2 in if lp1 > lp2 then true else if lp2 > lp1 then false else begin (* if compatible tparams, it's fine *) if not (compatible_tparams p1 p2) then raise Exit; (* meaning: found, but incompatible type parameters *) true end end else try let c, p = jcl_from_jsig com s1 in let jparams = mk_jparams c.ctypes p in let super = japply_params jparams c.csuper in let implements = List.map (japply_params jparams) c.cinterfaces in loop ~first_error:first_error super s2 || List.exists (fun super -> loop ~first_error:first_error super s2) implements with | Not_found -> prerr_endline ("-java-lib: The type " ^ (s_sig s1) ^ " is referred but was not found. Compilation may not occur correctly."); prerr_endline "Did you forget to include a needed lib?"; if first_error then not (loop ~first_error:false s2 s1) else false in if loop s1 s2 then if loop s2 s1 then 0 else 1 else if loop s2 s1 then -1 else -2 end (* given a list of same overload functions, choose the best (or none) *) let select_best com flist = let rec loop cur_best = function | [] -> Some cur_best | f :: flist -> match get_adapted_sig f cur_best, cur_best.jf_signature with | TMethod(_,Some r), TMethod(_, Some r2) -> (try match compare_type com r r2 with | 0 -> (* same type - select any of them *) loop cur_best flist | 1 -> loop f flist | -1 -> loop cur_best flist | -2 -> (* error - no type is compatible *) if com.verbose then prerr_endline (f.jf_name ^ ": The types " ^ (s_sig r) ^ " and " ^ (s_sig r2) ^ " are incompatible"); (* bet that the current best has "beaten" other types *) loop cur_best flist | _ -> assert false with | Exit -> (* incompatible type parameters *) (* error mode *) if com.verbose then prerr_endline (f.jf_name ^ ": Incompatible argument return signatures: " ^ (s_sig r) ^ " and " ^ (s_sig r2)); None) | TMethod _, _ -> (* select the method *) loop f flist | _ -> loop cur_best flist in match loop (List.hd flist) (List.tl flist) with | Some f -> Some f | None -> match List.filter (fun f -> not (is_override f)) flist with (* error mode; take off all override methods *) | [] -> None | f :: [] -> Some f | f :: flist -> Some f (* pick one *) (**** begin normalize_jclass helpers ****) let fix_overrides_jclass com cls = let force_check = Common.defined com Define.ForceLibCheck in let methods = if force_check then List.map (fun f -> del_override f) cls.cmethods else cls.cmethods in let cmethods = methods in let super_fields = [] in let super_methods = [] in let nonstatics = List.filter (fun f -> not (List.mem JStatic f.jf_flags)) (cls.cfields @ cls.cmethods) in let is_pub = fun f -> List.exists (function | JPublic | JProtected -> true | _ -> false) f.jf_flags in let cmethods, super_fields = if not (List.mem JInterface cls.cflags) then List.filter is_pub cmethods, List.filter is_pub super_fields else cmethods,super_fields in let rec loop cls super_methods super_fields cmethods nonstatics = try match cls.csuper with | TObject((["java";"lang"],"Object"),_) -> super_methods,super_fields,cmethods,nonstatics | _ -> let cls, params = jcl_from_jsig com cls.csuper in let cls = jclass_with_params com cls params in let nonstatics = (List.filter (fun f -> (List.mem JStatic f.jf_flags)) (cls.cfields @ cls.cmethods)) @ nonstatics in let super_methods = cls.cmethods @ super_methods in let super_fields = cls.cfields @ super_fields in let cmethods = if force_check then begin let overriden = ref [] in let cmethods = List.map (fun jm -> (* TODO rewrite/standardize empty spaces *) if not (is_override jm) && not (List.mem JStatic jm.jf_flags) && List.exists (fun msup -> let ret = msup.jf_name = jm.jf_name && not(List.mem JStatic msup.jf_flags) && compatible_methods msup jm in if ret then begin let f = mk_override msup in overriden := { f with jf_flags = jm.jf_flags } :: !overriden end; ret ) cls.cmethods then mk_override jm else jm ) cmethods in !overriden @ cmethods end else cmethods in loop cls super_methods super_fields cmethods nonstatics with | Not_found -> super_methods,super_fields,cmethods,nonstatics in loop cls super_methods super_fields cmethods nonstatics let normalize_jclass com cls = (* after adding the noCheck metadata, this option will annotate what changes were needed *) (* and that are now deprecated *) let force_check = Common.defined com Define.ForceLibCheck in (* fix overrides *) let super_methods, super_fields, cmethods, nonstatics = fix_overrides_jclass com cls in let all_methods = cmethods @ super_methods in (* look for interfaces and add missing implementations (may happen on abstracts or by vmsig differences *) (* (libType): even with libType enabled, we need to add these missing fields - otherwise we won't be able to use them from Haxe *) let added_interface_fields = ref [] in let rec loop_interface abstract cls iface = try match iface with | TObject ((["java";"lang"],"Object"), _) -> () | TObject (path,_) when path = cls.cpath -> () | _ -> let cif, params = jcl_from_jsig com iface in let cif = jclass_with_params com cif params in List.iter (fun jf -> if not(List.mem JStatic jf.jf_flags) && not (List.exists (fun jf2 -> jf.jf_name = jf2.jf_name && not (List.mem JStatic jf2.jf_flags) && jf.jf_signature = jf2.jf_signature) all_methods) then begin let jf = if abstract && force_check then del_override jf else jf in let jf = { jf with jf_flags = JPublic :: jf.jf_flags } in (* interfaces implementations are always public *) added_interface_fields := jf :: !added_interface_fields; end ) cif.cmethods; (* we don't need to loop again in the interface unless we are in an abstract class, since these interfaces are already normalized *) if abstract then List.iter (loop_interface abstract cif) cif.cinterfaces; with Not_found -> () in List.iter (loop_interface (List.mem JAbstract cls.cflags) cls) cls.cinterfaces; let nonstatics = !added_interface_fields @ nonstatics in let cmethods = !added_interface_fields @ cmethods in (* for each added field in the interface, lookup in super_methods possible methods to include *) (* so we can choose the better method still *) let cmethods = if not force_check then cmethods else List.fold_left (fun cmethods im -> (* see if any of the added_interface_fields need to be declared as override *) let f = List.find_all (fun jf -> jf.jf_name = im.jf_name && compatible_methods jf im) super_methods in let f = List.map mk_override f in f @ cmethods ) cmethods !added_interface_fields; in (* take off equals, hashCode and toString from interface *) let cmethods = if List.mem JInterface cls.cflags then List.filter (fun jf -> match jf.jf_name, jf.jf_vmsignature with | "equals", TMethod([TObject( (["java";"lang"],"Object"), _)],_) | "hashCode", TMethod([], _) | "toString", TMethod([], _) -> false | _ -> true ) cmethods else cmethods in (* change field name to not collide with haxe keywords and with static/non-static members *) let fold_field acc f = let change, both = match f.jf_name with | _ when List.mem JStatic f.jf_flags && List.exists (fun f2 -> f.jf_name = f2.jf_name) nonstatics -> true, true | _ -> is_haxe_keyword f.jf_name, false in let f2 = if change then { f with jf_name = "%" ^ f.jf_name } else f in if both then f :: f2 :: acc else f2 :: acc in (* change static fields that have the same name as methods *) let cfields = List.fold_left fold_field [] cls.cfields in let cmethods = List.fold_left fold_field [] cmethods in (* take off variable fields that have the same name as methods *) (* and take off variables that already have been declared *) let filter_field f f2 = f != f2 && (List.mem JStatic f.jf_flags = List.mem JStatic f2.jf_flags) && f.jf_name = f2.jf_name && f2.jf_kind <> f.jf_kind in let cfields = List.filter (fun f -> if List.mem JStatic f.jf_flags then not (List.exists (filter_field f) cmethods) else not (List.exists (filter_field f) nonstatics) && not (List.exists (fun f2 -> f != f2 && f.jf_name = f2.jf_name && not (List.mem JStatic f2.jf_flags)) super_fields) ) cfields in (* now filter any method that clashes with a field - on a superclass *) let cmethods = if force_check then List.filter (fun f -> if List.mem JStatic f.jf_flags then true else not (List.exists (filter_field f) super_fields) ) cmethods else cmethods in (* removing duplicate fields. They are there because of return type covariance in Java *) (* Also, if a method overrides a previous definition, and changes a type parameters' variance, *) (* we will take it off *) (* this means that some rare codes will never compile on Haxe, but unless Haxe adds variance support *) (* I can't see how this can be any different *) let rec loop acc = function | [] -> acc | f :: cmeths -> match List.partition (fun f2 -> f.jf_name = f2.jf_name && compatible_methods f f2) cmeths with | [], cmeths -> loop (f :: acc) cmeths | flist, cmeths -> match select_best com (f :: flist) with | None -> loop acc cmeths | Some f -> loop (f :: acc) cmeths in (* last pass: take off all cfields that are internal / private (they won't be accessible anyway) *) let cfields = List.filter(fun f -> List.exists (fun f -> f = JPublic || f = JProtected) f.jf_flags) cfields in let cmethods = loop [] cmethods in { cls with cfields = cfields; cmethods = cmethods } (**** end normalize_jclass helpers ****) let get_classes_zip zip = let ret = ref [] in List.iter (function | { Zip.is_directory = false; Zip.filename = f } when (String.sub (String.uncapitalize f) (String.length f - 6) 6) = ".class" && not (String.exists f "$") -> (match List.rev (String.nsplit f "/") with | clsname :: pack -> if not (String.contains clsname '$') then begin let path = jpath_to_hx (List.rev pack, String.sub clsname 0 (String.length clsname - 6)) in ret := path :: !ret end | _ -> ret := ([], jname_to_hx f) :: !ret) | _ -> () ) (Zip.entries zip); !ret let add_java_lib com file std = let file = if Sys.file_exists file then file else try Common.find_file com file with | Not_found -> try Common.find_file com (file ^ ".jar") with | Not_found -> failwith ("Java lib " ^ file ^ " not found") in let hxpack_to_jpack = Hashtbl.create 16 in let get_raw_class, close, list_all_files = (* check if it is a directory or jar file *) match (Unix.stat file).st_kind with | S_DIR -> (* open classes directly from directory *) let all = ref [] in let rec iter_files pack dir path = try let file = Unix.readdir dir in let filepath = path ^ "/" ^ file in (if String.ends_with file ".class" && not (String.exists file "$") then let file = String.sub file 0 (String.length file - 6) in let path = jpath_to_hx (pack,file) in all := path :: !all; Hashtbl.add hxpack_to_jpack path (pack,file) else if (Unix.stat filepath).st_kind = S_DIR && file <> "." && file <> ".." then let pack = pack @ [file] in iter_files (pack) (Unix.opendir filepath) filepath); iter_files pack dir path with | End_of_file | Unix.Unix_error _ -> Unix.closedir dir in iter_files [] (Unix.opendir file) file; let all = !all in (fun (pack, name) -> let real_path = file ^ "/" ^ (String.concat "/" pack) ^ "/" ^ (name ^ ".class") in try let data = Std.input_file ~bin:true real_path in Some(JReader.parse_class (IO.input_string data), real_path, real_path) with | _ -> None), (fun () -> ()), (fun () -> all) | _ -> (* open zip file *) let closed = ref false in let zip = ref (Zip.open_in file) in let check_open () = if !closed then begin prerr_endline ("JAR file " ^ file ^ " already closed"); (* if this happens, find when *) zip := Zip.open_in file; closed := false end in List.iter (function | { Zip.is_directory = false; Zip.filename = filename } when String.ends_with filename ".class" -> let pack = String.nsplit filename "/" in (match List.rev pack with | [] -> () | name :: pack -> let name = String.sub name 0 (String.length name - 6) in let pack = List.rev pack in Hashtbl.add hxpack_to_jpack (jpath_to_hx (pack,name)) (pack,name)) | _ -> () ) (Zip.entries !zip); (fun (pack, name) -> check_open(); try let location = (String.concat "/" (pack @ [name]) ^ ".class") in let entry = Zip.find_entry !zip location in let data = Zip.read_entry !zip entry in Some(JReader.parse_class (IO.input_string data), file, file ^ "@" ^ location) with | Not_found -> None), (fun () -> if not !closed then begin closed := true; Zip.close_in !zip end), (fun () -> check_open(); get_classes_zip !zip) in let cached_types = Hashtbl.create 12 in let get_raw_class path = try Hashtbl.find cached_types path with | Not_found -> try let pack, name = Hashtbl.find hxpack_to_jpack path in let try_file (pack,name) = match get_raw_class (pack,name) with | None -> Hashtbl.add cached_types path None; None | Some (i, p1, p2) -> Hashtbl.add cached_types path (Some(i,p1,p2)); (* type loop normalization *) let ret = Some (normalize_jclass com i, p1, p2) in Hashtbl.replace cached_types path ret; ret in try_file (pack,name) with Not_found -> None in let replace_canonical_name p pack name_original name_replace decl = let mk_meta name = (Meta.JavaCanonical, [EConst (String (String.concat "." pack)), p; EConst(String name), p], p) in let add_meta name metas = if Meta.has Meta.JavaCanonical metas then List.map (function | (Meta.JavaCanonical,[EConst (String cpack), _; EConst(String cname), _],_) -> let did_replace,name = String.replace cname name_original name_replace in if not did_replace then print_endline (cname ^ " -> " ^ name_original ^ " -> " ^ name_replace); mk_meta name | m -> m ) metas else mk_meta name :: metas in match decl with | EClass c -> EClass { c with d_meta = add_meta (fst c.d_name) c.d_meta } | EEnum e -> EEnum { e with d_meta = add_meta (fst e.d_name) e.d_meta } | EAbstract a -> EAbstract { a with d_meta = add_meta (fst a.d_name) a.d_meta } | d -> d in let rec build ctx path p types = try if List.mem path !types then None else begin let first = match !types with | [ ["java";"lang"], "String" ] | [] -> true | p :: _ -> false in types := path :: !types; match get_raw_class path, path with | None, ([], c) -> build ctx (["haxe";"root"], c) p types | None, _ -> None | Some (cls, real_path, pos_path), _ -> let is_disallowed_inner = first && String.exists (snd cls.cpath) "$" in let is_disallowed_inner = if is_disallowed_inner then begin let outer, inner = String.split (snd cls.cpath) "$" in match get_raw_class (fst path, outer) with | None -> false | _ -> true end else false in if is_disallowed_inner then None else begin if com.verbose then print_endline ("Parsed Java class " ^ (s_type_path cls.cpath)); let old_types = ctx.jtparams in ctx.jtparams <- cls.ctypes :: ctx.jtparams; let pos = { pfile = pos_path; pmin = 0; pmax = 0; } in let pack = match fst path with | ["haxe";"root"] -> [] | p -> p in let ppath = Hashtbl.find hxpack_to_jpack path in let inner = List.fold_left (fun acc (path,out,_,_) -> let path = jpath_to_hx path in (if out <> Some ppath then acc else match build ctx path p types with | Some(_,(_, classes)) -> let base = snd ppath ^ "$" in (List.map (fun (def,p) -> replace_canonical_name p (fst ppath) base (snd ppath ^ ".") def, p) classes) @ acc | _ -> acc); ) [] cls.cinner_types in (* add _Statics class *) let inner = try if not (List.mem JInterface cls.cflags) then raise Not_found; let smethods = List.filter (fun f -> List.mem JStatic f.jf_flags) cls.cmethods in let sfields = List.filter (fun f -> List.mem JStatic f.jf_flags) cls.cfields in if not (smethods <> [] || sfields <> []) then raise Not_found; let obj = TObject( (["java";"lang"],"Object"), []) in let ncls = convert_java_class ctx pos { cls with cmethods = smethods; cfields = sfields; cflags = []; csuper = obj; cinterfaces = []; cinner_types = []; ctypes = [] } in match ncls with | EClass c :: imports -> (EClass { c with d_name = (fst c.d_name ^ "_Statics"),snd c.d_name }, pos) :: inner @ List.map (fun i -> i,pos) imports | _ -> assert false with | Not_found -> inner in let inner_alias = ref SS.empty in List.iter (fun x -> match fst x with | EClass c -> inner_alias := SS.add (fst c.d_name) !inner_alias; | _ -> () ) inner; let alias_list = ref [] in List.iter (fun x -> match x with | (EClass c, pos) -> begin let parts = String.nsplit (fst c.d_name) "_24" in match parts with | _ :: _ -> let alias_name = String.concat "_" parts in if (not (SS.mem alias_name !inner_alias)) && (not (String.exists (snd path) "_24")) then begin let alias_def = ETypedef { d_name = alias_name,null_pos; d_doc = None; d_params = c.d_params; d_meta = []; d_flags = []; d_data = CTPath { tpackage = pack; tname = snd path; tparams = List.map (fun tp -> TPType (CTPath { tpackage = []; tname = fst tp.tp_name; tparams = []; tsub = None; },null_pos) ) c.d_params; tsub = Some(fst c.d_name); },null_pos; } in inner_alias := SS.add alias_name !inner_alias; alias_list := (alias_def, pos) :: !alias_list; end | _ -> () end | _ -> () ) inner; let inner = List.concat [!alias_list ; inner] in let classes = List.map (fun t -> t,pos) (convert_java_class ctx pos cls) in let imports, defs = List.partition (function | (EImport(_),_) -> true | _ -> false) (classes @ inner) in let ret = Some ( real_path, (pack, imports @ defs) ) in ctx.jtparams <- old_types; ret end end with | JReader.Error_message msg -> prerr_endline ("Class reader failed: " ^ msg); None | e -> if com.verbose then begin (* prerr_endline (Printexc.get_backtrace ()); requires ocaml 3.11 *) prerr_endline (Printexc.to_string e) end; None in let build path p = build (create_ctx com) path p (ref [["java";"lang"], "String"]) in let cached_files = ref None in let list_all_files () = match !cached_files with | None -> let ret = list_all_files () in cached_files := Some ret; ret | Some r -> r in (* TODO: add_dependency m mdep *) com.load_extern_type <- com.load_extern_type @ [build]; com.java_libs <- (file, std, close, list_all_files, get_raw_class) :: com.java_libs haxe_3.4.4.orig/src/generators/genjs.ml0000664000175000017500000013465513166552354020032 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open Ast open Type open Common type sourcemap = { sources : (string) DynArray.t; sources_hash : (string, int) Hashtbl.t; mappings : Rbuffer.t; mutable source_last_line : int; mutable source_last_col : int; mutable source_last_file : int; mutable print_comma : bool; mutable output_last_col : int; mutable output_current_col : int; mutable current_expr : texpr option; } type ctx = { com : Common.context; buf : Rbuffer.t; chan : out_channel; packages : (string list,unit) Hashtbl.t; smap : sourcemap option; js_modern : bool; js_flatten : bool; es_version : int; store_exception_stack : bool; mutable current : tclass; mutable statics : (tclass * string * texpr) list; mutable inits : texpr list; mutable tabs : string; mutable in_value : tvar option; mutable in_loop : bool; mutable handle_break : bool; mutable id_counter : int; mutable type_accessor : module_type -> string; mutable separator : bool; mutable found_expose : bool; } type object_store = { os_name : string; mutable os_fields : object_store list; } let get_exposed ctx path meta = try let (_, args, pos) = Meta.get Meta.Expose meta in (match args with | [ EConst (String s), _ ] -> [s] | [] -> [path] | _ -> abort "Invalid @:expose parameters" pos) with Not_found -> [] let dot_path = s_type_path let flat_path (p,s) = (* Replace _ with _$ in paths to prevent name collisions. *) let escape str = String.concat "_$" (ExtString.String.nsplit str "_") in match p with | [] -> escape s | _ -> String.concat "_" (List.map escape p) ^ "_" ^ (escape s) let s_path ctx = if ctx.js_flatten then flat_path else dot_path let kwds = let h = Hashtbl.create 0 in List.iter (fun s -> Hashtbl.add h s ()) [ "abstract"; "as"; "boolean"; "break"; "byte"; "case"; "catch"; "char"; "class"; "continue"; "const"; "debugger"; "default"; "delete"; "do"; "double"; "else"; "enum"; "export"; "extends"; "false"; "final"; "finally"; "float"; "for"; "function"; "goto"; "if"; "implements"; "import"; "in"; "instanceof"; "int"; "interface"; "is"; "let"; "long"; "namespace"; "native"; "new"; "null"; "package"; "private"; "protected"; "public"; "return"; "short"; "static"; "super"; "switch"; "synchronized"; "this"; "throw"; "throws"; "transient"; "true"; "try"; "typeof"; "use"; "var"; "void"; "volatile"; "while"; "with"; "yield" ]; h (* Identifiers Haxe reserves to make the JS output cleaner. These can still be used in untyped code (TLocal), but are escaped upon declaration. *) let kwds2 = let h = Hashtbl.create 0 in List.iter (fun s -> Hashtbl.add h s ()) [ (* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects *) "Infinity"; "NaN"; "decodeURI"; "decodeURIComponent"; "encodeURI"; "encodeURIComponent"; "escape"; "eval"; "isFinite"; "isNaN"; "parseFloat"; "parseInt"; "undefined"; "unescape"; "JSON"; "Number"; "Object"; "console"; "window"; "require"; ]; h let valid_js_ident s = String.length s > 0 && try for i = 0 to String.length s - 1 do match String.unsafe_get s i with | 'a'..'z' | 'A'..'Z' | '$' | '_' -> () | '0'..'9' when i > 0 -> () | _ -> raise Exit done; true with Exit -> false let field s = if Hashtbl.mem kwds s || not (valid_js_ident s) then "[\"" ^ s ^ "\"]" else "." ^ s let ident s = if Hashtbl.mem kwds s then "$" ^ s else s let check_var_declaration v = if Hashtbl.mem kwds2 v.v_name then v.v_name <- "$" ^ v.v_name let anon_field s = if Hashtbl.mem kwds s || not (valid_js_ident s) then "'" ^ s ^ "'" else s let static_field c s = match s with | "length" | "name" when not c.cl_extern || Meta.has Meta.HxGen c.cl_meta-> ".$" ^ s | s -> field s let has_feature ctx = Common.has_feature ctx.com let add_feature ctx = Common.add_feature ctx.com let unsupported p = abort "This expression cannot be compiled to Javascript" p let add_mapping smap force e = if e.epos.pmin < 0 then () else let pos = e.epos in let file = try Hashtbl.find smap.sources_hash pos.pfile with Not_found -> let length = DynArray.length smap.sources in Hashtbl.replace smap.sources_hash pos.pfile length; DynArray.add smap.sources pos.pfile; length in let line, col = Lexer.find_pos pos in let line = line - 1 in if force || smap.source_last_file != file || smap.source_last_line != line || smap.source_last_col != col then begin smap.current_expr <- Some e; if smap.print_comma then Rbuffer.add_char smap.mappings ',' else smap.print_comma <- true; let base64_vlq number = let encode_digit digit = let chars = [| 'A';'B';'C';'D';'E';'F';'G';'H';'I';'J';'K';'L';'M';'N';'O';'P'; 'Q';'R';'S';'T';'U';'V';'W';'X';'Y';'Z';'a';'b';'c';'d';'e';'f'; 'g';'h';'i';'j';'k';'l';'m';'n';'o';'p';'q';'r';'s';'t';'u';'v'; 'w';'x';'y';'z';'0';'1';'2';'3';'4';'5';'6';'7';'8';'9';'+';'/' |] in Array.unsafe_get chars digit in let to_vlq number = if number < 0 then ((-number) lsl 1) + 1 else number lsl 1 in let rec loop vlq = let shift = 5 in let base = 1 lsl shift in let mask = base - 1 in let continuation_bit = base in let digit = vlq land mask in let next = vlq asr shift in Rbuffer.add_char smap.mappings (encode_digit ( if next > 0 then digit lor continuation_bit else digit)); if next > 0 then loop next else () in loop (to_vlq number) in base64_vlq (smap.output_current_col - smap.output_last_col); base64_vlq (file - smap.source_last_file); base64_vlq (line - smap.source_last_line); base64_vlq (col - smap.source_last_col); smap.source_last_file <- file; smap.source_last_line <- line; smap.source_last_col <- col; smap.output_last_col <- smap.output_current_col end let handle_newlines ctx str = Option.may (fun smap -> let rec loop from = try begin let next = String.index_from str from '\n' + 1 in Rbuffer.add_char smap.mappings ';'; smap.output_last_col <- 0; smap.output_current_col <- 0; smap.print_comma <- false; Option.may (fun e -> add_mapping smap true e) smap.current_expr; loop next end with Not_found -> smap.output_current_col <- smap.output_current_col + (String.length str - from); in loop 0 ) ctx.smap let flush ctx = Rbuffer.output_buffer ctx.chan ctx.buf; Rbuffer.clear ctx.buf let spr ctx s = ctx.separator <- false; handle_newlines ctx s; Rbuffer.add_string ctx.buf s let print ctx = ctx.separator <- false; Printf.kprintf (fun s -> begin handle_newlines ctx s; Rbuffer.add_string ctx.buf s end) let write_mappings ctx smap = let basefile = Filename.basename ctx.com.file in print ctx "\n//# sourceMappingURL=%s.map" basefile; let channel = open_out_bin (ctx.com.file ^ ".map") in let sources = DynArray.to_list smap.sources in let to_url file = ExtString.String.map (fun c -> if c == '\\' then '/' else c) (Path.get_full_path file) in output_string channel "{\n"; output_string channel "\"version\":3,\n"; output_string channel ("\"file\":\"" ^ (String.concat "\\\\" (ExtString.String.nsplit basefile "\\")) ^ "\",\n"); output_string channel ("\"sourceRoot\":\"file:///\",\n"); output_string channel ("\"sources\":[" ^ (String.concat "," (List.map (fun s -> "\"" ^ to_url s ^ "\"") sources)) ^ "],\n"); if Common.defined ctx.com Define.SourceMapContent then begin output_string channel ("\"sourcesContent\":[" ^ (String.concat "," (List.map (fun s -> try "\"" ^ Ast.s_escape (Std.input_file ~bin:true s) ^ "\"" with _ -> "null") sources)) ^ "],\n"); end; output_string channel "\"names\":[],\n"; output_string channel "\"mappings\":\""; Rbuffer.output_buffer channel smap.mappings; output_string channel "\"\n"; output_string channel "}"; close_out channel let newline ctx = match Rbuffer.nth ctx.buf (Rbuffer.length ctx.buf - 1) with | '}' | '{' | ':' | ';' when not ctx.separator -> print ctx "\n%s" ctx.tabs | _ -> print ctx ";\n%s" ctx.tabs let newprop ctx = match Rbuffer.nth ctx.buf (Rbuffer.length ctx.buf - 1) with | '{' -> print ctx "\n%s" ctx.tabs | _ -> print ctx "\n%s," ctx.tabs let semicolon ctx = match Rbuffer.nth ctx.buf (Rbuffer.length ctx.buf - 1) with | '}' when not ctx.separator -> () | _ -> spr ctx ";" let rec concat ctx s f = function | [] -> () | [x] -> f x | x :: l -> f x; spr ctx s; concat ctx s f l let fun_block ctx f p = let e = List.fold_left (fun e (a,c) -> match c with | None | Some TNull -> e | Some c -> Type.concat (Codegen.set_default ctx.com a c p) e ) f.tf_expr f.tf_args in e let open_block ctx = let oldt = ctx.tabs in ctx.tabs <- "\t" ^ ctx.tabs; (fun() -> ctx.tabs <- oldt) let rec has_return e = match e.eexpr with | TBlock [] -> false | TBlock el -> has_return (List.hd (List.rev el)) | TReturn _ -> true | _ -> false let rec iter_switch_break in_switch e = match e.eexpr with | TFunction _ | TWhile _ | TFor _ -> () | TSwitch _ when not in_switch -> iter_switch_break true e | TBreak when in_switch -> raise Exit | _ -> iter (iter_switch_break in_switch) e let handle_break ctx e = let old = ctx.in_loop, ctx.handle_break in ctx.in_loop <- true; try iter_switch_break false e; ctx.handle_break <- false; (fun() -> ctx.in_loop <- fst old; ctx.handle_break <- snd old; ) with Exit -> spr ctx "try {"; let b = open_block ctx in newline ctx; ctx.handle_break <- true; (fun() -> b(); ctx.in_loop <- fst old; ctx.handle_break <- snd old; newline ctx; spr ctx "} catch( e ) { if( e != \"__break__\" ) throw e; }"; ) let this ctx = match ctx.in_value with None -> "this" | Some _ -> "$this" let is_dynamic_iterator ctx e = let check x = let rec loop t = match follow t with | TInst ({ cl_path = [],"Array" },_) | TInst ({ cl_kind = KTypeParameter _}, _) | TAnon _ | TDynamic _ | TMono _ -> true | TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> loop (Abstract.get_underlying_type a tl) | _ -> false in has_feature ctx "HxOverrides.iter" && loop x.etype in match e.eexpr with | TField (x,f) when field_name f = "iterator" -> check x | _ -> false let gen_constant ctx p = function | TInt i -> print ctx "%ld" i | TFloat s -> spr ctx s | TString s -> print ctx "\"%s\"" (Ast.s_escape s) | TBool b -> spr ctx (if b then "true" else "false") | TNull -> spr ctx "null" | TThis -> spr ctx (this ctx) | TSuper -> assert false let rec gen_call ctx e el in_value = match e.eexpr , el with | TConst TSuper , params -> (match ctx.current.cl_super with | None -> abort "Missing api.setCurrentClass" e.epos | Some (c,_) -> print ctx "%s.call(%s" (ctx.type_accessor (TClassDecl c)) (this ctx); List.iter (fun p -> print ctx ","; gen_value ctx p) params; spr ctx ")"; ); | TField ({ eexpr = TConst TSuper },f) , params -> (match ctx.current.cl_super with | None -> abort "Missing api.setCurrentClass" e.epos | Some (c,_) -> let name = field_name f in print ctx "%s.prototype%s.call(%s" (ctx.type_accessor (TClassDecl c)) (field name) (this ctx); List.iter (fun p -> print ctx ","; gen_value ctx p) params; spr ctx ")"; ); | TCall (x,_) , el when (match x.eexpr with TLocal { v_name = "__js__" } -> false | _ -> true) -> spr ctx "("; gen_value ctx e; spr ctx ")"; spr ctx "("; concat ctx "," (gen_value ctx) el; spr ctx ")"; | TLocal { v_name = "__new__" }, { eexpr = TConst (TString cl) } :: params -> print ctx "new %s(" cl; concat ctx "," (gen_value ctx) params; spr ctx ")"; | TLocal { v_name = "__new__" }, e :: params -> spr ctx "new "; gen_value ctx e; spr ctx "("; concat ctx "," (gen_value ctx) params; spr ctx ")"; | TLocal { v_name = "__js__" }, [{ eexpr = TConst (TString "this") }] -> spr ctx (this ctx) | TLocal { v_name = "__js__" }, [{ eexpr = TConst (TString code) }] -> spr ctx (String.concat "\n" (ExtString.String.nsplit code "\r\n")) | TLocal { v_name = "__js__" }, { eexpr = TConst (TString code); epos = p } :: tl -> Codegen.interpolate_code ctx.com code tl (spr ctx) (gen_expr ctx) p | TLocal { v_name = "__instanceof__" }, [o;t] -> spr ctx "("; gen_value ctx o; print ctx " instanceof "; gen_value ctx t; spr ctx ")"; | TLocal { v_name = "__typeof__" }, [o] -> spr ctx "typeof("; gen_value ctx o; spr ctx ")"; | TLocal { v_name = "__strict_eq__" } , [x;y] -> (* add extra parenthesis here because of operator precedence *) spr ctx "(("; gen_value ctx x; spr ctx ") === "; gen_value ctx y; spr ctx ")"; | TLocal { v_name = "__strict_neq__" } , [x;y] -> (* add extra parenthesis here because of operator precedence *) spr ctx "(("; gen_value ctx x; spr ctx ") !== "; gen_value ctx y; spr ctx ")"; | TLocal ({v_name = "__define_feature__"}), [_;e] -> gen_expr ctx e | TLocal { v_name = "__feature__" }, { eexpr = TConst (TString f) } :: eif :: eelse -> (if has_feature ctx f then gen_value ctx eif else match eelse with | [] -> () | e :: _ -> gen_value ctx e) | TLocal { v_name = "__rethrow__" }, [] -> spr ctx "throw $hx_rethrow"; | TLocal { v_name = "__resources__" }, [] -> spr ctx "["; concat ctx "," (fun (name,data) -> spr ctx "{ "; spr ctx "name : "; gen_constant ctx e.epos (TString name); spr ctx ", data : "; gen_constant ctx e.epos (TString (Codegen.bytes_serialize data)); spr ctx "}" ) (Hashtbl.fold (fun name data acc -> (name,data) :: acc) ctx.com.resources []); spr ctx "]"; | TLocal { v_name = "`trace" }, [e;infos] -> if has_feature ctx "haxe.Log.trace" then begin let t = (try List.find (fun t -> t_path t = (["haxe"],"Log")) ctx.com.types with _ -> assert false) in spr ctx (ctx.type_accessor t); spr ctx ".trace("; gen_value ctx e; spr ctx ","; gen_value ctx infos; spr ctx ")"; end else begin spr ctx "console.log("; gen_value ctx e; spr ctx ")"; end | _ -> gen_value ctx e; spr ctx "("; concat ctx "," (gen_value ctx) el; spr ctx ")" (* this wraps {} in parenthesis which is required to produce valid js code for field and array access to it. the case itself is very rare and most probably comes from redundant code fused by the analyzer, but we still have to support it. *) and add_objectdecl_parens e = let rec loop e = match e.eexpr with | TCast(e1,None) | TMeta(_,e1) -> loop e1 (* TODO: do we really want to lose these? *) | TObjectDecl _ -> {e with eexpr = TParenthesis e} | _ -> e in loop e and gen_expr ctx e = Option.may (fun smap -> add_mapping smap false e) ctx.smap; (match e.eexpr with | TConst c -> gen_constant ctx e.epos c | TLocal v -> spr ctx (ident v.v_name) (*| TArray (e1,{ eexpr = TConst (TString s) }) when valid_js_ident s && (match e1.eexpr with TConst (TInt _|TFloat _) -> false | _ -> true) -> gen_value ctx (add_objectdecl_parens e1); spr ctx (field s)*) | TArray (e1,e2) -> gen_value ctx (add_objectdecl_parens e1); spr ctx "["; gen_value ctx e2; spr ctx "]"; | TBinop (op,{ eexpr = TField (x,f) },e2) when field_name f = "iterator" -> gen_value ctx x; spr ctx (field "iterator"); print ctx " %s " (Ast.s_binop op); gen_value ctx e2; | TBinop (op,e1,e2) -> gen_value ctx e1; print ctx " %s " (Ast.s_binop op); gen_value ctx e2; | TField (x,f) when field_name f = "iterator" && is_dynamic_iterator ctx e -> add_feature ctx "use.$iterator"; print ctx "$iterator("; gen_value ctx x; print ctx ")"; (* Don't generate `$iterator(value)` for exprs like `value.iterator--` *) | TUnop (op,flag,({eexpr = TField (x,f)} as fe)) when field_name f = "iterator" && is_dynamic_iterator ctx fe -> (match flag with | Prefix -> spr ctx (Ast.s_unop op); gen_value ctx x; spr ctx ".iterator" | Postfix -> gen_value ctx x; spr ctx ".iterator"; spr ctx (Ast.s_unop op)) | TField (x,FClosure (Some ({cl_path=[],"Array"},_), {cf_name="push"})) -> (* see https://github.com/HaxeFoundation/haxe/issues/1997 *) add_feature ctx "use.$arrayPush"; add_feature ctx "use.$bind"; print ctx "$bind("; gen_value ctx x; print ctx ",$arrayPush)" | TField (x,FClosure (_,f)) -> add_feature ctx "use.$bind"; (match x.eexpr with | TConst _ | TLocal _ -> print ctx "$bind("; gen_value ctx x; print ctx ","; gen_value ctx x; print ctx "%s)" (if Meta.has Meta.SelfCall f.cf_meta then "" else (field f.cf_name)) | _ -> print ctx "($_="; gen_value ctx x; print ctx ",$bind($_,$_%s))" (if Meta.has Meta.SelfCall f.cf_meta then "" else (field f.cf_name))) | TEnumParameter (x,_,i) -> gen_value ctx x; print ctx "[%i]" (i + 2) | TField (x, (FInstance(_,_,f) | FStatic(_,f) | FAnon(f))) when Meta.has Meta.SelfCall f.cf_meta -> gen_value ctx x; | TField (x,f) -> let rec skip e = match e.eexpr with | TCast(e1,None) | TMeta(_,e1) -> skip e1 | TConst(TInt _ | TFloat _) | TObjectDecl _ -> {e with eexpr = TParenthesis e} | _ -> e in let x = skip x in gen_value ctx x; let name = field_name f in spr ctx (match f with FStatic(c,_) -> static_field c name | FEnum _ | FInstance _ | FAnon _ | FDynamic _ | FClosure _ -> field name) | TTypeExpr t -> spr ctx (ctx.type_accessor t) | TParenthesis e -> spr ctx "("; gen_value ctx e; spr ctx ")"; | TMeta (_,e) -> gen_expr ctx e | TReturn eo -> if ctx.in_value <> None then unsupported e.epos; (match eo with | None -> spr ctx "return" | Some e -> spr ctx "return "; gen_value ctx e); | TBreak -> if not ctx.in_loop then unsupported e.epos; if ctx.handle_break then spr ctx "throw \"__break__\"" else spr ctx "break" | TContinue -> if not ctx.in_loop then unsupported e.epos; spr ctx "continue" | TBlock el -> print ctx "{"; let bend = open_block ctx in List.iter (gen_block_element ctx) el; bend(); newline ctx; print ctx "}"; | TFunction f -> let old = ctx.in_value, ctx.in_loop in ctx.in_value <- None; ctx.in_loop <- false; print ctx "function(%s) " (String.concat "," (List.map ident (List.map arg_name f.tf_args))); gen_expr ctx (fun_block ctx f e.epos); ctx.in_value <- fst old; ctx.in_loop <- snd old; ctx.separator <- true | TCall (e,el) -> gen_call ctx e el false | TArrayDecl el -> spr ctx "["; concat ctx "," (gen_value ctx) el; spr ctx "]" | TThrow e -> spr ctx "throw "; gen_value ctx e; | TVar (v,eo) -> spr ctx "var "; check_var_declaration v; spr ctx (ident v.v_name); begin match eo with | None -> () | Some e -> spr ctx " = "; gen_value ctx e end | TNew ({ cl_path = [],"Array" },_,[]) -> print ctx "[]" | TNew (c,_,el) -> (match c.cl_constructor with | Some cf when Meta.has Meta.SelfCall cf.cf_meta -> () | _ -> print ctx "new "); print ctx "%s(" (ctx.type_accessor (TClassDecl c)); concat ctx "," (gen_value ctx) el; spr ctx ")" | TIf (cond,e,eelse) -> spr ctx "if"; gen_value ctx cond; spr ctx " "; gen_expr ctx (mk_block e); (match eelse with | None -> () | Some e2 -> (match e.eexpr with | TObjectDecl _ -> ctx.separator <- false | _ -> ()); semicolon ctx; spr ctx " else "; gen_expr ctx (match e2.eexpr with | TIf _ -> e2 | _ -> mk_block e2)); | TUnop (op,Ast.Prefix,e) -> spr ctx (Ast.s_unop op); gen_value ctx e | TUnop (op,Ast.Postfix,e) -> gen_value ctx e; spr ctx (Ast.s_unop op) | TWhile (cond,e,Ast.NormalWhile) -> let handle_break = handle_break ctx e in spr ctx "while"; gen_value ctx cond; spr ctx " "; gen_expr ctx e; handle_break(); | TWhile (cond,e,Ast.DoWhile) -> let handle_break = handle_break ctx e in spr ctx "do "; gen_expr ctx e; semicolon ctx; spr ctx " while"; gen_value ctx cond; handle_break(); | TObjectDecl fields -> spr ctx "{ "; concat ctx ", " (fun (f,e) -> (match e.eexpr with | TMeta((Meta.QuotedField,_,_),e) -> print ctx "\"%s\" : " (Ast.s_escape f); | _ -> print ctx "%s : " (anon_field f)); gen_value ctx e ) fields; spr ctx "}"; ctx.separator <- true | TFor (v,it,e) -> check_var_declaration v; let handle_break = handle_break ctx e in let it = ident (match it.eexpr with | TLocal v -> v.v_name | _ -> let id = ctx.id_counter in ctx.id_counter <- ctx.id_counter + 1; let name = "$it" ^ string_of_int id in print ctx "var %s = " name; gen_value ctx it; newline ctx; name ) in print ctx "while( %s.hasNext() ) {" it; let bend = open_block ctx in newline ctx; print ctx "var %s = %s.next()" (ident v.v_name) it; gen_block_element ctx e; bend(); newline ctx; spr ctx "}"; handle_break(); | TTry (e,catchs) -> spr ctx "try "; gen_expr ctx e; let vname = (match catchs with [(v,_)] -> check_var_declaration v; v.v_name | _ -> let id = ctx.id_counter in ctx.id_counter <- ctx.id_counter + 1; "$e" ^ string_of_int id ) in print ctx " catch( %s ) {" vname; let bend = open_block ctx in let last = ref false in let else_block = ref false in if ctx.store_exception_stack then begin newline ctx; print ctx "%s.lastException = %s" (ctx.type_accessor (TClassDecl { null_class with cl_path = ["haxe"],"CallStack" })) vname end; if (has_feature ctx "js.Lib.rethrow") then begin let has_rethrow (_,e) = let rec loop e = match e.eexpr with | TCall({eexpr = TLocal {v_name = "__rethrow__"}}, []) -> raise Exit | _ -> Type.iter loop e in try (loop e; false) with Exit -> true in if List.exists has_rethrow catchs then begin newline ctx; print ctx "var $hx_rethrow = %s" vname; end end; if (has_feature ctx "js.Boot.HaxeError") then begin let catch_var_used = try List.iter (fun (v,e) -> match follow v.v_type with | TDynamic _ -> (* Dynamic catch - unrap if the catch value is used *) let rec loop e = match e.eexpr with | TLocal v2 when v2 == v -> raise Exit | _ -> Type.iter loop e in loop e | _ -> (* not a Dynamic catch - we need to unwrap the error for type-checking *) raise Exit ) catchs; false with Exit -> true in if catch_var_used then begin newline ctx; print ctx "if (%s instanceof %s) %s = %s.val" vname (ctx.type_accessor (TClassDecl { null_class with cl_path = ["js";"_Boot"],"HaxeError" })) vname vname; end; end; List.iter (fun (v,e) -> if !last then () else let t = (match follow v.v_type with | TEnum (e,_) -> Some (TEnumDecl e) | TInst (c,_) -> Some (TClassDecl c) | TAbstract (a,_) -> Some (TAbstractDecl a) | TFun _ | TLazy _ | TType _ | TAnon _ -> assert false | TMono _ | TDynamic _ -> None ) in match t with | None -> last := true; if !else_block then print ctx "{"; if vname <> v.v_name then begin newline ctx; print ctx "var %s = %s" v.v_name vname; end; gen_block_element ctx e; if !else_block then begin newline ctx; print ctx "}"; end | Some t -> if not !else_block then newline ctx; print ctx "if( %s.__instanceof(%s," (ctx.type_accessor (TClassDecl { null_class with cl_path = ["js"],"Boot" })) vname; gen_value ctx (mk (TTypeExpr t) (mk_mono()) e.epos); spr ctx ") ) {"; let bend = open_block ctx in if vname <> v.v_name then begin newline ctx; print ctx "var %s = %s" v.v_name vname; end; gen_block_element ctx e; bend(); newline ctx; spr ctx "} else "; else_block := true ) catchs; if not !last then print ctx "throw(%s)" vname; bend(); newline ctx; spr ctx "}"; | TSwitch (e,cases,def) -> spr ctx "switch"; gen_value ctx e; spr ctx " {"; newline ctx; List.iter (fun (el,e2) -> List.iter (fun e -> match e.eexpr with | TConst(c) when c = TNull -> spr ctx "case null: case undefined:"; | _ -> spr ctx "case "; gen_value ctx e; spr ctx ":" ) el; let bend = open_block ctx in gen_block_element ctx e2; if not (has_return e2) then begin newline ctx; print ctx "break"; end; bend(); newline ctx; ) cases; (match def with | None -> () | Some e -> spr ctx "default:"; let bend = open_block ctx in gen_block_element ctx e; bend(); newline ctx; ); spr ctx "}" | TCast (e,None) -> gen_expr ctx e | TCast (e1,Some t) -> print ctx "%s.__cast(" (ctx.type_accessor (TClassDecl { null_class with cl_path = ["js"],"Boot" })); gen_expr ctx e1; spr ctx " , "; spr ctx (ctx.type_accessor t); spr ctx ")"); Option.may (fun smap -> smap.current_expr <- None) ctx.smap and gen_block_element ?(after=false) ctx e = match e.eexpr with | TBlock el -> List.iter (gen_block_element ~after ctx) el | TCall ({ eexpr = TLocal { v_name = "__feature__" } }, { eexpr = TConst (TString f) } :: eif :: eelse) -> if has_feature ctx f then gen_block_element ~after ctx eif else (match eelse with | [] -> () | [e] -> gen_block_element ~after ctx e | _ -> assert false) | TFunction _ -> gen_block_element ~after ctx (mk (TParenthesis e) e.etype e.epos) | TObjectDecl fl -> List.iter (fun (_,e) -> gen_block_element ~after ctx e) fl | _ -> if not after then newline ctx; gen_expr ctx e; if after then newline ctx and gen_value ctx e = Option.may (fun smap -> add_mapping smap false e) ctx.smap; let assign e = mk (TBinop (Ast.OpAssign, mk (TLocal (match ctx.in_value with None -> assert false | Some v -> v)) t_dynamic e.epos, e )) e.etype e.epos in let value() = let old = ctx.in_value, ctx.in_loop in let r = alloc_var "$r" t_dynamic e.epos in ctx.in_value <- Some r; ctx.in_loop <- false; spr ctx "(function($this) "; spr ctx "{"; let b = open_block ctx in newline ctx; spr ctx "var $r"; newline ctx; (fun() -> newline ctx; spr ctx "return $r"; b(); newline ctx; spr ctx "}"; ctx.in_value <- fst old; ctx.in_loop <- snd old; print ctx "(%s))" (this ctx) ) in (match e.eexpr with | TConst _ | TLocal _ | TArray _ | TBinop _ | TField _ | TEnumParameter _ | TTypeExpr _ | TParenthesis _ | TObjectDecl _ | TArrayDecl _ | TNew _ | TUnop _ | TFunction _ -> gen_expr ctx e | TMeta (_,e1) -> gen_value ctx e1 | TCall (e,el) -> gen_call ctx e el true | TReturn _ | TBreak | TContinue -> unsupported e.epos | TCast (e1, None) -> gen_value ctx e1 | TCast (e1, Some t) -> print ctx "%s.__cast(" (ctx.type_accessor (TClassDecl { null_class with cl_path = ["js"],"Boot" })); gen_value ctx e1; spr ctx " , "; spr ctx (ctx.type_accessor t); spr ctx ")" | TVar _ | TFor _ | TWhile _ | TThrow _ -> (* value is discarded anyway *) let v = value() in gen_expr ctx e; v() | TBlock [e] -> gen_value ctx e | TBlock el -> let v = value() in let rec loop = function | [] -> spr ctx "return null"; | [e] -> gen_expr ctx (assign e); | e :: l -> gen_expr ctx e; newline ctx; loop l in loop el; v(); | TIf (cond,e,eo) -> (* remove parenthesis unless it's an operation with higher precedence than ?: *) let cond = (match cond.eexpr with | TParenthesis { eexpr = TBinop ((Ast.OpAssign | Ast.OpAssignOp _),_,_) | TIf _ } -> cond | TParenthesis e -> e | _ -> cond ) in gen_value ctx cond; spr ctx " ? "; gen_value ctx e; spr ctx " : "; (match eo with | None -> spr ctx "null" | Some e -> gen_value ctx e); | TSwitch (cond,cases,def) -> let v = value() in gen_expr ctx (mk (TSwitch (cond, List.map (fun (e1,e2) -> (e1,assign e2)) cases, match def with None -> None | Some e -> Some (assign e) )) e.etype e.epos); v() | TTry (b,catchs) -> let v = value() in let block e = mk (TBlock [e]) e.etype e.epos in gen_expr ctx (mk (TTry (block (assign b), List.map (fun (v,e) -> v, block (assign e)) catchs )) e.etype e.epos); v()); Option.may (fun smap -> smap.current_expr <- None) ctx.smap let generate_package_create ctx (p,_) = let rec loop acc = function | [] -> () | p :: l when Hashtbl.mem ctx.packages (p :: acc) -> loop (p :: acc) l | p :: l -> Hashtbl.add ctx.packages (p :: acc) (); (match acc with | [] -> if ctx.js_modern then print ctx "var %s = {}" p else print ctx "var %s = %s || {}" p p | _ -> let p = String.concat "." (List.rev acc) ^ (field p) in if ctx.js_modern then print ctx "%s = {}" p else print ctx "if(!%s) %s = {}" p p ); ctx.separator <- true; newline ctx; loop (p :: acc) l in match p with | [] -> print ctx "var " | _ -> loop [] p let check_field_name c f = match f.cf_name with | "prototype" | "__proto__" | "constructor" -> abort ("The field name '" ^ f.cf_name ^ "' is not allowed in JS") (match f.cf_expr with None -> c.cl_pos | Some e -> e.epos); | _ -> () (* convert a.b.c to ["a"]["b"]["c"] *) let path_to_brackets path = let parts = ExtString.String.nsplit path "." in "[\"" ^ (String.concat "\"][\"" parts) ^ "\"]" let gen_class_static_field ctx c f = match f.cf_expr with | None | Some { eexpr = TConst TNull } when not (has_feature ctx "Type.getClassFields") -> () | None when is_extern_field f -> () | None -> print ctx "%s%s = null" (s_path ctx c.cl_path) (static_field c f.cf_name); newline ctx | Some e -> match e.eexpr with | TFunction _ -> let path = (s_path ctx c.cl_path) ^ (static_field c f.cf_name) in let dot_path = (dot_path c.cl_path) ^ (static_field c f.cf_name) in ctx.id_counter <- 0; print ctx "%s = " path; (match (get_exposed ctx dot_path f.cf_meta) with [s] -> print ctx "$hx_exports%s = " (path_to_brackets s) | _ -> ()); gen_value ctx e; newline ctx; | _ -> ctx.statics <- (c,f.cf_name,e) :: ctx.statics let can_gen_class_field ctx = function | { cf_expr = (None | Some { eexpr = TConst TNull }) } when not (has_feature ctx "Type.getInstanceFields") -> false | f -> not (is_extern_field f) let gen_class_field ctx c f = check_field_name c f; match f.cf_expr with | None -> newprop ctx; print ctx "%s: " (anon_field f.cf_name); print ctx "null"; | Some e -> newprop ctx; print ctx "%s: " (anon_field f.cf_name); ctx.id_counter <- 0; gen_value ctx e; ctx.separator <- false let generate_class___name__ ctx c = if has_feature ctx "js.Boot.isClass" then begin let p = s_path ctx c.cl_path in print ctx "%s.__name__ = " p; if has_feature ctx "Type.getClassName" then print ctx "[%s]" (String.concat "," (List.map (fun s -> Printf.sprintf "\"%s\"" (Ast.s_escape s)) (fst c.cl_path @ [snd c.cl_path]))) else print ctx "true"; newline ctx; end let generate_class ctx c = ctx.current <- c; ctx.id_counter <- 0; (match c.cl_path with | [],"Function" -> abort "This class redefine a native one" c.cl_pos | _ -> ()); let p = s_path ctx c.cl_path in let hxClasses = has_feature ctx "Type.resolveClass" in if ctx.js_flatten then print ctx "var " else generate_package_create ctx c.cl_path; if ctx.js_modern || not hxClasses then print ctx "%s = " p else print ctx "%s = $hxClasses[\"%s\"] = " p (dot_path c.cl_path); (match (get_exposed ctx (dot_path c.cl_path) c.cl_meta) with [s] -> print ctx "$hx_exports%s = " (path_to_brackets s) | _ -> ()); (match c.cl_kind with | KAbstractImpl _ -> (* abstract implementations only contain static members and don't need to have constructor functions *) print ctx "{}"; ctx.separator <- true | _ -> (match c.cl_constructor with | Some { cf_expr = Some e } -> gen_expr ctx e | _ -> (print ctx "function() { }"); ctx.separator <- true) ); newline ctx; if ctx.js_modern && hxClasses then begin print ctx "$hxClasses[\"%s\"] = %s" (dot_path c.cl_path) p; newline ctx; end; generate_class___name__ ctx c; (match c.cl_implements with | [] -> () | l -> print ctx "%s.__interfaces__ = [%s]" p (String.concat "," (List.map (fun (i,_) -> ctx.type_accessor (TClassDecl i)) l)); newline ctx; ); let gen_props props = String.concat "," (List.map (fun (p,v) -> p ^":\""^v^"\"") props) in let has_property_reflection = (has_feature ctx "Reflect.getProperty") || (has_feature ctx "Reflect.setProperty") in if has_property_reflection then begin (match Codegen.get_properties c.cl_ordered_statics with | [] -> () | props -> print ctx "%s.__properties__ = {%s}" p (gen_props props); ctx.separator <- true; newline ctx); end; List.iter (gen_class_static_field ctx c) c.cl_ordered_statics; let has_class = has_feature ctx "js.Boot.getClass" && (c.cl_super <> None || c.cl_ordered_fields <> [] || c.cl_constructor <> None) in let has_prototype = c.cl_super <> None || has_class || List.exists (can_gen_class_field ctx) c.cl_ordered_fields in if has_prototype then begin (match c.cl_super with | None -> print ctx "%s.prototype = {" p; | Some (csup,_) -> let psup = ctx.type_accessor (TClassDecl csup) in print ctx "%s.__super__ = %s" p psup; newline ctx; print ctx "%s.prototype = $extend(%s.prototype,{" p psup; ); let bend = open_block ctx in List.iter (fun f -> if can_gen_class_field ctx f then gen_class_field ctx c f) c.cl_ordered_fields; if has_class then begin newprop ctx; print ctx "__class__: %s" p; end; if has_property_reflection then begin let props = Codegen.get_properties c.cl_ordered_fields in (match c.cl_super with | _ when props = [] -> () | Some (csup,_) when Codegen.has_properties csup -> newprop ctx; let psup = ctx.type_accessor (TClassDecl csup) in print ctx "__properties__: $extend(%s.prototype.__properties__,{%s})" psup (gen_props props) | _ -> newprop ctx; print ctx "__properties__: {%s}" (gen_props props)); end; bend(); print ctx "\n}"; (match c.cl_super with None -> ctx.separator <- true | _ -> print ctx ")"); newline ctx end; flush ctx let generate_enum ctx e = let p = s_path ctx e.e_path in let ename = List.map (fun s -> Printf.sprintf "\"%s\"" (Ast.s_escape s)) (fst e.e_path @ [snd e.e_path]) in if ctx.js_flatten then print ctx "var " else generate_package_create ctx e.e_path; print ctx "%s = " p; if has_feature ctx "Type.resolveEnum" then print ctx "$hxClasses[\"%s\"] = " (dot_path e.e_path); print ctx "{"; if has_feature ctx "js.Boot.isEnum" then print ctx " __ename__ : %s," (if has_feature ctx "Type.getEnumName" then "[" ^ String.concat "," ename ^ "]" else "true"); print ctx " __constructs__ : [%s] }" (String.concat "," (List.map (fun s -> Printf.sprintf "\"%s\"" s) e.e_names)); ctx.separator <- true; newline ctx; List.iter (fun n -> let f = PMap.find n e.e_constrs in print ctx "%s%s = " p (field f.ef_name); (match f.ef_type with | TFun (args,_) -> let sargs = String.concat "," (List.map (fun (n,_,_) -> ident n) args) in print ctx "function(%s) { var $x = [\"%s\",%d,%s]; $x.__enum__ = %s;" sargs f.ef_name f.ef_index sargs p; if has_feature ctx "has_enum" then spr ctx " $x.toString = $estr;"; spr ctx " return $x; }"; ctx.separator <- true; | _ -> print ctx "[\"%s\",%d]" f.ef_name f.ef_index; newline ctx; if has_feature ctx "has_enum" then begin print ctx "%s%s.toString = $estr" p (field f.ef_name); newline ctx; end; print ctx "%s%s.__enum__ = %s" p (field f.ef_name) p; ); newline ctx ) e.e_names; if has_feature ctx "Type.allEnums" then begin let ctors_without_args = List.filter (fun s -> let ef = PMap.find s e.e_constrs in match follow ef.ef_type with | TFun _ -> false | _ -> true ) e.e_names in print ctx "%s.__empty_constructs__ = [%s]" p (String.concat "," (List.map (fun s -> Printf.sprintf "%s.%s" p s) ctors_without_args)); newline ctx end; begin match Codegen.build_metadata ctx.com (TEnumDecl e) with | None -> () | Some e -> print ctx "%s.__meta__ = " p; gen_expr ctx e; newline ctx end; flush ctx let generate_static ctx (c,f,e) = print ctx "%s%s = " (s_path ctx c.cl_path) (static_field c f); gen_value ctx e; newline ctx let generate_require ctx path meta = let _, args, mp = Meta.get Meta.JsRequire meta in let p = (s_path ctx path) in if ctx.js_flatten then spr ctx "var " else generate_package_create ctx path; (match args with | [(EConst(String(module_name)),_)] -> print ctx "%s = require(\"%s\")" p module_name | [(EConst(String(module_name)),_) ; (EConst(String(object_path)),_)] -> print ctx "%s = require(\"%s\").%s" p module_name object_path | _ -> abort "Unsupported @:jsRequire format" mp); newline ctx let generate_type ctx = function | TClassDecl c -> (match c.cl_init with | None -> () | Some e -> ctx.inits <- e :: ctx.inits); (* Special case, want to add Math.__name__ only when required, handle here since Math is extern *) let p = s_path ctx c.cl_path in if p = "Math" then generate_class___name__ ctx c; (* Another special case for Std because we do not want to generate it if it's empty. *) if p = "Std" && c.cl_ordered_statics = [] then () else if not c.cl_extern then generate_class ctx c else if Meta.has Meta.JsRequire c.cl_meta && is_directly_used ctx.com c.cl_meta then generate_require ctx c.cl_path c.cl_meta else if not ctx.js_flatten && Meta.has Meta.InitPackage c.cl_meta then (match c.cl_path with | ([],_) -> () | _ -> generate_package_create ctx c.cl_path) | TEnumDecl e when e.e_extern -> if Meta.has Meta.JsRequire e.e_meta && is_directly_used ctx.com e.e_meta then generate_require ctx e.e_path e.e_meta | TEnumDecl e -> generate_enum ctx e | TTypeDecl _ | TAbstractDecl _ -> () let set_current_class ctx c = ctx.current <- c let alloc_ctx com = let smap = if com.debug || Common.defined com Define.JsSourceMap then Some { source_last_line = 0; source_last_col = 0; source_last_file = 0; print_comma = false; output_last_col = 0; output_current_col = 0; sources = DynArray.create(); sources_hash = Hashtbl.create 0; mappings = Rbuffer.create 16; current_expr = None; } else None in let ctx = { com = com; buf = Rbuffer.create 16000; chan = open_out_bin com.file; packages = Hashtbl.create 0; smap = smap; js_modern = not (Common.defined com Define.JsClassic); js_flatten = not (Common.defined com Define.JsUnflatten); es_version = (try int_of_string (Common.defined_value com Define.JsEs) with _ -> 0); store_exception_stack = if Common.has_dce com then (Common.has_feature com "haxe.CallStack.exceptionStack") else List.exists (function TClassDecl { cl_path=["haxe"],"CallStack" } -> true | _ -> false) com.types; statics = []; inits = []; current = null_class; tabs = ""; in_value = None; in_loop = false; handle_break = false; id_counter = 0; type_accessor = (fun _ -> assert false); separator = false; found_expose = false; } in ctx.type_accessor <- (fun t -> let p = t_path t in match t with | TClassDecl ({ cl_extern = true } as c) when not (Meta.has Meta.JsRequire c.cl_meta) -> dot_path p | TEnumDecl ({ e_extern = true } as e) when not (Meta.has Meta.JsRequire e.e_meta) -> dot_path p | _ -> s_path ctx p); ctx let gen_single_expr ctx e expr = if expr then gen_expr ctx e else gen_value ctx e; let str = Rbuffer.unsafe_contents ctx.buf in Rbuffer.reset ctx.buf; ctx.id_counter <- 0; str let generate com = (match com.js_gen with | Some g -> g() | None -> let ctx = alloc_ctx com in Codegen.map_source_header com (fun s -> print ctx "// %s\n" s); if has_feature ctx "Class" || has_feature ctx "Type.getClassName" then add_feature ctx "js.Boot.isClass"; if has_feature ctx "Enum" || has_feature ctx "Type.getEnumName" then add_feature ctx "js.Boot.isEnum"; let nodejs = Common.raw_defined com "nodejs" in let exposed = List.concat (List.map (fun t -> match t with | TClassDecl c -> let path = dot_path c.cl_path in let class_exposed = get_exposed ctx path c.cl_meta in let static_exposed = List.map (fun f -> get_exposed ctx (path ^ static_field c f.cf_name) f.cf_meta ) c.cl_ordered_statics in List.concat (class_exposed :: static_exposed) | _ -> [] ) com.types) in let anyExposed = exposed <> [] in let exportMap = ref (PMap.create String.compare) in let exposedObject = { os_name = ""; os_fields = [] } in let toplevelExposed = ref [] in List.iter (fun path -> ( let parts = ExtString.String.nsplit path "." in let rec loop p pre = match p with | f :: g :: ls -> let path = match pre with "" -> f | pre -> (pre ^ "." ^ f) in if not (PMap.exists path !exportMap) then ( let elts = { os_name = f; os_fields = [] } in exportMap := PMap.add path elts !exportMap; let cobject = match pre with "" -> exposedObject | pre -> PMap.find pre !exportMap in cobject.os_fields <- elts :: cobject.os_fields ); loop (g :: ls) path; | f :: [] when pre = "" -> toplevelExposed := f :: !toplevelExposed; | _ -> () in loop parts ""; )) exposed; let include_files = List.rev com.include_files in List.iter (fun file -> match file with | path, "top" -> let file_content = Std.input_file ~bin:true (fst file) in print ctx "%s\n" file_content; () | _ -> () ) include_files; let var_console = ( "console", "typeof console != \"undefined\" ? console : {log:function(){}}" ) in let var_exports = ( "$hx_exports", "typeof exports != \"undefined\" ? exports : typeof window != \"undefined\" ? window : typeof self != \"undefined\" ? self : this" ) in let var_global = ( "$global", "typeof window != \"undefined\" ? window : typeof global != \"undefined\" ? global : typeof self != \"undefined\" ? self : this" ) in let closureArgs = [] in let closureArgs = if has_feature ctx "js.Lib.global" then var_global :: closureArgs else closureArgs in let closureArgs = if (anyExposed && not (Common.defined com Define.ShallowExpose)) then var_exports :: closureArgs else closureArgs in (* Provide console for environments that may not have it. *) let closureArgs = if ctx.es_version < 5 then var_console :: closureArgs else closureArgs in if nodejs then (* Add node globals to pseudo-keywords, so they are not shadowed by local vars *) List.iter (fun s -> Hashtbl.replace kwds2 s ()) [ "global"; "process"; "__filename"; "__dirname"; "module" ]; if (anyExposed && ((Common.defined com Define.ShallowExpose) || not ctx.js_modern)) then ( print ctx "var %s = %s" (fst var_exports) (snd var_exports); ctx.separator <- true; newline ctx ); if ctx.js_modern then begin (* Additional ES5 strict mode keywords. *) List.iter (fun s -> Hashtbl.replace kwds s ()) [ "arguments"; "eval" ]; (* Wrap output in a closure *) print ctx "(function (%s) { \"use strict\"" (String.concat ", " (List.map fst closureArgs)); newline ctx; end; let rec print_obj f root = ( let path = root ^ (path_to_brackets f.os_name) in print ctx "%s = %s || {}" path path; ctx.separator <- true; newline ctx; concat ctx ";" (fun g -> print_obj g path) f.os_fields ) in List.iter (fun f -> print_obj f "$hx_exports") exposedObject.os_fields; List.iter (fun file -> match file with | path, "closure" -> let file_content = Std.input_file ~bin:true (fst file) in print ctx "%s\n" file_content; () | _ -> () ) include_files; (* If ctx.js_modern, console is defined in closureArgs. *) if (not ctx.js_modern) && (ctx.es_version < 5) then add_feature ctx "js.Lib.global"; (* console polyfill will check console from $global *) if (not ctx.js_modern) && (has_feature ctx "js.Lib.global") then print ctx "var %s = %s;\n" (fst var_global) (snd var_global); if (not ctx.js_modern) && (ctx.es_version < 5) then spr ctx "var console = $global.console || {log:function(){}};\n"; (* TODO: fix $estr *) let vars = [] in let vars = (if has_feature ctx "Type.resolveClass" || has_feature ctx "Type.resolveEnum" then ("$hxClasses = " ^ (if ctx.js_modern then "{}" else "$hxClasses || {}")) :: vars else vars) in let vars = if has_feature ctx "has_enum" then ("$estr = function() { return " ^ (ctx.type_accessor (TClassDecl { null_class with cl_path = ["js"],"Boot" })) ^ ".__string_rec(this,''); }") :: vars else vars in (match List.rev vars with | [] -> () | vl -> print ctx "var %s" (String.concat "," vl); ctx.separator <- true; newline ctx ); if List.exists (function TClassDecl { cl_extern = false; cl_super = Some _ } -> true | _ -> false) com.types then begin print ctx "function $extend(from, fields) { function Inherit() {} Inherit.prototype = from; var proto = new Inherit(); for (var name in fields) proto[name] = fields[name]; if( fields.toString !== Object.prototype.toString ) proto.toString = fields.toString; return proto; } "; end; List.iter (generate_type ctx) com.types; let rec chk_features e = if is_dynamic_iterator ctx e then add_feature ctx "use.$iterator"; match e.eexpr with | TField (_,FClosure _) -> add_feature ctx "use.$bind" | _ -> Type.iter chk_features e in List.iter chk_features ctx.inits; List.iter (fun (_,_,e) -> chk_features e) ctx.statics; if has_feature ctx "use.$iterator" then begin add_feature ctx "use.$bind"; print ctx "function $iterator(o) { if( o instanceof Array ) return function() { return HxOverrides.iter(o); }; return typeof(o.iterator) == 'function' ? $bind(o,o.iterator) : o.iterator; }"; newline ctx; end; if has_feature ctx "use.$bind" then begin print ctx "var $_, $fid = 0"; newline ctx; print ctx "function $bind(o,m) { if( m == null ) return null; if( m.__id__ == null ) m.__id__ = $fid++; var f; if( o.hx__closures__ == null ) o.hx__closures__ = {}; else f = o.hx__closures__[m.__id__]; if( f == null ) { f = function(){ return f.method.apply(f.scope, arguments); }; f.scope = o; f.method = m; o.hx__closures__[m.__id__] = f; } return f; }"; newline ctx; end; if has_feature ctx "use.$arrayPush" then begin print ctx "function $arrayPush(x) { this.push(x); }"; newline ctx end; List.iter (gen_block_element ~after:true ctx) (List.rev ctx.inits); List.iter (generate_static ctx) (List.rev ctx.statics); (match com.main with | None -> () | Some e -> gen_expr ctx e; newline ctx); if ctx.js_modern then begin print ctx "})(%s)" (String.concat ", " (List.map snd closureArgs)); newline ctx; end; if (anyExposed && (Common.defined com Define.ShallowExpose)) then ( List.iter (fun f -> print ctx "var %s = $hx_exports%s" f.os_name (path_to_brackets f.os_name); ctx.separator <- true; newline ctx ) exposedObject.os_fields; List.iter (fun f -> print ctx "var %s = $hx_exports%s" f (path_to_brackets f); ctx.separator <- true; newline ctx ) !toplevelExposed ); (match ctx.smap with | Some smap -> write_mappings ctx smap | None -> try Sys.remove (com.file ^ ".map") with _ -> ()); flush ctx; close_out ctx.chan) haxe_3.4.4.orig/src/generators/genlua.ml0000664000175000017500000020174013166552354020165 0ustar andyandy00000000000000(* * 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 ExtList type pos = Globals.pos type ctx = { com : Common.context; buf : Buffer.t; packages : (string list,unit) Hashtbl.t; mutable current : tclass; mutable statics : (tclass * string * texpr) list; mutable inits : texpr list; mutable tabs : string; mutable in_value : tvar option; mutable in_loop : bool; mutable iife_assign : bool; mutable handle_break : bool; mutable break_depth : int; mutable handle_continue : bool; mutable id_counter : int; mutable type_accessor : module_type -> string; mutable separator : bool; mutable found_expose : bool; mutable lua_jit : bool; mutable lua_ver : float; } type object_store = { os_name : string; mutable os_fields : object_store list; } let debug_expression expression = " --[[ " ^ Type.s_expr_kind expression ^ " --]] " let debug_type t = " --[[ " ^ Type.s_type_kind t ^ " --]] ";; let get_exposed ctx path meta = try let (_, args, pos) = Meta.get Meta.Expose meta in (match args with | [ EConst (String s), _ ] -> [s] | [] -> [path] | _ -> abort "Invalid @:expose parameters" pos) with Not_found -> [] let dot_path = Globals.s_type_path let s_path ctx = dot_path (* Lua requires decimal encoding for characters, rather than the hex *) (* provided by Ast.s_escape *) let s_escape_lua ?(dec=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 && dec -> Buffer.add_string b (Printf.sprintf "\\%.3d" (int_of_char c)) | c -> Buffer.add_char b c done; Buffer.contents b (* TODO: are all these kwds necessary for field quotes *and* id escapes? *) let kwds = let h = Hashtbl.create 0 in List.iter (fun s -> Hashtbl.add h s ()) [ "_G"; ""; "and"; "break"; "do"; "else"; "elseif"; "end"; "false"; "for"; "function"; "if"; "in"; "local"; "nil"; "not"; "or"; "repeat"; "return"; "then"; "true"; "until"; "while"; "goto"; "self"; ]; h let valid_lua_ident s = try for i = 0 to String.length s - 1 do match String.unsafe_get s i with | 'a'..'z' | 'A'..'Z' | '_' -> () | '0'..'9' when i > 0 -> () | _ -> raise Exit done; true with Exit -> false let field s = if Hashtbl.mem kwds s || not (valid_lua_ident s) then "[\"" ^ s ^ "\"]" else "." ^ s let ident s = if Hashtbl.mem kwds s then "_" ^ s else s let anon_field s = if Hashtbl.mem kwds s || not (valid_lua_ident s) then "['" ^ (s_escape_lua s) ^ "']" else s let static_field c s = match s with | "length" | "name" when not c.cl_extern || Meta.has Meta.HxGen c.cl_meta-> "._hx" ^ s | s -> field s let has_feature ctx = Common.has_feature ctx.com let add_feature ctx = Common.add_feature ctx.com let temp ctx = ctx.id_counter <- ctx.id_counter + 1; "_hx_" ^ string_of_int (ctx.id_counter) let spr ctx s = ctx.separator <- false; Buffer.add_string ctx.buf s let print ctx = ctx.separator <- false; Printf.kprintf (fun s -> begin Buffer.add_string ctx.buf s end) let newline ctx = print ctx "\n%s" ctx.tabs (* print with newline *) let println ctx = ctx.separator <- false; Printf.kprintf (fun s -> begin Buffer.add_string ctx.buf s; newline ctx end) let unsupported p = abort "This expression cannot be compiled to Lua" p let basename path = try let idx = String.rindex path '/' in String.sub path (idx + 1) (String.length path - idx - 1) with Not_found -> path (* TODO : is this necessary any more?*) let newprop ctx = match Buffer.nth ctx.buf (Buffer.length ctx.buf - 1) with | '{' -> print ctx "\n%s" ctx.tabs | _ -> print ctx "\n%s" ctx.tabs let semicolon ctx = match Buffer.nth ctx.buf (Buffer.length ctx.buf - 1) with | '}' when not ctx.separator -> () | _ -> spr ctx ";" let rec concat ctx s f = function | [] -> () | [x] -> f x | x :: l -> f x; spr ctx s; concat ctx s f l let fun_block ctx f p = let e = List.fold_left (fun e (a,c) -> match c with | None | Some TNull -> e | Some c -> Type.concat (Codegen.set_default ctx.com a c p) e ) f.tf_expr f.tf_args in e let open_block ctx = let oldt = ctx.tabs in ctx.tabs <- " " ^ ctx.tabs; (fun() -> ctx.tabs <- oldt) let rec iter_switch_break in_switch e = match e.eexpr with | TFunction _ | TWhile _ | TFor _ -> () | TSwitch _ when not in_switch -> iter_switch_break true e | TBreak when in_switch -> raise Exit | _ -> iter (iter_switch_break in_switch) e let handle_break ctx e = (* TODO: This got messy. Find a way to unify the implementation with a try/catch helper at least *) let old = ctx.in_loop, ctx.handle_break in ctx.in_loop <- true; try iter_switch_break false e; ctx.handle_break <- false; (fun() -> ctx.in_loop <- fst old; ctx.handle_break <- snd old; ) with Exit -> println ctx "local _hx_expected_result = {}"; println ctx "local _hx_status, _hx_result = pcall(function() "; let b = open_block ctx in newline ctx; ctx.handle_break <- true; (fun() -> b(); ctx.in_loop <- fst old; ctx.handle_break <- snd old; newline ctx; println ctx "end"; println ctx " return _hx_expected_result end)"; spr ctx " if not _hx_status then "; newline ctx; println ctx " elseif _hx_result ~= _hx_expected_result then return _hx_result"; ) let this ctx = match ctx.in_value with None -> "self" | Some _ -> "self" let is_dynamic_iterator ctx e = let check x = has_feature ctx "HxOverrides.iter" && (match follow x.etype with | TInst ({ cl_path = [],"Array" },_) | TInst ({ cl_kind = KTypeParameter _}, _) | TAnon _ | TDynamic _ | TMono _ -> true | _ -> false ) in match e.eexpr with | TField (x,f) when field_name f = "iterator" -> check x | _ -> false (* return index of a first element in the list for which `f` returns true TODO: is there some standard function to do that? *) let index_of f l = let rec find lst idx = match lst with | [] -> raise Not_found | el :: rest -> if f el then idx else find rest (idx + 1) in find l 0 (* create a __lua__ call *) let mk_lua_code com code args t pos = let lua_local = Codegen.ExprBuilder.make_local (alloc_var "__lua__" t_dynamic pos) pos in let code_const = Codegen.ExprBuilder.make_string com code pos in mk (TCall (lua_local, code_const :: args)) t pos (* create a multi-return boxing call for given expr *) let mk_mr_box ctx e = let s_fields = match follow e.etype with | TInst (c,_) -> String.concat ", " (List.map (fun f -> "\"" ^ f.cf_name ^ "\"") c.cl_ordered_fields) | _ -> assert false in add_feature ctx "use._hx_box_mr"; add_feature ctx "use._hx_table"; let code = Printf.sprintf "_hx_box_mr(_hx_table.pack({0}), {%s})" s_fields in mk_lua_code ctx.com code [e] e.etype e.epos (* create a multi-return select call for given expr and field name *) let mk_mr_select com e name = let i = match follow e.etype with | TInst (c,_) -> index_of (fun f -> f.cf_name = name) c.cl_ordered_fields | _ -> assert false in if i == 0 then e else let code = Printf.sprintf "_G.select(%i, {0})" (i + 1) in mk_lua_code com code [e] e.etype e.epos (* from genphp *) let rec is_string_type t = match follow t with | TInst ({cl_path = ([], "String")}, _) -> true | TAnon a -> (match !(a.a_status) with | Statics ({cl_path = ([], "String")}) -> true | _ -> false) | TAbstract (a,pl) -> is_string_type (Abstract.get_underlying_type a pl) | _ -> false let is_string_expr e = is_string_type e.etype (* /from genphp *) let rec is_int_type ctx t = match follow t with | TInst ({cl_path = ([], "Int")}, _) -> true | TAnon a -> (match !(a.a_status) with | Statics ({cl_path = ([], "Int")}) -> true | _ -> false) | TAbstract ({a_path = ([],"Float")}, pl) -> false | TAbstract ({a_path = ([],"Int")}, pl) -> true | TAbstract (a,pl) -> is_int_type ctx (Abstract.get_underlying_type a pl) | _ -> false let rec extract_expr e = match e.eexpr with | TParenthesis e | TMeta (_,e) | TCast(e,_) -> extract_expr e | _ -> e let gen_constant ctx p = function | TInt i -> print ctx "%ld" i | TFloat s -> spr ctx s | TString s -> begin add_feature ctx "use.string"; print ctx "\"%s\"" (s_escape_lua s) end | TBool b -> spr ctx (if b then "true" else "false") | TNull -> spr ctx "nil" | TThis -> spr ctx (this ctx) | TSuper -> assert false let rec gen_call ctx e el in_value = ctx.iife_assign <- true; (match e.eexpr , el with | TConst TSuper , params -> (match ctx.current.cl_super with | None -> abort "Missing api.setCurrentClass" e.epos | Some (c,_) -> print ctx "%s.super(%s" (ctx.type_accessor (TClassDecl c)) (this ctx); List.iter (fun p -> print ctx ","; gen_value ctx p) params; spr ctx ")"; ); | TField ({ eexpr = TConst TSuper },f) , params -> (match ctx.current.cl_super with | None -> abort "Missing api.setCurrentClass" e.epos | Some (c,_) -> let name = field_name f in print ctx "%s.prototype%s(%s" (ctx.type_accessor (TClassDecl c)) (field name) (this ctx); List.iter (fun p -> print ctx ","; gen_value ctx p) params; spr ctx ")"; ); | TCall (x,_) , el when (match x.eexpr with TLocal { v_name = "__lua__" } -> false | _ -> true) -> spr ctx "("; gen_value ctx e; spr ctx ")"; spr ctx "("; concat ctx "," (gen_value ctx) el; spr ctx ")"; | TLocal { v_name = "__new__" }, { eexpr = TConst (TString cl) } :: params -> print ctx "%s.new(" cl; concat ctx "," (gen_value ctx) params; spr ctx ")"; | TLocal { v_name = "__new__" }, e :: params -> gen_value ctx e; spr ctx ".new("; concat ctx "," (gen_value ctx) params; spr ctx ")"; | TLocal { v_name = "__callself__" }, { eexpr = TConst (TString head) } :: { eexpr = TConst (TString tail) } :: el -> print ctx "%s:%s" head tail; spr ctx "("; concat ctx ", " (gen_value ctx) el; spr ctx ")"; | TLocal { v_name = "__call__" }, { eexpr = TConst (TString code) } :: el -> spr ctx code; spr ctx "("; concat ctx ", " (gen_value ctx) el; spr ctx ")"; | TLocal { v_name = "__lua_length__" }, [e]-> spr ctx "#"; gen_value ctx e; | TLocal { v_name = "__lua_table__" }, el -> let count = ref 0 in spr ctx "({"; List.iter (fun e -> (match e with | { eexpr = TArrayDecl arr } -> if (!count > 0 && List.length(arr) > 0) then spr ctx ","; concat ctx "," (gen_value ctx) arr; if List.length(arr) > 0 then incr count; | { eexpr = TObjectDecl fields } -> if (!count > 0 && List.length(fields) > 0) then spr ctx ","; concat ctx ", " (fun (f,e) -> print ctx "%s = " (anon_field f); gen_value ctx e ) fields; if List.length(fields) > 0 then incr count; | { eexpr = TConst(TNull)} -> () | _ -> abort "__lua_table__ only accepts array or anonymous object arguments" e.epos; )) el; spr ctx "})"; | TLocal { v_name = "__lua__" }, [{ eexpr = TConst (TString code) }] -> spr ctx (String.concat "\n" (ExtString.String.nsplit code "\r\n")) | TLocal { v_name = "__lua__" }, { eexpr = TConst (TString code); epos = p } :: tl -> Codegen.interpolate_code ctx.com code tl (spr ctx) (gen_expr ctx) p | TLocal { v_name = "__type__" }, [o] -> spr ctx "type("; gen_value ctx o; spr ctx ")"; | TLocal ({v_name = "__define_feature__"}), [_;e] -> gen_expr ctx e | TLocal { v_name = "__feature__" }, { eexpr = TConst (TString f) } :: eif :: eelse -> (if has_feature ctx f then gen_value ctx eif else match eelse with | [] -> () | e :: _ -> gen_value ctx e) | TLocal { v_name = "__resources__" }, [] -> (* TODO: Array declaration helper *) spr ctx "_hx_tab_array({"; let count = ref 0 in concat ctx "," (fun (name,data) -> if (!count == 0) then spr ctx "[0]="; spr ctx "{ "; spr ctx "name = "; gen_constant ctx e.epos (TString name); spr ctx ", data = "; gen_constant ctx e.epos (TString (Codegen.bytes_serialize data)); spr ctx "}"; incr count ) (Hashtbl.fold (fun name data acc -> (name,data) :: acc) ctx.com.resources []); print ctx "}, %i)" !count; | TLocal { v_name = "`trace" }, [e;infos] -> if has_feature ctx "haxe.Log.trace" then begin let t = (try List.find (fun t -> t_path t = (["haxe"],"Log")) ctx.com.types with _ -> assert false) in spr ctx (ctx.type_accessor t); spr ctx ".trace("; gen_value ctx e; spr ctx ","; gen_value ctx infos; spr ctx ")"; end else begin spr ctx "_hx_print("; gen_value ctx e; spr ctx ")"; end | TField ( { eexpr = TConst(TInt _ | TFloat _| TString _| TBool _) } as e , ((FInstance _ | FAnon _) as ef)), el -> spr ctx ("("); gen_value ctx e; print ctx ("):%s(") (field_name ef); concat ctx "," (gen_value ctx) el; spr ctx ")"; | TField (e, ((FInstance _ | FAnon _ | FDynamic _) as ef)), el -> let s = (field_name ef) in if Hashtbl.mem kwds s || not (valid_lua_ident s) then begin add_feature ctx "use._hx_apply_self"; spr ctx "_hx_apply_self("; gen_value ctx e; print ctx ",\"%s\"" (field_name ef); if List.length(el) > 0 then spr ctx ","; concat ctx "," (gen_value ctx) el; spr ctx ")"; end else begin gen_value ctx e; print ctx ":%s(" (field_name ef); concat ctx "," (gen_value ctx) el; spr ctx ")" end; | _ -> gen_value ctx e; spr ctx "("; concat ctx "," (gen_value ctx) el; spr ctx ")"); ctx.iife_assign <- false; and gen_expr ?(local=true) ctx e = begin match e.eexpr with TConst c -> gen_constant ctx e.epos c; | TLocal v when v.v_name = "this" -> spr ctx "self"; | TLocal v -> spr ctx (ident v.v_name) | TArray (e1,{ eexpr = TConst (TString s) }) when valid_lua_ident s && (match e1.eexpr with TConst (TInt _|TFloat _) -> false | _ -> true) -> gen_value ctx e1; spr ctx (field s) | TArray (e1,e2) -> gen_value ctx e1; spr ctx "["; gen_value ctx e2; spr ctx "]"; | TBinop (op,e1,e2) -> gen_tbinop ctx op e1 e2; | TField (x,f) when field_name f = "iterator" && is_dynamic_iterator ctx e -> add_feature ctx "use._iterator"; print ctx "_iterator("; gen_value ctx x; print ctx ")"; | TField (x,FClosure (_,f)) -> add_feature ctx "use._hx_bind"; (match x.eexpr with | TConst _ | TLocal _ -> print ctx "_hx_bind("; gen_value ctx x; print ctx ","; gen_value ctx x; print ctx "%s)" (if Meta.has Meta.SelfCall f.cf_meta then "" else (field f.cf_name)) | _ -> print ctx "(function() local __="; gen_value ctx x; print ctx "; return _hx_bind(__,__%s) end)()" (if Meta.has Meta.SelfCall f.cf_meta then "" else (field f.cf_name))) | TEnumParameter (x,_,i) -> gen_value ctx x; print ctx "[%i]" (i + 2) | TField (x, (FInstance(_,_,f) | FStatic(_,f) | FAnon(f))) when Meta.has Meta.SelfCall f.cf_meta -> gen_value ctx x; | TField ({ eexpr = TConst(TInt _ | TFloat _| TString _| TBool _) } as e , ((FInstance _ | FAnon _) as ef)) -> spr ctx ("("); gen_value ctx e; print ctx (").%s") (field_name ef); | TField ({ eexpr = TConst (TInt _ | TFloat _) } as x,f) -> gen_expr ctx { e with eexpr = TField(mk (TParenthesis x) x.etype x.epos,f) } | TField ({ eexpr = TObjectDecl fields }, ef ) -> spr ctx "(function(x) return x."; print ctx "%s" (field_name ef); spr ctx " end )({"; concat ctx ", " (fun (f,e) -> print ctx "%s = " (anon_field f); gen_value ctx e) fields; spr ctx "})"; | TField ({eexpr = TLocal v}, f) when Meta.has Meta.MultiReturn v.v_meta -> (* field of a multireturn local var is actually just a local var *) let (_, args, pos) = Meta.get (Meta.Custom ":lua_mr_id") v.v_meta in (match args with | [(EConst(String(id)), _)] -> spr ctx (id ^ "_" ^ (ident v.v_name) ^ "_" ^ (field_name f)); | _ -> assert false); | TField (x,f) -> gen_value ctx x; let name = field_name f in spr ctx (match f with FStatic _ | FEnum _ | FInstance _ | FAnon _ | FDynamic _ | FClosure _ -> field name) | TTypeExpr t -> spr ctx (ctx.type_accessor t) | TParenthesis e -> spr ctx "("; gen_value ctx e; spr ctx ")"; | TMeta (_,e) -> gen_expr ctx e | TReturn eo -> gen_return ctx e eo; | TBreak -> if not ctx.in_loop then unsupported e.epos; if ctx.handle_break then spr ctx "_G.error(\"_hx__break__\")" else if ctx.handle_continue then print ctx "_hx_break_%i = true; break" ctx.break_depth else spr ctx "break" (*todo*) | TContinue -> if not ctx.in_loop then unsupported e.epos; spr ctx "break"; | TBlock el -> let bend = open_block ctx in List.iter (gen_block_element ctx) el; bend(); newline ctx; | TFunction f -> let old = ctx.in_value, ctx.in_loop in ctx.in_value <- None; ctx.in_loop <- false; print ctx "function(%s) " (String.concat "," (List.map ident (List.map arg_name f.tf_args))); let fblock = fun_block ctx f e.epos in (match fblock.eexpr with | TBlock el -> let bend = open_block ctx in List.iter (gen_block_element ctx) el; bend(); newline ctx; |_ -> ()); spr ctx "end"; ctx.in_value <- fst old; ctx.in_loop <- snd old; ctx.separator <- true | TCall (e,el) -> gen_call ctx e el false; | TArrayDecl el -> spr ctx "_hx_tab_array({"; let count = ref 0 in List.iteri (fun i e -> incr count; if (i == 0) then spr ctx "[0]=" else spr ctx ", "; gen_value ctx e) el; print ctx " }, %i)" !count; | TThrow e -> spr ctx "_G.error("; gen_value ctx e; spr ctx ",0)"; | TVar (v,eo) -> begin match eo with | None -> if local then spr ctx "local "; spr ctx (ident v.v_name); | Some e -> match e.eexpr with | TBinop(OpAssign, e1, e2) -> gen_tbinop ctx OpAssign e1 e2; if local then spr ctx " local "; spr ctx (ident v.v_name); spr ctx " = "; gen_value ctx e1; | _ when Meta.has Meta.MultiReturn v.v_meta -> (* multi-return var is generated as several vars for unpacking *) let id = temp ctx in let temp_expr = (EConst(String(id)), Globals.null_pos) in v.v_meta <- (Meta.Custom ":lua_mr_id", [temp_expr], v.v_pos) :: v.v_meta; let name = ident v.v_name in let names = match follow v.v_type with | TInst (c, _) -> List.map (fun f -> id ^ "_" ^name ^ "_" ^ f.cf_name) c.cl_ordered_fields | _ -> assert false in spr ctx "local "; spr ctx (String.concat ", " names); spr ctx " = "; gen_value ctx e; | _ -> if local then spr ctx "local "; spr ctx (ident v.v_name); spr ctx " = "; (* if it was a multi-return var but it was used as a value itself, we have to box it in an object conforming to a multi-return extern class *) let is_boxed_multireturn = Meta.has (Meta.Custom ":lua_mr_box") v.v_meta in let e = if is_boxed_multireturn then mk_mr_box ctx e else e in gen_value ctx e; end | TNew (c,_,el) -> (match c.cl_constructor with | Some cf when Meta.has Meta.SelfCall cf.cf_meta -> print ctx "%s" (ctx.type_accessor (TClassDecl c)); | Some cf when Meta.has Meta.Native cf.cf_meta -> let _, args, mp = Meta.get Meta.Native cf.cf_meta in (match args with | [( EConst(String s),_)] -> print ctx "%s.%s" (ctx.type_accessor (TClassDecl c)) s; | _ -> print ctx "%s.new" (ctx.type_accessor (TClassDecl c))); | _ -> print ctx "%s.new" (ctx.type_accessor (TClassDecl c))); spr ctx "("; concat ctx "," (gen_value ctx) el; spr ctx ")" | TIf (cond,e,eelse) -> ctx.iife_assign <- true; spr ctx "if "; gen_cond ctx cond; spr ctx " then "; let bend = open_block ctx in gen_block_element ctx e; bend(); newline ctx; (match eelse with | None -> (); | Some e2 -> (match e.eexpr with | TObjectDecl _ -> ctx.separator <- false | _ ->()); spr ctx "else"; let bend = open_block ctx in gen_block_element ctx e2; bend(); newline ctx); spr ctx "end"; ctx.iife_assign <- false; | TUnop ((Increment|Decrement) as op,unop_flag, e) -> (* TODO: Refactor this mess *) println ctx "(function() "; (match e.eexpr, unop_flag with | TArray(e1,e2), _ -> spr ctx "local _hx_idx = "; gen_value ctx e2; semicolon ctx; newline ctx; spr ctx "local _hx_arr ="; gen_value ctx e1; semicolon ctx; newline ctx; (match unop_flag with | Ast.Postfix -> spr ctx "local _ = _hx_arr[_hx_idx]"; semicolon ctx; newline ctx; | _ -> ()); spr ctx "_hx_arr[_hx_idx] = _hx_arr[_hx_idx]"; | TField(e1,e2), _ -> spr ctx "local _hx_obj = "; gen_value ctx e1; semicolon ctx; newline ctx; spr ctx "local _hx_fld = "; (match e2 with | FInstance(_,_,fld) | FStatic(_,fld) | FAnon fld | FClosure(_,fld) -> print ctx "'%s'" fld.cf_name; | FDynamic name -> print ctx "'%s'" name; | FEnum(_,efld) -> print ctx "'%s'" efld.ef_name); semicolon ctx; newline ctx; (match unop_flag with | Ast.Postfix -> spr ctx "local _ = _hx_obj[_hx_fld]"; semicolon ctx; newline ctx; | _ -> ()); spr ctx "_hx_obj[_hx_fld] = _hx_obj[_hx_fld] "; | _, Ast.Prefix -> gen_value ctx e; spr ctx " = "; gen_value ctx e; | _, Ast.Postfix -> spr ctx "local _ = "; gen_value ctx e; semicolon ctx; gen_value ctx e; spr ctx " = "; gen_value ctx e); (match op with |Increment -> spr ctx " + 1;" |Decrement -> spr ctx " - 1;" |_-> print ctx " %s 1;" (Ast.s_unop op)); newline ctx; spr ctx " return "; (match unop_flag, e.eexpr with | Ast.Postfix, _ -> spr ctx "_"; | _, TArray(e1,e2) -> spr ctx "_hx_arr[_hx_idx]"; | _, TField(e1,e2) -> spr ctx "_hx_obj[_hx_fld]"; | _, _ -> gen_value ctx e; ); semicolon ctx; newline ctx; spr ctx " end)()"; | TUnop (Not,unop_flag,e) -> spr ctx "not "; gen_value ctx e; | TUnop (NegBits,unop_flag,e) -> add_feature ctx "use._bitop"; spr ctx "_hx_bit.bnot("; gen_value ctx e; spr ctx ")"; | TUnop (op,Ast.Prefix,e) -> spr ctx (Ast.s_unop op); gen_value ctx e | TUnop (op,Ast.Postfix,e) -> gen_value ctx e; spr ctx (Ast.s_unop op) | TWhile (cond,e,Ast.NormalWhile) -> let handle_break = handle_break ctx e in let has_continue = has_continue e in let old_ctx_continue = ctx.handle_continue in ctx.handle_continue <- has_continue; if has_continue then println ctx "local _hx_break_%i = false;" ctx.break_depth; spr ctx "while "; gen_cond ctx cond; let b = open_block ctx in print ctx " do "; if has_continue then begin newline ctx; (open_block ctx)(); spr ctx "repeat " end; ctx.break_depth <- ctx.break_depth + 1; gen_block_element ctx e; newline ctx; handle_break(); if has_continue then begin b(); newline ctx; println ctx "until true"; println ctx "if _hx_break_%i then _hx_break_%i = false; break; end" ctx.break_depth ctx.break_depth; end; b(); spr ctx "end"; ctx.break_depth <- ctx.break_depth-1; ctx.handle_continue <- old_ctx_continue; | TWhile (cond,e,Ast.DoWhile) -> let handle_break = handle_break ctx e in let has_continue = has_continue e in let old_ctx_continue = ctx.handle_continue in ctx.handle_continue <- has_continue; println ctx "while true do "; gen_block_element ctx e; newline ctx; if has_continue then println ctx "local _hx_break_%i = false;" ctx.break_depth; spr ctx " while "; gen_cond ctx cond; let b = open_block ctx in println ctx " do "; let b2 = open_block ctx in if has_continue then begin newline ctx; (open_block ctx)(); spr ctx "repeat " end; ctx.break_depth <- ctx.break_depth + 1; gen_block_element ctx e; handle_break(); if has_continue then begin b2(); newline ctx; println ctx "until true"; println ctx "if _hx_break_%i then _hx_break_%i = false; break; end" ctx.break_depth ctx.break_depth; end; b(); spr ctx "end"; ctx.break_depth <- ctx.break_depth-1; ctx.handle_continue <- old_ctx_continue; | TObjectDecl [] -> spr ctx "_hx_e()"; ctx.separator <- true | TObjectDecl fields -> spr ctx "_hx_o({__fields__={"; concat ctx "," (fun (f,e) -> print ctx "%s=" (anon_field f); spr ctx "true") fields; spr ctx "},"; concat ctx "," (fun (f,e) -> print ctx "%s=" (anon_field f); gen_anon_value ctx e) fields; spr ctx "})"; ctx.separator <- true | TFor (v,it,e) -> let handle_break = handle_break ctx e in let it = ident (match it.eexpr with | TLocal v -> v.v_name | _ -> let name = temp ctx in print ctx "local %s = " name; gen_value ctx it; newline ctx; name ) in print ctx "while( %s:hasNext() ) do" it; let bend = open_block ctx in newline ctx; print ctx "local %s = %s:next();" (ident v.v_name) it; gen_block_element ctx e; bend(); newline ctx; spr ctx "end"; handle_break(); newline ctx; | TTry (e,catchs) -> (* TODO: add temp variables *) println ctx "local _hx_expected_result = {}"; println ctx "local _hx_status, _hx_result = pcall(function() "; let b = open_block ctx in gen_expr ctx e; let vname = temp ctx in b(); println ctx " return _hx_expected_result end)"; spr ctx " if not _hx_status then "; let bend = open_block ctx in newline ctx; print ctx "local %s = _hx_result" vname; let last = ref false in let else_block = ref false in List.iter (fun (v,e) -> if !last then () else let t = (match follow v.v_type with | TEnum (e,_) -> Some (TEnumDecl e) | TInst (c,_) -> Some (TClassDecl c) | TAbstract (a,_) -> Some (TAbstractDecl a) | TFun _ | TLazy _ | TType _ | TAnon _ -> assert false | TMono _ | TDynamic _ -> None ) in match t with | None -> last := true; if !else_block then print ctx ""; if vname <> v.v_name then begin newline ctx; print ctx "local %s = %s" v.v_name vname; end; gen_block_element ctx e; if !else_block then begin newline ctx; print ctx " end "; end | Some t -> if not !else_block then newline ctx; print ctx "if( %s.__instanceof(%s," (ctx.type_accessor (TClassDecl { null_class with cl_path = ["lua"],"Boot" })) vname; gen_value ctx (mk (TTypeExpr t) (mk_mono()) e.epos); spr ctx ") ) then "; let bend = open_block ctx in if vname <> v.v_name then begin newline ctx; print ctx "local %s = %s" v.v_name vname; end; gen_block_element ctx e; bend(); newline ctx; spr ctx "else"; else_block := true ) catchs; if not !last then begin println ctx " _G.error(%s)" vname; spr ctx "end"; end; bend(); newline ctx; print ctx " elseif _hx_result ~= _hx_expected_result then return _hx_result end"; | TSwitch (e,cases,def) -> List.iteri (fun cnt (el,e2) -> if cnt == 0 then spr ctx "if " else (newline ctx; spr ctx "elseif "); List.iteri (fun ccnt e3 -> if ccnt > 0 then spr ctx " or "; gen_value ctx e; spr ctx " == "; gen_value ctx e3; ) el; print ctx " then "; let bend = open_block ctx in gen_block_element ctx e2; bend(); ) cases; (match def with | None -> spr ctx " end" | Some e -> begin if (List.length(cases) > 0) then spr ctx "else"; let bend = open_block ctx in bend(); gen_block_element ctx e; if (List.length(cases) > 0) then spr ctx " end"; end;); | TCast (e1,Some t) -> print ctx "%s.__cast(" (ctx.type_accessor (TClassDecl { null_class with cl_path = ["lua"],"Boot" })); gen_expr ctx e1; spr ctx " , "; spr ctx (ctx.type_accessor t); spr ctx ")" | TCast (e1,None) -> gen_value ctx e1; end; (* gen_block_element handles expressions that map to "statements" in lua. *) (* It handles no-op situations, and ensures that expressions are formatted with newlines *) and gen_block_element ctx e = ctx.iife_assign <- false; begin match e.eexpr with | TTypeExpr _ | TConst _ | TLocal _ | TFunction _ -> () | TCast (e',_) | TParenthesis e' | TMeta (_,e') -> gen_block_element ctx e' | TArray (e1,e2) -> gen_block_element ctx e1; gen_block_element ctx e2; | TArrayDecl el | TBlock el -> List.iter (gen_block_element ctx) el; (* For plain lua table instantiations, just capture argument operations *) | TCall({ eexpr = TLocal { v_name = "__lua_table__" }} , el) -> List.iter(fun x -> gen_block_element ctx x) el (* make a no-op __define_feature__ expression possible *) | TCall({eexpr = TLocal ({v_name = "__define_feature__"})}, [_;e]) -> gen_block_element ctx e | TObjectDecl fl -> List.iter (fun (_,e) -> gen_block_element ctx e) fl | TBinop (op,e1,e2) when op <> Ast.OpAssign -> newline ctx; let f () = gen_tbinop ctx op e1 e2 in gen_iife_assign ctx f; | TUnop ((Increment|Decrement) as op,_,e) -> newline ctx; gen_expr ctx e; print ctx " = "; gen_expr ctx e; (match op with | Increment -> print ctx " + 1;" | _ -> print ctx " - 1;" ) | TSwitch (e,[],def) -> (match def with | None -> () | Some e -> gen_block_element ctx e) | TField _ -> newline ctx; let f () = gen_expr ctx e in gen_iife_assign ctx f; semicolon ctx; | TCall ({ eexpr = TLocal { v_name = "__feature__" } }, { eexpr = TConst (TString f) } :: eif :: eelse) -> if has_feature ctx f then gen_block_element ctx eif else (match eelse with | [] -> () | [e] -> gen_block_element ctx e | _ -> assert false) | _ -> newline ctx; gen_expr ctx e; semicolon ctx; end; (* values generated in anon structures can get modified. Functions are bind-ed *) (* and include a dummy "self" leading variable so they can be called like normal *) (* instance methods *) and gen_anon_value ctx e = match e with | { eexpr = TFunction f} -> let old = ctx.in_value, ctx.in_loop in ctx.in_value <- None; ctx.in_loop <- false; print ctx "function(%s) " (String.concat "," ("self" :: (List.map ident (List.map arg_name f.tf_args)))); let fblock = fun_block ctx f e.epos in (match fblock.eexpr with | TBlock el -> let bend = open_block ctx in List.iter (gen_block_element ctx) el; bend(); newline ctx; |_ -> ()); spr ctx "end"; ctx.in_value <- fst old; ctx.in_loop <- snd old; ctx.separator <- true | { etype = TFun (args, ret)} -> spr ctx "function(_,...) return "; gen_value ctx e; spr ctx "(...) end"; | _-> gen_value ctx e and gen_value ctx e = let assign e = mk (TBinop (Ast.OpAssign, mk (TLocal (match ctx.in_value with None -> assert false | Some v -> v)) t_dynamic e.epos, e )) e.etype e.epos in let value() = let old = ctx.in_value, ctx.in_loop in let r_id = temp ctx in let r = alloc_var r_id t_dynamic e.epos in ctx.in_value <- Some r; ctx.in_loop <- false; spr ctx "(function() "; let b = open_block ctx in newline ctx; println ctx "local %s" r_id; (fun() -> newline ctx; spr ctx ("return " ^ r_id); b(); newline ctx; ctx.in_value <- fst old; ctx.in_loop <- snd old; spr ctx "end )()" ) in match e.eexpr with | TBinop (OpAssign, e1, e2) -> spr ctx "(function() "; gen_block_element ctx e; spr ctx " return "; gen_value ctx e1; spr ctx " end)()"; | TConst _ | TLocal _ | TArray _ | TBinop _ | TField _ | TEnumParameter _ | TTypeExpr _ | TParenthesis _ | TObjectDecl _ | TArrayDecl _ | TNew _ | TUnop _ | TFunction _ -> gen_expr ctx e | TMeta (_,e1) -> gen_value ctx e1 | TCall (e,el) -> gen_call ctx e el true | TReturn _ | TBreak | TContinue -> unsupported e.epos (* TODO: this is just a hack because this specific case is a TestReflect unit test. I don't know how to address this properly at the moment. - Simon *) | TCast ({ eexpr = TTypeExpr mt } as e1, None) when (match mt with TClassDecl {cl_path = ([],"Array")} -> false | _ -> true) -> add_feature ctx "use._hx_staticToInstance"; spr ctx "_hx_staticToInstance("; gen_expr ctx e1; spr ctx ")"; | TCast (e1, Some t) -> print ctx "%s.__cast(" (ctx.type_accessor (TClassDecl { null_class with cl_path = ["lua"],"Boot" })); gen_value ctx e1; spr ctx " , "; spr ctx (ctx.type_accessor t); spr ctx ")" | TCast (e1, _) -> gen_value ctx e1 | TVar _ | TFor _ | TWhile _ | TThrow _ -> (* value is discarded anyway *) let v = value() in gen_expr ctx e; v() | TBlock [e] -> gen_value ctx e | TBlock el -> let v = value() in let rec loop = function | [] -> spr ctx "return nil"; | [e] -> gen_block_element ctx (assign e); | e :: l -> gen_block_element ctx e; newline ctx; loop l in loop el; v(); | TIf (cond,e,eo) -> let v = value() in spr ctx "if "; gen_cond ctx cond; spr ctx " then "; gen_block_element ctx (assign e); let rec gen_elseif ctx e = (match e with | None->(); | Some e2-> (match e2.eexpr with | TIf(cond3, e3, eo3) -> spr ctx " elseif "; gen_cond ctx cond3; spr ctx " then "; gen_block_element ctx (assign e3); gen_elseif ctx eo3; | _ -> spr ctx " else "; gen_block_element ctx (assign e2); )); in gen_elseif ctx eo; spr ctx " end"; v() | TSwitch (cond,cases,def) -> let v = value() in gen_expr ctx (mk (TSwitch (cond, List.map (fun (e1,e2) -> (e1,assign e2)) cases, match def with None -> None | Some e -> Some (assign e) )) e.etype e.epos); v() | TTry (b,catchs) -> let v = value() in let block e = mk (TBlock [e]) e.etype e.epos in gen_block_element ctx (mk (TTry (block (assign b), List.map (fun (v,e) -> v, block (assign e)) catchs )) e.etype e.epos); v() and is_function_type ctx t = match t with | TFun _ -> true | TMono r -> (match !r with | Some (TFun _) -> true | _ -> false) | _ -> false; and gen_tbinop ctx op e1 e2 = (match op, e1.eexpr, e2.eexpr with | Ast.OpAssign, TField(e3, FInstance _), TFunction f -> gen_expr ctx e1; spr ctx " = " ; print ctx "function(%s) " (String.concat "," ("self" :: List.map ident (List.map arg_name f.tf_args))); let fblock = fun_block ctx f e1.epos in (match fblock.eexpr with | TBlock el -> let rec loop ctx el = (match el with | [hd] -> (match hd.eexpr with | TReturn eo -> begin newline ctx; gen_return ctx e1 eo; end; | _ -> gen_block_element ctx hd); | hd :: tl -> gen_block_element ctx hd; loop ctx tl |[] ->() ) in let bend = open_block ctx in loop ctx el; bend(); newline ctx; | _ -> gen_value ctx e2); spr ctx " end" | Ast.OpAssign, _, _ -> let iife_assign = ctx.iife_assign in if iife_assign then spr ctx "(function() "; (match e1.eexpr, e2.eexpr with | _, TBinop(OpAssign as op, e3, e4) -> gen_tbinop ctx op e3 e4; newline ctx; gen_value ctx e1; spr ctx " = "; gen_value ctx e3; | TField(e3, FInstance _ ), TField(e4, FClosure _ ) -> gen_value ctx e1; print ctx " %s " (Ast.s_binop op); add_feature ctx "use._hx_funcToField"; spr ctx "_hx_funcToField("; gen_value ctx e2; spr ctx ")"; | TField(_, FInstance _ ), TLocal t when (is_function_type ctx t.v_type) -> gen_value ctx e1; print ctx " %s " (Ast.s_binop op); add_feature ctx "use._hx_funcToField"; spr ctx "_hx_funcToField("; gen_value ctx e2; spr ctx ")"; | _ -> gen_value ctx e1; print ctx " %s " (Ast.s_binop op); gen_value ctx e2); if iife_assign then begin spr ctx " return "; gen_value ctx e1; spr ctx " end)()"; end; | Ast.OpAssignOp(op2), TArray(e3,e4), _ -> (* TODO: Figure out how to rewrite this expression more cleanly *) println ctx "(function() "; let idx = alloc_var "idx" e4.etype e4.epos in let idx_var = mk (TVar( idx , Some(e4))) e4.etype e4.epos in gen_expr ctx idx_var; let arr = alloc_var "arr" e3.etype e3.epos in let arr_var = mk (TVar(arr, Some(e3))) e3.etype e3.epos in gen_expr ctx arr_var; newline ctx; let arr_expr = (mk (TArray( (mk ( TLocal(arr)) e3.etype e3.epos), (mk ( TLocal(idx)) e4.etype e4.epos) )) e3.etype e3.epos) in spr ctx "arr[idx] = "; gen_tbinop ctx op2 arr_expr e2; semicolon ctx; newline ctx; spr ctx "return arr[idx]"; spr ctx " end)()"; | Ast.OpAssignOp(op2), TField(e3,e4), _ -> (* TODO: Figure out how to rewrite this expression more cleanly *) println ctx "(function() "; let obj = alloc_var "obj" e3.etype e3.epos in spr ctx "local fld = "; (match e4 with | FInstance(_,_,fld) | FStatic(_,fld) | FAnon fld | FClosure(_,fld) -> print ctx "'%s'" fld.cf_name; | FDynamic name -> print ctx "'%s'" name; | FEnum(_,efld) -> print ctx "'%s'" efld.ef_name); semicolon ctx; newline ctx; let obj_var = mk (TVar(obj, Some(e3))) e3.etype e3.epos in gen_expr ctx obj_var; newline ctx; let obj_expr = (mk (TField( (mk ( TLocal(obj)) e3.etype e3.epos), e4 )) e3.etype e3.epos) in spr ctx "obj[fld] = "; gen_tbinop ctx op2 obj_expr e2; semicolon ctx; newline ctx; spr ctx "return obj[fld]"; spr ctx " end)()"; | Ast.OpAssignOp(op2),_,_ -> (* TODO: Rewrite expression *) spr ctx "(function() "; gen_value ctx e1; spr ctx " = "; gen_tbinop ctx op2 e1 e2; spr ctx " return "; gen_value ctx e1; spr ctx " end)()"; | Ast.OpXor,_,_ | Ast.OpAnd,_,_ | Ast.OpShl,_,_ | Ast.OpShr,_,_ | Ast.OpUShr,_,_ | Ast.OpOr,_,_ -> gen_bitop ctx op e1 e2; | Ast.OpMod,_,_ -> spr ctx "_G.math.fmod("; gen_expr ctx e1; spr ctx ", "; gen_expr ctx e2; spr ctx ")"; | Ast.OpAdd,_,_ when (is_string_expr e1 || is_string_expr e2) -> gen_value ctx e1; print ctx " .. "; gen_value ctx e2; | _ -> begin (* wrap expressions used in comparisons for lua *) gen_paren_tbinop ctx e1; (match op with | Ast.OpNotEq -> print ctx " ~= "; | Ast.OpBoolAnd -> print ctx " and "; | Ast.OpBoolOr -> print ctx " or "; | _ -> print ctx " %s " (Ast.s_binop op)); gen_paren_tbinop ctx e2; end; ); and gen_paren_tbinop ctx e = let ee = extract_expr e in match ee.eexpr with | TBinop _ -> spr ctx "("; gen_value ctx ee; spr ctx ")"; | _ -> gen_value ctx ee and gen_bitop ctx op e1 e2 = add_feature ctx "use._bitop"; print ctx "_hx_bit.%s(" (match op with | Ast.OpXor -> "bxor" | Ast.OpAnd -> "band" | Ast.OpShl -> "lshift" | Ast.OpShr -> "arshift" | Ast.OpUShr -> "rshift" | Ast.OpOr -> "bor" | _ -> ""); gen_value ctx e1; spr ctx ","; gen_value ctx e2; spr ctx ")" and gen_return ctx e eo = if ctx.in_value <> None then unsupported e.epos; (match eo with | None -> spr ctx "do return end" | Some e -> (match e.eexpr with | TBinop(OpAssign, e1, e2) -> gen_expr ctx e; spr ctx " do return "; gen_value ctx e1; spr ctx " end"; | _ -> spr ctx "do return "; gen_value ctx e; spr ctx " end"); ) and gen_iife_assign ctx f = spr ctx "(function() return "; f(); spr ctx " end)()"; and gen_cond ctx cond = ctx.iife_assign <- true; gen_value ctx cond; ctx.iife_assign <- false; and has_class ctx c = has_feature ctx "lua.Boot.getClass" && (c.cl_super <> None || c.cl_ordered_fields <> [] || c.cl_constructor <> None) and has_prototype ctx c = c.cl_super <> None || (has_class ctx c) || List.exists (can_gen_class_field ctx) c.cl_ordered_fields and can_gen_class_field ctx = function | { cf_expr = (None | Some { eexpr = TConst TNull }) } when not (has_feature ctx "Type.getInstanceFields") -> false | f -> not (is_extern_field f) and has_continue e = let rec loop e = match e.eexpr with | TContinue -> raise Exit | TWhile(e1,_,_) | TFor(_,e1,_) -> loop e1 (* in theory there could be a continue there. Note that we don't want to recurse into the loop body because we do not care about inner continue expressions *) | _ -> Type.iter loop e in try loop e; false; with Exit -> true let check_multireturn ctx c = match c with | _ when Meta.has Meta.MultiReturn c.cl_meta -> if not c.cl_extern then abort "MultiReturns must be externs" c.cl_pos else if List.length c.cl_ordered_statics > 0 then abort "MultiReturns must not contain static fields" c.cl_pos else if (List.exists (fun cf -> match cf.cf_kind with Method _ -> true | _-> false) c.cl_ordered_fields) then abort "MultiReturns must not contain methods" c.cl_pos; | {cl_super = Some(csup,_)} when Meta.has Meta.MultiReturn csup.cl_meta -> abort "Cannot extend a MultiReturn" c.cl_pos | _ -> () let generate_package_create ctx (p,_) = let rec loop acc = function | [] -> () | p :: l when Hashtbl.mem ctx.packages (p :: acc) -> loop (p :: acc) l | p :: l -> Hashtbl.add ctx.packages (p :: acc) (); (match acc with | [] -> print ctx "local %s = {}" p | _ -> let p = String.concat "." (List.rev acc) ^ (field p) in print ctx "%s = {}" p ); ctx.separator <- true; newline ctx; loop (p :: acc) l in match p with | [] -> print ctx "local " | _ -> loop [] p let check_field_name c f = match f.cf_name with | "prototype" | "__proto__" | "constructor" -> abort ("The field name '" ^ f.cf_name ^ "' is not allowed in Lua") (match f.cf_expr with None -> c.cl_pos | Some e -> e.epos); | _ -> () (* convert a.b.c to ["a"]["b"]["c"] *) let path_to_brackets path = let parts = ExtString.String.nsplit path "." in "[\"" ^ (String.concat "\"][\"" parts) ^ "\"]" let gen_class_static_field ctx c f = match f.cf_expr with | None | Some { eexpr = TConst TNull } when not (has_feature ctx "Type.getClassFields") -> () | None when is_extern_field f -> () | None -> println ctx "%s%s = nil" (s_path ctx c.cl_path) (field f.cf_name); | Some e -> match e.eexpr with | TFunction _ -> let path = (s_path ctx c.cl_path) ^ (field f.cf_name) in let dot_path = (dot_path c.cl_path) ^ (static_field c f.cf_name) in ctx.id_counter <- 0; print ctx "%s = " path; gen_value ctx e; newline ctx; (match (get_exposed ctx dot_path f.cf_meta) with [s] -> (print ctx "_hx_exports%s = %s" (path_to_brackets s) path; newline ctx) | _ -> ()); | _ -> ctx.statics <- (c,f.cf_name,e) :: ctx.statics let gen_class_field ctx c f predelimit = check_field_name c f; if predelimit then println ctx ","; match f.cf_expr with | None -> print ctx "'%s', nil" f.cf_name; | Some e -> ctx.id_counter <- 0; (match e.eexpr with | TFunction f2 -> let old = ctx.in_value, ctx.in_loop in ctx.in_value <- None; ctx.in_loop <- false; print ctx "'%s', function" f.cf_name; print ctx "(%s) " (String.concat "," ("self" :: List.map ident (List.map arg_name f2.tf_args))); let fblock = fun_block ctx f2 e.epos in (match fblock.eexpr with | TBlock el -> let rec loop ctx el = (match el with | [hd] -> (match hd.eexpr with | TReturn eo -> begin newline ctx; gen_return ctx e eo; end; | _ -> gen_block_element ctx hd); | hd :: tl -> gen_block_element ctx hd; loop ctx tl |[] ->() ) in let bend = open_block ctx in loop ctx el; bend(); newline ctx; |_ -> ()); spr ctx "end"; ctx.in_value <- fst old; ctx.in_loop <- snd old; ctx.separator <- true; | _ -> gen_value ctx e) let generate_class___name__ ctx c = if has_feature ctx "lua.Boot.isClass" then begin let p = s_path ctx c.cl_path in print ctx "%s.__name__ = " p; if has_feature ctx "Type.getClassName" then println ctx "{%s}" (String.concat "," (List.map (fun s -> Printf.sprintf "\"%s\"" (s_escape_lua s)) (fst c.cl_path @ [snd c.cl_path]))) else println ctx "true"; end let generate_class ctx c = ctx.current <- c; ctx.id_counter <- 0; (match c.cl_path with | [],"Function" -> abort "This class redefines a native one" c.cl_pos | _ -> ()); let p = s_path ctx c.cl_path in let hxClasses = has_feature ctx "Type.resolveClass" in newline ctx; print ctx "%s.new = " p; (match c.cl_kind with | KAbstractImpl _ -> (* abstract implementations only contain static members and don't need to have constructor functions *) print ctx "{}"; ctx.separator <- true | _ -> (match c.cl_constructor with | Some { cf_expr = Some e } -> (match e.eexpr with | TFunction f -> let old = ctx.in_value, ctx.in_loop in ctx.in_value <- None; ctx.in_loop <- false; print ctx "function(%s) " (String.concat "," (List.map ident (List.map arg_name f.tf_args))); let fblock = fun_block ctx f e.epos in (match fblock.eexpr with | TBlock el -> let bend = open_block ctx in newline ctx; if not (has_prototype ctx c) then println ctx "local self = _hx_new()" else println ctx "local self = _hx_new(%s.prototype)" p; println ctx "%s.super(%s)" p (String.concat "," ("self" :: (List.map ident (List.map arg_name f.tf_args)))); if p = "String" then println ctx "self = string"; spr ctx "return self"; bend(); newline ctx; spr ctx "end"; newline ctx; let bend = open_block ctx in print ctx "%s.super = function(%s) " p (String.concat "," ("self" :: (List.map ident (List.map arg_name f.tf_args)))); List.iter (gen_block_element ctx) el; bend(); newline ctx; spr ctx "end"; |_ -> ()); ctx.in_value <- fst old; ctx.in_loop <- snd old; ctx.separator <- true | _ -> gen_expr ctx e); | _ -> (print ctx "{}"); ctx.separator <- true) ); newline ctx; (match (get_exposed ctx (dot_path c.cl_path) c.cl_meta) with [s] -> (print ctx "_hx_exports%s = %s" (path_to_brackets s) p; newline ctx) | _ -> ()); if hxClasses then println ctx "_hxClasses[\"%s\"] = %s" (dot_path c.cl_path) p; generate_class___name__ ctx c; (match c.cl_implements with | [] -> () | l -> println ctx "%s.__interfaces__ = {%s}" p (String.concat "," (List.map (fun (i,_) -> ctx.type_accessor (TClassDecl i)) l)); ); let gen_props props = String.concat "," (List.map (fun (p,v) -> p ^"=\""^v^"\"") props) in let has_property_reflection = (has_feature ctx "Reflect.getProperty") || (has_feature ctx "Reflect.setProperty") in if has_property_reflection then begin (match Codegen.get_properties c.cl_ordered_statics with | [] -> () | props -> println ctx "%s.__properties__ = {%s}" p (gen_props props); ); end; List.iter (gen_class_static_field ctx c) c.cl_ordered_statics; if (has_prototype ctx c) then begin print ctx "%s.prototype = _hx_a(" p; let bend = open_block ctx in newline ctx; let count = ref 0 in List.iter (fun f -> if can_gen_class_field ctx f then (gen_class_field ctx c f (!count > 0); incr count;) ) c.cl_ordered_fields; if (has_class ctx c) then begin newprop ctx; if !count > 0 then spr ctx ","; print ctx "'__class__', %s" p; incr count; end; if has_property_reflection then begin let props = Codegen.get_properties c.cl_ordered_fields in (match c.cl_super with | _ when props = [] -> () | _ -> if !count > 0 then spr ctx ","; newprop ctx; print ctx "'__properties__', {%s}" (gen_props props)); end; bend(); newline ctx; println ctx ")"; (match c.cl_super with | None -> () | Some (csup,_) -> let psup = ctx.type_accessor (TClassDecl csup) in println ctx "%s.__super__ = %s" p psup; println ctx "setmetatable(%s.prototype,{__index=%s.prototype})" p psup; (* Also use the __properties__ from the super class as the __index metatable *) if has_property_reflection && Codegen.has_properties csup then println ctx "setmetatable(%s.prototype.__properties__,{__index=%s.prototype.__properties__})" p psup; ); end let generate_enum ctx e = let p = s_path ctx e.e_path in let ename = List.map (fun s -> Printf.sprintf "\"%s\"" (s_escape_lua s)) (fst e.e_path @ [snd e.e_path]) in (* TODO: Unify the _hxClasses declaration *) if has_feature ctx "Type.resolveEnum" then begin print ctx "_hxClasses[\"%s\"] = %s" (dot_path e.e_path) p; semicolon ctx; newline ctx; end; if has_feature ctx "lua.Boot.isEnum" then begin print ctx "_hxClasses[\"%s\"] = {" (dot_path e.e_path); if has_feature ctx "lua.Boot.isEnum" then begin print ctx " __ename__ = %s," (if has_feature ctx "Type.getEnumName" then "{" ^ String.concat "," ename ^ "}" else "true"); end; (* TODO : Come up with a helper function for _hx_tab_array declarations *) spr ctx " __constructs__ = _hx_tab_array({"; if ((List.length e.e_names) > 0) then begin spr ctx "[0]="; spr ctx (String.concat "," (List.map (fun s -> Printf.sprintf "\"%s\"" s) e.e_names)); end; print ctx "},%i)}" (List.length e.e_names); ctx.separator <- true; newline ctx; end; if has_feature ctx "Type.resolveEnum" || has_feature ctx "lua.Boot.isEnum" then print ctx "%s = _hxClasses[\"%s\"];" p (dot_path e.e_path); newline ctx; List.iter (fun n -> let f = PMap.find n e.e_constrs in print ctx "%s%s = " p (field f.ef_name); (match f.ef_type with | TFun (args,_) -> let count = List.length args in let sargs = String.concat "," (List.map (fun (n,_,_) -> ident n) args) in print ctx "function(%s) local _x = _hx_tab_array({[0]=\"%s\",%d,%s,__enum__=%s}, %i);" sargs f.ef_name f.ef_index sargs p (count + 2); if has_feature ctx "may_print_enum" then (* TODO: better namespacing for _estr *) spr ctx " rawset(_x, 'toString', _estr);"; spr ctx " return _x; end "; ctx.separator <- true; | _ -> println ctx "_hx_tab_array({[0]=\"%s\",%d,__enum__ = %s},2)" f.ef_name f.ef_index p; if has_feature ctx "may_print_enum" then begin println ctx "rawset(%s%s, 'toString', _estr)" p (field f.ef_name); end; ); newline ctx ) e.e_names; if has_feature ctx "Type.allEnums" then begin let ctors_without_args = List.filter (fun s -> let ef = PMap.find s e.e_constrs in match follow ef.ef_type with | TFun _ -> false | _ -> true ) e.e_names in print ctx "%s.__empty_constructs__ = " p; spr ctx "_hx_tab_array({"; if (List.length ctors_without_args) > 0 then begin spr ctx "[0] = "; print ctx "%s" (String.concat "," (List.map (fun s -> Printf.sprintf "%s.%s" p s) ctors_without_args)); end; println ctx "}, %i)" (List.length ctors_without_args); end let generate_static ctx (c,f,e) = print ctx "%s%s = " (s_path ctx c.cl_path) (field f); gen_value ctx e; newline ctx let generate_enumMeta_fields ctx = function | TEnumDecl e -> begin let p = s_path ctx e.e_path in match Codegen.build_metadata ctx.com (TEnumDecl e) with | None -> () | Some e -> print ctx "%s.__meta__ = " p; gen_expr ctx e; newline ctx end | _ -> () let generate_require ctx path meta = let _, args, mp = Meta.get Meta.LuaRequire meta in let p = (s_path ctx path) in generate_package_create ctx path; (match args with | [(EConst(String(module_name)),_)] -> print ctx "%s = _G.require(\"%s\")" p module_name | [(EConst(String(module_name)),_) ; (EConst(String(object_path)),_)] -> print ctx "%s = _G.require(\"%s\").%s" p module_name object_path | _ -> abort "Unsupported @:luaRequire format" mp); newline ctx let generate_type ctx = function | TClassDecl c -> (match c.cl_init with | None -> () | Some e -> ctx.inits <- e :: ctx.inits); let p = s_path ctx c.cl_path in (* A special case for Std because we do not want to generate it if it's empty. *) if p = "Std" && c.cl_ordered_statics = [] then () else if not c.cl_extern then generate_class ctx c else if Meta.has Meta.InitPackage c.cl_meta then (match c.cl_path with | ([],_) -> () | _ -> generate_package_create ctx c.cl_path); check_multireturn ctx c; | TEnumDecl e -> if not e.e_extern then generate_enum ctx e else (); | TTypeDecl _ | TAbstractDecl _ | _ -> () let generate_type_forward ctx = function | TClassDecl c -> if not c.cl_extern then begin generate_package_create ctx c.cl_path; let p = s_path ctx c.cl_path in println ctx "%s = _hx_e()" p end else if Meta.has Meta.LuaRequire c.cl_meta && is_directly_used ctx.com c.cl_meta then generate_require ctx c.cl_path c.cl_meta | TEnumDecl e when e.e_extern -> if Meta.has Meta.LuaRequire e.e_meta && is_directly_used ctx.com e.e_meta then generate_require ctx e.e_path e.e_meta; | TEnumDecl e -> generate_package_create ctx e.e_path; let p = s_path ctx e.e_path in println ctx "%s = _hx_e()" p; | TTypeDecl _ | TAbstractDecl _ -> () let alloc_ctx com = let ctx = { com = com; buf = Buffer.create 16000; packages = Hashtbl.create 0; statics = []; inits = []; current = null_class; tabs = ""; in_value = None; iife_assign = false; in_loop = false; handle_break = false; break_depth = 0; handle_continue = false; id_counter = 0; type_accessor = (fun _ -> assert false); separator = false; found_expose = false; lua_jit = Common.defined com Define.LuaJit; lua_ver = try float_of_string (PMap.find "lua_ver" com.defines) with | Not_found -> 5.2; } in ctx.type_accessor <- (fun t -> let p = t_path t in match t with | TClassDecl ({ cl_extern = true } as c) when not (Meta.has Meta.LuaRequire c.cl_meta) -> dot_path p | TEnumDecl { e_extern = true } -> dot_path p | _ -> s_path ctx p); ctx let transform_multireturn ctx = function | TClassDecl c -> let transform_field f = match f.cf_expr with | Some e -> let rec loop e = let is_multireturn t = match follow t with | TInst (c, _) when Meta.has Meta.MultiReturn c.cl_meta -> true | _ -> false in match e.eexpr with (* if we found a var declaration initialized by a multi-return call, mark it with @:multiReturn meta, so it will later be generated as multiple locals unpacking the value *) | TVar (v, Some ({ eexpr = TCall _ } as ecall)) when is_multireturn v.v_type -> v.v_meta <- (Meta.MultiReturn,[],v.v_pos) :: v.v_meta; let ecall = Type.map_expr loop ecall in { e with eexpr = TVar (v, Some ecall) } (* if we found a field access for the multi-return call, generate select call *) | TField ({ eexpr = TCall _ } as ecall, f) when is_multireturn ecall.etype -> let ecall = Type.map_expr loop ecall in mk_mr_select ctx.com ecall (field_name f) (* if we found a multi-return call used as a value, box it *) | TCall _ when is_multireturn e.etype -> let e = Type.map_expr loop e in mk_mr_box ctx e (* Don't bother wrapping multireturn function results if we don't use the return values *) | TBlock el -> let el2 = List.map (fun x -> match x.eexpr with | TCall (e2, el) when is_multireturn x.etype -> mk (TCall (e2, List.map(fun x-> Type.map_expr loop x) el)) x.etype x.epos | _ -> loop x) el in mk (TBlock el2) e.etype e.epos; (* if we found a field access for a multi-return local - that's fine, because it'll be generated as a local var *) | TField ({ eexpr = TLocal v}, _) when Meta.has Meta.MultiReturn v.v_meta -> e | TReturn Some(e2) -> if is_multireturn e2.etype then failwith "You cannot return a multireturn type from a haxe function" else Type.map_expr loop e; (* if we found usage of local var we previously marked with @:multiReturn as a value itself, remove the @:multiReturn meta and add "box me" meta so it'll be boxed on var initialization *) | TLocal v when Meta.has Meta.MultiReturn v.v_meta -> v.v_meta <- List.filter (fun (m,_,_) -> m <> Meta.MultiReturn) v.v_meta; v.v_meta <- (Meta.Custom ":lua_mr_box", [], v.v_pos) :: v.v_meta; e | _ -> Type.map_expr loop e in f.cf_expr <- Some (loop e); | _ -> () in List.iter transform_field c.cl_ordered_fields; List.iter transform_field c.cl_ordered_statics; Option.may transform_field c.cl_constructor; | _ -> () let generate com = let ctx = alloc_ctx com in Codegen.map_source_header com (fun s -> print ctx "-- %s\n" s); if has_feature ctx "Class" || has_feature ctx "Type.getClassName" then add_feature ctx "lua.Boot.isClass"; if has_feature ctx "Enum" || has_feature ctx "Type.getEnumName" then add_feature ctx "lua.Boot.isEnum"; let include_files = List.rev com.include_files in List.iter (fun file -> match file with | path, "top" -> let file_content = Std.input_file ~bin:true (fst file) in print ctx "%s\n" file_content; () | _ -> () ) include_files; let var_exports = ( "_hx_exports", "_hx_exports or {}" ) in let exposed = List.concat (List.map (fun t -> match t with | TClassDecl c -> let path = dot_path c.cl_path in let class_exposed = get_exposed ctx path c.cl_meta in let static_exposed = List.map (fun f -> get_exposed ctx (path ^ static_field c f.cf_name) f.cf_meta ) c.cl_ordered_statics in List.concat (class_exposed :: static_exposed) | _ -> [] ) com.types) in let anyExposed = exposed <> [] in let exportMap = ref (PMap.create String.compare) in let exposedObject = { os_name = ""; os_fields = [] } in let toplevelExposed = ref [] in List.iter (fun path -> ( let parts = ExtString.String.nsplit path "." in let rec loop p pre = match p with | f :: g :: ls -> let path = match pre with "" -> f | pre -> (pre ^ "." ^ f) in if not (PMap.exists path !exportMap) then ( let elts = { os_name = f; os_fields = [] } in exportMap := PMap.add path elts !exportMap; let cobject = match pre with "" -> exposedObject | pre -> PMap.find pre !exportMap in cobject.os_fields <- elts :: cobject.os_fields ); loop (g :: ls) path; | f :: [] when pre = "" -> toplevelExposed := f :: !toplevelExposed; | _ -> () in loop parts ""; )) exposed; if (anyExposed) then ( print ctx "local %s = %s" (fst var_exports) (snd var_exports); ctx.separator <- true; newline ctx ); let rec print_obj f root = ( let path = root ^ (path_to_brackets f.os_name) in print ctx "%s = %s or _hx_e()" path path; ctx.separator <- true; newline ctx; concat ctx ";" (fun g -> print_obj g path) f.os_fields ) in List.iter (fun f -> print_obj f "_hx_exports") exposedObject.os_fields; let vars = [] in (* let vars = (if has_feature ctx "Type.resolveClass" || has_feature ctx "Type.resolveEnum" then ("_hxClasses = " ^ "{}") :: vars else vars) in *) let vars = if has_feature ctx "may_print_enum" then ("_estr = function(self) return " ^ (ctx.type_accessor (TClassDecl { null_class with cl_path = ["lua"],"Boot" })) ^ ".__string_rec(self,''); end") :: vars else vars in (match List.rev vars with | [] -> () | vl -> print ctx "local %s" (String.concat ";" vl); ctx.separator <- true; newline ctx ); List.iter (generate_type_forward ctx) com.types; newline ctx; (* Generate some dummy placeholders for utility libs that may be required*) println ctx "local _hx_bind, _hx_bit, _hx_staticToInstance, _hx_funcToField, _hx_maxn, _hx_print, _hx_apply_self, _hx_box_mr, _hx_bit_clamp, _hx_table, _hx_bit_raw"; List.iter (transform_multireturn ctx) com.types; List.iter (generate_type ctx) com.types; if has_feature ctx "use._bitop" || has_feature ctx "lua.Boot.clamp" then begin println ctx "_hx_bit_clamp = function(v) "; println ctx " if v <= 2147483647 and v >= -2147483648 then"; println ctx " if v > 0 then return _G.math.floor(v)"; println ctx " else return _G.math.ceil(v)"; println ctx " end"; println ctx " end"; println ctx " if v > 2251798999999999 then v = v*2 end;"; println ctx " if (v ~= v or math.abs(v) == _G.math.huge) then return nil end"; println ctx " return _hx_bit.band(v, 2147483647 ) - math.abs(_hx_bit.band(v, 2147483648))"; println ctx "end"; println ctx "pcall(require, 'bit')"; (* require this for lua 5.1 *) println ctx "if bit then"; println ctx " _hx_bit = bit"; println ctx "elseif bit32 then"; println ctx " local _hx_bit_raw = bit32"; println ctx " _hx_bit = setmetatable({}, { __index = _hx_bit_raw });"; println ctx " _hx_bit.bnot = function(...) return _hx_bit_clamp(_hx_bit_raw.bnot(...)) end;"; (* lua 5.2 weirdness *) println ctx " _hx_bit.bxor = function(...) return _hx_bit_clamp(_hx_bit_raw.bxor(...)) end;"; (* lua 5.2 weirdness *) println ctx "end"; end; (* If we use haxe Strings, patch Lua's string *) if has_feature ctx "use.string" then begin println ctx "local _hx_string_mt = _G.getmetatable('');"; println ctx "String.__oldindex = _hx_string_mt.__index;"; println ctx "_hx_string_mt.__index = String.__index;"; println ctx "_hx_string_mt.__add = function(a,b) return Std.string(a)..Std.string(b) end;"; println ctx "_hx_string_mt.__concat = _hx_string_mt.__add"; end; (* Array is required, always patch it *) println ctx "_hx_array_mt.__index = Array.prototype"; newline ctx; let b = open_block ctx in println ctx "local _hx_static_init = function()"; (* Generate statics *) List.iter (generate_static ctx) (List.rev ctx.statics); (* Localize init variables inside a do-block *) (* Note: __init__ logic can modify static variables. *) (* Generate statics *) List.iter (gen_block_element ctx) (List.rev ctx.inits); b(); newline ctx; println ctx "end"; newline ctx; if has_feature ctx "use._iterator" then begin add_feature ctx "use._hx_bind"; println ctx "function _hx_iterator(o) if ( lua.Boot.__instanceof(o, Array) ) then return function() return HxOverrides.iter(o) end elseif (typeof(o.iterator) == 'function') then return _hx_bind(o,o.iterator) else return o.iterator end end"; end; if has_feature ctx "use._hx_bind" then begin println ctx "_hx_bind = function(o,m)"; println ctx " if m == nil then return nil end;"; println ctx " local f;"; println ctx " if o._hx__closures == nil then"; println ctx " _G.rawset(o, '_hx__closures', {});"; println ctx " else "; println ctx " f = o._hx__closures[m];"; println ctx " end"; println ctx " if (f == nil) then"; println ctx " f = function(...) return m(o, ...) end;"; println ctx " o._hx__closures[m] = f;"; println ctx " end"; println ctx " return f;"; println ctx "end"; end; if has_feature ctx "use._hx_staticToInstance" then begin println ctx "_hx_staticToInstance = function (tab)"; println ctx " return setmetatable({}, {"; println ctx " __index = function(t,k)"; println ctx " if type(rawget(tab,k)) == 'function' then "; println ctx " return function(self,...)"; println ctx " return rawget(tab,k)(...)"; println ctx " end"; println ctx " else"; println ctx " return rawget(tab,k)"; println ctx " end"; println ctx " end"; println ctx " })"; println ctx "end"; end; if has_feature ctx "use._hx_funcToField" then begin println ctx "_hx_funcToField = function(f)"; println ctx " if type(f) == 'function' then "; println ctx " return function(self,...) "; println ctx " return f(...) "; println ctx " end"; println ctx " else "; println ctx " return f"; println ctx " end"; println ctx "end"; end; if has_feature ctx "Math.random" then begin println ctx "_G.math.randomseed(_G.os.time());" end; if has_feature ctx "use._hx_print" then println ctx "_hx_print = print or (function() end)"; if has_feature ctx "use._hx_apply_self" then begin println ctx "_hx_apply_self = function(self, f, ...)"; println ctx " return self[f](self,...)"; println ctx "end"; end; if has_feature ctx "use._hx_box_mr" then begin println ctx "_hx_box_mr = function(x,nt)"; println ctx " res = _hx_o({__fields__={}})"; println ctx " for i,v in ipairs(nt) do"; println ctx " res[v] = x[i]"; println ctx " end"; println ctx " return res"; println ctx "end"; end; if has_feature ctx "use._hx_table" then begin println ctx "_hx_table = {}"; println ctx "_hx_table.pack = _G.table.pack or function(...)"; println ctx " return {...}"; println ctx "end"; println ctx "_hx_table.unpack = _G.table.unpack or _G.unpack"; println ctx "_hx_table.maxn = _G.table.maxn or function(t)"; println ctx " local maxn=0;"; println ctx " for i in pairs(t) do"; println ctx " maxn=type(i)=='number'and i>maxn and i or maxn"; println ctx " end"; println ctx " return maxn"; println ctx "end;"; end; println ctx "_hx_static_init();"; List.iter (generate_enumMeta_fields ctx) com.types; (match com.main with | None -> () | Some e -> gen_expr ctx e; newline ctx); println ctx "return _hx_exports"; let ch = open_out_bin com.file in output_string ch (Buffer.contents ctx.buf); close_out ch haxe_3.4.4.orig/src/generators/genneko.ml0000664000175000017500000006553413166552354020351 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Globals open Type open Nast open Common type context = { version : int; com : Common.context; packages : (string list, unit) Hashtbl.t; globals : (string list * string, string) Hashtbl.t; mutable curglobal : int; mutable macros : bool; mutable curclass : string; mutable curmethod : string; mutable inits : (tclass * texpr) list; mutable label_count : int; } let files = Hashtbl.create 0 let pos ctx p = if ctx.macros then { psource = p.pfile; pline = p.pmin lor ((p.pmax - p.pmin) lsl 20); } else let file = (match ctx.com.debug with | true -> ctx.curclass ^ "::" ^ ctx.curmethod | false -> try Hashtbl.find files p.pfile with Not_found -> let path = (match Common.defined ctx.com Common.Define.AbsolutePath with | true -> if (Filename.is_relative p.pfile) then Filename.concat (Sys.getcwd()) p.pfile else p.pfile | false -> try (* lookup relative path *) let len = String.length p.pfile in let base = List.find (fun path -> let l = String.length path in len > l && String.sub p.pfile 0 l = path ) ctx.com.Common.class_path in let l = String.length base in String.sub p.pfile l (len - l) with Not_found -> p.pfile ) in Hashtbl.add files p.pfile path; path ) in { psource = file; pline = Lexer.get_error_line p; } let gen_global_name ctx path = match path with | [], name -> name | _ -> try Hashtbl.find ctx.globals path with Not_found -> let name = "@G" ^ string_of_int ctx.curglobal in ctx.curglobal <- ctx.curglobal + 1; Hashtbl.add ctx.globals path name; name let null p = (EConst Null,p) let this p = (EConst This,p) let int p n = (EConst (Int n),p) let str p s = (EConst (String s),p) let ident p s = let l = String.length s in if l > 10 && String.sub s 0 10 = "__dollar__" then (EConst (Builtin (String.sub s 10 (l - 10))),p) else (EConst (Ident s),p) let field p e f = (EField (e,f),p) let builtin p n = (EConst (Builtin n),p) let call p e el = (ECall (e,el),p) let array p el = call p (builtin p "array") el let pmap_list f p = PMap.fold (fun v acc -> f v :: acc) p [] let rec needs_return e = match e with | (EBlock l,_) -> let rec loop = function | [] -> true | [x] -> needs_return x | _ :: l -> loop l in loop l | (EReturn _,_) -> false | _ -> true let with_return e = if needs_return e then let p = snd e in let ret = EReturn (Some (null p)),p in match e with | (EBlock l,_) -> (EBlock (l @ [ret]),p) | _ -> (EBlock [e;ret] , p) else e let gen_type_path p (path,t) = match path with | [] -> ident p t | path :: l -> let epath = List.fold_left (fun e path -> field p e path) (ident p path) l in field p epath t let rec gen_big_string ctx p s = let max = 1 lsl 16 - 1 in if String.length s > max then (EBinop ("+",str p (String.sub s 0 max),gen_big_string ctx p (String.sub s max (String.length s - max))),p) else str p s let gen_constant ctx pe c = let p = pos ctx pe in match c with | TInt i -> (try let h = Int32.to_int (Int32.shift_right_logical i 24) in if (h land 128 = 0) <> (h land 64 = 0) then raise Exit; int p (Int32.to_int i) with _ -> if ctx.version < 2 then abort "This integer is too big to be compiled to a Neko 31-bit integer. Please use a Float instead" pe; (EConst (Int32 i),p)) | TFloat f -> (EConst (Float f),p) | TString s -> call p (field p (ident p "String") "new") [gen_big_string ctx p s] | TBool b -> (EConst (if b then True else False),p) | TNull -> null p | TThis -> this p | TSuper -> assert false let rec gen_binop ctx p op e1 e2 = (EBinop (Ast.s_binop op,gen_expr ctx e1,gen_expr ctx e2),p) and gen_unop ctx p op flag e = match op with | Increment -> (EBinop ((if flag = Prefix then "+=" else "++="), gen_expr ctx e , int p 1),p) | Decrement -> (EBinop ((if flag = Prefix then "-=" else "--="), gen_expr ctx e , int p 1),p) | Not -> call p (builtin p "not") [gen_expr ctx e] | Neg -> (EBinop ("-",int p 0, gen_expr ctx e),p) | NegBits -> (EBinop ("-",int p (-1), gen_expr ctx e),p) and gen_call ctx p e el = match e.eexpr , el with | TConst TSuper , _ -> let c = (match follow e.etype with TInst (c,_) -> c | _ -> assert false) in call p (builtin p "call") [ field p (gen_type_path p c.cl_path) "__construct__"; this p; array p (List.map (gen_expr ctx) el) ] | TLocal { v_name = "__resources__" }, [] -> call p (builtin p "array") (Hashtbl.fold (fun name data acc -> (EObject [("name",gen_constant ctx e.epos (TString name));("data",gen_big_string ctx p data)],p) :: acc ) ctx.com.resources []) | TField ({ eexpr = TConst TSuper; etype = t },f) , _ -> let c = (match follow t with TInst (c,_) -> c | _ -> assert false) in call p (builtin p "call") [ field p (gen_type_path p (fst c.cl_path,"@" ^ snd c.cl_path)) (field_name f); this p; array p (List.map (gen_expr ctx) el) ] | _ , _ -> let e = (match gen_expr ctx e with EFunction _, _ as e -> (EBlock [e],p) | e -> e) in call p e (List.map (gen_expr ctx) el) and gen_expr ctx e = let p = pos ctx e.epos in match e.eexpr with | TConst c -> gen_constant ctx e.epos c | TLocal v when v.v_name.[0] = '$' -> (EConst (Builtin (String.sub v.v_name 1 (String.length v.v_name - 1))),p) | TLocal v -> if v.v_capture then (EArray (ident p v.v_name,int p 0),p) else ident p v.v_name | TArray (e1,e2) -> (EArray (gen_expr ctx e1,gen_expr ctx e2),p) | TBinop (OpAssign,{ eexpr = TField (e1,f) },e2) -> (EBinop ("=",field p (gen_expr ctx e1) (field_name f),gen_expr ctx e2),p) | TBinop (op,e1,e2) -> gen_binop ctx p op e1 e2 | TField (e2,FClosure (_,f)) -> (match follow e.etype with | TFun (args,_) -> let n = List.length args in if n > 5 then abort "Cannot create closure with more than 5 arguments" e.epos; let tmp = ident p "@tmp" in EBlock [ (EVars ["@tmp", Some (gen_expr ctx e2); "@fun", Some (field p tmp f.cf_name)] , p); if ctx.macros then call p (builtin p "closure") [ident p "@fun";tmp] else call p (ident p ("@closure" ^ string_of_int n)) [tmp;ident p "@fun"] ] , p | _ -> assert false) | TEnumParameter (e,_,i) -> EArray (field p (gen_expr ctx e) "args",int p i),p | TField (e,f) -> field p (gen_expr ctx e) (field_name f) | TTypeExpr t -> gen_type_path p (t_path t) | TParenthesis e -> (EParenthesis (gen_expr ctx e),p) | TMeta (_,e) -> gen_expr ctx e | TObjectDecl fl -> let hasToString = ref false in let fl = List.map (fun (f,e) -> if f = "toString" then hasToString := (match follow e.etype with TFun ([],_) -> true | _ -> false); f , gen_expr ctx e) fl in (EObject (if !hasToString then ("__string",ident p "@default__string") :: fl else fl),p) | TArrayDecl el -> call p (field p (ident p "Array") "new1") [array p (List.map (gen_expr ctx) el); int p (List.length el)] | TCall (e,el) -> gen_call ctx p e el | TNew (c,_,params) -> call p (field p (gen_type_path p c.cl_path) "new") (List.map (gen_expr ctx) params) | TUnop (op,flag,e) -> gen_unop ctx p op flag e | TVar (v,eo) -> (EVars ( let e = (match eo with | None -> if v.v_capture then Some (call p (builtin p "array") [null p]) else None | Some e -> let e = gen_expr ctx e in if v.v_capture then Some (call p (builtin p "array") [e]) else Some e ) in [v.v_name, e] ),p) | TFunction f -> let inits = List.fold_left (fun acc (a,c) -> let acc = if a.v_capture then (EBinop ("=",ident p a.v_name,call p (builtin p "array") [ident p a.v_name]),p) :: acc else acc in match c with | None | Some TNull -> acc | Some c -> gen_expr ctx (Codegen.set_default ctx.com a c e.epos) :: acc ) [] f.tf_args in let e = gen_expr ctx f.tf_expr in let e = (match inits with [] -> e | _ -> EBlock (List.rev (e :: inits)),p) in (EFunction (List.map arg_name f.tf_args, with_return e),p) | TBlock el -> (EBlock (List.map (gen_expr ctx) el), p) | TFor (v, it, e) -> let it = gen_expr ctx it in let e = gen_expr ctx e in let next = call p (field p (ident p "@tmp") "next") [] in let next = (if v.v_capture then call p (builtin p "array") [next] else next) in (EBlock [(EVars ["@tmp", Some it],p); (EWhile (call p (field p (ident p "@tmp") "hasNext") [], (EBlock [ (EVars [v.v_name, Some next],p); e ],p) ,NormalWhile),p)] ,p) | TIf (cond,e1,e2) -> (* if(e)-1 is parsed as if( e - 1 ) *) let parent e = mk (TParenthesis e) e.etype e.epos in let e1 = (match e1.eexpr with TConst (TInt n) when n < 0l -> parent e1 | TConst (TFloat f) when f.[0] = '-' -> parent e1 | _ -> e1) in (EIf (gen_expr ctx cond,gen_expr ctx e1,(match e2 with None -> None | Some e -> Some (gen_expr ctx e))),p) | TWhile (econd,e,flag) -> (EWhile (gen_expr ctx econd, gen_expr ctx e, match flag with Ast.NormalWhile -> NormalWhile | Ast.DoWhile -> DoWhile),p) | TTry (e,catchs) -> let rec loop = function | [] -> call p (builtin p "rethrow") [ident p "@tmp"] | (v,e) :: l -> let e2 = loop l in let path = (match follow v.v_type with | TInst (c,_) -> Some c.cl_path | TEnum (e,_) -> Some e.e_path | TAbstract (a,_) -> Some a.a_path | TDynamic _ -> None | _ -> assert false ) in let cond = (match path with | None -> (EConst True,p) | Some path -> call p (field p (gen_type_path p (["neko"],"Boot")) "__instanceof") [ident p "@tmp"; gen_type_path p path] ) in let id = ident p "@tmp" in let id = (if v.v_capture then call p (builtin p "array") [id] else id) in let e = gen_expr ctx e in (EIf (cond,(EBlock [ EVars [v.v_name,Some id],p; e; ],p),Some e2),p) in let catchs = loop catchs in let catchs = (EBlock [ (EIf ( (EBinop ("==",call p (builtin p "typeof") [ident p "@tmp"],builtin p "tstring"),p), (EBinop ("=",ident p "@tmp",call p (field p (ident p "String") "new") [ident p "@tmp"]),p), None ),p); catchs; ],p) in (ETry (gen_expr ctx e,"@tmp",catchs),p) | TReturn eo -> (EReturn (match eo with None -> Some (null p) | Some e -> Some (gen_expr ctx e)),p) | TBreak -> (EBreak None,p) | TContinue -> (EContinue,p) | TThrow e -> call p (builtin p "throw") [gen_expr ctx e] | TCast (e,None) -> gen_expr ctx e | TCast (e1,Some t) -> gen_expr ctx (Codegen.default_cast ~vtmp:"@tmp" ctx.com e1 t e.etype e.epos) | TSwitch (e,cases,eo) -> let e = gen_expr ctx e in let eo = (match eo with None -> None | Some e -> Some (gen_expr ctx e)) in try (ESwitch ( e, List.map (fun (el,e2) -> match List.map (gen_expr ctx) el with | [] -> assert false | [e] -> e, gen_expr ctx e2 | _ -> raise Exit ) cases, eo ),p) with Exit -> (EBlock [ (EVars ["@tmp",Some e],p); List.fold_left (fun acc (el,e) -> let cond = (match el with | [] -> assert false | e :: l -> let eq e = (EBinop ("==",ident p "@tmp",gen_expr ctx e),p) in List.fold_left (fun acc e -> (EBinop ("||",acc,eq e),p)) (eq e) l ) in EIf (cond,gen_expr ctx e,Some acc),p ) (match eo with None -> null p | Some e -> e) (List.rev cases) ],p) let gen_method ctx p c acc = ctx.curmethod <- c.cf_name; if is_extern_field c then acc else match c.cf_expr with | None -> ((c.cf_name, null p) :: acc) | Some e -> match e.eexpr with | TCall ({ eexpr = TField (_,FStatic ({cl_path=["neko"],"Lib"},{cf_name="load" | "loadLazy" as load})) },[{ eexpr = TConst (TString m) };{ eexpr = TConst (TString f) };{ eexpr = TConst (TInt n) }]) -> let p = pos ctx e.epos in let e = call p (EField (builtin p "loader","loadprim"),p) [(EBinop ("+",(EBinop ("+",str p m,str p "@"),p),str p f),p); (EConst (Int (Int32.to_int n)),p)] in let e = (if load = "load" then e else (ETry (e,"@e",call p (ident p "@lazy_error") [ident p "@e"]),p)) in (c.cf_name, e) :: acc | TFunction _ -> ((if c.cf_name = "new" then "__construct__" else c.cf_name), gen_expr ctx e) :: acc | _ -> (c.cf_name, null p) :: acc let gen_class ctx c = ctx.curclass <- s_type_path c.cl_path; ctx.curmethod <- "$init"; let p = pos ctx c.cl_pos in let clpath = gen_type_path p (fst c.cl_path,"@" ^ snd c.cl_path) in let stpath = gen_type_path p c.cl_path in let fnew = (match c.cl_constructor with | Some f -> (match f.cf_expr with | Some {eexpr = TFunction tf} -> let params = List.map (fun (v,_) -> v.v_name) tf.tf_args in gen_method ctx p f ["new",(EFunction (params,(EBlock [ (EVars ["@o",Some (call p (builtin p "new") [null p])],p); (call p (builtin p "objsetproto") [ident p "@o"; clpath]); (call p (builtin p "call") [field p (this p) "__construct__"; ident p "@o"; array p (List.map (ident p) params)]); (EReturn (Some (ident p "@o")),p) ],p)),p)] | _ -> []) | None -> [] ) in let fstring = (try let f = PMap.find "toString" c.cl_fields in match follow f.cf_type with | TFun ([],_) -> ["__string",ident p "@default__string"] | _ -> [] with Not_found -> [] ) in let fserialize = "__serialize" , ident p "@serialize" in let others = (match c.cl_implements with | [] -> [] | l -> ["__interfaces__",array p (List.map (fun (c,_) -> gen_type_path p c.cl_path) l)] ) @ (match c.cl_super with | None -> [] | Some (c,_) -> ["__super__", gen_type_path p c.cl_path] ) in let build (f,e) = (EBinop ("=",field p (ident p "@tmp") f,e),p) in let tmp = (EVars ["@tmp",Some (call p (builtin p "new") [null p])],p) in let estat = (EBinop ("=", stpath, ident p "@tmp"),p) in let gen_props props = (EObject (List.map (fun (n,s) -> n,str p s) props),p) in let sprops = (match Codegen.get_properties c.cl_ordered_statics with | [] -> [] | l -> ["__properties__",gen_props l] ) in let sfields = List.map build ( ("prototype",clpath) :: sprops @ PMap.fold (gen_method ctx p) c.cl_statics (fnew @ others) ) in let eclass = (EBinop ("=", clpath, ident p "@tmp"),p) in let mfields = List.map build (PMap.fold (gen_method ctx p) c.cl_fields (fserialize :: fstring)) in let props = Codegen.get_properties c.cl_ordered_fields in let emeta = (EBinop ("=",field p clpath "__class__",stpath),p) :: (match props with | [] -> [] | _ -> let props = gen_props props in let props = (match c.cl_super with | Some (csup,_) when Codegen.has_properties csup -> (EBlock [ (EVars ["@tmp",Some props],p); call p (builtin p "objsetproto") [ident p "@tmp";field p (field p (gen_type_path p csup.cl_path) "prototype") "__properties__"]; ident p "@tmp" ],p) | _ -> props ) in [EBinop ("=",field p clpath "__properties__",props),p]) @ match c.cl_path with | [] , name -> [(EBinop ("=",field p (ident p "@classes") name,ident p name),p)] | _ -> [] in let emeta = if ctx.macros then (EBinop ("=",field p stpath "__ct__",call p (builtin p "typewrap") [Obj.magic (TClassDecl c)]),p) :: emeta else emeta in let eextends = (match c.cl_super with | None -> [] | Some (c,_) -> let esuper = gen_type_path p (fst c.cl_path,"@" ^ snd c.cl_path) in [call p (builtin p "objsetproto") [clpath; esuper]] ) in (EBlock (tmp :: eclass :: mfields @ tmp :: estat :: sfields @ eextends @ emeta),p) let gen_enum_constr ctx path c = ctx.curmethod <- c.ef_name; let p = pos ctx c.ef_pos in (EBinop ("=",field p path c.ef_name, match follow c.ef_type with | TFun (params,_) -> let params = List.map (fun (n,_,_) -> n) params in (EFunction (params, (EBlock [ (EVars ["@tmp",Some (EObject [ "tag" , str p c.ef_name; "index" , int p c.ef_index; "args" , array p (List.map (ident p) params); ],p)],p); call p (builtin p "objsetproto") [ident p "@tmp"; field p path "prototype"]; ident p "@tmp"; ],p) ),p) | _ -> (EBlock [ (EVars ["@tmp",Some (EObject ["tag" , str p c.ef_name; "index", int p c.ef_index; "__serialize" , ident p "@tag_serialize"],p)],p); call p (builtin p "objsetproto") [ident p "@tmp"; field p path "prototype"]; ident p "@tmp"; ],p) ),p) let gen_enum ctx e = ctx.curclass <- s_type_path e.e_path; ctx.curmethod <- "$init"; let p = pos ctx e.e_pos in let path = gen_type_path p e.e_path in let uname = (EConst (Ident (gen_global_name ctx e.e_path)),p) in (EBlock ( (EBinop ("=",uname, call p (builtin p "new") [null p]),p) :: (EBinop ("=",path, uname),p) :: (EBinop ("=",field p uname "prototype", (EObject [ "__enum__" , uname; "__serialize" , ident p "@serialize"; "__string" , ident p "@enum_to_string" ],p)),p) :: pmap_list (gen_enum_constr ctx uname) e.e_constrs @ (match e.e_path with | [] , name -> [EBinop ("=",field p (ident p "@classes") name,ident p name),p] | _ -> []) ),p) let gen_type ctx t acc = match t with | TClassDecl c -> (match c.cl_init with | None -> () | Some e -> ctx.inits <- (c,e) :: ctx.inits); if c.cl_extern then acc else gen_class ctx c :: acc | TEnumDecl e -> if e.e_extern then acc else gen_enum ctx e :: acc | TTypeDecl _ | TAbstractDecl _ -> acc let gen_static_vars ctx t = match t with | TEnumDecl _ | TTypeDecl _ | TAbstractDecl _ -> [] | TClassDecl c -> if c.cl_extern then [] else List.fold_right (fun f acc -> match f.cf_expr with | None -> acc | Some e -> match e.eexpr with | TFunction _ -> acc | _ -> ctx.curclass <- s_type_path c.cl_path; ctx.curmethod <- "$statics"; let p = pos ctx e.epos in (EBinop ("=", (field p (gen_type_path p c.cl_path) f.cf_name), gen_expr ctx e ),p) :: acc ) c.cl_ordered_statics [] let gen_package ctx t = let rec loop acc p = match p with | [] -> [] | x :: l -> let path = acc @ [x] in if not (Hashtbl.mem ctx.packages path) then begin let p = pos ctx (t_infos t).mt_pos in let e = (EBinop ("=",gen_type_path p (acc,x),call p (builtin p "new") [null p]),p) in Hashtbl.add ctx.packages path (); (match acc with | [] -> let reg = (EBinop ("=",field p (ident p "@classes") x,ident p x),p) in e :: reg :: loop path l | _ -> e :: loop path l) end else loop path l in loop [] (fst (t_path t)) let gen_boot ctx = (EBlock [ EBinop ("=",field null_pos (gen_type_path null_pos (["neko"],"Boot")) "__classes",ident null_pos "@classes"),null_pos; call null_pos (field null_pos (gen_type_path null_pos (["neko"],"Boot")) "__init") []; ],null_pos) let gen_name ctx acc t = match t with | TEnumDecl e when e.e_extern -> acc | TEnumDecl e -> let p = pos ctx e.e_pos in let name = fst e.e_path @ [snd e.e_path] in let arr = call p (field p (ident p "Array") "new1") [array p (List.map (fun n -> gen_constant ctx e.e_pos (TString n)) name); int p (List.length name)] in let path = gen_type_path p e.e_path in let setname = (EBinop ("=",field p path "__ename__",arr),p) in let arr = call p (field p (ident p "Array") "new1") [array p (List.map (fun n -> gen_constant ctx e.e_pos (TString n)) e.e_names); int p (List.length e.e_names)] in let setconstrs = (EBinop ("=", field p path "__constructs__", arr),p) in let meta = (match Codegen.build_metadata ctx.com (TEnumDecl e) with | None -> [] | Some e -> [EBinop ("=",field p path "__meta__", gen_expr ctx e),p] ) in let meta = if ctx.macros then (EBinop ("=",field p path "__et__",call p (builtin p "typewrap") [Obj.magic t]),p) :: meta else meta in setname :: setconstrs :: meta @ acc | TClassDecl c -> if c.cl_extern || (match c.cl_kind with KTypeParameter _ -> true | _ -> false) then acc else let p = pos ctx c.cl_pos in let name = fst c.cl_path @ [snd c.cl_path] in let arr = call p (field p (ident p "Array") "new1") [array p (List.map (fun n -> gen_constant ctx c.cl_pos (TString n)) name); int p (List.length name)] in (EBinop ("=",field p (gen_type_path p c.cl_path) "__name__",arr),p) :: (match c.cl_implements with | [] -> acc | l -> let interf = field p (gen_type_path p c.cl_path) "__interfaces__" in (EBinop ("=",interf, call p (field p (ident p "Array") "new1") [interf; int p (List.length l)]),p) :: acc) | TTypeDecl _ | TAbstractDecl _ -> acc let generate_libs_init = function | [] -> [] | libs -> (* var @s = $loader.loadprim("std@sys_string",0)(); var @env = $loader.loadprim("std@get_env",1); var @b = if( @s == "Windows" ) @env("HAXEPATH") + "\\lib\\" else try $loader.loadprim("std@file_contents",1)(@env("HOME")+"/.haxelib") + "/" catch e if( @s == "Linux" ) if( $loader(loadprim("std@sys_exists",1))("/usr/lib/haxe/lib") ) "/usr/lib/haxe/lib" else "/usr/share/haxe/lib/" else "/usr/local/lib/haxe/lib/"; if( try $loader.loadprim("std@sys_file_type",1)(".haxelib") == "dir" catch e false ) @b = $loader.loadprim("std@file_full_path",1)(".haxelib") + "/"; if( $loader.loadprim("std@sys_is64",0)() ) @s = @s + 64; @b = @b + "/" *) let p = null_pos in let es = ident p "@s" in let loadp n nargs = call p (field p (builtin p "loader") "loadprim") [str p ("std@" ^ n); int p nargs] in let op o e1 e2 = (EBinop (o,e1,e2),p) in let boot = [ (EVars [ "@s",Some (call p (loadp "sys_string" 0) []); "@env",Some (loadp "get_env" 1); "@b", Some (EIf (op "==" es (str p "Windows"), op "+" (call p (ident p "@env") [str p "HAXEPATH"]) (str p "\\lib\\"), Some (ETry ( op "+" (call p (loadp "file_contents" 1) [op "+" (call p (ident p "@env") [str p "HOME"]) (str p "/.haxelib")]) (str p "/"), "e", (EIf (op "==" es (str p "Linux"), (EIf (call p (loadp "sys_exists" 1) [ str p "/usr/lib/haxe/lib" ], str p "/usr/lib/haxe/lib/", Some (str p "/usr/share/haxe/lib/")),p), Some (str p "/usr/local/lib/haxe/lib/") ),p) ),p) ),p); ],p); (EIf ((ETry (op "==" (call p (loadp "sys_file_type" 1) [str p ".haxelib"]) (str p "dir"),"e",(EConst False,p)),p),op "=" (ident p "@b") (op "+" (call p (loadp "file_full_path" 1) [str p ".haxelib"]) (str p "/")), None),p); (EIf (call p (loadp "sys_is64" 0) [],op "=" es (op "+" es (int p 64)),None),p); op "=" es (op "+" es (str p "/")); ] in let lpath = field p (builtin p "loader") "path" in boot @ List.map (fun dir -> let full_path = dir.[0] = '/' || dir.[1] = ':' in let dstr = str p dir in (* // for each lib dir $loader.path = $array($loader.path,@b+dir+@s); *) op "=" lpath (call p (builtin p "array") [op "+" (if full_path then dstr else op "+" (ident p "@b") dstr) (ident p "@s"); lpath]) ) libs let new_context com ver macros = { version = ver; com = com; globals = Hashtbl.create 0; curglobal = 0; packages = Hashtbl.create 0; macros = macros; curclass = "$boot"; curmethod = "$init"; inits = []; label_count = 0; } let header() = let p = { psource = "
"; pline = 1 } in let fields l = let rec loop = function | [] -> assert false | [x] -> ident p x | x :: l -> field p (loop l) x in loop (List.rev l) in let func pl e = (EFunction (pl,(EReturn (Some e),p)),p) in let inits = [ "@classes",call p (builtin p "new") [null p]; "@enum_to_string",func [] (call p (fields ["neko";"Boot";"__enum_str"]) [this p]); "@serialize",func [] (call p (fields ["neko";"Boot";"__serialize"]) [this p]); "@tag_serialize",func [] (call p (fields ["neko";"Boot";"__tagserialize"]) [this p]); "@lazy_error",func ["e"] (call p (builtin p "varargs") [func ["_"] (call p (builtin p "throw") [ident p "e"])]); "@default__string",func [] (EBlock [ EVars ["@s",Some (call p (field p (this p) "toString") [])] ,p; EIf ((EBinop ("!=",call p (builtin p "typeof") [ident p "@s"],builtin p "tobject"),p),(EReturn (Some (null p)),p),None),p; EReturn (Some (field p (ident p "@s") "__s")),p; ],p) ] in let inits = inits @ List.map (fun nargs -> let args = Array.to_list (Array.init nargs (fun i -> Printf.sprintf "%c" (char_of_int (int_of_char 'a' + i)))) in let efun = (EFunction (args,(EBlock [ (EBinop ("=",(EConst This,p),ident p "@this"),p); call p (ident p "@fun") (List.map (ident p) args); ],p)),p) in let eif = EIf ((EBinop ("==",ident p "@fun",null p),p),null p,Some efun) in let e = func ["@this";"@fun"] (eif,p) in "@closure" ^ string_of_int nargs, e ) [0;1;2;3;4;5] in List.map (fun (v,e)-> EBinop ("=",ident p v,e),p) inits let build ctx types = let packs = List.concat (List.map (gen_package ctx) types) in let names = List.fold_left (gen_name ctx) [] types in let methods = List.rev (List.fold_left (fun acc t -> gen_type ctx t acc) [] types) in let boot = gen_boot ctx in let inits = List.map (fun (c,e) -> ctx.curclass <- s_type_path c.cl_path; ctx.curmethod <- "__init__"; gen_expr ctx e ) (List.rev ctx.inits) in ctx.inits <- []; let vars = List.concat (List.map (gen_static_vars ctx) types) in packs @ methods @ boot :: names @ inits @ vars let generate com = Hashtbl.clear files; let ctx = new_context com (if Common.defined com Define.NekoV1 then 1 else 2) false in let libs = (EBlock (generate_libs_init com.neko_libs) , { psource = "
"; pline = 1; }) in let el = build ctx com.types in let emain = (match com.main with None -> [] | Some e -> [gen_expr ctx e]) in let e = (EBlock ((header()) @ libs :: el @ emain), null_pos) in let source = Common.defined com Define.NekoSource in let use_nekoc = Common.defined com Define.UseNekoc in if not use_nekoc then begin try mkdir_from_path com.file; let ch = IO.output_channel (open_out_bin com.file) in Nbytecode.write ch (Ncompile.compile ctx.version e); IO.close_out ch; with Ncompile.Error (msg,pos) -> let pfile = Common.find_file com pos.psource in let rec loop p = let pp = { pfile = pfile; pmin = p; pmax = p; } in if Lexer.get_error_line pp >= pos.pline then pp else loop (p + 1) in abort msg (loop 0) end; let command cmd = try com.run_command cmd with _ -> -1 in let neko_file = (try Filename.chop_extension com.file with _ -> com.file) ^ ".neko" in if source || use_nekoc then begin let ch = IO.output_channel (open_out_bin neko_file) in Binast.write ch e; IO.close_out ch; end; if use_nekoc && command ("nekoc" ^ (if ctx.version > 1 then " -version " ^ string_of_int ctx.version else "") ^ " \"" ^ neko_file ^ "\"") <> 0 then failwith "Neko compilation failure"; if source then begin if command ("nekoc -p \"" ^ neko_file ^ "\"") <> 0 then failwith "Failed to print neko code"; Sys.remove neko_file; Sys.rename ((try Filename.chop_extension com.file with _ -> com.file) ^ "2.neko") neko_file; end haxe_3.4.4.orig/src/generators/genphp.ml0000664000175000017500000020623713166552354020201 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Type open Common open Codegen type method_name = { mutable mpath : path; mutable mname : string; } type inline_method = { iname : string; iindex : int; iexpr : texpr; ihasthis : bool; iin_block : bool; iarguments : string list; ilocals : (string,string) PMap.t; iinv_locals : (string,string) PMap.t; } type context = { com : Common.context; ch : out_channel; buf : Buffer.t; path : path; stack : Codegen.stack_context; mutable nested_loops : int; mutable inline_index : int; mutable curclass : tclass; mutable curmethod : string; mutable tabs : string; mutable in_value : string option; mutable in_loop : bool; mutable in_block : bool; mutable in_instance_method : bool; mutable imports : (string,string list list) Hashtbl.t; mutable extern_required_paths : (string list * string) list; mutable extern_classes_with_init : path list; mutable locals : (string,string) PMap.t; mutable inv_locals : (string,string) PMap.t; mutable local_types : t list; mutable inits : texpr list; mutable constructor_block : bool; mutable all_dynamic_methods: method_name list; mutable dynamic_methods: tclass_field list; mutable is_call : bool; mutable cwd : string; mutable inline_methods : inline_method list; mutable lib_path : string; } let follow = Abstract.follow_with_abstracts (** Check if specified expression is of `Float` type *) let is_float expr = match follow expr.etype with TAbstract ({ a_path = ([], "Float") }, _) -> true | _ -> false (** If `expr` is a TCast or TMeta, then returns underlying expression (recursively bypassing nested casts). Otherwise returns `expr` as is. *) let rec reveal_expr expr = match expr.eexpr with | TCast (e, _) -> reveal_expr e | TMeta (_, e) -> reveal_expr e | _ -> expr let join_class_path path separator = let result = match fst path, snd path with | [], s -> s | el, s -> String.concat separator el ^ separator ^ s in if (String.contains result '+') then begin let idx = String.index result '+' in (String.sub result 0 idx) ^ (String.sub result (idx+1) ((String.length result) - idx -1 ) ) end else result;; (* Get a string to represent a type. The "suffix" will be nothing or "_obj", depending if we want the name of the pointer class or the pointee (_obj class *) let rec class_string klass suffix params = (match klass.cl_path with (* Array class *) | ([],"Array") -> (snd klass.cl_path) ^ suffix ^ "<" ^ (String.concat "," (List.map type_string params) ) ^ " >" | _ when (match klass.cl_kind with KTypeParameter _ -> true | _ -> false) -> "Dynamic" | ([],"#Int") -> "/* # */int" | (["haxe";"io"],"Unsigned_char__") -> "unsigned char" | ([],"Class") -> "Class" | ([],"Null") -> (match params with | [t] -> (match follow t with | TInst ({ cl_path = [],"Int" },_) | TInst ({ cl_path = [],"Float" },_) | TEnum ({ e_path = [],"Bool" },_) -> "Dynamic" | _ -> "/*NULL*/" ^ (type_string t) ) | _ -> assert false); (* Normal class *) | _ -> (join_class_path klass.cl_path "::") ^ suffix ) and type_string_suff suffix haxe_type = (match haxe_type with | TMono r -> (match !r with None -> "Dynamic" | Some t -> type_string_suff suffix t) | TAbstract ({ a_path = [],"Int" },[]) -> "int" | TAbstract ({ a_path = [],"Float" },[]) -> "double" | TAbstract ({ a_path = [],"Bool" },[]) -> "bool" | TAbstract ({ a_path = [],"Void" },[]) -> "Void" | TEnum (enum,params) -> (join_class_path enum.e_path "::") ^ suffix | TInst (klass,params) -> (class_string klass suffix params) | TAbstract (abs,params) -> (join_class_path abs.a_path "::") ^ suffix | TType (type_def,params) -> (match type_def.t_path with | [] , "Null" -> (match params with | [t] -> (match follow t with | TInst ({ cl_path = [],"Int" },_) | TInst ({ cl_path = [],"Float" },_) | TEnum ({ e_path = [],"Bool" },_) -> "Dynamic" | _ -> type_string_suff suffix t) | _ -> assert false); | [] , "Array" -> (match params with | [t] -> "Array<" ^ (type_string (follow t) ) ^ " >" | _ -> assert false) | _ -> type_string_suff suffix (apply_params type_def.t_params params type_def.t_type) ) | TFun (args,haxe_type) -> "Dynamic" | TAnon anon -> "Dynamic" | TDynamic haxe_type -> "Dynamic" | TLazy func -> type_string_suff suffix ((!func)()) ) and type_string haxe_type = type_string_suff "" haxe_type;; let debug_expression expression type_too = "/* " ^ Type.s_expr_kind expression ^ (if (type_too) then " = " ^ (type_string (follow expression.etype)) else "") ^ " */";; let rec register_extern_required_path ctx path = if (List.exists(fun p -> p = path) ctx.extern_classes_with_init) && not (List.exists(fun p -> p = path) ctx.extern_required_paths) then ctx.extern_required_paths <- path :: ctx.extern_required_paths let s_expr_expr = Type.s_expr_kind let s_expr_name e = s_type (print_context()) (follow e.etype) let s_type_name t = s_type (print_context()) t and start_with s test = let len = String.length test in (String.length s > len && String.sub s 0 len = test) let rec is_uncertain_type t = match follow t with | TInst (c, _) -> c.cl_interface | TMono _ -> true | TAnon a -> (match !(a.a_status) with | Statics _ | EnumStatics _ -> false | _ -> true) | TDynamic _ -> true | _ -> false let is_uncertain_expr e = is_uncertain_type e.etype let rec is_anonym_type t = match follow t with | TAnon a -> (match !(a.a_status) with | Statics _ | EnumStatics _ -> false | _ -> true) | TDynamic _ -> true | _ -> false let is_anonym_expr e = is_anonym_type e.etype let rec is_unknown_type t = match follow t with | TMono r -> (match !r with | None -> true | Some t -> is_unknown_type t) | _ -> false let is_unknown_expr e = is_unknown_type e.etype let rec is_string_type t = match follow t with | TInst ({cl_path = ([], "String")}, _) -> true | TAnon a -> (match !(a.a_status) with | Statics ({cl_path = ([], "String")}) -> true | _ -> false) | TAbstract (a,pl) -> is_string_type (Abstract.get_underlying_type a pl) | _ -> false let is_string_expr e = is_string_type e.etype let to_string ctx e = let v = alloc_var "__call__" t_dynamic e.epos in let f = mk (TLocal v) t_dynamic e.epos in mk (TCall (f, [ ExprBuilder.make_string ctx.com "_hx_string_rec" e.epos; e; ExprBuilder.make_string ctx.com "" e.epos])) ctx.com.basic.tstring e.epos let as_string_expr ctx e = match e.eexpr with | TConst (TNull) -> to_string ctx e | _ when not (is_string_expr e) -> to_string ctx e | _ -> e (* for known String type that could have null value *) let to_string_null ctx e = let v = alloc_var "__call__" t_dynamic e.epos in let f = mk (TLocal v) t_dynamic e.epos in mk (TCall (f, [ ExprBuilder.make_string ctx.com "_hx_string_or_null" e.epos; e])) ctx.com.basic.tstring e.epos let as_string_expr ctx e = match e.eexpr with | TConst (TNull) -> to_string ctx e | TConst (TString s) -> e | TBinop (op,_,_) when (is_string_expr e)-> e | TCall ({eexpr = TField({eexpr = TTypeExpr(TClassDecl {cl_path = ([],"Std")})},FStatic(c,f) )}, [_]) when (f.cf_name="string") -> e | TCall ({eexpr = TLocal _}, [{eexpr = TConst (TString ("_hx_string_rec" | "_hx_str_or_null"))}]) -> e | _ when not (is_string_expr e) -> to_string ctx e | _ -> to_string_null ctx e let spr ctx s = Buffer.add_string ctx.buf s let print ctx = Printf.kprintf (fun s -> Buffer.add_string ctx.buf s) (*--php-prefix - added by skial bainn*) let prefix_class com name = match com.php_prefix with | Some prefix_class (* when not (String.length name <= 2 || String.sub name 0 2 = "__") *) -> prefix_class ^ name | _ -> name let prefix_init_replace com code = let r = Str.regexp "php_Boot" in Str.global_replace r ("php_" ^ (prefix_class com "Boot")) code let s_path ctx path isextern p = if isextern then begin register_extern_required_path ctx path; snd path end else begin (match path with (*--php-prefix*) | ([],"List") -> (prefix_class ctx.com "HList") (*--php-prefix*) | ([],name) -> (prefix_class ctx.com name) | (pack,name) -> (try (match Hashtbl.find ctx.imports name with | [p] when p = pack -> () | packs -> if not (List.mem pack packs) then Hashtbl.replace ctx.imports name (pack :: packs)) with Not_found -> Hashtbl.add ctx.imports name [pack]); (*--php-prefix*) String.concat "_" pack ^ "_" ^ (prefix_class ctx.com name)) end let s_path_haxe path = match fst path, snd path with | [], s -> s | el, s -> String.concat "." el ^ "." ^ s let escape_bin s = let b = Buffer.create 0 in for i = 0 to String.length s - 1 do match Char.code (String.unsafe_get s i) with | c when c = Char.code('\\') || c = Char.code('"') || c = Char.code('$') -> Buffer.add_string b "\\"; Buffer.add_char b (Char.chr c) | c when c < 32 -> Buffer.add_string b (Printf.sprintf "\\x%.2X" c) | c -> Buffer.add_char b (Char.chr c) done; Buffer.contents b (* haxe reserved words that match php ones: break, case, class, continue, default, do, else, extends, for, function, if, new, return, static, switch, var, while, interface, implements, public, private, try, catch, throw *) (* PHP only (for future use): cfunction, old_function *) let is_keyword n = match String.lowercase n with | "and" | "or" | "xor" | "__file__" | "exception" | "__line__" | "array" | "as" | "const" | "declare" | "die" | "echo"| "elseif" | "empty" | "enddeclare" | "endfor" | "endforeach" | "endif" | "endswitch" | "endwhile" | "eval" | "exit" | "foreach"| "global" | "include" | "include_once" | "isset" | "list" | "namespace" | "print" | "require" | "require_once" | "unset" | "use" | "__function__" | "__class__" | "__method__" | "final" | "php_user_filter" | "protected" | "abstract" | "__set" | "__get" | "__call" | "clone" | "instanceof" | "break" | "case" | "class" | "continue" | "default" | "do" | "else" | "extends" | "for" | "function" | "if" | "new" | "return" | "static" | "switch" | "var" | "while" | "interface" | "implements" | "public" | "private" | "try" | "catch" | "throw" | "goto" | "yield" -> true | _ -> false let s_ident n = let suf = "h" in if (is_keyword n) then (suf ^ n) else n let s_ident_field n = if (is_keyword n) then ("{\"" ^ (escape_bin n) ^ "\"}") else n let s_ident_local n = let suf = "h" in match String.lowercase n with | "globals" | "_server" | "_get" | "_post" | "_cookie" | "_files" | "_env" | "_request" | "_session" -> suf ^ n | _ -> n let create_directory com ldir = let atm_path = ref (String.create 0) in atm_path := com.file; if not (Sys.file_exists com.file) then (Unix.mkdir com.file 0o755); (List.iter (fun p -> atm_path := !atm_path ^ "/" ^ p; if not (Sys.file_exists !atm_path) then (Unix.mkdir !atm_path 0o755);) ldir) let write_resource dir name data = let rdir = dir ^ "/res" in if not (Sys.file_exists dir) then Unix.mkdir dir 0o755; if not (Sys.file_exists rdir) then Unix.mkdir rdir 0o755; let name = Codegen.escape_res_name name false in let ch = open_out_bin (rdir ^ "/" ^ name) in output_string ch data; close_out ch let stack_init com use_add = Codegen.stack_context_init com "GLOBALS['%s']" "GLOBALS['%e']" "__hx__spos" "tmp" use_add Globals.null_pos let init com cwd path def_type = let rec create acc = function | [] -> () | d :: l -> let pdir = String.concat "/" (List.rev (d :: acc)) in if not (Sys.file_exists pdir) then Unix.mkdir pdir 0o755; create (d :: acc) l in let dir = if cwd <> "" then com.file :: (cwd :: fst path) else com.file :: fst path; in create [] dir; let filename path = prefix_class com (match path with | [], "List" -> "HList"; | _, s -> s) in (*--php-prefix*) let ch = open_out (String.concat "/" dir ^ "/" ^ (filename path) ^ (if def_type = 0 then ".class" else if def_type = 1 then ".enum" else if def_type = 2 then ".interface" else ".extern") ^ ".php") in let imports = Hashtbl.create 0 in Hashtbl.add imports (snd path) [fst path]; let ctx = { com = com; stack = stack_init com false; tabs = ""; ch = ch; path = path; buf = Buffer.create (1 lsl 14); in_value = None; in_loop = false; in_instance_method = false; imports = imports; extern_required_paths = []; extern_classes_with_init = []; curclass = null_class; curmethod = ""; locals = PMap.empty; inv_locals = PMap.empty; local_types = []; inits = []; constructor_block = false; dynamic_methods = []; all_dynamic_methods = []; is_call = false; cwd = cwd; inline_methods = []; nested_loops = 0; inline_index = 0; in_block = false; lib_path = match com.php_lib with None -> "lib" | Some s -> s; } in Codegen.map_source_header com (fun s -> print ctx "// %s\n" s); ctx let unsupported msg p = abort ("This expression cannot be generated to PHP: " ^ msg) p let newline ctx = match Buffer.nth ctx.buf (Buffer.length ctx.buf - 1) with | '{' | ':' | ' ' | '}' when Buffer.nth ctx.buf (Buffer.length ctx.buf - 2) != '"' -> print ctx "\n%s" ctx.tabs | _ -> print ctx ";\n%s" ctx.tabs let rec concat ctx s f = function | [] -> () | [x] -> f x | x :: l -> f x; spr ctx s; concat ctx s f l let open_block ctx = let oldt = ctx.tabs in ctx.tabs <- "\t" ^ ctx.tabs; (fun() -> ctx.tabs <- oldt) let parent e = match e.eexpr with | TParenthesis _ -> e | _ -> mk (TParenthesis e) e.etype e.epos let inc_extern_path ctx path = let rec slashes n = if n = 0 then "" else ("../" ^ slashes (n-1)) in let pre = if ctx.cwd = "" then ctx.lib_path ^ "/" else "" in match path with | ([],name) -> pre ^ (slashes (List.length (fst ctx.path))) ^ (prefix_class ctx.com name) ^ ".extern.php" | (pack,name) -> pre ^ (slashes (List.length (fst ctx.path))) ^ String.concat "/" pack ^ "/" ^ (prefix_class ctx.com name) ^ ".extern.php" let close ctx = output_string ctx.ch " if path <> ctx.path then output_string ctx.ch ("require_once dirname(__FILE__).'/" ^ (inc_extern_path ctx path) ^ "';\n"); ) (List.rev ctx.extern_required_paths); output_string ctx.ch "\n"; output_string ctx.ch (Buffer.contents ctx.buf); close_out ctx.ch let save_locals ctx = let old = ctx.locals in let old_inv = ctx.inv_locals in (fun() -> ctx.locals <- old; ctx.inv_locals <- old_inv) let define_local ctx l = let rec loop n = let name = (if n = 1 then s_ident_local l else s_ident_local (l ^ string_of_int n)) in if PMap.mem name ctx.inv_locals then loop (n+1) else begin ctx.locals <- PMap.add l name ctx.locals; ctx.inv_locals <- PMap.add name l ctx.inv_locals; name end in loop 1 let this ctx = if ctx.in_value <> None then "$__hx__this" else "$this" let gen_constant ctx p = function | TInt i -> print ctx "%ld" i | TFloat s -> spr ctx s | TString s -> print ctx "\"%s\"" (escape_bin s) | TBool b -> spr ctx (if b then "true" else "false") | TNull -> spr ctx "null" | TThis -> spr ctx (this ctx) | TSuper -> spr ctx "ERROR /* unexpected call to super in gen_constant */" let arg_is_opt c = match c with | Some _ -> true | None -> false let s_funarg ctx arg t p o = let byref = if (String.length arg > 7 && String.sub arg 0 7 = "byref__") then "&" else "" in print ctx "%s$%s" byref (s_ident_local arg); if o then spr ctx " = null" (* match c with | _, Some _ -> spr ctx " = null" | _, None -> () *) let is_in_dynamic_methods ctx e s = List.exists (fun dm -> (* TODO: I agree, this is a mess ... but after hours of trials and errors I gave up; maybe in a calmer day *) ((String.concat "." ((fst dm.mpath) @ ["#" ^ (snd dm.mpath)])) ^ "." ^ dm.mname) = (s_type_name e.etype ^ "." ^ s) ) ctx.all_dynamic_methods let is_dynamic_method f = (match f.cf_kind with | Var _ -> true | Method MethDynamic -> true | _ -> false) let fun_block ctx f p = let e = (match f.tf_expr with { eexpr = TBlock [{ eexpr = TBlock _ } as e] } -> e | e -> e) in let e = List.fold_left (fun e (v,c) -> match c with | None | Some TNull -> e | Some c -> Type.concat (Codegen.set_default ctx.com v c p) e ) e f.tf_args in if ctx.com.debug then begin Codegen.stack_block ctx.stack ctx.curclass ctx.curmethod e end else mk_block e let rec gen_array_args ctx lst = match lst with | [] -> () | h :: t -> spr ctx "["; gen_value ctx h; spr ctx "]"; gen_array_args ctx t and gen_call ctx e el = let rec genargs lst = (match lst with | [] -> () | h :: [] -> spr ctx " = "; gen_value ctx h; | h :: t -> spr ctx "["; gen_value ctx h; spr ctx "]"; genargs t) in match (reveal_expr e).eexpr , el with | TConst TSuper , params -> (match ctx.curclass.cl_super with | None -> assert false | Some (c,_) -> spr ctx "parent::__construct("; concat ctx "," (gen_value ctx) params; spr ctx ")"; ); | TField ({ eexpr = TConst TSuper },f) , params -> (match ctx.curclass.cl_super with | None -> assert false | Some (c,_) -> print ctx "parent::%s(" (s_ident (field_name f)); concat ctx "," (gen_value ctx) params; spr ctx ")"; ); | TField ({ eexpr = TTypeExpr _ }, FStatic (_, {cf_type = TDynamic _; cf_kind = Var _})) , params -> spr ctx "call_user_func("; ctx.is_call <- true; gen_value ctx e; ctx.is_call <- false; spr ctx ", "; concat ctx ", " (gen_value ctx) el; spr ctx ")"; | TLocal { v_name = "__set__" }, { eexpr = TConst (TString code) } :: el -> print ctx "$%s" code; genargs el; | TLocal { v_name = "__set__" }, e :: el -> gen_value ctx e; genargs el; | TLocal { v_name = "__setfield__" }, e :: (f :: el) -> gen_value ctx e; spr ctx "->{"; gen_value ctx f; spr ctx "}"; genargs el; | TLocal { v_name = "__field__" }, e :: ({ eexpr = TConst (TString code) } :: el) -> gen_value ctx e; spr ctx "->"; spr ctx code; gen_array_args ctx el; | TLocal { v_name = "__field__" }, e :: (f :: el) -> gen_value ctx e; spr ctx "->"; gen_value ctx f; gen_array_args ctx el; | TLocal { v_name = "__prefix__" }, [] -> (match ctx.com.php_prefix with | Some prefix -> print ctx "\"%s\"" prefix | None -> spr ctx "null") | TLocal { v_name = "__var__" }, { eexpr = TConst (TString code) } :: el -> print ctx "$%s" code; gen_array_args ctx el; | TLocal { v_name = "__var__" }, e :: el -> gen_value ctx e; gen_array_args ctx el; | TLocal { v_name = "__call__" }, { eexpr = TConst (TString code) } :: el -> spr ctx code; spr ctx "("; concat ctx ", " (gen_value ctx) el; spr ctx ")"; | TLocal { v_name = "__php__" }, [{ eexpr = TConst (TString code) }] -> (*--php-prefix*) spr ctx (prefix_init_replace ctx.com code) | TLocal { v_name = "__php__" }, { eexpr = TConst (TString code); epos = p } :: tl -> Codegen.interpolate_code ctx.com code tl (spr ctx) (gen_expr ctx) p | TLocal { v_name = "__instanceof__" }, [e1;{ eexpr = TConst (TString t) }] -> gen_value ctx e1; print ctx " instanceof %s" t; | TLocal { v_name = "__physeq__" }, [e1;e2] -> spr ctx "("; gen_value ctx e1; spr ctx " === "; gen_value ctx e2; spr ctx ")" | TLocal _, [] | TFunction _, [] | TCall _, [] | TParenthesis _, [] | TMeta _, [] | TBlock _, [] -> ctx.is_call <- true; spr ctx "call_user_func("; gen_value ctx e; ctx.is_call <- false; spr ctx ")"; | TLocal _, el | TFunction _, el | TCall _, el | TParenthesis _, el | TMeta _, el | TBlock _, el -> ctx.is_call <- true; spr ctx "call_user_func_array("; gen_value ctx e; ctx.is_call <- false; spr ctx ", array("; concat ctx ", " (gen_value ctx) el; spr ctx "))" (* | TCall (x,_), el when (match x.eexpr with | TLocal _ -> false | _ -> true) -> ctx.is_call <- true; spr ctx "call_user_func_array("; gen_value ctx e; ctx.is_call <- false; spr ctx ", array("; concat ctx ", " (gen_value ctx) el; spr ctx "))" *) | _ -> ctx.is_call <- true; gen_value ctx e; ctx.is_call <- false; spr ctx "("; concat ctx ", " (gen_value ctx) el; spr ctx ")"; and could_be_string_var s = s = "length" and gen_uncertain_string_var ctx s e = match s with | "length" -> spr ctx "_hx_len("; gen_value ctx e; spr ctx ")" | _ -> gen_field_access ctx true e s; and gen_string_var ctx s e = match s with | "length" -> spr ctx "strlen("; gen_value ctx e; spr ctx ")" | _ -> unsupported "gen_string_var " e.epos; and gen_string_static_call ctx s e el = match s with | "fromCharCode" -> spr ctx "chr("; concat ctx ", " (gen_value ctx) el; spr ctx ")"; | _ -> unsupported "gen_string_static_call " e.epos; and could_be_string_call s = s = "substr" || s = "substring" || s = "charAt" || s = "charCodeAt" || s = "indexOf" || s = "lastIndexOf" || s = "split" || s = "toLowerCase" || s = "toString" || s = "toUpperCase" and gen_string_call ctx s e el = match s with | "substr" -> spr ctx "_hx_substr("; gen_value ctx e; spr ctx ", "; concat ctx ", " (gen_value ctx) el; spr ctx ")" | "substring" -> spr ctx "_hx_substring("; gen_value ctx e; spr ctx ", "; concat ctx ", " (gen_value ctx) el; spr ctx ")" | "charAt" -> spr ctx "_hx_char_at("; gen_value ctx e; spr ctx ", "; concat ctx ", " (gen_value ctx) el; spr ctx ")" | "cca" -> spr ctx "ord(substr("; gen_value ctx e; spr ctx ","; concat ctx ", " (gen_value ctx) el; spr ctx ",1))" | "charCodeAt" -> spr ctx "_hx_char_code_at("; gen_value ctx e; spr ctx ", "; concat ctx ", " (gen_value ctx) el; spr ctx ")" | "indexOf" -> spr ctx "_hx_index_of("; gen_value ctx e; spr ctx ", "; concat ctx ", " (gen_value ctx) el; spr ctx ")" | "lastIndexOf" -> spr ctx "_hx_last_index_of("; gen_value ctx e; spr ctx ", "; concat ctx ", " (gen_value ctx) el; spr ctx ")" | "split" -> spr ctx "_hx_explode("; concat ctx ", " (gen_value ctx) el; spr ctx ", "; gen_value ctx e; spr ctx ")" | "toLowerCase" -> spr ctx "strtolower("; gen_value ctx e; spr ctx ")" | "toUpperCase" -> spr ctx "strtoupper("; gen_value ctx e; spr ctx ")" | "toString" -> gen_value ctx e; | _ -> unsupported "gen_string_call" e.epos; and gen_uncertain_string_call ctx s e el = spr ctx "_hx_string_call("; gen_value ctx e; print ctx ", \"%s\", array(" s; concat ctx ", " (gen_value ctx) el; spr ctx "))" and gen_field_op ctx e = match e.eexpr with | TField (f,s) -> (match follow e.etype with | TFun _ -> gen_field_access ctx true f (field_name s) | _ -> gen_value_op ctx e) | _ -> gen_value_op ctx e and gen_value_op ctx e = match e.eexpr with | TBinop (op,_,_) when op = Ast.OpAnd || op = Ast.OpOr || op = Ast.OpXor -> gen_value ctx e; | _ -> gen_value ctx e and is_static t = match follow t with | TAnon a -> (match !(a.a_status) with | Statics c -> true | _ -> false) | _ -> false and get_constant_prefix meta = let (_, args, pos) = Meta.get Meta.PhpConstants meta in (match args with | [EConst(String prefix), _] -> prefix | [] -> "" | _ -> abort "Invalid @:phpConstant parameters" pos) and gen_member_access ctx isvar e s = match follow e.etype with | TAnon a -> (match !(a.a_status) with | EnumStatics _ -> let (isvar, access_operator) = match e.eexpr with | TField _ -> (false, "->") | _ -> (isvar, "::") in print ctx "%s%s" (access_operator ^ (if isvar then "$" else "")) (s_ident s) | Statics sta -> let (sep, no_dollar) = if Meta.has Meta.PhpGlobal sta.cl_meta then ("", false) else match e.eexpr with | TField _ -> ("->", true) | _ -> ("::", false) in let isconst = Meta.has Meta.PhpConstants sta.cl_meta in let cprefix = if isconst then get_constant_prefix sta.cl_meta else "" in print ctx "%s%s%s" sep (if isvar && not isconst && not no_dollar then "$" else cprefix) (if sta.cl_extern && sep = "" then s else s_ident s) | _ -> print ctx "->%s" (if isvar then s_ident_field s else s_ident s)) | _ -> print ctx "->%s" (if isvar then s_ident_field s else s_ident s) and gen_field_access ctx isvar e s = match (reveal_expr e).eexpr with | TTypeExpr t -> let isglobal = match t with | TClassDecl(c) -> Meta.has Meta.PhpGlobal c.cl_meta && c.cl_extern | _ -> false in spr ctx (if isglobal then "" else (s_path ctx (t_path t) false e.epos)); gen_member_access ctx isvar e s | TLocal _ -> gen_expr ctx e; print ctx "->%s" (if isvar then s_ident_field s else s_ident s) | TArray (e1,e2) -> spr ctx "_hx_array_get("; gen_value ctx e1; spr ctx ", "; gen_value ctx e2; spr ctx ")"; gen_member_access ctx isvar e s | TBlock _ | TParenthesis _ | TMeta _ | TObjectDecl _ | TArrayDecl _ | TNew _ -> spr ctx "_hx_deref("; ctx.is_call <- false; gen_value ctx e; spr ctx ")"; gen_member_access ctx isvar e s | TCast (ec, _) when (match ec.eexpr with | TNew _ | TArrayDecl _ | TConst TNull -> true | _ -> false) -> spr ctx "_hx_deref("; ctx.is_call <- false; gen_value ctx e; spr ctx ")"; gen_member_access ctx isvar e s | TConst TNull -> spr ctx "_hx_deref(null)"; gen_member_access ctx isvar e s | _ -> gen_expr ctx e; gen_member_access ctx isvar e s and gen_dynamic_function ctx isstatic name f params p = let old = ctx.in_value in let old_l = ctx.locals in let old_li = ctx.inv_locals in let old_t = ctx.local_types in ctx.in_value <- None; ctx.local_types <- List.map snd params @ ctx.local_types; let byref = if (String.length name > 9 && String.sub name 0 9 = "__byref__") then "&" else "" in print ctx "function %s%s(" byref name; concat ctx ", " (fun (v,c) -> let arg = define_local ctx v.v_name in s_funarg ctx arg v.v_type p (arg_is_opt c); ) f.tf_args; spr ctx ") {"; if (List.length f.tf_args) > 0 then begin if isstatic then print ctx " return call_user_func_array(self::$%s, array(" name else print ctx " return call_user_func_array($this->%s, array(" name; concat ctx ", " (fun (v,_) -> spr ctx ("$" ^ v.v_name) ) f.tf_args; print ctx ")); }"; end else if isstatic then print ctx " return call_user_func(self::$%s); }" name else print ctx " return call_user_func($this->%s); }" name; newline ctx; if isstatic then print ctx "public static $%s = null" name else print ctx "public $%s = null" name; ctx.in_value <- old; ctx.locals <- old_l; ctx.inv_locals <- old_li; ctx.local_types <- old_t and gen_function ctx name f params p = let old = ctx.in_value in let old_l = ctx.locals in let old_li = ctx.inv_locals in let old_t = ctx.local_types in ctx.in_value <- None; ctx.local_types <- List.map snd params @ ctx.local_types; let byref = if (String.length name > 9 && String.sub name 0 9 = "__byref__") then "&" else "" in print ctx "function %s%s(" byref name; concat ctx ", " (fun (v,o) -> let arg = define_local ctx v.v_name in s_funarg ctx arg v.v_type p (arg_is_opt o); ) f.tf_args; print ctx ") "; gen_expr ctx (fun_block ctx f p); ctx.in_value <- old; ctx.locals <- old_l; ctx.inv_locals <- old_li; ctx.local_types <- old_t and gen_inline_function ctx f hasthis p = ctx.nested_loops <- ctx.nested_loops - 1; let old = ctx.in_value in let old_l = ctx.locals in let old_li = ctx.inv_locals in let old_t = ctx.local_types in ctx.in_value <- Some "closure"; let args a = List.map (fun (v,_) -> v.v_name) a in let used_locals = ref PMap.empty in let rec loop e = match e.eexpr with | TLocal v when not (start_with v.v_name "__hx__") && PMap.mem v.v_name old_l -> used_locals := PMap.add v.v_name v.v_name !used_locals | _ -> Type.iter loop e in loop f.tf_expr; spr ctx "array(new _hx_lambda(array("; let c = ref 0 in let print_arg a = if !c > 0 then spr ctx ", "; incr c; print ctx "&$%s" a; in if hasthis then print_arg "this"; PMap.iter (fun _ a -> print_arg a) !used_locals; spr ctx "), \""; spr ctx (inline_function ctx (args f.tf_args) hasthis !used_locals (fun_block ctx f p)); print ctx "\"), 'execute')"; ctx.in_value <- old; ctx.locals <- old_l; ctx.inv_locals <- old_li; ctx.local_types <- old_t; ctx.nested_loops <- ctx.nested_loops + 1; and unset_locals ctx old_l = let lst = ref [] in PMap.iter (fun n _ -> if not (PMap.exists n old_l) then lst := ["$" ^ n] @ !lst; ) ctx.inv_locals; if (List.length !lst) > 0 then begin newline ctx; spr ctx "unset("; concat ctx "," (fun (s) -> spr ctx s; ) !lst; spr ctx ")" end and gen_while_expr ctx e = let old_loop = ctx.in_loop in ctx.in_loop <- true; let old_nested_loops = ctx.nested_loops in ctx.nested_loops <- 1; let old_l = ctx.inv_locals in let b = save_locals ctx in (match e.eexpr with | TBlock (el) -> List.iter (fun e -> newline ctx; gen_expr ctx e) el; | _ -> newline ctx; gen_expr ctx e); unset_locals ctx old_l; b(); ctx.nested_loops <- old_nested_loops; ctx.in_loop <- old_loop and gen_tfield ctx e e1 s = let name = (field_name s) in match follow e.etype with | TFun (args, _) -> (if ctx.is_call then begin gen_field_access ctx false e1 name end else if is_in_dynamic_methods ctx e1 name then begin gen_field_access ctx true e1 name; end else begin let ob ex = (match ex with | TTypeExpr t -> print ctx "\""; spr ctx (s_path ctx (t_path t) false e1.epos); print ctx "\"" | _ -> gen_expr ctx e1) in spr ctx "(property_exists("; ob e1.eexpr; print ctx ", \"%s\") ? " (s_ident name); gen_field_access ctx true e1 name; spr ctx ": array("; ob e1.eexpr; print ctx ", \"%s\"))" (s_ident name); end) | TMono _ -> if ctx.is_call then gen_field_access ctx false e1 name else gen_uncertain_string_var ctx name e1 | TDynamic _ when not ctx.is_call && (match s with FDynamic _ -> true | _ -> false) -> spr ctx "_hx_field("; gen_value ctx e1; print ctx ", \"%s\")" name | _ -> if is_string_expr e1 then gen_string_var ctx name e1 else if is_uncertain_expr e1 then gen_uncertain_string_var ctx name e1 else gen_field_access ctx true e1 name and gen_expr ctx e = let in_block = ctx.in_block in ctx.in_block <- false; let restore_in_block ctx inb = if inb then ctx.in_block <- true in match e.eexpr with | TConst c -> gen_constant ctx e.epos c | TLocal v -> spr ctx ("$" ^ (try PMap.find v.v_name ctx.locals with Not_found -> (s_ident_local v.v_name))) | TArray (e1,e2) -> (match e1.eexpr with | TCall _ | TBlock _ | TParenthesis _ | TMeta _ | TArrayDecl _ -> spr ctx "_hx_array_get("; gen_value ctx e1; spr ctx ", "; gen_value ctx e2; spr ctx ")"; | TCast (ec, _) when (match ec.eexpr with | TArrayDecl _ | TBlock _ -> true | _ -> false) -> spr ctx "_hx_array_get("; gen_value ctx e1; spr ctx ", "; gen_value ctx e2; spr ctx ")"; | _ -> gen_value ctx e1; spr ctx "["; gen_value ctx e2; spr ctx "]"); | TBinop (op,e1,e2) -> (* these operators are non-assoc in php, let let's make sure to separate them with parenthesises *) let non_assoc = function | (Ast.OpEq | Ast.OpNotEq | Ast.OpGt | Ast.OpGte | Ast.OpLt | Ast.OpLte) -> true | _ -> false in (match e1.eexpr with | TBinop (op2,_,_) when non_assoc op && non_assoc op2 -> gen_expr ctx { e with eexpr = TBinop (op,mk (TParenthesis e1) e1.etype e1.epos,e2) } | _ -> let leftside e = (match e.eexpr with | TArray(te1, te2) -> gen_value ctx te1; spr ctx "->a["; gen_value ctx te2; spr ctx "]"; | _ -> gen_field_op ctx e1;) in let leftsidec e = (match e.eexpr with | TArray(te1, te2) -> gen_value ctx te1; spr ctx "->a["; gen_value ctx te2; spr ctx "]"; | TField (e1,s) -> gen_field_access ctx true e1 (field_name s) | _ -> gen_field_op ctx e1;) in let leftsidef e = (match e.eexpr with | TField (e1,s) -> gen_field_access ctx true e1 (field_name s) | _ -> gen_field_op ctx e1; ) in (match op with | Ast.OpMod -> spr ctx "_hx_mod("; gen_value_op ctx e1; spr ctx ", "; gen_value_op ctx e2; spr ctx ")"; | Ast.OpAssign -> (match e1.eexpr with | TArray(te1, te2) when (match te1.eexpr with | TCall _ | TParenthesis _ -> true | _ -> false) -> spr ctx "_hx_array_assign("; gen_value ctx te1; spr ctx ", "; gen_value ctx te2; spr ctx ", "; gen_value_op ctx e2; spr ctx ")"; | _ -> leftsidef e1; spr ctx " = "; gen_value_op ctx e2; ) | Ast.OpAssignOp(Ast.OpAdd) when (is_uncertain_expr e1 && is_uncertain_expr e2) -> (match e1.eexpr with | TArray(te1, te2) -> let t1 = define_local ctx "__hx__t1" in let t2 = define_local ctx "__hx__t2" in print ctx "_hx_array_assign($%s = " t1; gen_value ctx te1; print ctx ", $%s = " t2; gen_value ctx te2; print ctx ", $%s->a[$%s] + " t1 t2; gen_value_op ctx e2; spr ctx ")"; | _ -> leftside e1; spr ctx " = "; spr ctx "_hx_add("; gen_value_op ctx e1; spr ctx ", "; gen_value_op ctx e2; spr ctx ")"; ) | Ast.OpAssignOp(Ast.OpAdd) when (is_string_expr e1 || is_string_expr e2) -> leftside e1; spr ctx " .= "; gen_value_op ctx (as_string_expr ctx e2); | Ast.OpAssignOp(Ast.OpShl) -> leftside e1; spr ctx " <<= "; gen_value_op ctx e2; | Ast.OpAssignOp(Ast.OpUShr) -> leftside e1; spr ctx " = "; spr ctx "_hx_shift_right("; gen_value_op ctx e1; spr ctx ", "; gen_value_op ctx e2; spr ctx ")"; | Ast.OpAssignOp(Ast.OpMod) -> leftside e1; spr ctx " = "; spr ctx "_hx_mod("; gen_value_op ctx e1; spr ctx ", "; gen_value_op ctx e2; spr ctx ")"; | Ast.OpAssignOp(_) -> leftsidec e1; print ctx " %s " (Ast.s_binop op); gen_value_op ctx e2; | Ast.OpAdd when (is_uncertain_expr e1 && is_uncertain_expr e2) -> spr ctx "_hx_add("; gen_value_op ctx e1; spr ctx ", "; gen_value_op ctx e2; spr ctx ")"; | Ast.OpAdd when (is_string_expr e1 || is_string_expr e2) -> gen_value_op ctx (as_string_expr ctx e1); spr ctx " . "; gen_value_op ctx (as_string_expr ctx e2); | Ast.OpShl -> gen_value_op ctx e1; spr ctx " << "; gen_value_op ctx e2; | Ast.OpUShr -> spr ctx "_hx_shift_right("; gen_value_op ctx e1; spr ctx ", "; gen_value_op ctx e2; spr ctx ")"; | Ast.OpNotEq | Ast.OpEq -> let s_op = if op = Ast.OpNotEq then " != " else " == " in let s_phop = if op = Ast.OpNotEq then " !== " else " === " in let se1 = s_expr_name e1 in let se2 = s_expr_name e2 in if e1.eexpr = TConst (TNull) || e2.eexpr = TConst (TNull) then begin (match e1.eexpr with | TField (f, s) when is_anonym_expr e1 || is_unknown_expr e1 -> spr ctx "_hx_field("; gen_value ctx f; print ctx ", \"%s\")" (field_name s); | _ -> gen_field_op ctx e1; ); spr ctx s_phop; (match e2.eexpr with | TField (f, s) when is_anonym_expr e2 || is_unknown_expr e2 -> spr ctx "_hx_field("; gen_value ctx f; print ctx ", \"%s\")" (field_name s); | _ -> gen_field_op ctx e2); end else if ((se1 = "Int" || se1 = "Null") && (se2 = "Int" || se2 = "Null")) || ((se1 = "Float" || se1 = "Null") && (se2 = "Float" || se2 = "Null")) && not (is_float e1 && is_float e2) then begin gen_field_op ctx e1; spr ctx s_phop; gen_field_op ctx e2; end else if ((se1 = "Int" || se1 = "Float" || se1 = "Null" || se1 = "Null") && (se1 = "Int" || se1 = "Float" || se1 = "Null" || se1 = "Null")) || (is_unknown_expr e1 && is_unknown_expr e2) || is_anonym_expr e1 || is_anonym_expr e2 then begin if op = Ast.OpNotEq then spr ctx "!"; spr ctx "_hx_equal("; gen_field_op ctx e1; spr ctx ", "; gen_field_op ctx e2; spr ctx ")"; end else if ( se1 == se2 || (match e1.eexpr with | TConst _ | TLocal _ | TArray _ | TNew _ -> true | _ -> false) || (match e2.eexpr with | TConst _ | TLocal _ | TArray _ | TNew _ -> true | _ -> false) || is_string_expr e1 || is_string_expr e2 || is_anonym_expr e1 || is_anonym_expr e2 || is_unknown_expr e1 || is_unknown_expr e2 ) && (type_string (follow e1.etype)) <> "Dynamic" && (type_string (follow e2.etype)) <> "Dynamic" then begin gen_field_op ctx e1; spr ctx s_phop; gen_field_op ctx e2; end else begin let tmp = define_local ctx "_t" in print ctx "(is_object($%s = " tmp; gen_field_op ctx e1; print ctx ") && ($%s instanceof Enum) ? $%s%s" tmp tmp s_op; gen_field_op ctx e2; print ctx " : "; if op = Ast.OpNotEq then spr ctx "!"; print ctx "_hx_equal($%s, " tmp; gen_field_op ctx e2; spr ctx "))"; end | Ast.OpGt | Ast.OpGte | Ast.OpLt | Ast.OpLte when is_string_expr e1 -> spr ctx "(strcmp("; gen_field_op ctx e1; spr ctx ", "; gen_field_op ctx e2; spr ctx ")"; let op_str = match op with | Ast.OpGt -> ">" | Ast.OpGte -> ">=" | Ast.OpLt -> "<" | Ast.OpLte -> "<=" | _ -> assert false in print ctx "%s 0)" op_str | _ -> leftside e1; print ctx " %s " (Ast.s_binop op); gen_value_op ctx e2; )); | TEnumParameter(e1,_,i) -> spr ctx "_hx_deref("; gen_value ctx e1; spr ctx ")"; print ctx "->params[%d]" i; | TField (e1,s) -> gen_tfield ctx e e1 s | TTypeExpr t -> print ctx "_hx_qtype(\"%s\")" (s_path_haxe (t_path t)) | TParenthesis e -> (match e.eexpr with | TParenthesis _ | TReturn _ -> gen_value ctx e; | _ -> spr ctx "("; gen_value ctx e; spr ctx ")" ); | TMeta (_,e) -> gen_expr ctx e | TReturn eo -> (match eo with | None -> spr ctx "return" | Some e when (match follow e.etype with TEnum({ e_path = [],"Void" },[]) | TAbstract ({ a_path = [],"Void" },[]) -> true | _ -> false) -> gen_value ctx e; newline ctx; spr ctx "return" | Some e -> (match e.eexpr with | TThrow _ -> () | _ -> spr ctx "return "); gen_value ctx e; ); | TBreak -> if ctx.in_loop then spr ctx "break" else print ctx "break %d" ctx.nested_loops | TContinue -> if ctx.in_loop then spr ctx "continue" else print ctx "continue %d" ctx.nested_loops | TBlock [] when List.length ctx.dynamic_methods = 0 -> spr ctx "{}" | TBlock el -> let old_l = ctx.inv_locals in let b = save_locals ctx in print ctx "{"; let bend = open_block ctx in let cb = ( if not ctx.constructor_block then (fun () -> ()) else begin ctx.constructor_block <- false; if List.length ctx.dynamic_methods > 0 then newline ctx else spr ctx " "; List.iter (fun (f) -> let name = f.cf_name in match f.cf_expr with | Some { eexpr = TFunction fd } -> print ctx "if(!isset($this->%s)) $this->%s = " name name; gen_inline_function ctx fd true e.epos; newline ctx; | _ -> () ) ctx.dynamic_methods; if Codegen.constructor_side_effects e then begin print ctx "if(!%s::$skip_constructor) {" (s_path ctx (["php"],"Boot") false e.epos); (fun() -> print ctx "}") end else (fun() -> ()); end) in let remaining = ref (List.length el) in let build e = newline ctx; if (in_block && !remaining = 1) then begin (match e.eexpr with | TIf _ | TSwitch _ | TThrow _ | TWhile _ | TFor _ | TTry _ | TBreak | TBlock _ -> restore_in_block ctx in_block; gen_expr ctx e; unset_locals ctx old_l; | TReturn (Some e1) -> (match e1.eexpr with | TIf _ | TSwitch _ | TThrow _ | TWhile _ | TFor _ | TTry _ | TBlock _ -> () | _ -> spr ctx "return " ); gen_expr ctx e1; | _ -> spr ctx "return "; gen_value ctx e; ) end else begin gen_expr ctx e; end; decr remaining; in List.iter build el; if ctx.in_loop then begin unset_locals ctx old_l; end; bend(); newline ctx; cb(); print ctx "}"; b(); | TFunction f -> let old = ctx.in_value, ctx.in_loop in let old_meth = ctx.curmethod in ctx.in_value <- None; ctx.in_loop <- false; ctx.curmethod <- ctx.curmethod ^ "@" ^ string_of_int (Lexer.get_error_line e.epos); gen_inline_function ctx f false e.epos; ctx.curmethod <- old_meth; ctx.in_value <- fst old; ctx.in_loop <- snd old; | TCall (ec,el) -> (match ec.eexpr with | TArray _ -> spr ctx "call_user_func_array("; gen_value ctx ec; spr ctx ", array("; concat ctx ", " (gen_value ctx) el; spr ctx "))"; | TField (ef,s) when is_static ef.etype && is_string_expr ef -> gen_string_static_call ctx (field_name s) ef el | TField (ef,s) when is_string_expr ef -> gen_string_call ctx (field_name s) ef el | TField (ef,s) when is_anonym_expr ef && could_be_string_call (field_name s) -> gen_uncertain_string_call ctx (field_name s) ef el | _ -> gen_call ctx ec el); | TArrayDecl el -> spr ctx "(new _hx_array(array("; concat ctx ", " (gen_value ctx) el; spr ctx ")))"; | TThrow e -> spr ctx "throw new HException("; gen_value ctx e; spr ctx ")"; | TVar (v,eo) -> spr ctx "$"; let restore = save_locals ctx in let n = define_local ctx v.v_name in let restore2 = save_locals ctx in restore(); (match eo with | None -> print ctx "%s = null" (s_ident_local n) | Some e -> print ctx "%s = " (s_ident_local n); gen_value ctx e); restore2() | TNew (c,_,el) -> (match c.cl_path, el with | ([], "String"), _ -> concat ctx "" (gen_value ctx) el | ([], "Array"), el -> spr ctx "new _hx_array(array("; concat ctx ", " (gen_value ctx) el; spr ctx "))" | (_, _), _ -> print ctx "new %s(" (s_path ctx c.cl_path c.cl_extern e.epos); let count = ref (-1) in concat ctx ", " (fun e -> incr count; match c.cl_constructor with | Some f -> gen_value ctx e; | _ -> (); ) el; spr ctx ")") | TIf (cond,e,eelse) -> spr ctx "if"; gen_value ctx (parent cond); spr ctx " "; restore_in_block ctx in_block; gen_expr ctx (mk_block e); (match eelse with | None -> () | Some e when e.eexpr = TConst(TNull) -> () | Some e -> spr ctx " else "; restore_in_block ctx in_block; gen_expr ctx (mk_block e)); | TUnop (op,Ast.Prefix,e) -> (match e.eexpr with | TArray(te1, te2) -> (match op with | Increment -> spr ctx "_hx_array_increment("; gen_value ctx te1; spr ctx ","; gen_value ctx te2; spr ctx ")"; | Decrement -> spr ctx "_hx_array_decrement("; gen_value ctx te1; spr ctx ","; gen_value ctx te2; spr ctx ")"; | _ -> spr ctx (Ast.s_unop op); gen_value ctx te1; spr ctx "["; gen_value ctx te2; spr ctx "]"; ); | TField (e1,s) -> spr ctx (Ast.s_unop op); gen_tfield ctx e e1 s | _ -> spr ctx (Ast.s_unop op); gen_value ctx e) | TUnop (op,Ast.Postfix,e) -> (match e.eexpr with | TArray(te1, te2) -> gen_value ctx te1; spr ctx "->a["; gen_value ctx te2; spr ctx "]"; | TField (e1,s) -> gen_field_access ctx true e1 (field_name s) | _ -> gen_value ctx e); spr ctx (Ast.s_unop op) | TWhile (cond,e,Ast.NormalWhile) -> let old = save_locals ctx in spr ctx "while"; gen_value ctx (parent cond); spr ctx " {"; let bend = open_block ctx in gen_while_expr ctx e; bend(); newline ctx; spr ctx "}"; old() | TWhile (cond,e,Ast.DoWhile) -> let old = save_locals ctx in spr ctx "do {"; let bend = open_block ctx in gen_while_expr ctx e; bend(); newline ctx; spr ctx "} while"; gen_value ctx (parent cond); old() | TObjectDecl fields -> spr ctx "_hx_anonymous(array("; concat ctx ", " (fun (f,e) -> print ctx "\"%s\" => " (escape_bin f); gen_value ctx e) fields; spr ctx "))" | TFor (v,it,e) -> let b = save_locals ctx in let tmp = define_local ctx "__hx__it" in let v = define_local ctx v.v_name in (match it.eexpr with | TCall (e,_) -> (match e.eexpr with | TField (e,f) -> spr ctx "if(null == "; gen_value ctx e; spr ctx ") throw new HException('null iterable')"; newline ctx; | _ -> ()); | _ -> () ); print ctx "$%s = " tmp; gen_value ctx it; newline ctx; print ctx "while($%s->hasNext()) {" tmp; let bend = open_block ctx in newline ctx; (* unset loop variable (issue #2900) *) print ctx "unset($%s)" v; newline ctx; print ctx "$%s = $%s->next()" v tmp; gen_while_expr ctx e; bend(); newline ctx; spr ctx "}"; b(); | TTry (e,catchs) -> spr ctx "try "; restore_in_block ctx in_block; gen_expr ctx (mk_block e); let old = save_locals ctx in let ex = define_local ctx "__hx__e" in print ctx "catch(Exception $%s) {" ex; let bend = open_block ctx in let first = ref true in let catchall = ref false in let evar = define_local ctx "_ex_" in newline ctx; print ctx "$%s = ($%s instanceof HException) && $%s->getCode() == null ? $%s->e : $%s" evar ex ex ex ex; old(); List.iter (fun (v,e) -> let ev = define_local ctx v.v_name in newline ctx; let b = save_locals ctx in if not !first then spr ctx "else "; (match follow v.v_type with | TEnum (te,_) -> (match te.e_path with | [], "Bool" -> print ctx "if(is_bool($%s = $%s))" ev evar | _ -> print ctx "if(($%s = $%s) instanceof %s)" ev evar (s_path ctx te.e_path te.e_extern e.epos)); restore_in_block ctx in_block; gen_expr ctx (mk_block e); | TInst (tc,_) -> (match tc.cl_path with | [], "Int" -> print ctx "if(is_int($%s = $%s))" ev evar | [], "Float" -> print ctx "if(is_numeric($%s = $%s))" ev evar | [], "String" -> print ctx "if(is_string($%s = $%s))" ev evar | [], "Array" -> print ctx "if(($%s = $%s) instanceof _hx_array)" ev evar | _ -> print ctx "if(($%s = $%s) instanceof %s)" ev evar (s_path ctx tc.cl_path tc.cl_extern e.epos)); restore_in_block ctx in_block; gen_expr ctx (mk_block e); | TAbstract (ta,_) -> (match ta.a_path with | [], "Int" -> print ctx "if(is_int($%s = $%s))" ev evar | [], "Float" -> print ctx "if(is_numeric($%s = $%s))" ev evar | [], "Bool" -> print ctx "if(is_bool($%s = $%s))" ev evar | _ -> print ctx "if(($%s = $%s) instanceof %s)" ev evar (s_path ctx ta.a_path false e.epos)); restore_in_block ctx in_block; gen_expr ctx (mk_block e); | TFun _ | TLazy _ | TType _ | TAnon _ -> assert false | TMono _ | TDynamic _ -> catchall := true; if not !first then spr ctx "{ "; print ctx "$%s = $%s" ev evar; newline ctx; restore_in_block ctx in_block; gen_expr ctx (mk_block e); if not !first then spr ctx "}" ); b(); first := false; ) catchs; if not !catchall then print ctx " else throw $%s;" ex; bend(); newline ctx; spr ctx "}" | TSwitch (e,cases,def) -> let old_loop = ctx.in_loop in ctx.in_loop <- false; ctx.nested_loops <- ctx.nested_loops + 1; let old = save_locals ctx in spr ctx "switch"; gen_value ctx (parent e); spr ctx " {"; newline ctx; List.iter (fun (el,e2) -> List.iter (fun e -> spr ctx "case "; gen_value ctx e; spr ctx ":"; ) el; restore_in_block ctx in_block; gen_expr ctx (mk_block e2); print ctx "break"; newline ctx; ) cases; (match def with | None -> () | Some e -> spr ctx "default:"; restore_in_block ctx in_block; gen_expr ctx (mk_block e); print ctx "break"; newline ctx; ); spr ctx "}"; ctx.nested_loops <- ctx.nested_loops - 1; ctx.in_loop <- old_loop; old() | TCast (e,None) -> gen_expr ctx e | TCast (e1,Some t) -> 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 spr ctx "_hx_cast("; gen_expr ctx e1; spr ctx ", "; gen_expr ctx (mk (TTypeExpr t) (mk_texpr t) e1.epos); spr ctx ")" and argument_list_from_locals include_this in_var l = let lst = ref [] in if (include_this && in_var) then lst := "__hx__this" :: !lst else if include_this then lst := "this" :: !lst; PMap.iter (fun n _ -> lst := !lst @ [n]; ) l; !lst and remove_internals args = List.filter (fun a -> a = "__hx__this" || not (start_with a "__hx__")) args; and inline_block ctx e = let index = ctx.inline_index in ctx.inline_index <- ctx.inline_index + 1; let block = { iname = (s_path ctx ctx.curclass.cl_path ctx.curclass.cl_extern ctx.curclass.cl_pos) ^ "_" ^ string_of_int index; iindex = index; ihasthis = ctx.in_instance_method; (* param this *) iarguments = []; iexpr = e; ilocals = ctx.locals; iin_block = true; iinv_locals = ctx.inv_locals; } in print ctx "%s(" block.iname; let in_value = (match ctx.in_value with Some _ -> true | _ -> false) in (match remove_internals (argument_list_from_locals ctx.in_instance_method in_value ctx.locals) with | [] -> () | l -> print ctx "$%s" (String.concat ", $" l) ); spr ctx ")"; ctx.inline_methods <- ctx.inline_methods @ [block] and inline_function ctx args hasthis used_args e = let index = ctx.inline_index in ctx.inline_index <- ctx.inline_index + 1; let block = { iname = (s_path ctx ctx.curclass.cl_path ctx.curclass.cl_extern ctx.curclass.cl_pos) ^ "_" ^ string_of_int index; iindex = index; ihasthis = hasthis; (* param this *) iarguments = args; iexpr = e; ilocals = used_args; iin_block = false; iinv_locals = used_args; } in ctx.inline_methods <- ctx.inline_methods @ [block]; block.iname and canbe_ternary_param e = match e.eexpr with | TTypeExpr _ | TConst _ | TLocal _ | TField (_,FEnum _) | TParenthesis _ | TMeta _ | TObjectDecl _ | TArrayDecl _ | TCall _ | TUnop _ | TNew _ | TCast (_, _) | TBlock [_] -> true | TIf (_,e,eelse) -> cangen_ternary e eelse | _ -> false and cangen_ternary e eelse = match eelse with | Some other -> (canbe_ternary_param e) && (canbe_ternary_param other) | _ -> false and gen_value ctx e = match e.eexpr with | TTypeExpr _ | TConst _ | TLocal _ | TArray _ | TBinop _ | TEnumParameter _ | TField _ | TParenthesis _ | TObjectDecl _ | TArrayDecl _ | TCall _ | TUnop _ | TNew _ | TFunction _ -> gen_expr ctx e | TMeta (_,e1) -> gen_value ctx e1 | TBlock [] -> () | TCast (_, Some _) -> gen_expr ctx e | TCast (e, None) | TBlock [e] -> gen_value ctx e | TIf (cond,e,eelse) when (cangen_ternary e eelse) -> spr ctx "("; gen_value ctx cond; spr ctx " ? "; gen_value ctx e; (match eelse with | Some e -> spr ctx " : "; gen_value ctx e | _ ->()); spr ctx ")"; (* | TIf (cond,e,eelse) -> spr ctx "if"; gen_value ctx (parent cond); spr ctx " "; restore_in_block ctx in_block; gen_expr ctx (mk_block e); (match eelse with | None -> () | Some e when e.eexpr = TConst(TNull) -> () | Some e -> spr ctx " else "; restore_in_block ctx in_block; gen_expr ctx (mk_block e)); *) | TBlock _ | TBreak | TContinue | TVar _ | TReturn _ | TWhile _ | TThrow _ | TSwitch _ | TFor _ | TIf _ | TTry _ -> inline_block ctx e let rec is_instance_method_defined cls m = if PMap.exists m cls.cl_fields then true else match cls.cl_super with | Some (scls, _) -> is_instance_method_defined scls m | None -> false let is_method_defined ctx m static = if static then PMap.exists m ctx.curclass.cl_statics else is_instance_method_defined ctx.curclass m let generate_self_method ctx rights m static setter = if setter then ( if static then print ctx "%s function %s($v) { return call_user_func(self::$%s, $v); }" rights (s_ident m) (s_ident m) else print ctx "%s function %s($v) { return call_user_func($this->%s, $v); }" rights (s_ident m) (s_ident m) ) else ( if static then print ctx "%s function %s() { return call_user_func(self::$%s); }" rights (s_ident m) (s_ident m) else print ctx "%s function %s() { return call_user_func($this->%s); }" rights (s_ident m) (s_ident m) ); newline ctx let gen_assigned_value ctx eo = match eo with | Some ({eexpr = TConst _} as e) -> print ctx " = "; gen_value ctx e | _ -> () let generate_field ctx static f = if not (is_extern_field f) then newline ctx; ctx.locals <- PMap.empty; ctx.inv_locals <- PMap.empty; ctx.in_instance_method <- not static; let rights = if static then "static" else "public" in let p = ctx.curclass.cl_pos in match f.cf_expr with | Some { eexpr = TFunction fd } -> if f.cf_name = "__construct" then ctx.curmethod <- "new" else ctx.curmethod <- f.cf_name; spr ctx (rights ^ " "); if is_dynamic_method f then gen_dynamic_function ctx static (s_ident f.cf_name) fd f.cf_params p else gen_function ctx (s_ident f.cf_name) fd f.cf_params p | _ -> if (is_extern_field f) then () else if ctx.curclass.cl_interface then match follow f.cf_type, f.cf_kind with | TFun (args,r), Method _ -> print ctx "function %s(" (s_ident f.cf_name); concat ctx ", " (fun (arg,o,t) -> s_funarg ctx arg t p o; ) args; print ctx ")"; | _ -> spr ctx "//"; () else if (match f.cf_kind with | Var v -> (match v.v_read, v.v_write with | AccCall, AccCall -> let m1 = "get_" ^ f.cf_name in let m2 = "set_" ^ f.cf_name in if not (is_method_defined ctx m1 static) then ( generate_self_method ctx rights m1 static false; print ctx "%s $%s" rights (s_ident m1); if not (is_method_defined ctx m2 static) then newline ctx); if not (is_method_defined ctx m2 static) then ( generate_self_method ctx rights m2 static true; print ctx "%s $%s" rights (s_ident m2); newline ctx); false | AccCall, _ -> let m = "get_" ^ f.cf_name in if not (is_method_defined ctx m static) then generate_self_method ctx rights m static false; print ctx "%s $%s" rights (s_ident f.cf_name); gen_assigned_value ctx f.cf_expr; true | _, AccCall -> let m = "set_" ^ f.cf_name in if not (is_method_defined ctx m static) then generate_self_method ctx rights m static true; print ctx "%s $%s" rights (s_ident f.cf_name); gen_assigned_value ctx f.cf_expr; true | _ -> false) | _ -> false) then () else begin let name = if static then s_ident f.cf_name else f.cf_name in if static then (match f.cf_kind with | Var _ -> (match follow f.cf_type with | TFun _ | TDynamic _ -> print ctx "static function %s() { $args = func_get_args(); return call_user_func_array(self::$%s, $args); }" name name; newline ctx; | _ -> () ) | _ -> () ); print ctx "%s $%s" rights name; gen_assigned_value ctx f.cf_expr end let generate_static_field_assign ctx path f = let p = ctx.curclass.cl_pos in if not ctx.curclass.cl_interface then (match f.cf_expr with | None -> () | Some e -> match e.eexpr with | TConst _ -> () | TFunction fd -> (match f.cf_kind with | Var _ when (match follow f.cf_type with | TFun _ | TDynamic _ -> true; | _ -> false) -> newline ctx; print ctx "%s::$%s = " (s_path ctx path false p) (s_ident f.cf_name); gen_value ctx e | Method MethDynamic -> newline ctx; print ctx "%s::$%s = " (s_path ctx path false p) (s_ident f.cf_name); gen_value ctx e | _ -> ()) | _ when is_extern_field f -> () | _ -> newline ctx; print ctx "%s::$%s = " (s_path ctx path false p) (s_ident f.cf_name); gen_value ctx e) let rec super_has_dynamic c = match c.cl_super with | None -> false | Some (csup, _) -> (match csup.cl_dynamic with | Some _ -> true | _ -> super_has_dynamic csup) let generate_inline_method ctx c m = (match ctx.inline_methods with | [] -> () | h :: t -> ctx.inline_methods <- t ); ctx.curclass <- c; let old = save_locals ctx in ctx.in_value <- Some m.iname; ctx.in_block <- m.iin_block; ctx.in_loop <- false; ctx.locals <- m.ilocals; ctx.inv_locals <- m.iinv_locals; newline ctx; print ctx "function %s(" m.iname; (* arguments *) let in_value = (match ctx.in_value with Some _ -> true | _ -> false) in let arguments = remove_internals (argument_list_from_locals m.ihasthis in_value ctx.locals) in let arguments = match arguments with | [h] when h = "this" -> ["__hx__this"] | h :: t when h = "this" -> "__hx__this" :: t | _ -> arguments in let marguments = List.map (define_local ctx) m.iarguments in let arguments = (List.map (fun a -> "&$" ^ a) arguments) @ (List.map (fun a -> "$" ^ a) marguments) in (match arguments with | [] -> () | l -> spr ctx (String.concat ", " arguments) ); spr ctx ") {"; ctx.nested_loops <- ctx.nested_loops - 1; let block = open_block ctx in newline ctx; gen_expr ctx m.iexpr; block(); old(); ctx.nested_loops <- ctx.nested_loops + 1; newline ctx; spr ctx "}" let generate_class ctx c = let requires_constructor = ref true in ctx.curclass <- c; ctx.local_types <- List.map snd c.cl_params; print ctx "%s %s " (if c.cl_interface then "interface" else "class") (s_path ctx c.cl_path c.cl_extern c.cl_pos); (match c.cl_super with | None -> () | Some (csup,_) -> requires_constructor := false; print ctx "extends %s " (s_path ctx csup.cl_path csup.cl_extern c.cl_pos)); (* Do not add interfaces which are implemented through other interfaces inheritance *) let unique = List.filter (fun (iface, _) -> not (List.exists (fun (probably_descendant, _) -> if probably_descendant == iface then false else is_parent iface probably_descendant ) c.cl_implements ) ) c.cl_implements in let implements = ExtList.List.unique ~cmp:(fun a b -> (fst a).cl_path = (fst b).cl_path) unique in (match implements with | [] -> () | l -> spr ctx (if c.cl_interface then "extends " else "implements "); concat ctx ", " (fun (i,_) -> print ctx "%s" (s_path ctx i.cl_path i.cl_extern c.cl_pos)) l); spr ctx "{"; let get_dynamic_methods = List.filter is_dynamic_method c.cl_ordered_fields in if not ctx.curclass.cl_interface then ctx.dynamic_methods <- get_dynamic_methods; let cl = open_block ctx in (match c.cl_constructor with | None -> if !requires_constructor && not c.cl_interface then begin newline ctx; spr ctx "public function __construct(){}" end; | Some f -> let f = { f with cf_name = "__construct"; cf_public = true; } in ctx.constructor_block <- true; generate_field ctx false f; ctx.constructor_block <- false; ); List.iter (generate_field ctx false) c.cl_ordered_fields; (match c.cl_dynamic with | Some _ when not c.cl_interface && not (super_has_dynamic c) -> newline ctx; spr ctx "public $__dynamics = array();\n\tpublic function __get($n) {\n\t\tif(isset($this->__dynamics[$n]))\n\t\t\treturn $this->__dynamics[$n];\n\t}\n\tpublic function __set($n, $v) {\n\t\t$this->__dynamics[$n] = $v;\n\t}\n\tpublic function __call($n, $a) {\n\t\tif(isset($this->__dynamics[$n]) && is_callable($this->__dynamics[$n]))\n\t\t\treturn call_user_func_array($this->__dynamics[$n], $a);\n\t\tif('toString' == $n)\n\t\t\treturn $this->__toString();\n\t\tthrow new HException(\"Unable to call <\".$n.\">\");\n\t}" | Some _ | _ -> if List.length ctx.dynamic_methods > 0 then begin newline ctx; spr ctx "public function __call($m, $a) {\n\t\tif(isset($this->$m) && is_callable($this->$m))\n\t\t\treturn call_user_func_array($this->$m, $a);\n\t\telse if(isset($this->__dynamics[$m]) && is_callable($this->__dynamics[$m]))\n\t\t\treturn call_user_func_array($this->__dynamics[$m], $a);\n\t\telse if('toString' == $m)\n\t\t\treturn $this->__toString();\n\t\telse\n\t\t\tthrow new HException('Unable to call <'.$m.'>');\n\t}"; end; ); List.iter (generate_field ctx true) c.cl_ordered_statics; let gen_props props = String.concat "," (List.map (fun (p,v) -> "\"" ^ p ^ "\" => \"" ^ v ^ "\"") props) in let rec fields c = let list = Codegen.get_properties (c.cl_ordered_statics @ c.cl_ordered_fields) in match c.cl_super with | Some (csup, _) -> list @ fields csup | None -> list in if not c.cl_interface then (match fields c with | [] -> () | props -> newline ctx; print ctx "static $__properties__ = array(%s)" (gen_props props); ); cl(); newline ctx; if PMap.exists "__toString" c.cl_fields then () else if PMap.exists "toString" c.cl_fields && (not c.cl_interface) && (not c.cl_extern) then begin print ctx "\tfunction __toString() { return $this->toString(); }"; newline ctx end else if (not c.cl_interface) && (not c.cl_extern) then begin print ctx "\tfunction __toString() { return '%s'; }" (s_path_haxe c.cl_path) ; newline ctx end; print ctx "}" let createmain com e = let filename = match com.php_front with None -> "index.php" | Some n -> n in let ctx = { com = com; stack = stack_init com false; tabs = ""; ch = open_out (com.file ^ "/" ^ filename); path = ([], ""); buf = Buffer.create (1 lsl 14); in_value = None; in_loop = false; in_instance_method = false; imports = Hashtbl.create 0; extern_required_paths = []; extern_classes_with_init = []; curclass = null_class; curmethod = ""; locals = PMap.empty; inv_locals = PMap.empty; local_types = []; inits = []; constructor_block = false; dynamic_methods = []; all_dynamic_methods = []; is_call = false; cwd = ""; inline_methods = []; nested_loops = 0; inline_index = 0; in_block = false; lib_path = match com.php_lib with None -> "lib" | Some s -> s; } in spr ctx "if(version_compare(PHP_VERSION, '5.1.0', '<')) { exit('Your current PHP version is: ' . PHP_VERSION . '. Haxe/PHP generates code for version 5.1.0 or later'); } else if(version_compare(PHP_VERSION, '5.4.0', '<')) { trigger_error('Your current PHP version is: ' . PHP_VERSION . '. Code generated by Haxe/PHP might not work for versions < 5.4.0', E_USER_WARNING); }"; newline ctx; newline ctx; spr ctx ("require_once dirname(__FILE__).'/" ^ ctx.lib_path ^ "/php/" ^ (prefix_class com "Boot.class.php';\n\n")); gen_expr ctx e; newline ctx; spr ctx "\n?>"; close ctx let generate_main ctx c = (match c.cl_ordered_statics with | [{ cf_expr = Some e }] -> gen_value ctx e; | _ -> assert false); newline ctx let generate_enum ctx e = ctx.local_types <- List.map snd e.e_params; let pack = open_block ctx in let ename = s_path ctx e.e_path e.e_extern e.e_pos in print ctx "class %s extends Enum {" ename; PMap.iter (fun _ c -> newline ctx; match c.ef_type with | TFun (args,_) -> print ctx "public static function %s($" (s_ident c.ef_name); concat ctx ", $" (fun (a,o,t) -> spr ctx a; if o then spr ctx " = null"; ) args; spr ctx ") {"; print ctx " return new %s(\"%s\", %d, array($" ename (s_ident c.ef_name) c.ef_index; concat ctx ", $" (fun (a,_,_) -> spr ctx a) args; print ctx ")); }"; | _ -> print ctx "public static $%s" (s_ident c.ef_name); ) e.e_constrs; newline ctx; spr ctx "public static $__constructors = array("; let first = ref true in PMap.iter (fun _ c -> if not !first then spr ctx ", "; print ctx "%d => '%s'" c.ef_index (s_ident c.ef_name); first := false; ) e.e_constrs; spr ctx ")"; newline ctx; (match Codegen.build_metadata ctx.com (TEnumDecl e) with | None -> () | Some _ -> spr ctx "public static $__meta__"; newline ctx); pack(); print ctx "}"; PMap.iter (fun _ c -> match c.ef_type with | TFun (args,_) -> (); | _ -> newline ctx; print ctx "%s::$%s = new %s(\"%s\", %d)" ename (s_ident c.ef_name) ename c.ef_name c.ef_index; ) e.e_constrs; newline ctx; match Codegen.build_metadata ctx.com (TEnumDecl e) with | None -> () | Some e -> print ctx "%s::$__meta__ = " ename; gen_expr ctx e; newline ctx let generate com = let all_dynamic_methods = ref [] in let extern_classes_with_init = ref [] in let php_lib_path = (match com.php_lib with None -> "lib" | Some n -> n) in create_directory com (Str.split (Str.regexp "/") php_lib_path); (* check for methods with the same name but different case *) let check_class_fields c = let lc_names = ref [] in let special_cases = ["toString"] in let loop c lst static = let in_special_cases name = (List.exists (fun n -> String.lowercase n = name) (special_cases @ List.map (fun f -> f.cf_name) c.cl_overrides)) in List.iter(fun cf -> let name = String.lowercase cf.cf_name in let prefixed_name s = (if s then "s_" else "i_") ^ name in match cf.cf_kind, cf.cf_expr with | (Method _, Some e) when not (in_special_cases name) -> (try let lc = List.find (fun n -> let n = snd n in if static then (n = (prefixed_name false)) else ((n = (prefixed_name false)) || (n = (prefixed_name true))) ) !lc_names in unsupported ("method '" ^ (Globals.s_type_path c.cl_path) ^ "." ^ cf.cf_name ^ "' already exists here '" ^ (fst lc) ^ "' (different case?)") c.cl_pos with Not_found -> lc_names := ((Globals.s_type_path c.cl_path) ^ "." ^ cf.cf_name, prefixed_name static) :: !lc_names) | _ -> () ) lst in let rec _check_class_fields cl = (match cl.cl_super with | Some (s,_) -> _check_class_fields s | _ -> ()); loop cl cl.cl_ordered_statics true; loop cl cl.cl_ordered_fields false in _check_class_fields c in List.iter (fun t -> (match t with | TClassDecl c -> check_class_fields c | TEnumDecl e -> let e_names = ref [] in List.iter(fun en -> ( if List.exists (fun n -> n = String.lowercase en) !e_names then unsupported ("'" ^ en ^ "' constructor exists with different case") e.e_pos else e_names := (String.lowercase en) :: !e_names )) (e.e_names) | _ -> ()) ) com.types; List.iter (fun t -> (match t with | TClassDecl c -> let dynamic_methods_names lst = List.map (fun fd -> { mpath = c.cl_path; mname = fd.cf_name; }) (List.filter is_dynamic_method lst) in all_dynamic_methods := dynamic_methods_names c.cl_ordered_fields @ !all_dynamic_methods; if c.cl_extern then (match c.cl_init with | Some _ -> extern_classes_with_init := c.cl_path :: !extern_classes_with_init; | _ -> ()) else all_dynamic_methods := dynamic_methods_names c.cl_ordered_statics @ !all_dynamic_methods; | _ -> ()) ) com.types; List.iter (Codegen.fix_abstract_inheritance com) com.types; List.iter (fun t -> (match t with | TClassDecl c -> if c.cl_extern then begin (match c.cl_init with | None -> () | Some e -> let ctx = init com php_lib_path c.cl_path 3 in gen_expr ctx e; newline ctx; close ctx; ); end else let ctx = init com php_lib_path c.cl_path (if c.cl_interface then 2 else 0) in ctx.extern_classes_with_init <- !extern_classes_with_init; ctx.all_dynamic_methods <- !all_dynamic_methods; generate_class ctx c; (match c.cl_init with | None -> () | Some e -> newline ctx; gen_expr ctx e); List.iter (generate_static_field_assign ctx c.cl_path) c.cl_ordered_statics; if c.cl_path = (["php"], "Boot") && com.debug then begin newline ctx; print ctx "$%s = new _hx_array(array())" ctx.stack.Codegen.stack_var; newline ctx; print ctx "$%s = new _hx_array(array())" ctx.stack.Codegen.stack_exc_var; end; let rec loop l = match l with | [] -> () | h :: _ -> generate_inline_method ctx c h; loop ctx.inline_methods in loop ctx.inline_methods; newline ctx; close ctx | TEnumDecl e -> if e.e_extern then () else let ctx = init com php_lib_path e.e_path 1 in generate_enum ctx e; close ctx | TTypeDecl _ | TAbstractDecl _ -> ()); ) com.types; (match com.main with | None -> () | Some e -> createmain com e); Hashtbl.iter (fun name data -> write_resource com.file name data ) com.resources; haxe_3.4.4.orig/src/generators/genphp7.ml0000664000175000017500000035703413166552354020272 0ustar andyandy00000000000000(** Compatible with PHP 7+ *) open Ast open Type open Common open Meta open Globals open Sourcemaps let debug = ref false (** Do not add comments with Haxe positions before each line of generated php code *) let skip_line_directives = ref false (** Escape string for constant strings generation. Copy-pasted from genphp. *) let escape_bin s = let b = Buffer.create 0 in for i = 0 to String.length s - 1 do match Char.code (String.unsafe_get s i) with | c when c = Char.code('\\') || c = Char.code('"') || c = Char.code('$') -> Buffer.add_string b "\\"; Buffer.add_char b (Char.chr c) | c when c < 32 -> Buffer.add_string b (Printf.sprintf "\\x%.2X" c) | c -> Buffer.add_char b (Char.chr c) done; Buffer.contents b (** Write resources passed to compiler via `-resource` flag Copy-pasted from genphp *) let write_resource dir name data = let rdir = dir ^ "/res" in if not (Sys.file_exists dir) then Unix.mkdir dir 0o755; if not (Sys.file_exists rdir) then Unix.mkdir rdir 0o755; let name = Codegen.escape_res_name name false in let ch = open_out_bin (rdir ^ "/" ^ name) in output_string ch data; close_out ch (** Get list of keys in Hashtbl *) let hashtbl_keys tbl = Hashtbl.fold (fun key _ lst -> key :: lst) tbl [] (** @return List of items in `list1` which `list2` does not contain *) let diff_lists list1 list2 = List.filter (fun x -> not (List.mem x list2)) list1 (** Type path for native PHP Exception class *) let native_exception_path = ([], "Throwable") (** Type path for Haxe exceptions wrapper *) let hxexception_type_path = (["php"; "_Boot"], "HxException") (** Type path of `php.Boot` *) let boot_type_path = (["php"], "Boot") (** Type path of the base class for all enums: `php.Boot.HxEnum` *) let hxenum_type_path = (["php"; "_Boot"], "HxEnum") (** Type path of the implementation class for `Class` *) let hxclass_type_path = (["php"; "_Boot"], "HxClass") (** Type path of the implementation class for `String` *) let hxstring_type_path = (["php"; "_Boot"], "HxString") (** Type path of the special implementation class for `String` which is used when Dynamic value is suspected to be a string *) let hxdynamicstr_type_path = (["php"; "_Boot"], "HxDynamicStr") (** Type path of the implementation class for anonymous objects *) let hxanon_type_path = (["php"; "_Boot"], "HxAnon") (** Type path of the implementation class for closures *) let hxclosure_type_path = (["php"; "_Boot"], "HxClosure") (** Type path for special PHP extern class to support specific language expressions *) let syntax_type_path = (["php"], "Syntax") (** Special abstract which enables passing function arguments and return value by reference *) let ref_type_path = (["php"], "Ref") (** Type path of the implementation class for `Array` *) let array_type_path = ([], "Array") (** Type path of the implementation class for `Array` *) let native_array_type_path = (["php"], "NativeArray") (** Type path of the `Void` *) let void_type_path = ([], "Void") (** Type path of the `Bool` *) let bool_type_path = ([], "Bool") (** Type path of the `Std` *) let std_type_path = ([], "Std") (** Stub to use when you need a `Ast.pos` instance, but don't have one *) let dummy_pos = { pfile = ""; pmin = 0; pmax = 0 } (** Check if specified string is a reserved word in PHP *) let is_keyword str = match String.lowercase str with | "__halt_compiler" | "abstract" | "and" | "array" | "as" | "break" | "callable" | "case" | "catch" | "class" | "clone" | "const" | "continue" | "declare" | "default" | "die" | "do" | "echo" | "else" | "elseif" | "empty" | "enddeclare" | "endfor" | "endforeach" | "endif" | "endswitch" | "endwhile" | "eval" | "exit" | "extends" | "final" | "finally" | "for" | "foreach" | "function" | "global" | "goto" | "if" | "implements" | "include" | "include_once" | "instanceof" | "insteadof" | "interface" | "isset" | "list" | "namespace" | "new" | "or" | "print" | "private" | "protected" | "public" | "require" | "require_once" | "return" | "static" | "switch" | "throw" | "trait" | "try" | "unset" | "use" | "var" | "while" | "xor" | "yield" | "__class__" | "__dir__" | "__file__" | "__function__" | "__line__" | "__method__" | "__trait__" | "__namespace__" | "int" | "float" | "bool" | "string" | "true" | "false" | "null" | "parent" | "void" | "iterable" -> true | _ -> false (** Check if specified type is Void *) let is_void_type t = match follow t with TAbstract ({ a_path = void_type_path }, _) -> true | _ -> false (** Check if specified type is Bool *) let is_bool_type t = match follow t with TAbstract ({ a_path = bool_type_path }, _) -> true | _ -> false (** Check if specified type is php.NativeArray *) let is_native_array_type t = match follow t with TAbstract ({ a_path = native_array_type_path }, _) -> true | _ -> false (** If `name` is not a reserved word in PHP then `name` is returned as-is. Otherwise this method returns another string, which can be used instead of `name` *) let get_real_name name = if is_keyword name then name ^ "_hx" else name (** If `path` contains some reserved in PHP words, they will be replaced with allowed words. *) let get_real_path path = List.map get_real_name path (** Resolve real type (bypass abstracts and typedefs) *) let rec follow = Abstract.follow_with_abstracts let prefix = ref None (** Returns value of `--php-prefix` compiler flag *) let get_php_prefix ctx = match !prefix with | Some prefix -> prefix | None -> let lst = match ctx.php_prefix with | None -> [] | Some str -> if String.length str = 0 then [] else Str.split (Str.regexp "\\.") str in prefix := Some lst; lst (** Adds packages specified by `--php-prefix` to `type_path`. E.g. if `--php-prefix some.sub` and `type_path` is `(["pack"], "MyClass")`, then this function will return `(["some", "sub", "pack"], "MyClass")` *) let add_php_prefix ctx type_path = match type_path with | (pack, name) -> ((get_php_prefix ctx) @ pack, name) (** If `expr` is a TCast or TMeta, then returns underlying expression (recursively bypassing nested casts). Otherwise returns `expr` as is. *) let rec reveal_expr expr = match expr.eexpr with | TCast (e, _) -> reveal_expr e | TMeta (_, e) -> reveal_expr e | _ -> expr (** If `expr` is a TCast or TMeta or TParenthesis, then returns underlying expression (recursively bypassing nested casts and parenthesis). Otherwise returns `expr` as is. *) let rec reveal_expr_with_parenthesis expr = match expr.eexpr with | TCast (e, _) -> reveal_expr_with_parenthesis e | TMeta (_, e) -> reveal_expr_with_parenthesis e | TParenthesis e -> reveal_expr_with_parenthesis e | _ -> expr (** Get string representation of specified position in Haxe code. *) let stringify_pos pos = Lexer.get_error_pos (Printf.sprintf "%s:%d:") pos (** @return Error message with position information *) let error_message pos message = (stringify_pos pos) ^ ": " ^ message (** Terminates compiler process and prints user-friendly instructions about filing an issue in compiler repo. *) let fail hxpos mlpos = match mlpos with | (file, line, _) -> Printf.printf "%s\n" (error_message hxpos "Unexpected expression. Please submit an issue with expression example and following information:"); Printf.printf "%s:%d\n" file line; assert false (** Print compilation error message and abort compilation process. *) let error_and_exit pos message = Printf.printf "%s" (error_message pos message); exit 1 (** Check if `target` is a `Dynamic` type *) let rec is_dynamic_type (target:Type.t) = match follow target with TDynamic _ -> true | _ -> false (** Check if `target` is `php.Ref` *) let is_ref (target:Type.t) = match target with TType ({ t_path = type_path }, _) -> type_path = ref_type_path | _ -> false (** Check if `field` is a `dynamic function` *) let rec is_dynamic_method (field:tclass_field) = match field.cf_kind with | Method MethDynamic -> true | _ -> false (** Check if specified expression is of `Dynamic` type *) let is_dynamic expr = is_dynamic_type expr.etype (** Check if specified expression is of `Int` type *) let is_int expr = match follow expr.etype with TAbstract ({ a_path = ([], "Int") }, _) -> true | _ -> false (** Check if specified expression is of `Float` type *) let is_float expr = match follow expr.etype with TAbstract ({ a_path = ([], "Float") }, _) -> true | _ -> false (** Check if specified type is String *) let is_string_type t = match follow t with TInst ({ cl_path = ([], "String") }, _) -> true | _ -> false (** Check if specified expression is of String type *) let is_string expr = is_string_type expr.etype (** Check if `expr` is an access to a method of special `php.PHP` class *) let is_lang_extern expr = match expr.eexpr with | TField ({ eexpr = TTypeExpr (TClassDecl { cl_path = path }) }, _) when path = syntax_type_path -> true | _ -> false (** Check if specified type is actually a generic parameter *) let is_generic_parameter (target:Type.t) = match follow target with | TInst ({ cl_kind = KTypeParameter _ }, _) -> true | _ -> false (** Check if `target` type cannot be clarified on compilation *) let is_unknown_type (target:Type.t) = is_dynamic_type target || is_generic_parameter target (** @return `Type.t` instance for `Void` *) let void = ref None let get_void ctx : Type.t = match !void with | Some value -> value | None -> let find com_type = match com_type with | TAbstractDecl ({ a_path = ([], "Void") } as abstr) -> void := Some (TAbstract (abstr, [])); | _ -> () in List.iter find ctx.types; match !void with | Some value -> value | None -> fail dummy_pos (try assert false with Assert_failure mlpos -> mlpos) (** @return `tclass` instance for `php.Boot` *) let boot = ref None let get_boot ctx : tclass = match !boot with | Some value -> value | None -> let find com_type = match com_type with | TClassDecl ({ cl_path = path } as cls) when path = boot_type_path -> boot := Some cls; | _ -> () in List.iter find ctx.types; match !boot with | Some value -> value | None -> fail dummy_pos (try assert false with Assert_failure mlpos -> mlpos) (** @return `expr` wrapped in parenthesis *) let parenthesis expr = {eexpr = TParenthesis expr; etype = expr.etype; epos = expr.epos} (** Check if `current` binary should be surrounded with parenthesis *) let need_parenthesis_for_binop current parent = if current = parent then false else match (current, parent) with | (_, OpAssign) -> false | (_, OpAssignOp _) -> false | (OpAdd, OpSub) -> false | (OpSub, OpAdd) -> false | (OpMult, OpDiv) -> false | (OpDiv, OpMult) -> false | (OpMult, OpAdd) -> false | (OpMult, OpSub) -> false | (OpDiv, OpAdd) -> false | (OpDiv, OpSub) -> false | _ -> true (** Check if specified expression may require dereferencing if used as "temporary expression" *) let needs_dereferencing for_assignment expr = let rec is_create target_expr = match (reveal_expr target_expr).eexpr with | TParenthesis e -> is_create e | TCast (e, _) -> is_create e | TNew _ -> for_assignment | TArrayDecl _ -> for_assignment | TObjectDecl _ -> for_assignment | TConst TNull -> true | TIf _ -> true (* some of `php.Syntax` methods *) | TCall ({ eexpr = TField (_, FStatic ({ cl_path = syntax_type_path }, { cf_name = name })) }, _) -> (match name with | "binop" | "object" | "array" -> for_assignment | _ -> false ) | _ -> false in match (reveal_expr expr).eexpr with | TField (target_expr, _) -> is_create target_expr | TArray (target_expr, _) -> is_create target_expr | _ -> false (** @return (arguments_list, return_type) *) let get_function_signature (field:tclass_field) : (string * bool * Type.t) list * Type.t = match follow field.cf_type with | TFun (args, return_type) -> (args, return_type) | _ -> fail field.cf_pos (try assert false with Assert_failure mlpos -> mlpos) (** Check if `target` is 100% guaranteed to be a scalar type in PHP. Inversion of `is_sure_scalar` does not guarantee `target` is not scalar. *) let is_sure_scalar (target:Type.t) = match follow target with | TInst ({ cl_path = ([], "String") }, _) -> true | TAbstract (abstr, _) -> (match abstr.a_path with | ([],"Int") -> true | ([],"Float") -> true | ([],"Bool") -> true | _ -> false ) | _ -> false (** Indicates if `expr` is guaranteed to be an access to a `var` field. *) let is_sure_var_field_access expr = match (reveal_expr expr).eexpr with | TField (_, FStatic (_, { cf_kind = Var _ })) -> true | TField (_, FInstance (_, _, { cf_kind = Var _ })) -> true (* | TField (_, FAnon { cf_kind = Var _ }) -> true *) (* Sometimes we get anon access to non-anonymous objects *) | _ -> false (** Check if specified unary operation modifies value in place *) let is_modifying_unop op = match op with | Increment | Decrement -> true | _ -> false (** Check if specified binary operation contains assignment *) let is_assignment_binop op = match op with | OpAssign | OpAssignOp _ -> true | _ -> false (** Indicates whether `expr` is a field access which should be generated as global namespace function *) let is_php_global expr = match expr.eexpr with | TField (_, FStatic ({ cl_extern = true; cl_meta = meta }, _)) -> Meta.has Meta.PhpGlobal meta | _ -> false (** Indicates whether `expr` is a field access which should be generated as class constant access *) let is_php_class_const expr = match expr.eexpr with | TField (_, FStatic ({ cl_extern = true }, { cf_meta = meta; cf_kind = Var _ })) -> Meta.has Meta.PhpClassConst meta | _ -> false (** Check if specified enum constructor has arguments *) let is_enum_constructor_with_args (constructor:tenum_field) = match follow constructor.ef_type with | TFun _ -> true | _ -> false (** Check if `target` is 100% guaranteed to be or extend an extern class. Inversion of `sure_extends_extern` does not guarantee `target` does not extend an extern class. *) let rec sure_extends_extern (target:Type.t) = match follow target with | TInst ({ cl_path = ([], "String") }, _) -> false | TInst ({ cl_extern = true }, _) -> true | TInst ({ cl_super = Some (tsuper, params) }, _) -> sure_extends_extern (TInst (tsuper,params)) | _ -> false (** @return `opt` value or `default` if `opt` is None *) let get_option_value (opt:'a option) default = match opt with | None -> default | Some value -> value (** @param path Something like [ "/some/path/first_dir_to_create"; "nested_level1"; "nested_level2" ] @return String representation of created path (E.g. "/some/path/first_dir_to_create/nested_level1/nested_level2") *) let create_dir_recursive (path:string list) = let rec create dir nested_dirs = if not (Sys.file_exists dir) then (Unix.mkdir dir 0o755); match nested_dirs with | [] -> (); | next :: rest -> create (dir ^ "/" ^ next) rest in match path with | [] -> ""; | root :: rest -> create root rest; (String.concat "/" path) (** @return String representation of specified type path. E.g. returns "\example\Test" for (["example"], "Test") *) let get_full_type_name ?escape ?omit_first_slash (type_path:path) = let name = match type_path with | (module_path, type_name) -> let parts = match omit_first_slash with | Some true -> get_real_path module_path | _ -> "" :: get_real_path module_path in (String.concat "\\" parts) ^ "\\" ^ type_name in match escape with | Some true -> String.escaped name | _ -> name (** Check if `target` is or implements native PHP `Throwable` interface *) let rec is_native_exception (target:Type.t) = match follow target with | TInst ({ cl_path = path }, _) when path = native_exception_path -> true | TInst ({ cl_super = parent ; cl_implements = interfaces ; cl_path = path }, _) -> let (parent, params) = match parent with | Some (parent, params) -> (Some parent, params) | None -> (None, []) in let found = ref false in List.iter (fun (cls, params) -> if not !found then found := is_native_exception (TInst (cls, params)) ) interfaces; if !found then true else (match parent with | Some parent -> is_native_exception (TInst (parent, params)) | None -> false ) | _ -> false (** @return Short type name. E.g. returns "Test" for (["example"], "Test") *) let get_type_name (type_path:path) = match type_path with (_, type_name) -> type_name (** @return E.g. returns ["example"] for (["example"], "Test") *) let get_module_path (type_path:path) = match type_path with (module_path, _) -> module_path (** @return PHP visibility keyword. *) let get_visibility (meta:metadata) = if Meta.has Meta.Protected meta then "protected" else "public" (** Writes arguments list to output buffer *) let rec write_args (str_writer:string->unit) arg_writer (args:'a list) = match args with | [] -> () | [arg] -> arg_writer arg | arg :: rest -> arg_writer arg; str_writer ", "; write_args str_writer arg_writer rest (** Check if specified field is a var with non-constant expression *) let is_var_with_nonconstant_expr (field:tclass_field) = match field.cf_kind with | Var _ -> (match field.cf_expr with | None -> false | Some ({eexpr = TConst _ }) -> false | Some _ -> true ) | Method _ -> false (** Check if specified field is an `inline var` field. *) let is_inline_var (field:tclass_field) = match field.cf_kind with | Var { v_read = AccInline; v_write = AccNever } -> true | _ -> false (** @return New TBlock expression which is composed of setting default values for optional arguments and function body. *) let inject_defaults (ctx:Common.context) (func:tfunc) = let rec inject args body_exprs = match args with | [] -> body_exprs | (_, None) :: rest -> inject rest body_exprs | (_, Some TNull) :: rest -> inject rest body_exprs | (var, Some const) :: rest -> let expr = Codegen.set_default ctx var const func.tf_expr.epos in expr :: (inject rest body_exprs) in let exprs = match func.tf_expr.eexpr with | TBlock exprs -> inject func.tf_args exprs | _ -> inject func.tf_args [ func.tf_expr ] in { eexpr = TBlock exprs; etype = follow func.tf_expr.etype; epos = func.tf_expr.epos; } (** Check if `expr` is a constant string *) let is_constant_string expr = match expr.eexpr with | TConst (TString _) -> true | _ -> false (** Check if `expr` is a constant null *) let is_constant_null expr = match expr.eexpr with | TConst TNull -> true | _ -> false (** Check if `expr` is a constant *) let is_constant expr = match expr.eexpr with | TConst _ -> true | _ -> false (** Check if `expr` is a concatenation *) let is_concatenation expr = match expr.eexpr with | TBinop (OpAdd, expr1, expr2) -> (is_string expr1) || (is_string expr2) | _ -> false (** Check if provided expression is a block of expressions *) let is_block expr = match expr.eexpr with TBlock _ -> true | _ -> false (** Check if provided expression is a binary operation *) let is_binop expr = match expr.eexpr with TBinop _ -> true | _ -> false (** Check if provided expression is an assignment binary operation *) let is_binop_assign expr = match expr.eexpr with | TBinop (operation, _, _) -> (match operation with | OpAssign | OpAssignOp _ -> true | _ -> false ) | _ -> false (** Check if specified expression is field access or array access *) let is_access expr = match expr.eexpr with | TField _ | TArray _ -> true | _ -> false (** Indicates if `expr` is actually a call to Haxe->PHP magic function @see http://old.haxe.org/doc/advanced/magic#php-magic *) let is_magic expr = match expr.eexpr with | TCall ({ eexpr = TLocal { v_name = name }}, _) -> (match name with | "__php__" -> true | "__call__" -> true | "__physeq__" -> true | "__var__" -> true | _ -> false ) | _ -> false (** Check if `expr1` and `expr2` can be reliably checked for equality only with `Boot.equal()` *) let need_boot_equal expr1 expr2 = if is_constant_null expr1 || is_constant_null expr2 then false else (is_int expr1 && (is_float expr2 || is_unknown_type expr2.etype)) || (is_float expr1 && (is_float expr2 || is_int expr2 || is_unknown_type expr2.etype)) || (is_unknown_type expr1.etype && (is_int expr2 || is_float expr2)) || (is_unknown_type expr1.etype && is_unknown_type expr2.etype) (** Adds `return` expression to block if it does not have one already *) let ensure_return_in_block block_expr = match block_expr.eexpr with | TBlock [] -> fail block_expr.epos (try assert false with Assert_failure mlpos -> mlpos) | TBlock exprs -> let reversed = List.rev exprs in let last_expr = List.hd reversed in let return_expr = { last_expr with eexpr = TReturn (Some last_expr) } in let reversed = return_expr::(List.tl reversed) in { block_expr with eexpr = TBlock (List.rev reversed) } | _ -> fail block_expr.epos (try assert false with Assert_failure mlpos -> mlpos) (** If `expr` is a block, then return list of expressions in that block. Otherwise returns a list with `expr` as a single item. *) let unpack_block expr = match expr.eexpr with | TBlock exprs -> exprs | _ -> [ expr ] (** If `expr` is a block of a single expression, then return that single expression. If `expr` is a block with multiple expressions, fail compilation. Otherwise return `expr` as-is. *) let unpack_single_expr_block expr = match expr.eexpr with | TBlock [ e ] -> e | TBlock _ -> fail expr.epos (try assert false with Assert_failure mlpos -> mlpos) | _ -> expr (** Check if specified type has rtti meta *) let has_rtti_meta ctx mtype = match Codegen.build_metadata ctx mtype with | None -> false | Some _ -> true (** Check if user-defined field has the same name as one of php magic methods, but with not compatible signature. *) let field_needs_rename field = match field.cf_kind with | Var _ -> false | Method _ -> match field.cf_name with | "__construct" | "__destruct" | "__call" | "__callStatic" | "__get" | "__set" | "__isset" | "__unset" | "__sleep" | "__wakeup" | "__toString" | "__invoke" | "__set_state" | "__clone" | "__debugInfo" -> not (Meta.has Meta.PhpMagic field.cf_meta) | _ -> false (** Get valid `field` name. *) let field_name field = if field_needs_rename field then "__hx__renamed" ^ field.cf_name else field.cf_name (** Check if `expr` is `Std.is` *) let is_std_is expr = match expr.eexpr with | TField (_, FStatic ({ cl_path = path }, { cf_name = "is" })) -> path = boot_type_path || path = std_type_path | _ -> false (** Check if provided expression is actually a casting to NativeStructArray *) let is_native_struct_array_cast expr = match expr.eexpr with | TCall ({ eexpr = TField (_, field) }, _) -> (match field with | FStatic ({ cl_path = (["php"; "_NativeStructArray"], "NativeStructArray_Impl_") }, { cf_name = "__fromObject" }) -> true | _ -> false ) | _ -> false (** Check if `expr` is an anonymous object declaration *) let is_object_declaration expr = match (reveal_expr expr).eexpr with | TObjectDecl _ -> true | _ -> false (** Check if `subject_arg` and `type_arg` can be generated as `$subject instanceof Type` expression. *) let instanceof_compatible (subject_arg:texpr) (type_arg:texpr) : bool = match (reveal_expr_with_parenthesis type_arg).eexpr with | TTypeExpr (TClassDecl { cl_path = path }) when path <> ([], "String") && path <> ([], "Class") -> let subject_arg = reveal_expr_with_parenthesis subject_arg in (match subject_arg.eexpr with | TLocal _ | TField _ | TCall _ | TArray _ -> not (is_magic subject_arg) | _ -> false ) | _ -> false (** PHP DocBlock types *) type doc_type = | DocVar of string * (string option) (* (type name, description) *) | DocMethod of (string * bool * t) list * t * (string option) (* (arguments, return type, description) *) | DocClass of string option (** Common interface for module_type instances *) class virtual type_wrapper (type_path:path) (meta:metadata) (needs_generation:bool) = object (self) (** Indicates if this type should be rendered to corresponding php file *) method needs_generation = needs_generation (** Indicates if class initialization method should be executed upon class loaded *) method virtual needs_initialization : bool (** Returns hx source file name where this type was declared *) method virtual get_source_file : string (** Returns `Type.module_type` instance for this type *) method virtual get_module_type : module_type (** Returns expression of a user-defined static __init__ method @see http://old.haxe.org/doc/advanced/magic#initialization-magic *) method get_magic_init : texpr option = None (** Namespace path. E.g. ["some"; "pack"] for "some.pack.MyType" *) method get_namespace = get_module_path type_path (** Short type name. E.g. `SomeType` for `pack.SomeType` *) method get_name = get_type_name type_path (** Full type path *) method get_type_path = type_path (** If current type requires some additional type to be generated *) method get_service_type : module_type option = None end (** TClassDecl *) class class_wrapper (cls) = object (self) inherit type_wrapper cls.cl_path cls.cl_meta (not cls.cl_extern) (** Indicates if class initialization method should be executed upon class loaded *) method needs_initialization = (* Interfaces may need initialization only for RTTI meta data. But that meta is written in `class_wrapper#write_rtti_meta` *) if cls.cl_interface then false else match cls.cl_init with | Some _ -> true | None -> let needs = ref false in PMap.iter (fun _ field -> (* Skip `inline var` fields *) if not (is_inline_var field) then begin if not !needs then needs := is_var_with_nonconstant_expr field; (* Check static vars with non-constant expressions *) if not !needs then needs := is_var_with_nonconstant_expr field; (* Check static dynamic functions *) if not !needs then needs := is_dynamic_method field end ) cls.cl_statics; !needs (** Returns expression of a user-defined static __init__ method @see http://old.haxe.org/doc/advanced/magic#initialization-magic *) method get_magic_init = cls.cl_init (** Returns hx source file name where this type was declared *) method get_source_file = cls.cl_pos.pfile (** Returns `Type.module_type` instance for this type *) method get_module_type = TClassDecl cls (** If current type requires some additional type to be generated *) method get_service_type : module_type option = if not cls.cl_extern then None else match cls.cl_init with | None -> None | Some body -> let path = match cls.cl_path with | (pack, name) -> (pack @ ["_" ^ name], ("_extern_" ^ name)) in let additional_cls = { cls with cl_extern = false; cl_path = path; cl_fields = PMap.create (fun a b -> 0); cl_statics = PMap.create (fun a b -> 0); cl_ordered_fields = []; cl_ordered_statics = []; cl_constructor = None; cl_overrides = []; cl_init = Some body } in Some (TClassDecl additional_cls) end (** TEnumDecl *) class enum_wrapper (enm) = object (self) inherit type_wrapper enm.e_path enm.e_meta (not enm.e_extern) (** Indicates if class initialization method should be executed upon class loaded *) method needs_initialization = false (** Returns hx source file name where this type was declared *) method get_source_file = enm.e_pos.pfile (** Returns `Type.module_type` instance for this type *) method get_module_type = TEnumDecl enm end (** TTypeDecl *) class typedef_wrapper (tdef) = object (self) inherit type_wrapper tdef.t_path tdef.t_meta false (** Indicates if class initialization method should be executed upon class loaded *) method needs_initialization = false (** Returns hx source file name where this type was declared *) method get_source_file = tdef.t_pos.pfile (** Returns `Type.module_type` instance for this type *) method get_module_type = TTypeDecl tdef end (** TAbstractDecl *) class abstract_wrapper (abstr) = object (self) inherit type_wrapper abstr.a_path abstr.a_meta false (** Indicates if class initialization method should be executed upon class loaded *) method needs_initialization = false (** Returns hx source file name where this type was declared *) method get_source_file = abstr.a_pos.pfile (** Returns `Type.module_type` instance for this type *) method get_module_type = TAbstractDecl abstr end (** type_wrapper for classes *) let classes = Hashtbl.create 1000 let get_class_wrapper cls : type_wrapper = try let wrapper = Hashtbl.find classes cls in wrapper with | Not_found -> let wrapper = new class_wrapper cls in Hashtbl.add classes cls wrapper; wrapper | e -> raise e (** type_wrapper for enums *) let enums = Hashtbl.create 200 let get_enum_wrapper enm : type_wrapper= try let wrapper = Hashtbl.find enums enm in wrapper with | Not_found -> let wrapper = new enum_wrapper enm in Hashtbl.add enums enm wrapper; wrapper | e -> raise e (** type_wrapper for typedefs *) let typedefs = Hashtbl.create 200 let get_typedef_wrapper typedef : type_wrapper = try let wrapper = Hashtbl.find typedefs typedef in wrapper with | Not_found -> let wrapper = new typedef_wrapper typedef in Hashtbl.add typedefs typedef wrapper; wrapper | e -> raise e (** type_wrapper for abstracts *) let abstracts = Hashtbl.create 200 let get_abstract_wrapper abstr : type_wrapper = try let wrapper = Hashtbl.find abstracts abstr in wrapper with | Not_found -> let wrapper = new abstract_wrapper abstr in Hashtbl.add abstracts abstr wrapper; wrapper | e -> raise e (** Returns wrapper for module_type. Caches wrappers so that each type will always return the same wrapper instance. *) let get_wrapper (mtype:module_type) : type_wrapper = match mtype with | TClassDecl cls -> get_class_wrapper cls | TEnumDecl enm -> get_enum_wrapper enm | TTypeDecl typedef -> get_typedef_wrapper typedef | TAbstractDecl abstr -> get_abstract_wrapper abstr (** Drop cached instances of type_wrapper *) let clear_wrappers () = Hashtbl.clear classes; Hashtbl.clear enums; Hashtbl.clear typedefs; Hashtbl.clear abstracts (** Check if specified type name is used in specified namespace *) let namespaces_types_cache = Hashtbl.create 512 let type_name_used_in_namespace ctx name namespace = let types = Hashtbl.find_all namespaces_types_cache namespace in match types with | [] -> List.iter (fun ctx_type -> let wrapper = get_wrapper ctx_type in Hashtbl.add namespaces_types_cache wrapper#get_namespace wrapper#get_name ) ctx.types; let types = Hashtbl.find_all namespaces_types_cache namespace in List.mem name types | _ -> List.mem name types (** Simple list intersection implementation. @return A list of values existing in each of source lists. *) let rec list_intersect list1 list2 = match list2 with | [] -> [] | item :: rest -> if List.mem item list1 then item :: (list_intersect list1 rest) else list_intersect list1 rest (** Class to simplify collecting lists of declared and used local vars. Collected data is needed to generate closures correctly. *) class local_vars = object (self) (** Hashtbl to collect local var used in current scope *) val mutable used_locals = [Hashtbl.create 100] (** Hashtbl to collect local vars declared in current scope *) val mutable declared_locals = [Hashtbl.create 100] (** Local vars which were captured in closures (passed via `use` directive in php) *) val captured_locals = Hashtbl.create 0 (** Clear collected data *) method clear : unit = used_locals <- [Hashtbl.create 100]; declared_locals <- [Hashtbl.create 100]; Hashtbl.clear captured_locals (** This method should be called upone entering deeper scope. E.g. right before processing a closure. Just before closure arguments handling. *) method dive : unit = used_locals <- (Hashtbl.create 100) :: used_locals; declared_locals <- (Hashtbl.create 100) :: declared_locals (** This method should be called right after leaving a scope. @return List of vars names used in finished scope, but declared in higher scopes. And list of vars names declared in finished scope. And list of vars names declared in finished scope and captured by closures via `use` directive *) method pop : string list * string list * string list = match used_locals with | [] -> assert false | used :: rest_used -> match declared_locals with | [] -> assert false | declared :: rest_declared -> let higher_vars = diff_lists (hashtbl_keys used) (hashtbl_keys declared) and declared_vars = hashtbl_keys declared in used_locals <- rest_used; declared_locals <- rest_declared; List.iter self#used higher_vars; let captured_vars = list_intersect declared_vars (hashtbl_keys captured_locals) in List.iter (fun name -> Hashtbl.remove captured_locals name) declared_vars; (higher_vars, declared_vars, captured_vars) (** This method should be called right after leaving a scope. @return List of vars names used in finished scope, but declared in higher scopes *) method pop_used : string list = match self#pop with (higher_vars, _, _) -> higher_vars (** This method should be called right after leaving a scope. @return List of vars names declared in finished scope *) method pop_declared : string list = match self#pop with (_, declared_vars, _) -> declared_vars (** Get current list of captured variables. After leaving a scope all vars declared in that scope get removed from a list of captured variables. *) method pop_captured : string list = match self#pop with (_, _, captured_vars) -> captured_vars (** Specify local var name declared in current scope *) method declared (name:string) : unit = match declared_locals with | [] -> assert false | current :: _ -> Hashtbl.replace current name name (** Specify local var name used in current scope *) method used (name:string) : unit = match used_locals with | [] -> assert false | current :: _ -> Hashtbl.replace current name name (** Mark specified vars as captured by closures. *) method captured (var_names:string list) : unit = List.iter (fun name -> Hashtbl.replace captured_locals name name) var_names end (** Consumes expressions and generates php code to output buffer. *) class code_writer (ctx:Common.context) hx_type_path php_name = object (self) (** Namespace path. E.g. ["some"; "pack"] for "some.pack.MyType" *) val namespace = get_module_path hx_type_path (** List of types for "use" section *) val use_table = Hashtbl.create 50 (** Output buffer *) val mutable buffer = Buffer.create 1024 (** Intendation used for each line written *) val mutable indentation = "" (** Expressions nesting. E.g. "if(callFn(ident))" will be represented as [ident, callFn, if] *) val mutable expr_hierarchy : texpr list = [] (** Object to collect local vars declarations and usage as we iterate through methods' expressions *) val vars = new local_vars (** Sourcemap generator *) val mutable sourcemap : sourcemap_builder option = None (** Indicates if `super()` expressions should be generated if spotted. *) val mutable has_super_constructor = true (** Get php name of current type *) method get_name : string = php_name (** Returns generated file contents *) method get_contents = Buffer.contents buffer (** Clears current generated content *) method clear_contents = Buffer.clear buffer (** Reset current state (expr hierarchy, indentation, local vars) *) method reset = vars#clear; self#indent 0; expr_hierarchy <- [] (** Set sourcemap generator *) method set_sourcemap_generator generator = sourcemap <- Some generator (** Get sourcemap generator *) method get_sourcemap_generator = sourcemap (** Make this writer skip generation of `super()` expression if spotted. *) method extends_no_constructor = has_super_constructor <- false (** Increase indentation by one level *) method indent_more = indentation <- indentation ^ "\t"; (** Decrease indentation by one level *) method indent_less = indentation <- String.make ((String.length indentation) - 1) '\t'; (** Set indentation level (starting from zero for no indentation) *) method indent level = indentation <- String.make level '\t'; (** Get indentation level (starting from zero for no indentation) *) method get_indentation = String.length indentation (** Specify local var name declared in current scope *) method declared_local_var name = vars#declared name (** Adds type to "use" section if not added yet. If it's a top-level type then type name returned without adding to "use" section. @return Unique alias for specified type. *) method use ?prefix (type_path:path) = if type_path = hx_type_path then php_name else let type_path = match type_path with (pack, name) -> (pack, get_real_name name) in let type_path = match prefix with | Some false -> type_path | _ -> add_php_prefix ctx type_path in let module_path = get_module_path type_path in match type_path with | ([], type_name) -> "\\" ^ type_name | _ -> let alias_source = ref (List.rev module_path) in let get_alias_next_part () = match !alias_source with | [] -> failwith ("Failed to find already used type: " ^ get_full_type_name type_path) | name :: rest -> alias_source := rest; String.capitalize name and added = ref false and alias = ref (get_type_name type_path) in if !alias = php_name then alias := get_alias_next_part () ^ !alias; while not !added do try if (get_module_path type_path) <> namespace && type_name_used_in_namespace ctx !alias namespace then alias := get_alias_next_part () ^ !alias else let used_type = Hashtbl.find use_table !alias in if used_type = type_path then added := true else alias := get_alias_next_part () ^ !alias; with | Not_found -> Hashtbl.add use_table !alias type_path; added := true | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) done; !alias (** Extracts type path from Type.t value and execute self#use on it @return Unique alias for specified type. *) method use_t (t_inst:Type.t) = match follow t_inst with | TEnum (tenum, _) -> self#use tenum.e_path | TInst (tcls, _) -> (match tcls.cl_kind with | KTypeParameter _ -> "mixed" | _ -> (match tcls.cl_path with | ([], "String") -> "string" | _ -> self#use ~prefix:(not tcls.cl_extern) tcls.cl_path ) ) | TFun _ -> self#use ~prefix:false ([], "Closure") | TAnon _ -> "object" | TDynamic _ -> "mixed" | TLazy _ -> failwith "TLazy not implemented" | TMono mono -> (match !mono with | None -> "mixed" | Some t -> self#use_t t ) | TType _ -> failwith "TType not implemented" | TAbstract (abstr, _) -> match abstr.a_path with | ([],"Int") -> "int" | ([],"Float") -> "float" | ([],"Bool") -> "bool" | ([],"Void") -> "void" | ([],"Enum") -> "Enum" | ([], "Class") -> "Class" | _ when Meta.has Meta.CoreType abstr.a_meta -> "mixed" | _ -> self#use_t abstr.a_this (** Position of currently generated code in source hx files *) method pos = match expr_hierarchy with | { epos = pos } :: _ -> pos | _ -> dummy_pos (** Indicates whether current expression nesting level is a top level of a block *) method parent_expr_is_block single_expr_is_not_block = let rec expr_is_block expr parents no_parent_is_block = match expr.eexpr with | TBlock [_] when single_expr_is_not_block -> (match parents with | { eexpr = TBlock _ } :: _ -> true | { eexpr = TFunction _ } :: _ -> true | _ :: _ -> false | [] -> no_parent_is_block ) | TBlock _ -> true | TIf (_, if_expr, Some else_expr) -> if (expr_is_block if_expr [] false) || (expr_is_block else_expr [] false) then true else (match parents with | parent :: rest -> expr_is_block parent rest true | [] -> false ) | TIf (_, _, None) -> true | TTry _ -> true | TWhile _ -> true | TFor _ -> true | TSwitch _ -> true | _ -> false in match expr_hierarchy with | _ :: parent :: rest -> expr_is_block parent rest true | _ -> false (** Returns parent expression (bypasses casts and metas) *) method parent_expr = let rec traverse expr parents = match expr.eexpr with | TCast (_, None) | TMeta _ -> (match parents with | parent :: rest -> traverse parent rest | [] -> None ) | _ -> Some expr in match expr_hierarchy with | _ :: parent :: rest -> traverse parent rest | _ -> None (** Indicates if parent expression is a call (bypasses casts and metas) *) method parent_expr_is_call = match self#parent_expr with | Some { eexpr = TCall _ } -> true | _ -> false (** Check if currently generated expression is located in a left part of assignment. *) method is_in_write_context = let rec traverse current parents = match parents with | { eexpr = TBinop(OpAssign, left_expr, _) } :: _ | { eexpr = TBinop(OpAssignOp _, left_expr, _) } :: _ -> left_expr == current | { eexpr = TUnop(op, _, _) } :: _ -> is_modifying_unop op | [] -> false | parent :: rest -> traverse parent rest in match expr_hierarchy with | current :: parents -> traverse current parents | _ -> false (** Add a function call to "dereference" part of expression to avoid "Cannot use temporary expression in write context" erro in expressions like: ``` new MyClass().fieldName = 'value'; ``` *) method dereference expr = let boot_cls = get_boot ctx in let deref_field = PMap.find "deref" boot_cls.cl_statics in match expr.eexpr with | TField (target_expr, access) -> { expr with eexpr = TField ( { target_expr with eexpr = TCall ( { target_expr with eexpr = TField ( { target_expr with eexpr = TTypeExpr (TClassDecl boot_cls) }, FStatic (boot_cls, deref_field) ) }, [ target_expr ] ) }, access ) } | TArray (target_expr, access_expr) -> { expr with eexpr = TArray ( { target_expr with eexpr = TCall ( { target_expr with eexpr = TField ( { target_expr with eexpr = TTypeExpr (TClassDecl boot_cls) }, FStatic (boot_cls, deref_field) ) }, [ target_expr ] ) }, access_expr ) } | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes specified string to output buffer *) method write str = Buffer.add_string buffer str; Option.may (fun smap -> smap#insert (SMStr str)) sourcemap; (** Writes specified string to output buffer without affecting sourcemap generator *) method write_bypassing_sourcemap str = Buffer.add_string buffer str; (** Writes constant double-quoted string to output buffer *) method write_const_string str = self#write ("\"" ^ (escape_bin str) ^ "\"") (** Writes fixed amount of empty lines (E.g. between methods) *) method write_empty_lines = self#write "\n\n" (** Writes current indentation to output buffer *) method write_indentation = self#write indentation (** Writes specified line to output buffer and appends \n *) method write_line line = self#write (indentation ^ line ^ "\n") (** Writes specified statement to output buffer and appends ";\n" *) method write_statement statement = self#write (indentation ^ statement ^ ";\n") (** Build "use" statements *) method write_use = self#indent 0; let write alias type_path = if (get_module_path type_path) <> namespace then if get_type_name type_path = alias then self#write_statement ("use " ^ (get_full_type_name type_path)) else let full_name = get_full_type_name type_path in self#write_statement ("use " ^ full_name ^ " as " ^ alias) in Hashtbl.iter write use_table (** Writes array item declaration to output buffer and appends ",\n" *) method write_array_item ?key value_expr = (match key with | None -> self#write_indentation; self#write_expr value_expr; | Some key_str -> self#write (indentation ^ "\"" ^ (String.escaped key_str) ^ "\" => "); self#write_expr value_expr ); self#write ",\n" (** Writes expression to output buffer *) method write_expr (expr:texpr) = expr_hierarchy <- expr :: expr_hierarchy; Option.may (fun smap -> smap#insert (SMPos expr.epos)) sourcemap; (match expr.eexpr with | TConst const -> self#write_expr_const const | TLocal var -> vars#used var.v_name; self#write ("$" ^ var.v_name) | TArray (target, index) -> self#write_expr_array_access target index | TBinop (operation, expr1, expr2) when needs_dereferencing (is_assignment_binop operation) expr1 -> self#write_expr { expr with eexpr = TBinop (operation, self#dereference expr1, expr2) } | TBinop (operation, expr1, expr2) -> self#write_expr_binop operation expr1 expr2 | TField (fexpr, access) when is_php_global expr -> self#write_expr_php_global expr | TField (fexpr, access) when is_php_class_const expr -> self#write_expr_php_class_const expr | TField (fexpr, access) when needs_dereferencing (self#is_in_write_context) expr -> self#write_expr (self#dereference expr) | TField (fexpr, access) -> self#write_expr_field fexpr access | TTypeExpr mtype -> self#write_expr_type mtype | TParenthesis expr -> self#write "("; self#write_expr expr; self#write ")" | TObjectDecl fields -> self#write_expr_object_declaration fields | TArrayDecl exprs -> self#write_expr_array_decl exprs | TCall (target, [arg1; arg2]) when is_std_is target && instanceof_compatible arg1 arg2 -> self#write_expr_lang_instanceof [arg1; arg2] | TCall (_, [arg]) when is_native_struct_array_cast expr && is_object_declaration arg -> self#write_assoc_array_decl arg | TCall ({ eexpr = TLocal { v_name = name }}, args) when is_magic expr -> self#write_expr_magic name args | TCall ({ eexpr = TField (expr, access) }, args) when is_string expr -> self#write_expr_call_string expr access args | TCall (expr, args) when is_lang_extern expr -> self#write_expr_call_lang_extern expr args | TCall (target, args) when is_sure_var_field_access target -> self#write_expr_call (parenthesis target) args | TCall (target, args) -> self#write_expr_call target args | TNew (_, _, args) when is_string expr -> write_args self#write self#write_expr args | TNew (tcls, _, args) -> self#write_expr_new tcls args | TUnop (operation, flag, target_expr) when needs_dereferencing (is_modifying_unop operation) target_expr -> self#write_expr { expr with eexpr = TUnop (operation, flag, self#dereference target_expr) } | TUnop (operation, flag, expr) -> self#write_expr_unop operation flag expr | TFunction fn -> self#write_expr_function fn | TVar (var, expr) -> self#write_expr_var var expr | TBlock exprs -> self#write_expr_block expr | TFor (var, iterator, body) -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) | TIf (condition, if_expr, else_expr) -> self#write_expr_if condition if_expr else_expr | TWhile (condition, expr, do_while) -> self#write_expr_while condition expr do_while | TSwitch (switch, cases, default ) -> self#write_expr_switch switch cases default | TTry (try_expr, catches) -> self#write_expr_try_catch try_expr catches | TReturn expr -> self#write_expr_return expr | TBreak -> self#write_expr_loop_flow "break" | TContinue -> self#write_expr_loop_flow "continue" | TThrow expr -> self#write_expr_throw expr | TCast (expr, mtype) -> self#write_expr_cast expr mtype | TMeta (_, expr) -> self#write_expr expr | TEnumParameter (expr, constructor, index) -> self#write_expr_enum_parameter expr constructor index ); expr_hierarchy <- List.tl expr_hierarchy (** Writes `continue N` or `break N` with required N depending on nearest parent loop and amount of `switch` between loop and `continue/break` *) method write_expr_loop_flow word = let rec count_N parent_exprs count = match parent_exprs with | [] -> count | { eexpr = TWhile _ } :: _ -> count | { eexpr = TSwitch _ } :: rest -> count_N rest (count + 1) | _ :: rest -> count_N rest count in let count = count_N expr_hierarchy 1 in if count > 1 then self#write (word ^ " " ^ (string_of_int count)) else self#write word (** Writes TConst to output buffer *) method write_expr_const const = match const with | TFloat str -> self#write str | TString str -> self#write_const_string str | TBool value -> self#write (if value then "true" else "false") | TNull -> self#write "null" | TThis -> self#write "$this" | TSuper -> self#write "parent" | TInt value -> (* See https://github.com/HaxeFoundation/haxe/issues/5289 *) if value = Int32.min_int then self#write "((int)-2147483648)" else self#write (Int32.to_string value) (** Writes TArrayDecl to output buffer *) method write_expr_array_decl exprs = match exprs with | [] -> let decl () = self#write ("new " ^ (self#use array_type_path) ^ "()") in (* Wrap into parentheses if trying to access items of empty array declaration *) (match self#parent_expr with | Some { eexpr = TArray _ } -> self#write "("; decl(); self#write ")" | _ -> decl() ) | [expr] -> self#write ((self#use array_type_path) ^ "::wrap(["); self#write_expr expr; self#write "])" | _ -> self#write ((self#use array_type_path) ^ "::wrap([\n"); self#indent_more; List.iter (fun expr -> self#write_array_item expr) exprs; self#indent_less; self#write_indentation; self#write "])" (** Write associative array declaration (used for NativeStructArray) *) method write_assoc_array_decl object_decl = match (reveal_expr object_decl).eexpr with | TObjectDecl fields -> if List.length fields = 0 then self#write "[]" else begin self#write "[\n"; self#indent_more; List.iter (fun (name, field) -> self#write_indentation; self#write_const_string name; self#write " => "; self#write_expr field; self#write ",\n" ) fields; self#indent_less; self#write_indentation; self#write "]"; end | _ -> fail object_decl.epos (try assert false with Assert_failure mlpos -> mlpos) (** Writes TArray to output buffer *) method write_expr_array_access target index = let write_index left_bracket right_bracket = self#write left_bracket; self#write_expr index; self#write right_bracket in let write_fast_access () = self#write "("; self#write_expr target; self#write "->arr"; write_index "[" "] ?? null)" and write_normal_access () = self#write_expr target; write_index "[" "]" in match follow target.etype with | TInst ({ cl_path = path }, _) when path = array_type_path -> if self#is_in_write_context then write_normal_access() else write_fast_access() | _ -> write_normal_access () (** Writes TVar to output buffer *) method write_expr_var var expr = vars#declared var.v_name; self#write ("$" ^ var.v_name ^ " = "); match expr with | None -> self#write "null" | Some expr -> self#write_expr expr (** Writes TFunction to output buffer *) method write_expr_function func = self#write_closure_declaration func self#write_function_arg (** Writes closure declaration to output buffer *) method write_closure_declaration func write_arg = vars#dive; self#write "function ("; write_args self#write write_arg func.tf_args; self#write ")"; (* Generate closure body to separate buffer *) let original_buffer = buffer in let sm_pointer_before_body = get_sourcemap_pointer sourcemap in buffer <- Buffer.create 256; self#write_expr (inject_defaults ctx func); let body = Buffer.contents buffer in buffer <- original_buffer; set_sourcemap_pointer sourcemap sm_pointer_before_body; (* Capture local vars used in closures *) let used_vars = vars#pop_used in vars#captured used_vars; self#write " "; if List.length used_vars > 0 then begin self#write " use ("; write_args self#write (fun name -> self#write ("&$" ^ name)) used_vars; self#write ") " end; self#write_bypassing_sourcemap body; Option.may (fun smap -> smap#fast_forward) sourcemap (** Writes TBlock to output buffer *) method write_expr_block block_expr = (* Check if parent expr could not contain blocks in PHP, and this block needs to be wrapped in a closure. *) let needs_closure = match self#parent_expr with | None -> false | Some e -> match e.eexpr with | TIf (_, _, _) -> false | TWhile (_, _, _) -> false | TTry (_, _) -> false | TFor (_, _, _) -> false | TFunction _ -> false | TBlock _ -> false | TSwitch (_, _, _) -> false | _ -> true in if needs_closure then begin self#write "("; self#write_expr { block_expr with eexpr = TFunction { tf_args = []; tf_type = block_expr.etype; tf_expr = ensure_return_in_block block_expr; } }; self#write ")()" end else begin let inline_block = self#parent_expr_is_block false in self#write_as_block ~inline:inline_block block_expr end (** Emulates TBlock for parent expression and writes `expr` as inlined block *) method write_fake_block expr = self#write_indentation; let fake_block = { expr with eexpr = TBlock [expr] } in expr_hierarchy <- fake_block :: expr_hierarchy; self#write_as_block ~inline:true expr; expr_hierarchy <- List.tl expr_hierarchy (** Write position of specified expression to output buffer *) method write_pos expr = self#write ("#" ^ (stringify_pos expr.epos) ^ "\n"); (** Writes "{ }" to output buffer *) method write_as_block ?inline ?unset_locals expr = let unset_locals = match unset_locals with Some true -> true | _ -> false and exprs = match expr.eexpr with TBlock exprs -> exprs | _ -> [expr] in let write_body () = let write_expr expr = if not !skip_line_directives && not (is_block expr) then begin self#write_pos expr; self#write_indentation end; self#write_expr expr; match expr.eexpr with | TBlock _ | TIf _ | TTry _ | TSwitch _ | TWhile (_, _, NormalWhile) -> self#write "\n" | _ -> self#write ";\n" in let write_expr_with_indent expr = self#write_indentation; write_expr expr in let write_exprs () = match exprs with | [] -> () | first :: rest -> write_expr first; (* write first expression without indentation in case of block inlining *) List.iter write_expr_with_indent rest in if unset_locals then begin let original_buffer = buffer in let sm_pointer_before_body = get_sourcemap_pointer sourcemap in buffer <- Buffer.create 256; vars#dive; write_exprs(); let body = Buffer.contents buffer in buffer <- original_buffer; set_sourcemap_pointer sourcemap sm_pointer_before_body; let locals = vars#pop_captured in if List.length locals > 0 then begin self#write ("unset($" ^ (String.concat ", $" locals) ^ ");\n"); self#write_indentation end; self#write_bypassing_sourcemap body; Option.may (fun smap -> smap#fast_forward) sourcemap end else write_exprs() in match inline with | Some true -> write_body () | _ -> self#write "{\n"; self#indent_more; (match exprs with | [] -> () | _ -> self#write_indentation; (* indentation for the first expression in block *) write_body () ); self#indent_less; self#write_indentation; self#write "}" (** Writes TReturn to output buffer *) method write_expr_return expr = match expr with | None -> self#write "return"; | Some expr -> self#write "return "; self#write_expr expr (** Writes TThrow to output buffer *) method write_expr_throw expr = self#write "throw "; if is_native_exception expr.etype then self#write_expr expr else if sure_extends_extern expr.etype || is_dynamic_type expr.etype then begin self#write "(is_object($__hx__throw = "; self#write_expr expr; self#write (") && $__hx__throw instanceof \\Throwable ? $__hx__throw : new " ^ (self#use hxexception_type_path) ^ "($__hx__throw))") end else begin self#write ("new " ^ (self#use hxexception_type_path) ^ "("); self#write_expr expr; self#write ")" end (** Writes try...catch to output buffer *) method write_expr_try_catch try_expr catches = let catching_dynamic = ref false in let haxe_exception = self#use hxexception_type_path and first_catch = ref true in let write_catch (var, expr) = let dynamic = ref false in (match follow var.v_type with | TInst ({ cl_path = ([], "String") }, _) -> self#write "if (is_string($__hx__real_e)) {\n" | TAbstract ({ a_path = ([], "Float") }, _) -> self#write "if (is_float($__hx__real_e)) {\n" | TAbstract ({ a_path = ([], "Int") }, _) -> self#write "if (is_int($__hx__real_e)) {\n" | TAbstract ({ a_path = ([], "Bool") }, _) -> self#write "if (is_bool($__hx__real_e)) {\n" | TDynamic _ -> dynamic := true; catching_dynamic := true; if not !first_catch then self#write "{\n" | vtype -> self#write ("if ($__hx__real_e instanceof " ^ (self#use_t vtype) ^ ") {\n") ); if !dynamic && !first_catch then begin self#write ("$" ^ var.v_name ^ " = $__hx__real_e;\n"); self#write_indentation; self#write_as_block ~inline:true expr; end else begin self#indent_more; self#write_statement ("$" ^ var.v_name ^ " = $__hx__real_e"); self#write_indentation; self#write_as_block ~inline:true expr; self#indent_less; self#write_indentation; self#write "}"; end; if not !dynamic then self#write " else "; first_catch := false; in self#write "try "; self#write_as_block try_expr; self#write " catch (\\Throwable $__hx__caught_e) {\n"; self#indent_more; if has_feature ctx "haxe.CallStack.exceptionStack" then self#write_statement ((self#use (["haxe"], "CallStack")) ^ "::saveExceptionTrace($__hx__caught_e)"); self#write_statement ("$__hx__real_e = ($__hx__caught_e instanceof " ^ haxe_exception ^ " ? $__hx__caught_e->e : $__hx__caught_e)"); self#write_indentation; List.iter write_catch catches; if not !catching_dynamic then self#write " throw $__hx__caught_e;\n" else (match catches with [_] -> () | _ -> self#write "\n"); self#indent_less; self#write_indentation; self#write "}" (** Writes TCast to output buffer *) method write_expr_cast expr (mtype:module_type option) = match mtype with | None -> self#write_expr expr | Some mtype -> self#write ((self#use boot_type_path) ^ "::typedCast("); self#write_expr_type mtype; self#write ", "; self#write_expr expr; self#write ")" (** Write Haxe->PHP magic function call @see http://old.haxe.org/doc/advanced/magic#php-magic *) method write_expr_magic name args = let error = error_message self#pos ("Invalid arguments for " ^ name ^ " magic call") in match args with | [] -> failwith error | { eexpr = TConst (TString code) } as expr :: args -> (match name with | "__php__" -> (match expr.eexpr with | TConst (TString php) -> Codegen.interpolate_code ctx php args self#write self#write_expr self#pos | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) ) | "__call__" -> self#write (code ^ "("); write_args self#write self#write_expr args; self#write ")" | "__physeq__" -> (match args with | [expr2] -> self#write_expr_binop OpEq expr expr2 | _ -> failwith error ) | "__var__" -> (match args with | [] -> self#write ("$" ^ code) | [expr2] -> self#write ("$" ^ code ^ "["); self#write_expr expr2; self#write "]" | _ -> failwith error ) | _ -> failwith error ) | [expr1; expr2] -> (match name with | "__physeq__" -> (match args with | [expr1; expr2] -> self#write_expr_binop OpEq expr1 expr2 | _ -> failwith error ) | _ -> failwith error ) | _ -> failwith error (** Writes TTypeExpr to output buffer *) method write_expr_type (mtype:module_type) = let ttype = type_of_module_type mtype in match self#parent_expr with (* When type is used to access type fields. E.g. `TypeExpr.someField` *) | Some { eexpr = TField (_, FStatic _) } | Some { eexpr = TField (_, FEnum _) } -> self#write (self#use_t ttype) (* Other cases *) | _ -> let class_name = match self#use_t ttype with | "int" -> "'Int'" | "float" -> "'Float'" | "bool" -> "'Bool'" | "string" -> "'String'" | "mixed" -> "'Dynamic'" | "Enum" -> "'Enum'" | "Class" -> "'Class'" | name -> name ^ "::class" in self#write ((self#use boot_type_path) ^ "::getClass(" ^ class_name ^ ")") (** Writes binary operation to output buffer *) method write_expr_binop operation expr1 expr2 = let write_method method_name = self#write (method_name ^ "("); self#write_expr expr1; self#write ", "; self#write_expr expr2; self#write ")" in let write_for_concat expr = if ((is_constant expr) && not (is_constant_null expr)) || (is_concatenation expr) then self#write_expr expr else begin self#write "("; self#write_expr expr; self#write "??'null')" end and write_binop ?writer ?right_writer str = let write_left = match writer with None -> self#write_expr | Some writer -> writer in let write_right = match right_writer with None -> write_left | Some writer -> writer and need_parenthesis = match self#parent_expr with | Some { eexpr = TBinop (parent, _, _) } -> need_parenthesis_for_binop operation parent | _ -> false in if need_parenthesis then self#write "("; write_left expr1; self#write str; write_right expr2; if need_parenthesis then self#write ")" and compare_strings op = write_method "strcmp"; self#write (op ^ "0") in let compare op = if is_string expr1 && is_string expr2 then compare_strings op else write_binop op in match operation with | OpAdd -> if (is_string expr1) || (is_string expr2) then write_binop ~writer:write_for_concat " . " else if (is_unknown_type expr1.etype) && (is_unknown_type expr2.etype) then write_method ((self#use boot_type_path) ^ "::addOrConcat") else write_binop " + " | OpMult -> write_binop " * " | OpDiv -> write_binop " / " | OpSub -> write_binop " - " | OpAssign -> write_binop " = " | OpEq -> if need_boot_equal expr1 expr2 then write_method ((self#use boot_type_path) ^ "::equal") else write_binop " === " | OpNotEq -> if need_boot_equal expr1 expr2 then begin self#write "!"; write_method ((self#use boot_type_path) ^ "::equal") end else write_binop " !== " | OpGt -> compare " > " | OpGte -> compare " >= " | OpLt -> compare " < " | OpLte -> compare " <= " | OpAnd -> write_binop " & " | OpOr -> write_binop " | " | OpXor -> write_binop " ^ " | OpBoolAnd -> write_binop " && " | OpBoolOr -> write_binop " || " | OpShl -> write_binop " << " | OpShr -> write_binop " >> " | OpMod -> if is_int expr1 && is_int expr2 then write_binop " % " else write_method "fmod" | OpUShr -> write_method ((self#use boot_type_path) ^ "::shiftRightUnsigned") | OpAssignOp OpAdd -> if (is_string expr1) then begin self#write_expr expr1; self#write " = "; write_binop ~writer:write_for_concat " . " end else if (is_unknown_type expr1.etype) && (is_unknown_type expr2.etype) then begin self#write_expr expr1; self#write " = "; write_method ((self#use boot_type_path) ^ "::addOrConcat") end else write_binop " += " | OpAssignOp OpMult -> write_binop " *= " | OpAssignOp OpDiv -> write_binop " /= " | OpAssignOp OpSub -> write_binop " -= " | OpAssignOp OpAnd -> write_binop " &= " | OpAssignOp OpOr -> write_binop " |= " | OpAssignOp OpXor -> write_binop " ^= " | OpAssignOp OpShl -> write_binop " <<= " | OpAssignOp OpShr -> write_binop " >>= " | OpAssignOp OpMod -> if is_int expr1 && is_int expr2 then write_binop " %= " else write_method "fmod" | OpAssignOp OpUShr -> self#write_expr expr1; self#write " = "; write_method ((self#use boot_type_path) ^ "::shiftRightUnsigned") | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes TUnOp to output buffer *) method write_expr_unop operation flag expr = let write_unop operation = match operation with | Increment -> self#write "++" | Decrement -> self#write "--" | Not -> self#write "!" | Neg -> self#write "-" | NegBits -> self#write "~" in match flag with | Prefix -> write_unop operation; self#write_expr expr | Postfix -> self#write_expr expr; write_unop operation method private write_expr_for_field_access expr access_str field_str = let access_str = ref access_str in (match (reveal_expr expr).eexpr with | TNew _ | TArrayDecl _ | TObjectDecl _ -> self#write_expr (parenthesis expr) | TConst TSuper -> self#write "parent"; access_str := "::" | _ -> self#write_expr expr ); self#write (!access_str ^ field_str) (** Writes TField to output buffer *) method write_expr_field expr access = match access with | FInstance ({ cl_path = [], "String"}, _, { cf_name = "length"; cf_kind = Var _ }) -> self#write "strlen("; self#write_expr expr; self#write ")" | FInstance (_, _, field) -> self#write_expr_for_field_access expr "->" (field_name field) | FStatic (_, ({ cf_kind = Var _ } as field)) -> (match (reveal_expr expr).eexpr with | TTypeExpr _ -> self#write_expr_for_field_access expr "::" ("$" ^ (field_name field)) | _ -> self#write_expr_for_field_access expr "->" (field_name field) ) | FStatic (_, ({ cf_kind = Method MethDynamic } as field)) -> (match self#parent_expr with | Some { eexpr = TCall ({ eexpr = TField (e, a) }, _) } when a == access -> self#write "("; self#write_expr_for_field_access expr "::" ("$" ^ (field_name field)); self#write ")" | _ -> self#write_expr_for_field_access expr "::" ("$" ^ (field_name field)) ) | FStatic (_, ({ cf_kind = Method _ } as field)) -> self#write_expr_field_static expr field | FAnon field -> let written_as_probable_string = self#write_expr_field_if_string expr (field_name field) in if not written_as_probable_string then self#write_expr_for_field_access expr "->" (field_name field) | FDynamic field_name -> self#write_expr_field_dynamic expr field_name | FClosure (tcls, field) -> self#write_expr_field_closure tcls field expr | FEnum (_, field) -> self#write_expr_field_enum expr field (** Generate EField for enum constructor. *) method write_expr_field_enum expr field = let write_field () = self#write_expr expr; let access_operator = match (reveal_expr expr).eexpr with | TTypeExpr _ -> "::" | _ -> "->" in self#write (access_operator ^ field.ef_name) in if is_enum_constructor_with_args field then match self#parent_expr with (* Invoking this enum field *) | Some { eexpr = TCall ({ eexpr = TField (target_expr, FEnum (_, target_field)) }, _) } when target_expr == expr && target_field == field -> write_field () (* Passing this enum field somewhere *) | _ -> self#write_static_method_closure expr field.ef_name else begin write_field (); self#write "()" end (** Writes field access on Dynamic expression to output buffer *) method write_expr_field_if_string expr field_name = (* Special case for String fields *) match field_name with | "length" | "toUpperCase" | "toLowerCase" | "charAt" | "indexOf" | "lastIndexOf" | "split" | "toString" | "substring" | "substr" | "charCodeAt" -> self#write ((self#use hxdynamicstr_type_path) ^ "::wrap("); self#write_expr expr; self#write (")->" ^ field_name); true | _ -> false (** Convert field access expressions for strings to native PHP string functions and write to output buffer *) method write_expr_call_string expr access args = match access with | FInstance (_, _, ({ cf_kind = Method _ } as field)) -> self#write ((self#use hxstring_type_path) ^ "::" ^ (field_name field) ^ "("); write_args self#write self#write_expr (expr :: args); self#write ")" | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes FStatic field access for methods to output buffer *) method write_expr_field_static expr field = let write_expr () = match expr.eexpr with | TTypeExpr (TClassDecl { cl_path = ([], "String") }) -> self#write (self#use hxstring_type_path) | _ -> self#write_expr expr and operator = match (reveal_expr expr).eexpr with | TTypeExpr _ -> "::" | _ -> "->" in match self#parent_expr with | Some { eexpr = TCall ({ eexpr = TField (e, FStatic (_, f)) }, _) } when e == expr && f == field -> write_expr (); self#write (operator ^ (field_name field)) | _ -> self#write_static_method_closure expr field.cf_name (** Generates a closure of a static method. `expr` should contain a `HxClass` instance or a string name of a class. *) method write_static_method_closure expr field_name = let expr = reveal_expr expr in self#write ("new " ^ (self#use hxclosure_type_path) ^ "("); (match (reveal_expr expr).eexpr with | TTypeExpr (TClassDecl { cl_path = ([], "String") }) -> self#write ((self#use hxstring_type_path) ^ "::class") | TTypeExpr _ -> self#write_expr expr; self#write "::class" | _ -> self#write_expr expr; self#write "->phpClassName" ); self#write (", '" ^ field_name ^ "')") (** Writes FClosure field access to output buffer *) method write_expr_field_closure tcls field expr = if is_dynamic_method field then match expr.eexpr with | TTypeExpr mtype -> let class_name = self#use_t (type_of_module_type mtype) in self#write (class_name ^ "::$" ^ (field_name field) ^ "'"); | _ -> self#write_expr expr; self#write ("->" ^ (field_name field)) else let new_closure = "new " ^ (self#use hxclosure_type_path) in match expr.eexpr with | TTypeExpr mtype -> let class_name = self#use_t (type_of_module_type mtype) in self#write (new_closure ^ "(" ^ class_name ^ "::class, '" ^ (field_name field) ^ "')"); | _ -> self#write (new_closure ^ "("); (match follow expr.etype with | TInst ({ cl_path = ([], "String") }, []) -> self#write ((self#use hxdynamicstr_type_path) ^ "::wrap("); self#write_expr expr; self#write ")" | _ -> self#write_expr expr ); self#write (", '" ^ (field_name field) ^ "')") (** Write anonymous object declaration to output buffer *) method write_expr_object_declaration fields = match fields with | [] -> self#write ("new " ^ (self#use hxanon_type_path) ^ "()") | _ -> self#write ("new " ^ (self#use hxanon_type_path) ^ "([\n"); self#indent_more; let write_field (key, value) = self#write_array_item ~key:key value in List.iter write_field fields; self#indent_less; self#write_indentation; self#write "])" (** Writes specified type to output buffer depending on type of expression. *) method write_type type_expr = match type_expr.eexpr with | TTypeExpr (TClassDecl tcls) -> self#write (self#use_t (TInst (tcls, []))) | _ -> if is_string type_expr then self#write_expr type_expr else begin self#write "("; self#write_expr type_expr; self#write "->phpClassName)"; end (** Write language specific expression declared in `php.Syntax` extern *) method write_expr_call_lang_extern expr args = let name = match expr.eexpr with | TField (_, FStatic (_, field)) -> field_name field | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) in match name with | "int" | "float" | "string" | "bool" | "object" | "array" -> self#write_expr_lang_cast name args | "binop" -> self#write_expr_lang_binop args | "instanceof" -> self#write_expr_lang_instanceof args | "foreach" -> self#write_expr_lang_foreach args | "construct" -> self#write_expr_lang_construct args | "getField" -> self#write_expr_lang_get_field args | "setField" -> self#write_expr_lang_set_field args | "getStaticField" -> self#write_expr_lang_get_static_field args | "setStaticField" -> self#write_expr_lang_set_static_field args | "call" -> self#write_expr_lang_call args | "staticCall" -> self#write_expr_lang_static_call args | "arrayDecl" -> self#write_expr_lang_array_decl args | "splat" -> self#write_expr_lang_splat args | "suppress" -> self#write_expr_lang_suppress args | "keepVar" -> () | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes splat operator (for `php.Syntax.splat()`) *) method write_expr_lang_splat args = match args with | [ args_expr ] -> self#write "..."; self#write_expr args_expr | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes error suppression operator (for `php.Syntax.suppress()`) *) method write_expr_lang_suppress args = match args with | [ args_expr ] -> self#write "@"; self#write_expr args_expr | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes native array declaration (for `php.Syntax.arrayDecl()`) *) method write_expr_lang_array_decl args = self#write "["; write_args self#write (fun e -> self#write_expr e) args; self#write "]" (** Writes a call to instance method (for `php.Syntax.call()`) *) method write_expr_lang_call args = match args with | obj_expr :: method_expr :: args -> self#write_expr obj_expr; self#write "->{"; self#write_expr method_expr; self#write "}("; write_args self#write (fun e -> self#write_expr e) args; self#write ")" | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes a call to a static method (for `php.Syntax.staticCall()`) *) method write_expr_lang_static_call args = match args with | type_expr :: method_expr :: args -> self#write_type type_expr; self#write "::{"; self#write_expr method_expr; self#write "}("; write_args self#write (fun e -> self#write_expr e) args; self#write ")" | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes field access for reading (for `php.Syntax.getField()`) *) method write_expr_lang_get_field args = match args with | obj_expr :: field_expr :: [] -> self#write_expr obj_expr; self#write "->{"; self#write_expr field_expr; self#write "}" | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes field access for writing (for `php.Syntax.setField()`) *) method write_expr_lang_set_field args = match args with | obj_expr :: field_expr :: value_expr :: [] -> self#write_expr obj_expr; self#write "->{"; self#write_expr field_expr; self#write "}"; self#write " = "; self#write_expr value_expr | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes static field access for reading (for `php.Syntax.getStaticField()`) *) method write_expr_lang_get_static_field args = match args with | type_expr :: field_expr :: [] -> self#write_type type_expr; self#write "::${"; self#write_expr field_expr; self#write "}" | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes static field access for writing (for `php.Syntax.setField()`) *) method write_expr_lang_set_static_field args = match args with | type_expr :: field_expr :: value_expr :: [] -> self#write_expr type_expr; self#write "::${"; self#write_expr field_expr; self#write "}"; self#write " = "; self#write_expr value_expr | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes `new` expression with class name taken local variable (for `php.Syntax.construct()`) *) method write_expr_lang_construct args = let (class_expr, args) = match args with | class_expr :: args -> (class_expr, args) | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) in self#write "new "; self#write_expr class_expr; self#write "("; write_args self#write (fun e -> self#write_expr e) args; self#write ")" (** Writes native php type conversion to output buffer (e.g. `php.Syntax.int()`) *) method write_expr_lang_cast type_name args = match args with | expr :: [] -> let add_parentheses = match self#parent_expr with Some e -> is_access e | None -> false and expr = match expr.eexpr with | TLocal e -> expr | _ -> parenthesis expr in if add_parentheses then self#write "("; self#write ("(" ^ type_name ^")"); self#write_expr expr; if add_parentheses then self#write ")" | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Generates binary operation to output buffer (for `php.Syntax.binop()`) *) method write_expr_lang_binop args = match args with | val_expr1 :: operator_expr :: val_expr2 :: [] -> let operator = match operator_expr.eexpr with | TConst (TString operator) -> operator | _ -> error_and_exit self#pos "Second argument for php.Syntax.binop() must be a constant string" in self#write "("; self#write_expr val_expr1; self#write (" " ^ operator ^ " "); self#write_expr val_expr2; self#write ")" | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes `instanceof` expression to output buffer (for `php.Syntax.instanceof()`) *) method write_expr_lang_instanceof args = match args with | val_expr :: type_expr :: [] -> self#write "("; self#write_expr val_expr; self#write " instanceof "; (match (reveal_expr type_expr).eexpr with | TTypeExpr (TClassDecl tcls) -> self#write (self#use_t (TInst (tcls, []))) | _ -> self#write_expr type_expr; if not (is_string type_expr) then self#write "->phpClassName" ); self#write ")" | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes `foreach` expression to output buffer (for `php.Syntax.foreach()`) *) method write_expr_lang_foreach args = match args with | collection_expr :: { eexpr = TFunction fn } :: [] -> let (key_name, value_name) = match fn.tf_args with | ({ v_name = key_name }, _) :: ({ v_name = value_name }, _) :: [] -> (key_name, value_name) | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) and add_parentheses = match collection_expr.eexpr with | TLocal _ -> false | _ -> true in self#write "foreach ("; if add_parentheses then self#write "("; self#write_expr collection_expr; if add_parentheses then self#write ")"; self#write (" as $" ^ key_name ^ " => $" ^ value_name ^ ") "); self#write_as_block fn.tf_expr | _ -> error_and_exit self#pos "PHP.foreach() only accepts anonymous function declaration for second argument." (** Writes TCall to output buffer *) method write_expr_call target_expr args = let target_expr = reveal_expr target_expr and no_call = ref false in (match target_expr.eexpr with | TConst TSuper -> no_call := not has_super_constructor; if not !no_call then self#write "parent::__construct" | TField (expr, FClosure (_,_)) -> self#write_expr (parenthesis target_expr) | _ -> self#write_expr target_expr ); if not !no_call then begin self#write "("; write_args self#write self#write_expr args; self#write ")" end (** Writes a name of a function or a constant from global php namespace *) method write_expr_php_global target_expr = match target_expr.eexpr with | TField (_, FStatic (_, field)) -> self#write (field_name field) | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes access to PHP class constant *) method write_expr_php_class_const target_expr = match target_expr.eexpr with | TField (_, FStatic (ecls, field)) -> self#write ((self#use_t (TInst (ecls, []))) ^ "::" ^ (field_name field)) | _ -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes TNew to output buffer *) method write_expr_new inst_class args = let needs_php_prefix = not inst_class.cl_extern in self#write ("new " ^ (self#use ~prefix:needs_php_prefix inst_class.cl_path) ^ "("); write_args self#write self#write_expr args; self#write ")" (** Writes ternary operator expressions to output buffer *) method write_expr_ternary condition if_expr (else_expr:texpr) pos = let if_expr = unpack_single_expr_block if_expr and else_expr = unpack_single_expr_block else_expr in self#write "("; (match condition.eexpr with | TParenthesis expr -> self#write_expr expr; | _ -> self#write_expr else_expr ); self#write " ? "; self#write_expr if_expr; self#write " : "; self#write_expr else_expr; self#write ")" (** Writes "if...else..." expression to output buffer *) method write_expr_if condition if_expr (else_expr:texpr option) = let is_ternary = if self#parent_expr_is_block true then false else match (if_expr.eexpr, else_expr) with | (TBlock exprs, _) when (List.length exprs) > 1 -> false | (_, Some { eexpr=TBlock exprs }) when (List.length exprs) > 1 -> false | (_, None) -> false | _ -> true in if is_ternary then match else_expr with | None -> fail self#pos (try assert false with Assert_failure mlpos -> mlpos) | Some expr -> self#write_expr_ternary condition if_expr expr self#pos else begin self#write "if "; self#write_expr condition; self#write " "; self#write_as_block if_expr; (match else_expr with | None -> () | Some expr -> self#write " else "; match expr.eexpr with | TIf _ -> self#write_expr expr | _ -> self#write_as_block expr ) end (** Writes TWhile ("while..." or "do...while") to output buffer *) method write_expr_while condition expr do_while = match do_while with | NormalWhile -> self#write "while "; self#write_expr condition; self#write " "; self#write_as_block ~unset_locals:true expr | DoWhile -> self#write "do "; self#write_as_block ~unset_locals:true expr; self#write " while "; self#write_expr condition (** Writes TSwitch to output buffer *) method write_expr_switch switch cases default = let write_case (conditions, expr) = List.iter (fun condition -> self#write_indentation; self#write "case "; self#write_expr condition; self#write ":\n"; ) conditions; self#indent_more; self#write_indentation; self#write_as_block ~inline:true expr; self#write_statement "break"; self#indent_less in self#write "switch "; self#write_expr switch; self#write " {\n"; self#indent_more; List.iter write_case cases; (match default with | None -> () | Some expr -> self#write_line "default:"; self#indent_more; self#write_indentation; self#write_as_block ~inline:true expr; self#write_statement "break"; self#indent_less ); self#indent_less; self#write_indentation; self#write "}" (** Write TEnumParameter expression to output buffer *) method write_expr_enum_parameter expr constructor index = (match expr.eexpr with | TConst TNull -> self#write "(null)" | _ -> self#write_expr expr ); self#write ("->params[" ^ (string_of_int index) ^ "]") (** Writes argument for function declarations or calls *) method write_arg with_optionals (arg_name, optional, (arg_type:Type.t)) = self#write ("$" ^ arg_name ^ (if with_optionals && optional then " = null" else "")) (** Writes argument with optional value for function declarations *) method write_function_arg arg = match arg with | ({ v_name = arg_name; v_type = arg_type }, default_value) -> vars#declared arg_name; if is_ref arg_type then self#write "&"; self#write ("$" ^ arg_name); match default_value with | None -> () | Some const -> self#write " = "; self#write_expr_const const (** Write an access to a field of dynamic value *) method private write_expr_field_dynamic expr field_name = let write_direct_access () = let written_as_probable_string = self#write_expr_field_if_string expr field_name in if not written_as_probable_string then self#write_expr_for_field_access expr "->" field_name in let write_wrapped_access () = self#write ((self#use boot_type_path) ^ "::dynamicField("); self#write_expr expr; self#write (", '" ^ field_name ^ "')"); in let check_and_write checked_expr = match (reveal_expr checked_expr).eexpr with | TField (target, _) when target == expr -> write_direct_access() | _ -> write_wrapped_access() in match self#parent_expr with | Some { eexpr = TCall (callee, _) } -> check_and_write callee | Some { eexpr = TUnop (op, _, target) } when is_modifying_unop op -> check_and_write target | Some { eexpr = TBinop (op, left, _) } when is_assignment_binop op -> check_and_write left | _ -> write_wrapped_access() end (** Base class for type builders *) class virtual type_builder ctx (wrapper:type_wrapper) = object (self) (** PHP code writer *) val writer = new code_writer ctx wrapper#get_type_path (get_real_name wrapper#get_name) (** This is required to make wrapper accessible by extending classes *) val wrapper = wrapper (** This is required to make conext accessible by extending classes *) val ctx = ctx (** Cache for generated conent *) val mutable contents = "" (** Get PHP namespace path *) method get_namespace = match get_php_prefix ctx with | [] -> get_real_path wrapper#get_namespace | prefix -> get_real_path (prefix @ wrapper#get_namespace) (** Get type name *) method get_name : string = writer#get_name (** Get full type path *) method get_type_path : path = match wrapper#get_type_path with | (path, name) -> (get_real_path path, get_real_name name) (** Returns hx source file name where this type was declared *) method get_source_file : string = wrapper#get_source_file (** Writes type declaration line to output buffer. E.g. "class SomeClass extends Another implements IFace" *) method virtual private write_declaration : unit (** Writes type body to output buffer. E.g. for "class SomeClass { }" writes part. *) method virtual private write_body : unit (** Writes expressions for `__hx__init` method *) method virtual private write_hx_init_body : unit (** Writes additional initialization code, which should be called before `__hx__init()` *) method virtual private write_pre_hx_init : unit (** Writes initialization code for type instances *) method virtual private write_instance_initialization : unit (** Indicates if type should be declared as `final` *) method is_final = false (** Indicates if `field` should be declared as `final` *) method is_final_field (field:tclass_field) : bool = false (** Indicates if class has user-defined static __init__ method @see http://old.haxe.org/doc/advanced/magic#initialization-magic *) method has_magic_init = match wrapper#get_magic_init with None -> false | Some _ -> true (** Returns generated file contents *) method get_contents = if (String.length contents) = 0 then begin self#write_declaration; writer#write_line " {"; (** opening bracket for a class *) self#write_body; if wrapper#needs_initialization then self#write_hx_init; writer#indent 0; writer#write_line "}"; (** closing bracket for a class *) writer#write_empty_lines; let boot_class = writer#use boot_type_path in (* Boot initialization *) if boot_type_path = self#get_type_path then writer#write_statement (boot_class ^ "::__hx__init()"); let haxe_class = match wrapper#get_type_path with (path, name) -> String.concat "." (path @ [name]) in writer#write_statement (boot_class ^ "::registerClass(" ^ (self#get_name) ^ "::class, '" ^ haxe_class ^ "')"); self#write_rtti_meta; self#write_pre_hx_init; (* Current class initialization *) if wrapper#needs_initialization && boot_type_path <> self#get_type_path then writer#write_statement (self#get_name ^ "::__hx__init()"); let body = writer#get_contents in Option.may (fun smap -> smap#rewind) self#get_sourcemap_generator; writer#clear_contents; self#write_header; writer#write "\n"; let header = writer#get_contents in contents <- header ^ body; end; contents (** Indicates if there is no constructor in inheritance chain of this type. Own constructor is ignored. *) method private extends_no_constructor = true (** Build file header ( writer#write_line (" * " ^ s)); if ctx.debug then writer#write_line (" * Haxe source file: " ^ self#get_source_file); writer#write_line " */"; writer#write "\n"; let namespace = self#get_namespace in if List.length namespace > 0 then writer#write_line ("namespace " ^ (String.concat "\\" namespace) ^ ";\n"); writer#write_use (** Generates PHP docblock to output buffer. *) method private write_doc doc_block = match doc_block with | DocVar (type_name, doc) -> writer#write_line "/**"; writer#write_line (" * @var " ^ type_name); (match doc with | None -> () | Some txt -> self#write_doc_description txt ); writer#write_line " */" | DocClass doc -> (match doc with | None -> () | Some txt -> writer#write_line "/**"; self#write_doc_description txt; writer#write_line " */" ) | DocMethod (args, return, doc) -> self#write_method_docblock args return doc (** Writes description section of docblocks *) method write_doc_description (doc:string) = let lines = Str.split (Str.regexp "\n") (String.trim doc) and write_line line = let trimmed = String.trim line in if String.length trimmed > 0 then ( if String.get trimmed 0 = '*' then writer#write_line (" " ^ trimmed) else writer#write_line (" * " ^ trimmed) ) in List.iter write_line lines (** Generates docblock for a method and writes it to output buffer *) method write_method_docblock args return_type doc = writer#write_line "/**"; (match doc with | None -> () | Some txt -> self#write_doc_description txt; writer#write_line " * " ); let write_arg arg = match arg with | (arg_name, is_optional, arg_type) -> writer#write_line (" * @param " ^ (writer#use_t arg_type) ^ " $" ^ arg_name) in List.iter write_arg args; if List.length args > 0 then writer#write_line " * "; writer#write_line (" * @return " ^ (writer#use_t return_type)); writer#write_line " */" (** Writes rtti meta to output buffer *) method write_rtti_meta = match Codegen.build_metadata ctx wrapper#get_module_type with | None -> () | Some meta_expr -> let boot_class = writer#use boot_type_path in writer#write (boot_class ^ "::registerMeta(" ^ (self#get_name) ^ "::class, "); writer#write_expr meta_expr; writer#write ");\n" (** Writes type initialization method. *) method private write_hx_init = writer#write_empty_lines; writer#indent 1; writer#write_line "/**"; writer#write_line " * @internal"; writer#write_line " * @access private"; writer#write_line " */"; writer#write_line "static public function __hx__init ()"; writer#write_line "{"; writer#indent_more; writer#write_statement "static $called = false"; writer#write_statement "if ($called) return"; writer#write_statement "$called = true"; writer#write "\n"; writer#reset; (match wrapper#get_magic_init with | None -> () | Some expr -> writer#write_fake_block expr ); writer#write "\n"; writer#reset; self#write_hx_init_body; writer#indent 1; writer#write_line "}" (** Writes method to output buffer *) method private write_method name func = match name with | "__construct" -> self#write_constructor_declaration func | _ -> self#write_method_declaration name func (** Writes constructor declaration (except visibility and `static` keywords) to output buffer *) method private write_constructor_declaration func = if self#extends_no_constructor then writer#extends_no_constructor; writer#write ("function __construct ("); write_args writer#write writer#write_function_arg func.tf_args; writer#write ") {\n"; writer#indent_more; self#write_instance_initialization; let func = inject_defaults ctx func in begin match func.eexpr with | TBlock [] -> () | _ -> writer#write_fake_block func; end; writer#indent_less; writer#write_indentation; writer#write "}" (** Writes method declaration (except visibility and `static` keywords) to output buffer *) method private write_method_declaration name func = let by_ref = if is_ref func.tf_type then "&" else "" in writer#write ("function " ^ by_ref ^ name ^ " ("); write_args writer#write writer#write_function_arg func.tf_args; writer#write ") "; writer#write_expr (inject_defaults ctx func) (** Set sourcemap generator *) method set_sourcemap_generator generator = writer#set_sourcemap_generator generator (** Get sourcemap generator *) method get_sourcemap_generator = writer#get_sourcemap_generator end (** Builds enum contents *) class enum_builder ctx (enm:tenum) = object (self) inherit type_builder ctx (get_wrapper (TEnumDecl enm)) (** Writes type declaration line to output buffer. E.g. "class SomeClass extends Another implements IFace" *) method private write_declaration = self#write_doc (DocClass enm.e_doc); writer#write ("class " ^ self#get_name ^ " extends " ^ (writer#use hxenum_type_path)) (** Writes type body to output buffer. E.g. for "class SomeClass { }" writes part. *) method private write_body = let write_empty_lines = ref false in PMap.iter (fun name field -> if !write_empty_lines then writer#write_empty_lines else write_empty_lines := true; self#write_constructor name field ) enm.e_constrs; self#write_reflection (** Writes constructor declaration to output buffer *) method private write_constructor name (field:tenum_field) = let args = match follow field.ef_type with | TFun (args, _) -> args | TEnum _ -> [] | _ -> fail field.ef_pos (try assert false with Assert_failure mlpos -> mlpos) in writer#indent 1; self#write_doc (DocMethod (args, TEnum (enm, []), field.ef_doc)); writer#write_indentation; writer#write ("static public function " ^ name ^ " ("); write_args writer#write (writer#write_arg true) args; writer#write ") {\n"; writer#indent_more; writer#write_indentation; writer#write "return "; let index_str = string_of_int field.ef_index in (match args with | [] -> writer#write ((writer#use hxenum_type_path) ^ "::singleton(static::class, '" ^ name ^ "', " ^ index_str ^")") | args -> writer#write ("new " ^ self#get_name ^ "('" ^ name ^ "', " ^ index_str ^", ["); write_args writer#write (fun (name, _, _) -> writer#write ("$" ^ name)) args; writer#write "])" ); writer#write ";\n"; writer#indent_less; writer#write_line "}" (** Writes special methods for reflection *) method private write_reflection = (* __hx__list *) writer#write_empty_lines; writer#indent 1; writer#write_line "/**"; writer#write_line " * Returns array of (constructorIndex => constructorName)"; writer#write_line " *"; writer#write_line " * @return string[]"; writer#write_line " */"; writer#write_line "static public function __hx__list () {"; writer#indent_more; writer#write_line "return ["; writer#indent_more; PMap.iter (fun name field -> writer#write_line ((string_of_int field.ef_index) ^ " => '" ^ name ^ "',") ) enm.e_constrs; writer#indent_less; writer#write_statement "]"; writer#indent_less; writer#write_line "}"; (* __hx__paramsCount *) writer#write_empty_lines; writer#indent 1; writer#write_line "/**"; writer#write_line " * Returns array of (constructorName => parametersCount)"; writer#write_line " *"; writer#write_line " * @return int[]"; writer#write_line " */"; writer#write_line "static public function __hx__paramsCount () {"; writer#indent_more; writer#write_line "return ["; writer#indent_more; PMap.iter (fun name field -> let count = match follow field.ef_type with | TFun (params, _) -> List.length params | TEnum _ -> 0 | _ -> fail field.ef_pos (try assert false with Assert_failure mlpos -> mlpos) in writer#write_line ("'" ^ name ^ "' => " ^ (string_of_int count) ^ ",") ) enm.e_constrs; writer#indent_less; writer#write_statement "]"; writer#indent_less; writer#write_line "}"; (** Method `__hx__init` is not needed for enums **) method private write_hx_init_body = () (** No need for additional initialization of enum instances *) method private write_instance_initialization = () (** No need for additional type initialization for enums *) method private write_pre_hx_init = () end (** Builds class contents *) class class_builder ctx (cls:tclass) = object (self) inherit type_builder ctx (get_wrapper (TClassDecl cls)) as super (** Indicates if type should be declared as `final` *) method is_final = if not (Meta.has Meta.Final cls.cl_meta) then false else begin let hacked = ref false in List.iter (fun com_type -> if not !hacked then match com_type with | TClassDecl tcls -> if self#extended_by tcls then hacked := Meta.has Meta.Hack tcls.cl_meta | _ -> () ) ctx.types; not !hacked end (** Indicates if `field` should be declared as `final` *) method is_final_field (field:tclass_field) : bool = Meta.has Meta.Final field.cf_meta (** Check if there is no native php constructor in inheritance chain of this class. E.g. `StsClass` does have a constructor while still can be called with `new StdClass()`. So this method will return true for `MyClass` if `MyClass extends StdClass`. *) method private extends_no_constructor = let rec extends_no_constructor tcls = match tcls.cl_super with | None -> true | Some (parent, _) -> if Meta.has Meta.PhpNoConstructor parent.cl_meta then true else match parent.cl_constructor with | Some _ -> false | None -> extends_no_constructor parent in extends_no_constructor cls (** Recursively check if current class is a parent class for a `child` *) method private extended_by child = let result = if child == cls then false else let rec check current = match current.cl_super with | None -> false | Some (scls, _) -> if scls == cls then true else check scls in check child in result (** Writes type declaration line to output buffer. E.g. "class SomeClass extends Another implements IFace" *) method private write_declaration = if self#is_final then writer#write "final "; self#write_doc (DocClass cls.cl_doc); writer#write (if cls.cl_interface then "interface " else "class "); writer#write self#get_name; ( match cls.cl_super with | None -> (); | Some (super_class, params) -> let super_name = writer#use_t (TInst (super_class, params)) in writer#write (" extends " ^ super_name) ); if List.length cls.cl_implements > 0 then begin writer#write (if cls.cl_interface then " extends " else " implements "); let use_interface iface = match iface with | (i, params) -> writer#use_t (TInst (i, params)) in (* Do not add interfaces which are implemented through other interfaces inheritance *) let unique = List.filter (fun (iface, _) -> not (List.exists (fun (probably_descendant, _) -> if probably_descendant == iface then false else is_parent iface probably_descendant ) cls.cl_implements ) ) cls.cl_implements in let interfaces = List.map use_interface unique in writer#write (String.concat ", " interfaces); end; (** Returns either user-defined constructor or creates empty constructor if instance initialization is required. *) method private get_constructor : tclass_field option = match cls.cl_constructor with | Some field -> Some field | None -> if not self#constructor_is_required then None else Some { cf_name = "new"; cf_type = TFun ([], get_void ctx); cf_public = true; cf_pos = cls.cl_pos; cf_name_pos = cls.cl_pos; cf_doc = None; cf_meta = []; cf_kind = Method MethNormal; cf_params = []; cf_expr = Some { eexpr = TFunction { tf_args = []; tf_type = get_void ctx; tf_expr = { eexpr = TBlock []; epos = cls.cl_pos; etype = get_void ctx; }; }; epos = cls.cl_pos; etype = get_void ctx; }; cf_expr_unoptimized = None; cf_overloads = []; } (** Writes type body to output buffer. E.g. for "class SomeClass { }" writes part. *) method private write_body = let at_least_one_field_written = ref false in let write_if_constant _ field = match field.cf_kind with | Var { v_read = AccInline; v_write = AccNever } -> at_least_one_field_written := true; self#write_field true field | _ -> () and write_if_method is_static _ field = match field.cf_kind with | Var _ -> () | Method MethDynamic when is_static -> () | Method _ -> if !at_least_one_field_written then writer#write_empty_lines; at_least_one_field_written := true; self#write_field is_static field and write_if_var is_static _ field = match field.cf_kind with | Var { v_read = AccInline; v_write = AccNever } -> () | Method MethDynamic -> at_least_one_field_written := true; let kind = Var { v_read = AccNormal; v_write = AccNormal; } in self#write_field is_static { field with cf_kind = kind } | Var _ -> at_least_one_field_written := true; self#write_field is_static field | Method _ -> () in if boot_type_path = self#get_type_path then begin self#write_php_prefix (); at_least_one_field_written := true end; if not cls.cl_interface then begin (* Inlined statc vars (constants) *) PMap.iter (write_if_constant) cls.cl_statics; if !at_least_one_field_written then writer#write_empty_lines; at_least_one_field_written := false; (* Statc vars *) PMap.iter (write_if_var true) cls.cl_statics; if !at_least_one_field_written then writer#write_empty_lines; at_least_one_field_written := false; (* instance vars *) PMap.iter (write_if_var false) cls.cl_fields end; (* Statc methods *) PMap.iter (write_if_method true) cls.cl_statics; (* Constructor *) (match self#get_constructor with | Some field -> write_if_method false "new" field | None -> () ); (* Instance methods *) PMap.iter (write_if_method false) cls.cl_fields; (* Generate `__toString()` if not defined by user, but has `toString()` *) self#write_toString_if_required method private write_toString_if_required = if PMap.exists "toString" cls.cl_fields then if (not cls.cl_interface) && (not (PMap.exists "__toString" cls.cl_statics)) && (not (PMap.exists "__toString" cls.cl_fields)) then begin writer#write_empty_lines; writer#indent 1; writer#write_line "public function __toString() {"; writer#indent_more; writer#write_line "return $this->toString();"; writer#indent_less; writer#write_line "}" end (** Check if this class requires constructor to be generated even if there is no user-defined one *) method private constructor_is_required = if List.length self#get_namespace > 0 then false else begin let required = ref false in List.iter (fun field -> if not !required then required := (String.lowercase field.cf_name = String.lowercase self#get_name) ) (cls.cl_ordered_statics @ cls.cl_ordered_fields); !required end (** Writes `--php-prefix` value as class constant PHP_PREFIX *) method private write_php_prefix () = let prefix = String.concat "\\" (get_php_prefix ctx) in let indentation = writer#get_indentation in writer#indent 1; writer#write_statement ("const PHP_PREFIX = \"" ^ (String.escaped prefix) ^ "\""); writer#indent indentation (** Writes expressions for `__hx__init` method *) method private write_hx_init_body = (* `static dynamic function` initialization *) let write_dynamic_method_initialization field = let field_access = "self::$" ^ (field_name field) in writer#write_indentation; writer#write (field_access ^ " = "); (match field.cf_expr with | Some expr -> writer#write_expr expr | None -> fail field.cf_pos (try assert false with Assert_failure mlpos -> mlpos) ); writer#write ";\n" in PMap.iter (fun _ field -> match field.cf_kind with | Method MethDynamic -> write_dynamic_method_initialization field | _ -> () ) cls.cl_statics; (* `static var` initialization *) let write_var_initialization field = let write_assign expr = writer#write_indentation; writer#write ("self::$" ^ (field_name field) ^ " = "); writer#write_expr expr in (* Do not generate fields for RTTI meta, because this generator uses another way to store it. Also skip initialization for `inline var` fields as those are generated as PHP class constants. *) let is_auto_meta_var = field.cf_name = "__meta__" && (has_rtti_meta ctx wrapper#get_module_type) in if (is_var_with_nonconstant_expr field) && (not is_auto_meta_var) && (not (is_inline_var field)) then begin (match field.cf_expr with | None -> () (* There can be not-inlined blocks when compiling with `-debug` *) | Some { eexpr = TBlock exprs } -> let rec write_per_line exprs = match exprs with | [] -> () | [expr] -> write_assign expr | expr :: rest -> writer#write_indentation; writer#write_expr expr; writer#write ";\n"; write_per_line rest in write_per_line exprs | Some expr -> write_assign expr ); writer#write ";\n" end in List.iter write_var_initialization cls.cl_ordered_statics (** Writes single field to output buffer. *) method private write_field is_static field = match field.cf_kind with | Var { v_read = AccInline; v_write = AccNever } -> self#write_const field | Var _ when not (is_extern_field field) -> (* Do not generate fields for RTTI meta, because this generator uses another way to store it *) let is_auto_meta_var = is_static && field.cf_name = "__meta__" && (has_rtti_meta ctx wrapper#get_module_type) in if not is_auto_meta_var then self#write_var field is_static; | Var _ -> () | Method MethMacro -> () | Method MethDynamic when is_static -> () | Method MethDynamic -> self#write_dynamic_method field | Method _ -> self#write_class_method field is_static (** Writes var-field to output buffer *) method private write_var field is_static = writer#indent 1; self#write_doc (DocVar (writer#use_t field.cf_type, field.cf_doc)); writer#write_indentation; if is_static then writer#write "static "; let visibility = get_visibility field.cf_meta in writer#write (visibility ^ " $" ^ (field_name field)); match field.cf_expr with | None -> writer#write ";\n" | Some expr -> match expr.eexpr with | TConst _ -> writer#write " = "; writer#write_expr expr; writer#write ";\n" | _ -> writer#write ";\n" (** Writes "inline var" to output buffer as constant *) method private write_const field = match field.cf_expr with | None -> fail writer#pos (try assert false with Assert_failure mlpos -> mlpos) (* Do not generate a PHP constant of `inline var` field if expression is not compatible with PHP const *) | Some expr when not (is_constant expr) -> () | Some expr -> writer#indent 1; self#write_doc (DocVar (writer#use_t field.cf_type, field.cf_doc)); writer#write_indentation; writer#write ("const " ^ (field_name field) ^ " = "); writer#write_expr expr; writer#write ";\n" (** Writes method to output buffer *) method private write_class_method field is_static = writer#reset; writer#indent 1; let (args, return_type) = get_function_signature field in List.iter (fun (arg_name, _, _) -> writer#declared_local_var arg_name) args; self#write_doc (DocMethod (args, return_type, field.cf_doc)); writer#write_indentation; if self#is_final_field field then writer#write "final "; if is_static then writer#write "static "; writer#write ((get_visibility field.cf_meta) ^ " "); match field.cf_expr with | None -> writer#write ("function " ^ (field_name field) ^ " ("); write_args writer#write (writer#write_arg true) args; writer#write ")"; writer#write " ;\n" | Some { eexpr = TFunction fn } -> let name = if field.cf_name = "new" then "__construct" else (field_name field) in self#write_method name fn; writer#write "\n" | _ -> fail field.cf_pos (try assert false with Assert_failure mlpos -> mlpos) (** Writes dynamic method to output buffer. Only for non-static methods. Static methods are created as static vars in `__hx__init`. *) method private write_dynamic_method field = writer#reset; writer#indent 1; let (args, return_type) = get_function_signature field in List.iter (fun (arg_name, _, _) -> writer#declared_local_var arg_name) args; self#write_doc (DocMethod (args, return_type, field.cf_doc)); writer#write_indentation; writer#write ((get_visibility field.cf_meta) ^ " function " ^ (field_name field)); (match field.cf_expr with | None -> (* interface *) writer#write " ("; write_args writer#write (writer#write_arg true) args; writer#write ");\n"; | Some { eexpr = TFunction fn } -> (* normal class *) writer#write " ("; write_args writer#write writer#write_function_arg fn.tf_args; writer#write ")\n"; writer#write_line "{"; writer#indent_more; writer#write_indentation; let field_access = "$this->" ^ (field_name field) and default_value = "$this->__hx__default__" ^ (field_name field) in writer#write ("if (" ^ field_access ^ " !== " ^ default_value ^ ") return call_user_func_array(" ^ field_access ^ ", func_get_args());\n"); writer#write_fake_block fn.tf_expr; writer#indent_less; writer#write_line "}"; (* Don't forget to create a field for default value *) writer#write_statement ("protected $__hx__default__" ^ (field_name field)) | _ -> fail field.cf_pos (try assert false with Assert_failure mlpos -> mlpos) ); (** Writes initialization code for instances of this class *) method private write_instance_initialization = let init_dynamic_method field = let field_name = field_name field in let default_field = "$this->__hx__default__" ^ field_name in writer#write_line ("if (!" ^ default_field ^ ") {"); writer#indent_more; writer#write_statement (default_field ^ " = new " ^ (writer#use hxclosure_type_path) ^ "($this, '" ^ field_name ^ "')"); writer#write_statement ("if ($this->" ^ field_name ^ " === null) $this->" ^ field_name ^ " = " ^ default_field); writer#indent_less; writer#write_line "}" in List.iter (fun field -> match field.cf_kind with | Method MethDynamic -> init_dynamic_method field | _ -> () ) cls.cl_ordered_fields (** Writes additional initialization code, which should be called before `__hx__init()` *) method private write_pre_hx_init = let getters = ref [] and setters = ref [] in let collect field = match field.cf_kind with | Var { v_read = read; v_write = write } -> if read = AccCall then getters := field.cf_name :: !getters; if write = AccCall then setters := field.cf_name :: !setters; | _ -> () in List.iter collect cls.cl_ordered_fields; List.iter collect cls.cl_ordered_statics; let rec write lst = match lst with | [] -> () | [item] -> writer#write_line ("'" ^ item ^ "' => true"); | item :: rest -> writer#write_line ("'" ^ item ^ "' => true,"); write rest and type_name = get_full_type_name ~escape:true ~omit_first_slash:true (add_php_prefix ctx wrapper#get_type_path) in let write_register register_method lst = writer#write_line ((writer#use boot_type_path) ^ "::" ^ register_method ^ "('" ^ type_name ^ "', ["); writer#indent_more; write lst; writer#indent_less; writer#write_statement "])" in if List.length !getters > 0 then write_register "registerGetters" !getters; if List.length !setters > 0 then write_register "registerSetters" !setters; end (** Handles generation process *) class generator (ctx:context) = object (self) val mutable build_dir = "" val root_dir = ctx.file val mutable init_types = [] val mutable boot : (type_builder * string) option = None (** Perform required actions before actual php files generation *) method initialize = self#create_output_dirs; (** Generates php file for specified type *) method generate (builder:type_builder) = let namespace = builder#get_namespace and name = builder#get_name in let filename = (create_dir_recursive (build_dir :: namespace)) ^ "/" ^ name ^ ".php" in let channel = open_out filename in if Common.defined ctx Define.SourceMap then builder#set_sourcemap_generator (new sourcemap_builder filename); output_string channel builder#get_contents; close_out channel; (match builder#get_sourcemap_generator with | Some smap -> smap#generate ctx | None -> () ); if builder#get_type_path = boot_type_path then boot <- Some (builder, filename) else if builder#has_magic_init then init_types <- (get_full_type_name (namespace, name)) :: init_types (** Perform actions which should be executed after all classes were processed *) method finalize : unit = self#generate_magic_init; self#generate_entry_point; (** Generates calls to static __init__ methods in Boot.php *) method generate_magic_init : unit = match init_types with | [] -> () | _ -> match boot with | None -> fail dummy_pos (try assert false with Assert_failure mlpos -> mlpos) | Some (_, filename) -> let channel = open_out_gen [Open_creat; Open_text; Open_append] 0o644 filename in List.iter (fun class_name -> output_string channel (class_name ^ "::__hx__init();\n")) init_types; close_out channel (** Creates `index.php` which can be used as entry-point for standalone Haxe->PHP app *) method generate_entry_point = match self#get_entry_point with | None -> () | Some (uses, entry_point) -> let filename = match ctx.php_front with None -> "index.php" | Some n -> n in let channel = open_out (root_dir ^ "/" ^ filename) in output_string channel " fail dummy_pos (try assert false with Assert_failure mlpos -> mlpos) | Some (builder, filename) -> let boot_class = get_full_type_name (add_php_prefix ctx builder#get_type_path) in output_string channel (boot_class ^ "::__hx__init();\n") ); output_string channel entry_point; close_out channel (** Create necessary directories before processing types *) method private create_output_dirs = let build_path = (root_dir :: self#get_lib_path) in build_dir <- create_dir_recursive build_path (** Returns path from `index.php` to directory which will contain all generated classes *) method private get_lib_path : string list = match ctx.php_lib with | None -> ["lib"]; | Some path -> (Str.split (Str.regexp "/") path) (** Returns PHP code for entry point *) method private get_entry_point : (string * string) option = match ctx.main with | None -> None | Some expr -> let writer = new code_writer ctx ([], "") "" in writer#write_as_block ~inline:true expr; let code = writer#get_contents in writer#clear_contents; writer#write_use; let uses = writer#get_contents in Some (uses, code) end (** Entry point to Genphp7 *) let generate (com:context) = skip_line_directives := Common.defined com Define.RealPosition; let gen = new generator com in gen#initialize; let rec generate com_type = let wrapper = get_wrapper com_type in if wrapper#needs_generation then (match com_type with | TClassDecl cls -> gen#generate (new class_builder com cls); | TEnumDecl enm -> gen#generate (new enum_builder com enm); | TTypeDecl typedef -> (); | TAbstractDecl abstr -> () ); match wrapper#get_service_type with | None -> () | Some service_type -> generate service_type in List.iter generate com.types; gen#finalize; Hashtbl.iter (fun name data -> write_resource com.file name data ) com.resources; clear_wrappers (); haxe_3.4.4.orig/src/generators/genpy.ml0000664000175000017500000025453113166552354020042 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open Ast open Type open Common open Codegen.ExprBuilder module Utils = struct let class_of_module_type mt = match mt with | TClassDecl c -> c | _ -> failwith ("Not a class: " ^ (s_type_path (t_infos mt).mt_path)) let find_type com path = try List.find (fun mt -> match mt with | TAbstractDecl _ -> false | _ -> (t_infos mt).mt_path = path ) com.types with Not_found -> abort (Printf.sprintf "Could not find type %s\n" (s_type_path path)) null_pos let mk_static_field c cf p = let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in let ethis = mk (TTypeExpr (TClassDecl c)) ta p in let t = monomorphs cf.cf_params cf.cf_type in mk (TField (ethis,(FStatic (c,cf)))) t p let mk_static_call c cf el p = let ef = mk_static_field c cf p in let tr = match follow ef.etype with | TFun(args,tr) -> tr | _ -> assert false in mk (TCall(ef,el)) tr p let resolve_static_field c n = try PMap.find n c.cl_statics with Not_found -> failwith (Printf.sprintf "Class %s has no field %s" (s_type_path c.cl_path) n) let mk_static_field_2 c n p = mk_static_field c (resolve_static_field c n) p let mk_static_call_2 c n el p = mk_static_call c (resolve_static_field c n) el p end module KeywordHandler = struct let kwds = let h = Hashtbl.create 0 in List.iter (fun s -> Hashtbl.add h s ()) [ "and"; "as"; "assert"; "break"; "class"; "continue"; "def"; "del"; "elif"; "else"; "except"; "exec"; "finally"; "for"; "from"; "global"; "if"; "import"; "in"; "is"; "lambda"; "not"; "or"; "pass"; " raise"; "return"; "try"; "while"; "with"; "yield"; "None"; "True"; "False"; ]; h let kwds2 = let h = Hashtbl.create 0 in List.iter (fun s -> Hashtbl.add h s ()) [ "len"; "int"; "float"; "list"; "bool"; "str"; "isinstance"; "print"; "min"; "max"; "hasattr"; "getattr"; "setattr"; "delattr"; "callable"; "type"; "ord"; "chr"; "iter"; "map"; "filter"; "tuple"; "dict"; "set"; "bytes"; "bytearray"; "self"; ]; h let handle_keywords s = let l = String.length s in if Hashtbl.mem kwds s then "_hx_" ^ s (* handle special __ underscore behaviour (creates private fields for objects) for fields but only if the field doesn't end with at least one underscores like __iter__ because these are special fields *) else if l > 2 && String.sub s 0 2 = "__" && String.sub s (l - 1) 1 <> "_" then "_hx_" ^ s else s let check_var_declaration v = if not (Meta.has Meta.This v.v_meta) then if Hashtbl.mem kwds2 v.v_name then v.v_name <- "_hx_" ^ v.v_name end module Transformer = struct type adjusted_expr = { a_expr : texpr; a_blocks : texpr list; a_next_id : unit -> string; a_is_value : bool; } let como = ref None let t_bool = ref t_dynamic let t_void = ref t_dynamic let t_string = ref t_dynamic let t_int = ref t_dynamic let c_reflect = ref (fun () -> null_class) let init com = como := Some com; t_bool := com.basic.tbool; t_void := com.basic.tvoid; t_string := com.basic.tstring; t_int := com.basic.tint; c_reflect := fun () -> Utils.class_of_module_type (Utils.find_type com ([],"Reflect")) and debug_expr e = let s_type = Type.s_type (print_context()) in let s = Type.s_expr_pretty false " " false s_type e in Printf.printf "%s\n" s and debug_expr_with_type e = let s_type = Type.s_type (print_context()) in let es = Type.s_expr_pretty false " " false s_type e in let t = s_type e.etype in Printf.printf "%s : %s\n" es t and debug_type t = let s_type = Type.s_type (print_context()) in let t = s_type t in Printf.printf "%s\n" t let new_counter () = let n = ref (-1) in (fun () -> incr n; Printf.sprintf "_hx_local_%i" !n ) let to_expr ae = match ae.a_blocks with | [] -> ae.a_expr | el -> match ae.a_expr.eexpr with | TBlock el2 -> { ae.a_expr with eexpr = TBlock (el @ el2) } | _ -> { ae.a_expr with eexpr = TBlock (el @ [ae.a_expr])} let lift_expr ?(is_value = false) ?(next_id = None) ?(blocks = []) e = let next_id = match next_id with | None -> new_counter() | Some f -> f in { a_expr = e; a_blocks = blocks; a_next_id = next_id; a_is_value = is_value } let lift_expr1 is_value next_id blocks e = lift_expr ~is_value:is_value ~next_id:(Some next_id) ~blocks:blocks e let to_tvar ?(capture = false) n t p = alloc_var n t p (* { v_name = n; v_type = t; v_id = 0; v_capture = capture; v_extra = None; v_meta = [] } *) let create_non_local n pos = let s = "nonlocal " ^ (KeywordHandler.handle_keywords n) in (* TODO: this is a hack... *) let id = mk (TLocal (to_tvar "python_Syntax._pythonCode" t_dynamic pos) ) !t_void pos in let id2 = mk (TLocal( to_tvar s t_dynamic pos)) !t_void pos in mk (TCall(id, [id2])) t_dynamic pos let to_tlocal_expr ?(capture = false) n t p = mk (TLocal (to_tvar ~capture:capture n t p)) t p let check_unification e t = match follow e.etype,follow t with | TAnon an1, TAnon an2 -> PMap.iter (fun s cf -> if not (PMap.mem s an1.a_fields) then an1.a_fields <- PMap.add s cf an1.a_fields ) an2.a_fields; e | _ -> e let dynamic_field_read e s t = let e = Utils.mk_static_call_2 ((!c_reflect)()) "field" [e;mk (TConst (TString s)) !t_string e.epos] e.epos in { e with etype = t } let dynamic_field_write e1 s e2 = Utils.mk_static_call_2 ((!c_reflect)()) "setField" [e1;mk (TConst (TString s)) !t_string e1.epos;e2] e1.epos let dynamic_field_read_write next_id e1 s op e2 t = let id = next_id() in let temp_var = to_tvar id e1.etype e1.epos in let temp_var_def = mk (TVar(temp_var,Some e1)) e1.etype e1.epos in let temp_local = mk (TLocal temp_var) e1.etype e1.epos in let e_field = dynamic_field_read temp_local s t in let e_op = mk (TBinop(op,e_field,e2)) e_field.etype e_field.epos in let e_set_field = dynamic_field_write temp_local s e_op in mk (TBlock [ temp_var_def; e_set_field; ]) e_set_field.etype e_set_field.epos let add_non_locals_to_func e = match e.eexpr with | TFunction tf -> let cur = ref PMap.empty in let save () = let prev = !cur in (fun () -> cur := prev ) in let declare v = cur := PMap.add v.v_id v !cur; in List.iter (fun (v,_) -> declare v) tf.tf_args; let non_locals = Hashtbl.create 0 in let rec it e = match e.eexpr with | TVar(v,e1) -> begin match e1 with | Some e -> maybe_continue e | None -> () end; declare v; | TTry(e1,catches) -> it e1; List.iter (fun (v,e) -> let restore = save() in declare v; it e; restore() ) catches; | TBinop( (OpAssign | OpAssignOp(_)), { eexpr = TLocal v }, e2) -> if not (PMap.mem v.v_id !cur) then Hashtbl.add non_locals v.v_id v; maybe_continue e2; | TFunction _ -> () | _ -> Type.iter it e and maybe_continue e = match e.eexpr with | TFunction _ -> () | _ -> it e in it tf.tf_expr; let el = Hashtbl.fold (fun k v acc -> (create_non_local v.v_name e.epos) :: acc ) non_locals [] in let el = tf.tf_expr :: el in let tf = { tf with tf_expr = { tf.tf_expr with eexpr = TBlock(List.rev el)}} in {e with eexpr = TFunction tf} | _ -> assert false let rec transform_function tf ae is_value = let p = tf.tf_expr.epos in let assigns = List.fold_left (fun acc (v,value) -> KeywordHandler.check_var_declaration v; match value with | None | Some TNull -> acc | Some ct -> let a_local = mk (TLocal v) v.v_type p in let a_null = mk (TConst TNull) v.v_type p in let a_cmp = mk (TBinop(OpEq,a_local,a_null)) !t_bool p in let a_value = mk (TConst(ct)) v.v_type p in let a_assign = mk (TBinop(OpAssign,a_local,a_value)) v.v_type p in let a_if = mk (TIf(a_cmp,a_assign,None)) !t_void p in a_if :: acc ) [] tf.tf_args in let body = match assigns with | [] -> tf.tf_expr | _ -> let eb = mk (TBlock (List.rev assigns)) t_dynamic p in Type.concat eb tf.tf_expr in let e1 = to_expr (transform_expr ~next_id:(Some ae.a_next_id) body) in let fn = mk (TFunction({ tf_expr = e1; tf_args = tf.tf_args; tf_type = tf.tf_type; })) ae.a_expr.etype p in let fn = add_non_locals_to_func fn in if is_value then begin let new_name = ae.a_next_id() in let new_var = alloc_var new_name tf.tf_type p in let new_local = mk (TLocal new_var) fn.etype p in let def = mk (TVar(new_var,Some fn)) fn.etype p in lift_expr1 false ae.a_next_id [def] new_local end else lift_expr fn and transform_var_expr ae eo v = KeywordHandler.check_var_declaration v; let b,new_expr = match eo with | None -> [],None | Some e1 -> let f = transform_expr1 true ae.a_next_id [] e1 in let b = f.a_blocks in b,Some(f.a_expr) in let e = mk (TVar(v,new_expr)) ae.a_expr.etype ae.a_expr.epos in lift_expr ~next_id:(Some ae.a_next_id) ~blocks:b e and transform_expr ?(is_value = false) ?(next_id = None) ?(blocks = []) (e : texpr) : adjusted_expr = transform1 (lift_expr ~is_value ~next_id ~blocks e) and transform_expr1 is_value next_id blocks e = transform_expr ~is_value ~next_id:(Some next_id) ~blocks e and transform_exprs_to_block el tb is_value p next_id = match el with | [e] -> transform_expr ~is_value ~next_id:(Some next_id) e | _ -> let size = List.length el in let res = DynArray.create () in ExtList.List.iteri (fun i e -> (* this removes len(x) calls which are reproduced by the inlined return of Array.push even if the value is not used *) let is_removable_statement e = (not is_value || i < size-1) && match e.eexpr with | TField(_, FInstance({cl_path = [],"list"},_,{ cf_name = "length" })) -> true | _ -> false in if not (is_removable_statement e) then let ae = transform_expr ~is_value ~next_id:(Some next_id) e in List.iter (DynArray.add res) ae.a_blocks; DynArray.add res ae.a_expr else () ) el; lift_expr (mk (TBlock (DynArray.to_list res)) tb p) and transform_switch ae is_value e1 cases edef = let case_functions = ref [] in let case_to_if (el,e) eelse = let val_reversed = List.rev el in let mk_eq e = mk (TBinop(OpEq,e1,e)) !t_bool (punion e1.epos e.epos) in let cond = match val_reversed with | [] -> assert false | [e] -> mk_eq e | e :: el -> List.fold_left (fun eelse e -> mk (TBinop(OpBoolOr,eelse,mk_eq e)) !t_bool (punion eelse.epos e.epos)) (mk_eq e) el in let eif = if is_value then begin let name = ae.a_next_id() in let func = exprs_to_func [e] name ae in case_functions := !case_functions @ func.a_blocks; let call = func.a_expr in mk (TIf(cond,call,eelse)) ae.a_expr.etype ae.a_expr.epos end else mk (TIf(cond,e,eelse)) ae.a_expr.etype e.epos in eif in let rev_cases = List.rev cases in let edef = Some (match edef with | None -> mk (TBlock []) ae.a_expr.etype ae.a_expr.epos | Some e -> e) in let res = match rev_cases,edef with | [],Some edef -> edef | [],None -> (* I don't think that can happen? *) assert false | [case],_ -> case_to_if case edef | case :: cases,_ -> List.fold_left (fun acc case -> case_to_if case (Some acc)) (case_to_if case edef) cases in let res = if is_value then mk (TBlock ((List.rev (res :: !case_functions)))) res.etype res.epos else res in forward_transform res ae and transform_string_switch ae is_value e1 cases edef = let length_map = Hashtbl.create 0 in List.iter (fun (el,e) -> List.iter (fun es -> match es.eexpr with | TConst (TString s) -> let l = UTF8.length s in let sl = try Hashtbl.find length_map l with Not_found -> let sl = ref [] in Hashtbl.replace length_map l sl; sl in sl := ([es],e) :: !sl; | _ -> () ) el ) cases; if Hashtbl.length length_map < 2 then transform_switch ae is_value e1 cases edef else let mk_eq e1 e2 = mk (TBinop(OpEq,e1,e2)) !t_bool (punion e1.epos e2.epos) in let mk_or e1 e2 = mk (TBinop(OpOr,e1,e2)) !t_bool (punion e1.epos e2.epos) in let mk_if (el,e) eo = let eif = List.fold_left (fun eacc e -> mk_or eacc (mk_eq e1 e)) (mk_eq e1 (List.hd el)) (List.tl el) in mk (TIf(Codegen.mk_parent eif,e,eo)) e.etype e.epos in let cases = Hashtbl.fold (fun i el acc -> let eint = mk (TConst (TInt (Int32.of_int i))) !t_int e1.epos in let fs = match List.fold_left (fun eacc ec -> Some (mk_if ec eacc)) edef !el with Some e -> e | None -> assert false in ([eint],fs) :: acc ) length_map [] in let c_string = match !t_string with TInst(c,_) -> c | _ -> assert false in let cf_length = PMap.find "length" c_string.cl_fields in let ef = mk (TField(e1,FInstance(c_string,[],cf_length))) !t_int e1.epos in let res_var = alloc_var (ae.a_next_id()) ef.etype ef.epos in let res_local = {ef with eexpr = TLocal res_var} in let var_expr = {ef with eexpr = TVar(res_var,Some ef)} in let e = mk (TBlock [ var_expr; mk (TSwitch(res_local,cases,edef)) ae.a_expr.etype e1.epos ]) ae.a_expr.etype e1.epos in forward_transform e ae and transform_op_assign_op ae e1 op one is_value post = let e1_ = transform_expr e1 ~is_value:true ~next_id:(Some ae.a_next_id) in let handle_as_local temp_local = let ex = ae.a_expr in let res_var = alloc_var (ae.a_next_id()) ex.etype ex.epos in let res_local = {ex with eexpr = TLocal res_var} in let plus = {ex with eexpr = TBinop(op,temp_local,one)} in let var_expr = {ex with eexpr = TVar(res_var,Some temp_local)} in let assign_expr = {ex with eexpr = TBinop(OpAssign,e1_.a_expr,plus)} in let blocks = if post then [var_expr;assign_expr;res_local] else [assign_expr;temp_local] in (* TODO: block is ignored in the else case? *) let block = e1_.a_blocks @ blocks in if is_value then begin let f = exprs_to_func block (ae.a_next_id()) ae in lift_expr f.a_expr ~is_value:true ~next_id:(Some ae.a_next_id) ~blocks:f.a_blocks end else begin let block = e1_.a_blocks @ [assign_expr] in transform_exprs_to_block block ex.etype false ex.epos ae.a_next_id end in match e1_.a_expr.eexpr with | TArray({eexpr = TLocal _},{eexpr = TLocal _}) | TField({eexpr = TLocal _},_) | TLocal _ -> handle_as_local e1_.a_expr | TArray(e1,e2) -> let id = ae.a_next_id() in let temp_var_l = alloc_var id e1.etype e1.epos in let temp_local_l = {e1 with eexpr = TLocal temp_var_l} in let temp_var_l = {e1 with eexpr = TVar(temp_var_l,Some e1)} in let id = ae.a_next_id() in let temp_var_r = alloc_var id e2.etype e2.epos in let temp_local_r = {e2 with eexpr = TLocal temp_var_r} in let temp_var_r = {e2 with eexpr = TVar(temp_var_r,Some e2)} in let id = ae.a_next_id() in let temp_var = alloc_var id e1_.a_expr.etype e1_.a_expr.epos in let temp_local = {e1_.a_expr with eexpr = TLocal temp_var} in let temp_var_expr = {e1_.a_expr with eexpr = TArray(temp_local_l,temp_local_r)} in let temp_var = {e1_.a_expr with eexpr = TVar(temp_var,Some temp_var_expr)} in let plus = {ae.a_expr with eexpr = TBinop(op,temp_local,one)} in let assign_expr = {ae.a_expr with eexpr = TBinop(OpAssign,temp_var_expr,plus)} in let block = e1_.a_blocks @ [temp_var_l;temp_var_r;temp_var;assign_expr;if post then temp_local else temp_var_expr] in if is_value then begin let f = exprs_to_func block (ae.a_next_id()) ae in lift_expr f.a_expr ~is_value:true ~next_id:(Some ae.a_next_id) ~blocks:f.a_blocks end else transform_exprs_to_block block ae.a_expr.etype false ae.a_expr.epos ae.a_next_id | TField(e1,fa) -> let temp_var_l = alloc_var (ae.a_next_id()) e1.etype e1.epos in let temp_local_l = {e1 with eexpr = TLocal temp_var_l} in let temp_var_l = {e1 with eexpr = TVar(temp_var_l,Some e1)} in let temp_var = alloc_var (ae.a_next_id()) e1_.a_expr.etype e1_.a_expr.epos in let temp_local = {e1_.a_expr with eexpr = TLocal temp_var} in let temp_var_expr = {e1_.a_expr with eexpr = TField(temp_local_l,fa)} in let temp_var = {e1_.a_expr with eexpr = TVar(temp_var,Some temp_var_expr)} in let plus = {ae.a_expr with eexpr = TBinop(op,temp_local,one)} in let assign_expr = {ae.a_expr with eexpr = TBinop(OpAssign,temp_var_expr,plus)} in let block = e1_.a_blocks @ [temp_var_l;temp_var;assign_expr;if post then temp_local else temp_var_expr] in if is_value then begin let f = exprs_to_func block (ae.a_next_id()) ae in lift_expr f.a_expr ~is_value:true ~next_id:(Some ae.a_next_id) ~blocks:f.a_blocks end else transform_exprs_to_block block ae.a_expr.etype false ae.a_expr.epos ae.a_next_id | _ -> debug_expr e1_.a_expr; assert false and var_to_treturn_expr ?(capture = false) n t p = let x = mk (TLocal (to_tvar ~capture:capture n t p)) t p in mk (TReturn (Some x)) t p and exprs_to_func exprs name base = let convert_return_expr (expr:texpr) = match expr.eexpr with | TWhile(_,_,_) -> let ret = { expr with eexpr = TReturn (None) } in [expr; ret] | TFunction(f) -> let ret = var_to_treturn_expr name f.tf_type f.tf_expr.epos in [expr;ret] | TBinop(OpAssign, l, r) -> let r = { l with eexpr = TReturn(Some l) } in [expr; r] | x -> let ret_expr = { expr with eexpr = TReturn( Some(expr) )} in [ret_expr] in let def = (let ex = match exprs with | [] -> assert false | [x] -> (let exs = convert_return_expr x in match exs with | [] -> assert false | [x] -> x | x -> match List.rev x with | x::xs -> mk (TBlock exs) x.etype base.a_expr.epos | _ -> assert false) | x -> match List.rev x with | x::xs -> (let ret = x in let tail = List.rev xs in let block = tail @ (convert_return_expr ret) in match List.rev block with | x::_ -> mk (TBlock block) x.etype base.a_expr.epos | _ -> assert false) | _ -> assert false in let f1 = { tf_args = []; tf_type = TFun([],ex.etype); tf_expr = ex} in let fexpr = mk (TFunction f1) ex.etype ex.epos in let fvar = to_tvar name fexpr.etype fexpr.epos in let f = add_non_locals_to_func fexpr in let assign = { ex with eexpr = TVar(fvar, Some(f))} in let call_expr = (mk (TLocal fvar) fexpr.etype ex.epos ) in let substitute = mk (TCall(call_expr, [])) ex.etype ex.epos in lift_expr ~blocks:[assign] substitute) in match exprs with | [{ eexpr = TFunction({ tf_args = []} as f) } as x] -> let l = to_tlocal_expr name f.tf_type f.tf_expr.epos in let substitute = mk (TCall(l, [])) f.tf_type f.tf_expr.epos in lift_expr ~blocks:[x] substitute | _ -> def and transform_call is_value e params ae = let trans is_value blocks e = transform_expr1 is_value ae.a_next_id blocks e in let trans1 e params = let e = trans true [] e in let blocks = e.a_blocks @ (List.flatten (List.map (fun (p) -> p.a_blocks) params)) in let params = List.map (fun (p) -> p.a_expr) params in let e = { ae.a_expr with eexpr = TCall(e.a_expr, params) } in lift_expr ~blocks:blocks e in match e, params with (* the foreach block should not be handled as a value *) | ({ eexpr = TField(_, FStatic({cl_path = ["python";],"Syntax"},{ cf_name = "_foreach" }))} as e, [e1;e2;e3]) -> trans1 e [trans true [] e1; trans true [] e2; trans false [] e3] | (e, params) -> trans1 e (List.map (trans true []) params) and transform1 ae : adjusted_expr = let trans is_value blocks e = transform_expr1 is_value ae.a_next_id blocks e in let lift is_value blocks e = lift_expr1 is_value ae.a_next_id blocks e in let a_expr = ae.a_expr in match ae.a_is_value,ae.a_expr.eexpr with | (is_value,TBlock [x]) -> trans is_value [] x | (false,TBlock []) -> lift_expr a_expr | (true,TBlock []) -> lift_expr (mk (TConst TNull) ae.a_expr.etype ae.a_expr.epos) | (false,TBlock el) -> transform_exprs_to_block el ae.a_expr.etype false ae.a_expr.epos ae.a_next_id | (true,TBlock el) -> let name = ae.a_next_id() in let block,tr = match List.rev el with | e :: el -> List.rev ((mk (TReturn (Some e)) t_dynamic e.epos) :: el),e.etype | [] -> assert false in let my_block = transform_exprs_to_block block tr false ae.a_expr.epos ae.a_next_id in let fn = mk (TFunction { tf_args = []; tf_type = tr; tf_expr = my_block.a_expr; }) ae.a_expr.etype ae.a_expr.epos in let t_var = alloc_var name ae.a_expr.etype ae.a_expr.epos in let f = add_non_locals_to_func fn in let fn_assign = mk (TVar (t_var,Some f)) ae.a_expr.etype ae.a_expr.epos in let ev = mk (TLocal t_var) ae.a_expr.etype ae.a_expr.epos in let substitute = mk (TCall(ev,[])) ae.a_expr.etype ae.a_expr.epos in lift_expr ~blocks:[fn_assign] substitute | (is_value,TFunction(f)) -> transform_function f ae is_value | (_,TVar(v,None)) -> transform_var_expr ae None v | (false, TVar(v,Some({ eexpr = TUnop((Increment | Decrement as unop),post_fix,({eexpr = TLocal _ | TField({eexpr = TConst TThis},_)} as ve))} as e1))) -> let one = {e1 with eexpr = TConst (TInt (Int32.of_int 1))} in let op = if unop = Increment then OpAdd else OpSub in let inc = {e1 with eexpr = TBinop(op,ve,one)} in let inc_assign = {e1 with eexpr = TBinop(OpAssign,ve,inc)} in let var_assign = {e1 with eexpr = TVar(v,Some ve)} in if post_fix = Postfix then lift true [var_assign] inc_assign else lift true [inc_assign] var_assign | (_,TVar(v,eo)) -> transform_var_expr ae eo v | (_,TFor(v,e1,e2)) -> let a1 = trans true [] e1 in let a2 = to_expr (trans false [] e2) in let name = (ae.a_next_id ()) in let t_var = alloc_var name e1.etype e1.epos in let ev = make_local t_var e1.epos in let ehasnext = mk (TField(ev,quick_field e1.etype "hasNext")) (tfun [] (!t_bool) ) e1.epos in let ehasnext = mk (TCall(ehasnext,[])) ehasnext.etype ehasnext.epos in let enext = mk (TField(ev,quick_field e1.etype "next")) (tfun [] v.v_type) e1.epos in let enext = mk (TCall(enext,[])) v.v_type e1.epos in let var_assign = mk (TVar (v,Some enext)) v.v_type a_expr.epos in let ebody = Type.concat var_assign (a2) in let var_decl = mk (TVar (t_var,Some a1.a_expr)) (!t_void) e1.epos in let twhile = mk (TWhile((mk (TParenthesis ehasnext) ehasnext.etype ehasnext.epos),ebody,NormalWhile)) (!t_void) e1.epos in let blocks = a1.a_blocks @ [var_decl] in lift_expr ~blocks: blocks twhile | (_,TReturn None) -> ae | (_,TReturn (Some ({eexpr = TFunction f} as ef))) -> let n = ae.a_next_id() in let e1 = to_expr (trans false [] f.tf_expr) in let f = mk (TFunction { tf_args = f.tf_args; tf_type = f.tf_type; tf_expr = e1; }) ef.etype ef.epos in let f1 = add_non_locals_to_func f in let var_n = alloc_var n ef.etype ef.epos in let f1_assign = mk (TVar(var_n,Some f1)) !t_void f1.epos in let var_local = mk (TLocal var_n) ef.etype f1.epos in let er = mk (TReturn (Some var_local)) t_dynamic ae.a_expr.epos in lift true [f1_assign] er | (_,TReturn Some(x)) -> let x1 = trans true [] x in (match x1.a_blocks with | [] -> lift true [] { ae.a_expr with eexpr = TReturn(Some x1.a_expr) } | blocks -> let f = exprs_to_func (blocks @ [x1.a_expr]) (ae.a_next_id()) ae in lift true f.a_blocks {a_expr with eexpr = TReturn (Some f.a_expr)}) | (_, TParenthesis(e1)) -> let e1 = trans true [] e1 in let p = { ae.a_expr with eexpr = TParenthesis(e1.a_expr)} in lift true e1.a_blocks p | (_, TEnumParameter(e1,ef,i)) -> let e1 = trans true [] e1 in let p = { ae.a_expr with eexpr = TEnumParameter(e1.a_expr,ef,i)} in lift true e1.a_blocks p | (true, TIf(econd, eif, eelse)) -> (let econd1 = trans true [] econd in let eif1 = trans true [] eif in let eelse1 = match eelse with | Some x -> Some(trans true [] x) | None -> None in let blocks = [] in let eif2, blocks = match eif1.a_blocks with | [] -> eif1.a_expr, blocks | x -> let regular = let fname = eif1.a_next_id () in let f = exprs_to_func (List.append eif1.a_blocks [eif1.a_expr]) fname ae in f.a_expr, List.append blocks f.a_blocks in match eif1.a_blocks with | [{ eexpr = TVar(_, Some({ eexpr = TFunction(_)}))} as b] -> eif1.a_expr, List.append blocks [b] | _ -> regular in let eelse2, blocks = match eelse1 with | None -> None, blocks | Some({ a_blocks = []} as x) -> Some(x.a_expr), blocks | Some({ a_blocks = b} as eelse1) -> let regular = let fname = eelse1.a_next_id () in let f = exprs_to_func (List.append eelse1.a_blocks [eelse1.a_expr]) fname ae in Some(f.a_expr), List.append blocks f.a_blocks in match b with | [{ eexpr = TVar(_, Some({ eexpr = TFunction(f)}))} as b] -> Some(eelse1.a_expr), List.append blocks [b] | _ -> regular in let blocks = List.append econd1.a_blocks blocks in let new_if = { ae.a_expr with eexpr = TIf(econd1.a_expr, eif2, eelse2) } in match blocks with | [] -> let meta = Meta.Custom(":ternaryIf"), [], ae.a_expr.epos in let ternary = { ae.a_expr with eexpr = TMeta(meta, new_if) } in lift_expr ~blocks:blocks ternary | b -> let f = exprs_to_func (List.append blocks [new_if]) (ae.a_next_id ()) ae in lift_expr ~blocks:f.a_blocks f.a_expr) | (false, TIf(econd, eif, eelse)) -> let econd = trans true [] econd in let eif = to_expr (trans false [] eif) in let eelse = match eelse with | Some(x) -> Some(to_expr (trans false [] x)) | None -> None in let new_if = { ae.a_expr with eexpr = TIf(econd.a_expr, eif, eelse) } in lift false econd.a_blocks new_if | (false, TWhile(econd, e1, NormalWhile)) -> let econd1 = trans true [] econd in let e11 = to_expr (trans false [] e1) in let new_while = mk (TWhile(econd1.a_expr,e11,NormalWhile)) a_expr.etype a_expr.epos in lift false econd1.a_blocks new_while | (true, TWhile(econd, ebody, NormalWhile)) -> let econd = trans true [] econd in let ebody = to_expr (trans false [] ebody) in let ewhile = { ae.a_expr with eexpr = TWhile(econd.a_expr, ebody, NormalWhile) } in let eval = { ae.a_expr with eexpr = TConst(TNull) } in let f = exprs_to_func (List.append econd.a_blocks [ewhile; eval]) (ae.a_next_id ()) ae in lift true f.a_blocks f.a_expr | (false, TWhile(econd, ebody, DoWhile)) -> let not_expr = { econd with eexpr = TUnop(Not, Prefix, econd) } in let break_expr = mk TBreak !t_void econd.epos in let if_expr = mk (TIf(not_expr, break_expr, None)) (!t_void) econd.epos in let new_e = match ebody.eexpr with | TBlock(exprs) -> { econd with eexpr = TBlock( List.append exprs [if_expr]) } | _ -> { econd with eexpr = TBlock( List.append [ebody] [if_expr]) } in let true_expr = mk (TConst(TBool(true))) econd.etype ae.a_expr.epos in let new_expr = { ae.a_expr with eexpr = TWhile( true_expr, new_e, NormalWhile) } in forward_transform new_expr ae | (is_value, TSwitch(e, cases, edef)) -> begin match follow e.etype with | TInst({cl_path = [],"str"},_) -> transform_string_switch ae is_value e cases edef | _ -> transform_switch ae is_value e cases edef end (* anon field access on optional params *) | (is_value, TField(e,FAnon cf)) when Meta.has Meta.Optional cf.cf_meta -> let e = dynamic_field_read e cf.cf_name ae.a_expr.etype in transform_expr ~is_value:is_value e | (is_value, TBinop(OpAssign,{eexpr = TField(e1,FAnon cf)},e2)) when Meta.has Meta.Optional cf.cf_meta -> let e = dynamic_field_write e1 cf.cf_name e2 in transform_expr ~is_value:is_value e | (is_value, TBinop(OpAssignOp op,{eexpr = TField(e1,FAnon cf); etype = t},e2)) when Meta.has Meta.Optional cf.cf_meta -> let e = dynamic_field_read_write ae.a_next_id e1 cf.cf_name op e2 t in transform_expr ~is_value:is_value e (* TODO we need to deal with Increment, Decrement too! | (_, TUnop( (Increment | Decrement) as unop, op,{eexpr = TField(e1,FAnon cf)})) when Meta.has Meta.Optional cf.cf_meta -> let = dynamic_field_read e cf.cf_name in let e = dynamic_field_read_write_unop ae.a_next_id e1 cf.cf_name unop op in Printf.printf "dyn read write\n"; transform_expr e *) (* anon field access with non optional members like iterator, length, split must be handled too, we need to Reflect on them too when it's a runtime method *) | (is_value, TUnop( (Increment | Decrement) as unop, op, e)) -> let one = { ae.a_expr with eexpr = TConst(TInt(Int32.of_int(1)))} in let is_postfix = match op with | Postfix -> true | Prefix -> false in let op = match unop with | Increment -> OpAdd | Decrement -> OpSub | _ -> assert false in transform_op_assign_op ae e op one is_value is_postfix | (_, TUnop(op, Prefix, e)) -> let e1 = trans true [] e in let r = { a_expr with eexpr = TUnop(op, Prefix, e1.a_expr) } in lift_expr ~blocks:e1.a_blocks r | (is_value, TField(e,FDynamic s)) -> let e = dynamic_field_read e s ae.a_expr.etype in transform_expr ~is_value:is_value e | (is_value, TBinop(OpAssign,{eexpr = TField(e1,FDynamic s)},e2)) -> let e = dynamic_field_write e1 s e2 in transform_expr ~is_value:is_value e | (is_value, TBinop(OpAssignOp op,{eexpr = TField(e1,FDynamic s); etype = t},e2)) -> let e = dynamic_field_read_write ae.a_next_id e1 s op e2 t in transform_expr ~is_value:is_value e (* | (is_value, TField(e1, FClosure(Some ({cl_path = [],("str")},_),cf))) -> | (is_value, TField(e1, FClosure(Some ({cl_path = [],("list")},_),cf))) -> let e = dynamic_field_read e1 cf.cf_name ae.a_expr.etype in transform_expr ~is_value:is_value e *) | (is_value, TBinop(OpAssign, left, right))-> (let left = trans true [] left in let right = trans true [] right in let r = { a_expr with eexpr = TBinop(OpAssign, left.a_expr, right.a_expr)} in if is_value then (let blocks = List.concat [left.a_blocks; right.a_blocks; [r]] in let f = exprs_to_func blocks (ae.a_next_id ()) ae in lift true f.a_blocks f.a_expr) else lift false (List.append left.a_blocks right.a_blocks) r) | (is_value, TBinop(OpAssignOp(x), left, right)) -> let right = trans true [] right in let v = right.a_expr in let res = transform_op_assign_op ae left x v is_value false in lift true (List.append right.a_blocks res.a_blocks) res.a_expr | (_, TBinop(op, left, right))-> (let left = trans true [] left in let right = trans true [] right in let r = { a_expr with eexpr = TBinop(op, left.a_expr, right.a_expr)} in lift false (List.append left.a_blocks right.a_blocks) r) | (true, TThrow(x)) -> let block = TBlock([a_expr; { a_expr with eexpr = TConst(TNull) }]) in let r = { a_expr with eexpr = block } in forward_transform r ae | (false, TThrow(x)) -> let x = trans true [] x in let r = { a_expr with eexpr = TThrow(x.a_expr)} in lift false x.a_blocks r | (_, TNew(c, tp, params)) -> let params = List.map (trans true []) params in let blocks = List.flatten (List.map (fun (p) -> p.a_blocks) params) in let params = List.map (fun (p) -> p.a_expr) params in let e = { a_expr with eexpr = TNew(c, tp, params) } in lift false blocks e | (is_value, TCall(e,params)) -> transform_call is_value e params ae | (_, TArray(e1, e2)) -> let e1 = trans true [] e1 in let e2 = trans true [] e2 in let r = { a_expr with eexpr = TArray(e1.a_expr, e2.a_expr)} in let blocks = List.append e1.a_blocks e2.a_blocks in lift_expr ~blocks:blocks r | (false, TTry(etry, catches)) -> let etry = trans false [] etry in let catches = List.map (fun(v,e) -> KeywordHandler.check_var_declaration v; v, trans false [] e) catches in let blocks = List.flatten (List.map (fun (_,e) -> e.a_blocks) catches) in let catches = List.map (fun(v,e) -> v, e.a_expr) catches in let r = { a_expr with eexpr = TTry(etry.a_expr, catches)} in let blocks = List.append etry.a_blocks blocks in lift false blocks r | (true, TTry(etry, catches)) -> let id = ae.a_next_id () in let temp_var = to_tvar id a_expr.etype a_expr.epos in let temp_var_def = { a_expr with eexpr = TVar(temp_var, None) } in let temp_local = { a_expr with eexpr = TLocal(temp_var)} in let mk_temp_assign right = { a_expr with eexpr = TBinop(OpAssign, temp_local, right)} in let etry = mk_temp_assign etry in let catches = List.map (fun (v,e)-> KeywordHandler.check_var_declaration v; v, mk_temp_assign e) catches in let new_try = { a_expr with eexpr = TTry(etry, catches)} in let block = [temp_var_def; new_try; temp_local] in let new_block = { a_expr with eexpr = TBlock(block)} in forward_transform new_block ae | (_, TObjectDecl(fields)) -> let fields = List.map (fun (name,ex) -> name, trans true [] ex) fields in let blocks = List.flatten (List.map (fun (_,ex) -> ex.a_blocks) fields) in let fields = List.map (fun (name,ex) -> name, ex.a_expr) fields in let r = { a_expr with eexpr = (TObjectDecl(fields) )} in lift_expr ~blocks r | (_, TArrayDecl(values)) -> let values = List.map (trans true []) values in let blocks = List.flatten (List.map (fun (v) -> v.a_blocks) values) in let exprs = List.map (fun (v) -> v.a_expr) values in let r = { a_expr with eexpr = TArrayDecl exprs } in lift_expr ~blocks:blocks r | (is_value, TCast(e1,Some mt)) -> let e = Codegen.default_cast ~vtmp:(ae.a_next_id()) (match !como with Some com -> com | None -> assert false) e1 mt ae.a_expr.etype ae.a_expr.epos in transform_expr ~is_value:is_value e | (is_value, TCast(e,None)) -> let e = trans is_value [] e in let r = { a_expr with eexpr = TCast(e.a_expr, None)} in lift_expr ~blocks:e.a_blocks r | (_, TField(e,f)) -> let e = trans true [] e in let r = { a_expr with eexpr = TField(e.a_expr, f) } in lift_expr ~blocks:e.a_blocks r | (is_value, TMeta(m, e)) -> let e = trans is_value [] e in let r = { a_expr with eexpr = TMeta(m, e.a_expr); etype = e.a_expr.etype } in lift_expr ~blocks:e.a_blocks r | ( _, TLocal _ ) -> lift_expr a_expr | ( _, TConst _ ) -> lift_expr a_expr | ( _, TTypeExpr _ ) -> lift_expr a_expr | ( _, TUnop _ ) -> assert false | ( true, TWhile(econd, ebody, DoWhile) ) -> let new_expr = trans false [] a_expr in let f = exprs_to_func (new_expr.a_blocks @ [new_expr.a_expr]) (ae.a_next_id()) ae in lift_expr ~is_value:true ~blocks:f.a_blocks f.a_expr | ( _, TBreak ) | ( _, TContinue ) -> lift_expr a_expr and transform e = to_expr (transform1 (lift_expr e)) and forward_transform e base = transform1 (lift_expr1 base.a_is_value base.a_next_id base.a_blocks e) let transform_to_value e = to_expr (transform1 (lift_expr e ~is_value:true)) end module Printer = struct type print_context = { pc_indent : string; pc_next_anon_func : unit -> string; pc_debug : bool; pc_com : Common.context; } let has_feature pctx = Common.has_feature pctx.pc_com let add_feature pctx = Common.add_feature pctx.pc_com let create_context = let n = ref (-1) in (fun indent com debug -> { pc_indent = indent; pc_next_anon_func = (fun () -> incr n; Printf.sprintf "anon_%i" !n); pc_debug = debug; pc_com = com; } ) let tabs = ref "" let opt o f s = match o with | None -> "" | Some v -> s ^ (f v) (* TODO: both of these are crazy *) let is_type p t = (fun r -> let x = t_infos r in (String.concat "." (fst x.mt_path)) = p && (snd x.mt_path) = t ) let is_type1 p s = (fun t -> match follow t with | TInst(c,_) -> (is_type p s)(TClassDecl c) | TAbstract(a,_) -> (is_type p s)(TAbstractDecl a) | TEnum(en,_) -> (is_type p s)(TEnumDecl en) | _ -> false ) let is_underlying_string t = match follow t with | TAbstract(a,tl) -> (is_type1 "" "str")(Abstract.get_underlying_type a tl) | _ -> false let is_underlying_array t = match follow t with | TAbstract(a,tl) -> (is_type1 "" "list")(Abstract.get_underlying_type a tl) | _ -> false let rec is_anon_or_dynamic t = match follow t with | TAbstract(a,tl) -> is_anon_or_dynamic (Abstract.get_underlying_type a tl) | TAnon _ | TDynamic _ -> true | _ -> false let handle_keywords s = KeywordHandler.handle_keywords s let print_unop = function | Increment | Decrement -> assert false | Not -> "not " | Neg -> "-"; | NegBits -> "~" let print_binop = function | OpAdd -> "+" | OpSub -> "-" | OpMult -> "*" | OpDiv -> "/" | OpAssign -> "=" | OpEq -> "==" | OpNotEq -> "!=" | OpGt -> ">" | OpGte -> ">=" | OpLt -> "<" | OpLte -> "<=" | OpAnd -> "&" | OpOr -> "|" | OpXor -> "^" | OpBoolAnd -> "and" | OpBoolOr -> "or" | OpShl -> "<<" | OpShr -> ">>" | OpUShr -> ">>" | OpMod -> "%" | OpInterval | OpArrow | OpAssignOp _ -> assert false let print_string s = Printf.sprintf "\"%s\"" (Ast.s_escape s) let print_constant = function | TThis -> "self" | TNull -> "None" | TBool(true) -> "True" | TBool(false) -> "False" | TString(s) -> print_string s | TInt(i) -> Int32.to_string i | TFloat s -> s | TSuper -> "super" let print_base_type tp = try begin match Meta.get Meta.Native tp.mt_meta with | _,[EConst(String s),_],_ -> s | _ -> raise Not_found end with Not_found -> let pack,name = tp.mt_path in (String.concat "_" pack) ^ (if pack = [] then name else "_" ^ name) let print_module_type mt = print_base_type (t_infos mt) let print_metadata (name,_,_) = Printf.sprintf "@%s" name let rec remove_outer_parens e = match e.eexpr with | TParenthesis(e) -> remove_outer_parens e | TMeta((Meta.Custom ":ternaryIf",_,_),_) -> e | TMeta(_,e) -> remove_outer_parens e | _ -> e let print_args args p = let had_value = ref false in let had_var_args = ref false in let had_kw_args = ref false in let sl = List.map (fun (v,cto) -> let check_err () = if !had_var_args || !had_kw_args then abort "Arguments after KwArgs/VarArgs are not allowed" p in let name = handle_keywords v.v_name in match follow v.v_type with | TAbstract({a_path = ["python"],"KwArgs"},_) -> if !had_kw_args then abort "Arguments after KwArgs are not allowed" p; had_kw_args := true; "**" ^ name | TAbstract({a_path = ["python"],"VarArgs"},_) -> check_err (); had_var_args := true; "*" ^ name | _ -> check_err (); name ^ match cto with | None when !had_value -> " = None" | None -> "" | Some ct -> had_value := true; Printf.sprintf " = %s" (print_constant ct) ) args in String.concat "," sl let rec print_op_assign_right pctx e = match e.eexpr with | TIf({eexpr = TParenthesis econd},eif,Some eelse) | TIf(econd,eif,Some eelse) -> Printf.sprintf "%s if %s else %s" (print_expr pctx eif) (print_expr pctx econd) (print_expr pctx eelse) | _ -> print_expr pctx (remove_outer_parens e) and print_var pctx v eo = match eo with | Some ({eexpr = TFunction tf} as e) -> print_function pctx tf (Some v.v_name) e.epos | _ -> let s_init = match eo with | None -> "None" | Some e -> print_op_assign_right pctx e in Printf.sprintf "%s = %s" (handle_keywords v.v_name) s_init and print_function pctx tf name p = let s_name = match name with | None -> pctx.pc_next_anon_func() | Some s -> handle_keywords s in let s_args = print_args tf.tf_args p in let s_expr = print_expr {pctx with pc_indent = " " ^ pctx.pc_indent} tf.tf_expr in Printf.sprintf "def %s(%s):\n%s %s" s_name s_args pctx.pc_indent s_expr and print_tarray_list pctx e1 e2 = let s1 = (print_expr pctx e1) in let s2 = (print_expr pctx e2) in let default = Printf.sprintf "python_internal_ArrayImpl._get(%s, %s)" s1 s2 in let handle_index = match e2.eexpr with | TConst TInt index -> if Int32.to_int index >= 0 then Printf.sprintf "(%s[%s] if %s < len(%s) else None)" s1 s2 s2 s1 else "None" | TLocal _ -> Printf.sprintf "(%s[%s] if %s >= 0 and %s < len(%s) else None)" s1 s2 s2 s2 s1 | _ -> default in match e1.eexpr with | TLocal _ -> handle_index | TField ({eexpr=(TConst TThis | TLocal _)},_) -> handle_index | _ -> default and is_safe_string pctx x = let follow_parens e = match e.eexpr with | TParenthesis e -> e | _ -> e in match (follow_parens x).eexpr with | TBinop(OpAdd, e1, e2) -> is_safe_string pctx e1 && is_safe_string pctx e2 | TCall (e1,_) -> let id = print_expr pctx (follow_parens e1) in (match id with | "Std.string" -> true | _ -> false) | TConst (TString s) -> true | _ -> false and print_expr pctx e = let indent = pctx.pc_indent in let print_expr_indented e = print_expr {pctx with pc_indent = " " ^ pctx.pc_indent} e in match e.eexpr with | TConst ct -> print_constant ct | TTypeExpr mt -> print_module_type mt | (TLocal v | TParenthesis({ eexpr = (TLocal v) })) -> handle_keywords v.v_name | TEnumParameter(e1,_,index) -> Printf.sprintf "%s.params[%i]" (print_expr pctx e1) index | TArray(e1,e2) when (is_type1 "" "list")(e1.etype) || is_underlying_array e1.etype -> print_tarray_list pctx e1 e2 | TArray({etype = t} as e1,e2) when is_anon_or_dynamic t -> Printf.sprintf "HxOverrides.arrayGet(%s, %s)" (print_expr pctx e1) (print_expr pctx e2) | TArray(e1,e2) -> Printf.sprintf "%s[%s]" (print_expr pctx e1) (print_expr pctx e2) | TBinop(OpAssign, {eexpr = TArray(e1,e2)}, e3) when (is_type1 "" "list")(e1.etype) || is_underlying_array e1.etype -> Printf.sprintf "python_internal_ArrayImpl._set(%s, %s, %s)" (print_expr pctx e1) (print_expr pctx e2) (print_expr pctx e3) | TBinop(OpAssign,{eexpr = TArray({etype = t} as e1,e2)},e3) when is_anon_or_dynamic t -> Printf.sprintf "HxOverrides.arraySet(%s,%s,%s)" (print_expr pctx e1) (print_expr pctx e2) (print_expr pctx e3) | TBinop(OpAssign,{eexpr = TArray(e1,e2)},e3) -> Printf.sprintf "%s[%s] = %s" (print_expr pctx e1) (print_expr pctx e2) (print_expr pctx (remove_outer_parens e3) ) | TBinop(OpAssign,{eexpr = TField(ef1,fa)},e2) -> Printf.sprintf "%s = %s" (print_field pctx ef1 fa true) (print_op_assign_right pctx e2) | TBinop(OpAssign,e1,e2) -> Printf.sprintf "%s = %s" (print_expr pctx e1) (print_expr pctx (remove_outer_parens e2)) | TBinop(op,e1,({eexpr = TBinop(_,_,_)} as e2)) -> print_expr pctx { e with eexpr = TBinop(op, e1, { e2 with eexpr = TParenthesis(e2) })} | TBinop(OpEq,{eexpr = TCall({eexpr = TLocal {v_name = "__typeof__"}},[e1])},e2) -> begin match e2.eexpr with | TConst(TString s) -> begin match s with | "string" -> Printf.sprintf "Std._hx_is(%s, str)" (print_expr pctx e1) | "boolean" -> Printf.sprintf "Std._hx_is(%s, bool)" (print_expr pctx e1) | "number" -> Printf.sprintf "Std._hx_is(%s, float)" (print_expr pctx e1) | _ -> assert false end | _ -> assert false end | TBinop(OpEq,e1,({eexpr = TConst TNull} as e2)) -> Printf.sprintf "(%s is %s)" (print_expr pctx e1) (print_expr pctx e2) | TBinop(OpNotEq,e1,({eexpr = TConst TNull} as e2)) -> Printf.sprintf "(%s is not %s)" (print_expr pctx e1) (print_expr pctx e2) | TBinop(OpEq|OpNotEq as op,e1, e2) -> let ops = match op with | OpEq -> "is", "==", "HxOverrides.eq" | OpNotEq -> "is not", "!=", "not HxOverrides.eq" | _ -> assert false in let third (_,_,x) = x in let fst (x,_,_) = x in let snd (_,x,_) = x in let is_list_or_anon x = begin match x with | TInst({cl_path = [],("list")},_) -> true | TAnon _ -> true | _ -> false end in let is_const_byte x = match x.eexpr with | TConst TInt x -> let x = Int32.to_int x in x >= 0 && x <= 256 | _ -> false in (match follow e1.etype, follow e2.etype with | TAbstract({a_path = [],("Int")}, _),TAbstract({a_path = [],("Int")}, _) when is_const_byte e2 || is_const_byte e1 -> Printf.sprintf "(%s %s %s)" (print_expr pctx e1) (snd ops) (print_expr pctx e2) (* the following optimization causes a problem with polygonal unit tests see: https://github.com/HaxeFoundation/haxe/issues/2952 *) (* Printf.sprintf "(%s %s %s)" (print_expr pctx e1) (fst ops) (print_expr pctx e2) *) | TInst({cl_path = [],("list")},_), _ -> Printf.sprintf "(%s %s %s)" (print_expr pctx e1) (fst ops) (print_expr pctx e2) | x, _ when is_underlying_array x -> Printf.sprintf "(%s %s %s)" (print_expr pctx e1) (fst ops) (print_expr pctx e2) | TDynamic _, TDynamic _ -> Printf.sprintf "%s(%s,%s)" (third ops) (print_expr pctx e1) (print_expr pctx e2) | TDynamic _, x | x, TDynamic _ when is_list_or_anon x -> Printf.sprintf "%s(%s,%s)" (third ops) (print_expr pctx e1) (print_expr pctx e2) | _,_ -> Printf.sprintf "(%s %s %s)" (print_expr pctx e1) (snd ops) (print_expr pctx e2)) | TBinop(OpMod,e1,e2) when (is_type1 "" "Int")(e1.etype) && (is_type1 "" "Int")(e2.etype) -> (match e1.eexpr with | TConst(TInt(x)) when (Int32.to_int x) >= 0 -> (* constant optimization *) Printf.sprintf "%s %% %s" (print_expr pctx e1) (print_expr pctx e2) | _ -> Printf.sprintf "HxOverrides.mod(%s, %s)" (print_expr pctx e1) (print_expr pctx e2)) | TBinop(OpMod,e1,e2) -> Printf.sprintf "HxOverrides.modf(%s, %s)" (print_expr pctx e1) (print_expr pctx e2) | TBinop(OpUShr,e1,e2) -> Printf.sprintf "HxOverrides.rshift(%s, %s)" (print_expr pctx e1) (print_expr pctx e2) | TBinop(OpAdd,e1,e2) when (is_type1 "" "str")(e.etype) || is_underlying_string e.etype -> let rec safe_string ex = match ex.eexpr, ex.etype with | e, _ when is_safe_string pctx ex -> print_expr pctx ex | TBinop(OpAdd, e1, e2), x when (is_type1 "" "str")(x) -> Printf.sprintf "(%s + %s)" (safe_string e1) (safe_string e2) | (TLocal(_)),x when (is_type1 "" "str")(x) -> (* we could add this pattern too, but is it sideeffect free?? | TField({ eexpr = TLocal(_)},_) *) let s = (print_expr pctx ex) in Printf.sprintf "(\"null\" if %s is None else %s)" s s | _,x when (is_type1 "" "str")(x) -> Printf.sprintf "HxOverrides.stringOrNull(%s)" (print_expr pctx ex) | _,_ -> if has_feature pctx "Std.string" then Printf.sprintf "Std.string(%s)" (print_expr pctx ex) else Printf.sprintf "str(%s)" (print_expr pctx ex) in let e1_str = safe_string e1 in let e2_str = safe_string e2 in Printf.sprintf "(%s + %s)" e1_str e2_str | TBinop(OpAdd,e1,e2) when (match follow e.etype with TDynamic _ -> true | _ -> false) -> Printf.sprintf "python_Boot._add_dynamic(%s,%s)" (print_expr pctx e1) (print_expr pctx e2) | TBinop(op,e1,e2) -> Printf.sprintf "(%s %s %s)" (print_expr pctx e1) (print_binop op) (print_expr pctx e2) | TField(e1,fa) -> print_field pctx e1 fa false | TParenthesis e1 -> Printf.sprintf "(%s)" (print_expr pctx e1) | TObjectDecl fl -> let fl2 = ref fl in begin match follow e.etype with | TAnon an -> PMap.iter (fun s cf -> if not (List.mem_assoc s fl) then fl2 := (s,null cf.cf_type cf.cf_pos) :: !fl2 ) an.a_fields | _ -> () end; Printf.sprintf "_hx_AnonObject(%s)" (print_exprs_named pctx ", " !fl2) | TArrayDecl el -> Printf.sprintf "[%s]" (print_exprs pctx ", " el) | TCall(e1,el) -> print_call pctx e1 el e | TNew(c,_,el) -> let id = print_base_type (t_infos (TClassDecl c)) in Printf.sprintf "%s(%s)" id (print_call_args pctx e el) | TUnop(Not,Prefix,e1) -> Printf.sprintf "(%s%s)" (print_unop Not) (print_expr pctx e1) | TUnop(op,Prefix,e1) -> Printf.sprintf "%s%s" (print_unop op) (print_expr pctx e1) | TFunction tf -> print_function pctx tf None e.epos | TVar (v,eo) -> print_var pctx v eo | TBlock [] -> Printf.sprintf "pass" | TBlock [{ eexpr = TBlock _} as b] -> print_expr pctx b | TBlock el -> let old = !tabs in tabs := pctx.pc_indent; let s = print_block_exprs pctx ("\n" ^ !tabs) pctx.pc_debug el in tabs := old; Printf.sprintf "%s" s | TIf(econd,eif,(Some {eexpr = TIf _} as eelse)) -> print_if_else pctx econd eif eelse true | TIf(econd,eif,eelse) -> print_if_else pctx econd eif eelse false | TWhile(econd,e1,NormalWhile) -> Printf.sprintf "while %s:\n%s %s" (print_expr pctx (remove_outer_parens econd)) indent (print_expr_indented e1) | TWhile(econd,e1,DoWhile) -> abort "Currently not supported" e.epos | TTry(e1,catches) -> print_try pctx e1 catches | TReturn eo -> Printf.sprintf "return%s" (opt eo (print_op_assign_right pctx) " ") | TBreak -> "break" | TContinue -> "continue" | TThrow e1 -> let rec is_native_exception t = match Abstract.follow_with_abstracts t with | TInst ({ cl_path = [],"BaseException" }, _) -> true | TInst ({ cl_super = Some csup }, _) -> is_native_exception (TInst(fst csup, snd csup)) | _ -> false in if is_native_exception e1.etype then Printf.sprintf "raise %s" (print_expr pctx e1) else Printf.sprintf "raise _HxException(%s)" (print_expr pctx e1) | TCast(e1,None) -> print_expr pctx e1 | TMeta((Meta.Custom ":ternaryIf",_,_),{eexpr = TIf(econd,eif,Some eelse)}) -> Printf.sprintf "(%s if %s else %s)" (print_expr pctx eif) (print_expr pctx econd) (print_expr pctx eelse) | TMeta(_,e1) -> print_expr pctx e1 | TSwitch _ | TCast(_, Some _) | TFor _ | TUnop(_,Postfix,_) -> assert false and print_if_else pctx econd eif eelse as_elif = let econd1 = match econd.eexpr with | TParenthesis e -> e | _ -> econd in let if_str = print_expr {pctx with pc_indent = " " ^ pctx.pc_indent} eif in let indent = pctx.pc_indent in let else_str = if as_elif then opt eelse (print_expr pctx) "el" else opt eelse (print_expr {pctx with pc_indent = " " ^ pctx.pc_indent}) (Printf.sprintf "else:\n%s " indent) in let else_str = if else_str = "" then "" else "\n" ^ indent ^ else_str in Printf.sprintf "if %s:\n%s %s%s" (print_expr pctx (remove_outer_parens econd1)) indent if_str else_str and print_field pctx e1 fa is_assign = let obj = match e1.eexpr with | TConst TSuper -> "super()" | _ -> print_expr pctx e1 in let name = field_name fa in let is_extern = (match fa with | FInstance(c,_,_) -> c.cl_extern | FStatic(c,_) -> c.cl_extern | _ -> false) in let do_default () = Printf.sprintf "%s.%s" obj (if is_extern then name else (handle_keywords name)) in let call_override s = match s with | "iterator" | "toUpperCase" | "toLowerCase" | "pop" | "shift" | "join" | "push" | "map" | "filter" -> true | _ -> false in match fa with (* we need to get rid of these cases in the transformer, how is this handled in js *) | FInstance(c,_,{cf_name = "length"}) when (is_type "" "list")(TClassDecl c) -> Printf.sprintf "len(%s)" (print_expr pctx e1) | FInstance(c,_,{cf_name = "length"}) when (is_type "" "str")(TClassDecl c) -> Printf.sprintf "len(%s)" (print_expr pctx e1) | FStatic(c,{cf_name = "fromCharCode"}) when (is_type "" "str")(TClassDecl c) -> Printf.sprintf "HxString.fromCharCode" | FStatic({cl_path = ["python";"internal"],"UBuiltins"},{cf_name = s}) -> s | FClosure (Some(c,cf),_) when call_override(name) && ((is_type "" "list")(TClassDecl c)) -> Printf.sprintf "_hx_partial(python_internal_ArrayImpl.%s, %s)" name obj | FInstance (c,_,cf) when call_override(name) && ((is_type "" "list")(TClassDecl c)) -> Printf.sprintf "_hx_partial(python_internal_ArrayImpl.%s, %s)" name obj | FClosure (Some(c,cf),_) when call_override(name) && ((is_type "" "str")(TClassDecl c)) -> Printf.sprintf "_hx_partial(HxString.%s, %s)" name obj | FInstance (c,_,cf) when call_override(name) && ((is_type "" "str")(TClassDecl c)) -> Printf.sprintf "_hx_partial(HxString.%s, %s)" name obj | FInstance _ | FStatic _ -> do_default () | FAnon cf when is_assign && call_override(name) -> begin match follow cf.cf_type with | TFun([],_) -> Printf.sprintf "_hx_partial(HxOverrides.%s, %s)" name obj | _ -> do_default() end | _ -> do_default() and print_try pctx e1 catches = let has_catch_all = List.exists (fun (v,_) -> match v.v_type with | TDynamic _ -> true | _ -> false ) catches in let has_only_catch_all = has_catch_all && begin match catches with | [_] -> true | _ -> false end in let print_catch pctx i (v,e) = let is_empty_expr = begin match e.eexpr with | TBlock [] -> true | _ -> false end in let indent = pctx.pc_indent in (* Don't generate assignment to catch variable when catch expression is an empty block *) let assign = if is_empty_expr then "" else Printf.sprintf "%s = _hx_e1\n%s" v.v_name indent in let handle_base_type bt = let t = print_base_type bt in let print_type_check t_str = Printf.sprintf "if isinstance(_hx_e1, %s):\n%s %s %s" t_str indent assign (print_expr {pctx with pc_indent = " " ^ pctx.pc_indent} e) in let res = match t with | "str" -> print_type_check "str" | "Bool" -> print_type_check "bool" | "Int" -> print_type_check "int" | "Float" -> print_type_check "float" | t -> print_type_check t in if i > 0 then indent ^ "el" ^ res else res in match follow v.v_type with | TDynamic _ -> begin if has_only_catch_all then Printf.sprintf "%s%s" assign (print_expr pctx e) else (* Dynamic is always the last block *) Printf.sprintf "%selse:\n %s%s %s" indent indent assign (print_expr {pctx with pc_indent = " " ^ pctx.pc_indent} e) end | TInst(c,_) -> handle_base_type (t_infos (TClassDecl c)) | TEnum(en,_) -> handle_base_type (t_infos (TEnumDecl en)) | TAbstract(a,_) -> handle_base_type (t_infos (TAbstractDecl a)) | _ -> assert false in let indent = pctx.pc_indent in let print_expr_indented e = print_expr {pctx with pc_indent = " " ^ pctx.pc_indent} e in let try_str = Printf.sprintf "try:\n%s %s\n%s" indent (print_expr_indented e1) indent in let except = if has_feature pctx "has_throw" then Printf.sprintf "except Exception as _hx_e:\n%s _hx_e1 = _hx_e.val if isinstance(_hx_e, _HxException) else _hx_e\n%s " indent indent else Printf.sprintf "except Exception as _hx_e:\n%s _hx_e1 = _hx_e\n%s " indent indent in let catch_str = String.concat (Printf.sprintf "\n") (ExtList.List.mapi (fun i catch -> print_catch {pctx with pc_indent = " " ^ pctx.pc_indent} i catch) catches) in let except_end = if not has_catch_all then Printf.sprintf "\n%s else:\n%s raise _hx_e" indent indent else "" in Printf.sprintf "%s%s%s%s" try_str except catch_str except_end and print_call2 pctx e1 el = let id = print_expr pctx e1 in match id,el with | "__define_feature__",[_;e] -> print_expr pctx e | "super",_ -> let s_el = (print_call_args pctx e1 el) in Printf.sprintf "super().__init__(%s)" s_el | ("python_Syntax._pythonCode"),[({ eexpr = TConst (TString code) } as ecode); {eexpr = TArrayDecl tl}] -> let exprs = Array.of_list tl in let i = ref 0 in let err msg = let pos = { ecode.epos with pmin = ecode.epos.pmin + !i } in abort msg pos in let regex = Str.regexp "[{}]" in let rec loop m = match m with | [] -> "" | Str.Text txt :: tl -> i := !i + String.length txt; txt ^ (loop tl) | Str.Delim a :: Str.Delim b :: tl when a = b -> i := !i + 2; a ^ (loop tl) | Str.Delim "{" :: Str.Text n :: Str.Delim "}" :: tl -> (try let expr = Array.get exprs (int_of_string n) in let txt = print_expr pctx expr in i := !i + 2 + String.length n; txt ^ (loop tl) with | Failure "int_of_string" -> err ("Index expected. Got " ^ n) | Invalid_argument _ -> err ("Out-of-bounds pythonCode special parameter: " ^ n)) | Str.Delim x :: _ -> err ("Unexpected " ^ x) in loop (Str.full_split regex code) | ("python_Syntax._pythonCode"), [e] -> print_expr pctx e | "python_Syntax._callNamedUntyped",el -> let res,fields = match List.rev el with | {eexpr = TObjectDecl fields} :: el -> List.rev el,fields | _ -> assert false in begin match res with | e1 :: [] -> Printf.sprintf "%s(%s)" (print_expr pctx e1) (print_params_named pctx ", " fields) | e1 :: el -> Printf.sprintf "%s(%s, %s)" (print_expr pctx e1) (print_exprs pctx ", " el) (print_params_named pctx ", " fields) | [] -> Printf.sprintf "%s(%s)" (print_expr pctx e1) (print_params_named pctx ", " fields) end | "python_Syntax.varArgs",[e1] -> "*" ^ (print_expr pctx e1) | "python_Syntax.call" ,e1 :: [{eexpr = TArrayDecl el}]-> Printf.sprintf "%s(%s)" (print_expr pctx e1) (print_exprs pctx ", " el) | "python_Syntax.field",[e1;{eexpr = TConst(TString id)}] -> Printf.sprintf "%s.%s" (print_expr pctx e1) id | "python_Syntax._tuple", [{eexpr = TArrayDecl el}] -> (match el with | [e] -> Printf.sprintf "(%s,)" (print_expr pctx e) | _ -> Printf.sprintf "(%s)" (print_exprs pctx ", " el)) | "python_Syntax._arrayAccess", e1 :: {eexpr = TArrayDecl el} :: etrail -> let trailing_colon = match etrail with | [{eexpr = TConst(TBool(true))}] -> true | _ -> false in Printf.sprintf "%s[%s%s]" (print_expr pctx e1) (print_exprs pctx ":" el) (if trailing_colon then ":" else "") | "python_Syntax.isIn",[e1;e2] -> Printf.sprintf "(%s in %s)" (print_expr pctx e1) (print_expr pctx e2) | "python_Syntax.delete",[e1] -> Printf.sprintf "del %s" (print_expr pctx e1) | "python_Syntax.binop",[e0;{eexpr = TConst(TString id)};e2] -> Printf.sprintf "(%s %s %s)" (print_expr pctx e0) id (print_expr pctx e2) | "python_Syntax.assign",[e0;e1] -> Printf.sprintf "%s = %s" (print_expr pctx e0) (print_expr pctx e1) | "python_Syntax.arraySet",[e1;e2;e3] -> Printf.sprintf "%s[%s] = %s" (print_expr pctx e1) (print_expr pctx e2) (print_expr pctx e3) | "python_Syntax._newInstance", e1 :: [{eexpr = TArrayDecl el}] -> Printf.sprintf "%s(%s)" (print_expr pctx e1) (print_exprs pctx ", " el) | "python_Syntax.opPow", [e1;e2] -> Printf.sprintf "(%s ** %s)" (print_expr pctx e1) (print_expr pctx e2) | "python_Syntax._foreach",[e1;e2;e3] -> let pctx = {pctx with pc_indent = " " ^ pctx.pc_indent} in let i = pctx.pc_indent in Printf.sprintf "for %s in %s:\n%s%s" (print_expr pctx e1) (print_expr pctx e2) i (print_expr pctx e3) | _,el -> Printf.sprintf "%s(%s)" id (print_call_args pctx e1 el) and print_call pctx e1 el call_expr = let get_native_fields t = match follow t with | TAnon(a) -> let fold f cf acc = if Meta.has Meta.Native cf.cf_meta then begin let _, args, mp = Meta.get Meta.Native cf.cf_meta in match args with | [( EConst(String s),_)] -> PMap.add f s acc | _ -> acc end else acc in let mapping = PMap.foldi fold a.a_fields PMap.empty in mapping | _ -> PMap.empty in let native_fields_str native_fields = let fold_dict k v acc = let prefix = if acc = "" then "" else "," in Printf.sprintf "%s%s\"%s\":\"%s\"" acc prefix (handle_keywords k) v in PMap.foldi fold_dict native_fields "" in match e1.eexpr, el with | TLocal { v_name = "`trace" }, [e;infos] -> if has_feature pctx "haxe.Log.trace" then begin "haxe_Log.trace(" ^ (print_expr pctx e) ^ "," ^ (print_expr pctx infos) ^ ")" end else if is_safe_string pctx e then "print(" ^ (print_expr pctx e) ^ ")" else "print(str(" ^ (print_expr pctx e) ^ "))" | TField(e1,((FAnon {cf_name = (("join" | "push" | "map" | "filter") as s)}) | FDynamic (("join" | "push" | "map" | "filter") as s))), [x] -> Printf.sprintf "HxOverrides.%s(%s, %s)" s (print_expr pctx e1) (print_expr pctx x) | TField(e1,((FAnon {cf_name = (("iterator" | "toUpperCase" | "toLowerCase" | "pop" | "shift") as s)}) | FDynamic (("iterator" | "toUpperCase" | "toLowerCase" | "pop" | "shift") as s))), [] -> Printf.sprintf "HxOverrides.%s(%s)" s (print_expr pctx e1) | TField(_, (FStatic({cl_path = ["python"; "_KwArgs"], "KwArgs_Impl_"},{ cf_name="fromT" }))), [e2] -> let t = match follow call_expr.etype with | TAbstract(_, [t]) -> t | _ -> assert false in let native_fields = get_native_fields t in if PMap.is_empty native_fields then print_call2 pctx e1 el else let s1 = native_fields_str native_fields in Printf.sprintf "python__KwArgs_KwArgs_Impl_.fromT(HxOverrides.mapKwArgs(%s, {%s}))" (print_expr pctx e2) s1 | TField(_, (FStatic({cl_path = ["python"; "_KwArgs"], "KwArgs_Impl_"},{ cf_name="toDictHelper" }))), [e2; et] -> let native_fields = get_native_fields et.etype in if PMap.is_empty native_fields then print_call2 pctx e1 el else let s1 = native_fields_str native_fields in Printf.sprintf "python__KwArgs_KwArgs_Impl_.toDictHelper(HxOverrides.reverseMapKwArgs(%s, {%s}), None)" (print_expr pctx e2) s1 | _,_ -> print_call2 pctx e1 el and print_call_args pctx e1 el = let print_arg pctx i x = let e = match x.eexpr, follow x.etype with | TConst TNull, TAbstract({a_path = ["python"],"KwArgs"},_) -> "{}" | TConst TNull, TAbstract({a_path = ["python"],"VarArgs"},_) -> "[]" | _ -> (print_expr pctx x) in let prefix = match e1.eexpr, follow x.etype with (* the should not apply for the instance methods of the abstract itself *) | TField(_, FStatic({cl_path = ["python"; "_KwArgs"],"KwArgs_Impl_"},f)), _ when i == 0 && Meta.has Meta.Impl f.cf_meta -> "" | TField(_, FStatic({cl_path = ["python"; "_VarArgs"],"VarArgs_Impl_"},f)), _ when i == 0 && Meta.has Meta.Impl f.cf_meta -> "" | _, TAbstract({a_path = ["python"],"KwArgs"},_) -> "**" | _, TAbstract({a_path = ["python"],"VarArgs"},_) -> "*" | _, _ -> "" in prefix ^ e in String.concat "," (ExtList.List.mapi (print_arg pctx) el) and print_exprs pctx sep el = String.concat sep (List.map (print_expr pctx) el) and last_debug_comment = ref ("") and print_block_exprs pctx sep print_debug_comment el = if print_debug_comment then begin let el = List.fold_left (fun acc e -> let line = Lexer.get_error_line e.epos in let debug_line = (Printf.sprintf "# %s:%i" e.epos.pfile line) in let res = if (!last_debug_comment) <> debug_line then (print_expr pctx e) :: debug_line :: acc else (print_expr pctx e) :: acc in last_debug_comment := debug_line; res ) [] el in String.concat sep (List.rev el) end else print_exprs pctx sep el and print_exprs_named pctx sep fl = let args = String.concat sep (List.map (fun (s,e) -> Printf.sprintf "'%s': %s" (Ast.s_escape (handle_keywords s)) (print_expr pctx e)) fl) in Printf.sprintf "{%s}" args and print_params_named pctx sep fl = let args = String.concat sep (List.map (fun (s,e) -> Printf.sprintf "%s= %s" (handle_keywords s) (print_expr pctx e)) fl) in Printf.sprintf "%s" args let handle_keywords s = KeywordHandler.handle_keywords s end module Generator = struct type context = { com : Common.context; buf : Buffer.t; packages : (string,int) Hashtbl.t; mutable static_inits : (unit -> unit) list; mutable class_inits : (unit -> unit) list; mutable indent_count : int; transform_time : float; print_time : float; } let has_feature ctx = Common.has_feature ctx.com let add_feature ctx = Common.add_feature ctx.com type class_field_infos = { cfd_fields : string list; cfd_props : string list; cfd_methods : string list; } type import_type = | IModule of string | IObject of string * string let mk_context com = { com = com; buf = Buffer.create 16000; packages = Hashtbl.create 0; static_inits = []; class_inits = []; indent_count = 0; transform_time = 0.; print_time = 0.; } (* Transformer interface *) let transform_expr e = (* let e = Codegen.UnificationCallback.run Transformer.check_unification e in *) Transformer.transform e let transform_to_value e = (* let e = Codegen.UnificationCallback.run Transformer.check_unification e in *) Transformer.transform_to_value e (* Printer interface *) let get_path mt = Printer.print_base_type mt let tfunc_str f pctx name p = Printer.print_function pctx f name p let texpr_str e pctx = Printer.print_expr pctx e let handle_keywords s = Printer.handle_keywords s (* Helper *) let get_full_name mt = (* TODO: haxe source is crazy *) s_type_path mt.mt_path let collect_class_field_data cfl = let fields = DynArray.create () in let props = DynArray.create () in let methods = DynArray.create () in List.iter (fun cf -> match cf.cf_kind with | Var({v_read = AccResolve}) -> () | Var _ when is_extern_field cf -> () | Var({v_read = AccCall}) -> if Meta.has Meta.IsVar cf.cf_meta then DynArray.add fields cf.cf_name else DynArray.add props cf.cf_name | Var _ -> DynArray.add fields cf.cf_name | _ -> DynArray.add methods cf.cf_name ) cfl; { cfd_fields = DynArray.to_list fields; cfd_props = DynArray.to_list props; cfd_methods = DynArray.to_list methods; } let collect_class_statics_data cfl = let fields = DynArray.create () in List.iter (fun cf -> if not (is_extern_field cf) then DynArray.add fields cf.cf_name ) cfl; DynArray.to_list fields let filter_py_metas metas = List.filter (fun (n,_,_) -> match n with Meta.Custom ":python" -> true | _ -> false) metas let get_members_with_init_expr c = List.filter (fun cf -> match cf.cf_kind with | Var _ when is_extern_field cf -> false | Var _ when cf.cf_expr = None -> true | _ -> false ) c.cl_ordered_fields (* Printing *) let spr ctx s = Buffer.add_string ctx.buf s let spr_line ctx s = Buffer.add_string ctx.buf s; Buffer.add_string ctx.buf "\n" let print ctx = Printf.kprintf (fun s -> begin Buffer.add_string ctx.buf s end) let newline ctx = if not (Buffer.length ctx.buf = 0) then spr ctx "\n" (* Generating functions *) let gen_py_metas ctx metas indent = List.iter (fun (n,el,_) -> match el with | [EConst(String s),_] -> print ctx "%s@%s\n" indent s | _ -> assert false ) metas let gen_expr ctx e field indent = let pctx = Printer.create_context (" " ^ indent) ctx.com ctx.com.debug in let e = match e.eexpr with | TFunction(f) -> {e with eexpr = TBlock [e]} | _ -> e in let expr2 = transform_to_value e in let name = "_hx_init_" ^ (String.concat "_" (ExtString.String.nsplit field ".")) in let maybe_split_expr expr2 = match expr2.eexpr with | TBlock es when es <> [] && field <> "" -> begin match List.rev es with | e_last :: el -> let new_last = {e_last with eexpr = TReturn (Some e_last)} in let new_block = {expr2 with eexpr = TBlock (List.rev (new_last :: el))} in let v_name = alloc_var name (tfun [] e_last.etype) e_last.epos in let f_name = mk (TLocal v_name) v_name.v_type e_last.epos in let call_f = mk (TCall(f_name,[])) e_last.etype e_last.epos in Some new_block,call_f | _ -> assert false end | _ -> None,expr2 in let r = maybe_split_expr expr2 in match r with | Some e1,e2 -> let expr_string_1 = texpr_str e1 pctx in let expr_string_2 = texpr_str e2 pctx in print ctx "%sdef %s():\n %s" indent name expr_string_1; newline ctx; print ctx "%s%s = %s" indent field expr_string_2; | None,e2 -> let expr_string_2 = texpr_str e2 pctx in if field = "" then spr ctx expr_string_2 else print ctx "%s%s = %s" indent field expr_string_2 let gen_func_expr ctx e c name metas add_self indent stat p = let pctx = Printer.create_context indent ctx.com ctx.com.debug in let e = match e.eexpr with | TFunction(f) -> let args = if add_self then let v = alloc_var "self" t_dynamic p in v.v_meta <- (Meta.This,[],p) :: v.v_meta; (v,None) :: f.tf_args else f.tf_args in {e with eexpr = TFunction {f with tf_args = args}} | _ -> e in if stat then begin newline ctx; spr ctx indent; spr ctx "@staticmethod\n" end; let expr1 = transform_expr e in let expr_string = match expr1.eexpr with | TFunction f -> tfunc_str f pctx (Some name) p | _ -> Printf.sprintf "%s = %s" name (texpr_str expr1 pctx) in gen_py_metas ctx metas indent; spr ctx indent; spr ctx expr_string let gen_class_constructor ctx c cf = let member_inits = get_members_with_init_expr c in let py_metas = filter_py_metas cf.cf_meta in begin match cf.cf_expr with | Some ({eexpr = TFunction f} as ef) -> let ethis = mk (TConst TThis) (TInst(c,List.map snd c.cl_params)) cf.cf_pos in let assigned_fields = ref [] in (* Collect all fields that are assigned to but panic out as soon as `this`, `super`, `return` or `throw` appears (regardless of control flow). *) let collect_assignments e = let rec loop e = match e.eexpr with | TBinop(OpAssign,{eexpr = TField({eexpr = TConst TThis}, FInstance(_,_,cf))},e2) -> loop e2; assigned_fields := cf :: !assigned_fields | TConst (TSuper | TThis) | TThrow _ | TReturn _ -> raise Exit (* TODO: We could do some branch intersection stunts to make this more accurate. *) | TIf(e1,_,_) | TSwitch(e1,_,_) | TWhile(e1,_,_) -> loop e1 | _ -> Type.iter loop e in try loop e with Exit -> () in collect_assignments f.tf_expr; let member_data = List.fold_left (fun acc cf -> if not (List.memq cf !assigned_fields) then begin let ef = mk (TField(ethis,FInstance(c,[],cf))) cf.cf_type cf.cf_pos in (* TODO *) let e = mk (TBinop(OpAssign,ef,null ef.etype ef.epos)) ef.etype ef.epos in e :: acc end else acc ) [] member_inits in let e = concat (mk (TBlock member_data) ctx.com.basic.tvoid cf.cf_pos) f.tf_expr in let ef = {ef with eexpr = TFunction {f with tf_expr = e}} in cf.cf_expr <- Some ef; newline ctx; newline ctx; gen_func_expr ctx ef c "__init__" py_metas true " " false cf.cf_pos | _ -> assert false end let gen_class_field ctx c p cf = let field = handle_keywords cf.cf_name in begin match cf.cf_expr with | None -> ()(* print ctx " # var %s" field *) | Some e -> newline ctx; newline ctx; begin match cf.cf_kind with | Method _ -> let py_metas = filter_py_metas cf.cf_meta in gen_func_expr ctx e c field py_metas true " " false cf.cf_pos; | _ -> gen_expr ctx e (Printf.sprintf "# var %s" field) " "; end end let gen_class_empty_constructor ctx p cfl = if has_feature ctx "Type.createEmptyInstance" then begin newline ctx; newline ctx; print ctx " @staticmethod\n def _hx_empty_init(_hx_o):"; let found_fields = ref false in List.iter (fun cf -> match cf.cf_kind with | Var ({v_read = AccResolve | AccCall}) -> () | Var _ -> found_fields := true; newline ctx; print ctx " _hx_o.%s = None" (handle_keywords cf.cf_name) | _ -> () ) cfl; if not !found_fields then spr ctx " pass" end else begin newline ctx end let gen_class_statics ctx c p = let methods, other = List.partition (fun cf -> match cf.cf_kind with | Method _ -> (match cf.cf_expr with Some _ -> true | _ -> false) | _ -> false ) c.cl_ordered_statics in (* generate non methods *) let has_empty_static_vars = ref false in List.iter (fun cf -> let p = get_path (t_infos (TClassDecl c)) in let field = handle_keywords cf.cf_name in match cf.cf_expr with | None -> has_empty_static_vars := true; newline ctx; print ctx " %s = None" field | Some e -> (let f = fun () -> newline ctx; gen_expr ctx e (Printf.sprintf "%s.%s" p field) ""; in ctx.static_inits <- f :: ctx.static_inits) ) other; (* generate static methods *) let has_static_methods = ref false in List.iter (fun cf -> has_static_methods := true; let field = handle_keywords cf.cf_name in let py_metas = filter_py_metas cf.cf_meta in let e = match cf.cf_expr with Some e -> e | _ -> assert false in newline ctx; gen_func_expr ctx e c field py_metas false " " true cf.cf_pos; ) methods; !has_static_methods || !has_empty_static_vars let gen_class_init ctx c = match c.cl_init with | None -> () | Some e -> let is_math = c.cl_path = ([], "Math") in let math_feature = has_feature ctx "Math" in let f = if is_math && not math_feature then fun () -> () else fun () -> let e = transform_expr e in newline ctx; spr ctx (texpr_str e (Printer.create_context "" ctx.com ctx.com.debug)); in ctx.class_inits <- f :: ctx.class_inits let gen_class ctx c = if not c.cl_extern then begin let is_nativegen = Meta.has Meta.NativeGen c.cl_meta in let mt = (t_infos (TClassDecl c)) in let p = get_path mt in let p_name = get_full_name mt in let x = collect_class_field_data c.cl_ordered_fields in let p_super = match c.cl_super with | None -> None | Some (csup,_) -> Some (get_path (t_infos (TClassDecl csup))) in let p_interfaces = List.map (fun (c,tl) -> get_path (t_infos (TClassDecl c)) ) c.cl_implements in newline ctx; newline ctx; newline ctx; print ctx "class %s" p; (match p_super with Some p -> print ctx "(%s)" p | _ -> ()); spr ctx ":"; let use_pass = ref true in if not is_nativegen then begin if has_feature ctx "python._hx_class_name" then begin use_pass := false; print ctx "\n _hx_class_name = \"%s\"" p_name end; let print_field names field quote = if has_feature ctx ("python." ^ field) then try let q s = if quote then "\"" ^ s ^ "\"" else s in let s = match names with | [] when (match c.cl_super with Some _ -> false | _ -> true) -> (* always overwrite parent's class fields *) raise Exit | _ -> "[" ^ (String.concat ", " (List.map q names)) ^ "]" in use_pass := false; print ctx "\n %s = %s" field s with Exit -> () in (try ( let real_fields = List.filter (fun f -> match f.cf_kind with | Method MethDynamic -> raise Exit (* if a class has dynamic method, we can't use __slots__ because python will complain *) | Var _ -> not (is_extern_field f) | _ -> false ) c.cl_ordered_fields in let field_names = List.map (fun f -> handle_keywords f.cf_name) real_fields in let field_names = match c.cl_dynamic with Some _ -> "__dict__" :: field_names | None -> field_names in use_pass := false; print ctx "\n __slots__ = ("; (match field_names with | [] -> () | [name] -> print ctx "\"%s\"," name | names -> print ctx "\"%s\"" (String.concat "\", \"" names)); print ctx ")"; ) with Exit -> ()); print_field x.cfd_fields "_hx_fields" true; print_field x.cfd_methods "_hx_methods" true; (* TODO: It seems strange to have a separation for member fields but a plain _hx_statics for static ones *) print_field (collect_class_statics_data c.cl_ordered_statics) "_hx_statics" true; print_field (p_interfaces) "_hx_interfaces" false; if has_feature ctx "python._hx_super" then (match p_super with | None -> () | Some ps -> use_pass := false; print ctx "\n _hx_super = %s\n" ps ); end; begin match c.cl_constructor with | Some cf -> gen_class_constructor ctx c cf; | None -> () end; List.iter (fun cf -> gen_class_field ctx c p cf) c.cl_ordered_fields; let has_inner_static = gen_class_statics ctx c p in let has_empty_constructor = match ((Meta.has Meta.NativeGen c.cl_meta) || c.cl_interface), c.cl_ordered_fields with | true,_ | _, [] -> false | _ -> gen_class_empty_constructor ctx p c.cl_ordered_fields; has_feature ctx "Type.createEmptyInstance" in let use_pass = !use_pass && (not has_inner_static) && (not has_empty_constructor) && match x.cfd_methods with | [] -> c.cl_constructor = None | _ -> c.cl_interface in if use_pass then spr ctx "\n pass"; if not is_nativegen then begin if has_feature ctx "python._hx_class" then print ctx "\n%s._hx_class = %s" p p; if has_feature ctx "python._hx_classes" then print ctx "\n_hx_classes[\"%s\"] = %s" p_name p; end end; gen_class_init ctx c let gen_enum_metadata ctx en p = let meta = Codegen.build_metadata ctx.com (TEnumDecl en) in match meta with | None -> () | Some e -> newline ctx; print ctx "%s.__meta__ = " p; gen_expr ctx e "" "" let gen_enum ctx en = let mt = (t_infos (TEnumDecl en)) in let p = get_path mt in let p_name = get_full_name mt in let enum_constructs = PMap.foldi (fun k ef acc -> ef :: acc) en.e_constrs [] in let enum_constructs = List.sort (fun a b -> if a.ef_index < b.ef_index then -1 else if a.ef_index > b.ef_index then 1 else 0) enum_constructs in newline ctx; newline ctx; print ctx "class %s(Enum):" p; print ctx "\n __slots__ = ()"; if has_feature ctx "python._hx_class_name" then begin print ctx "\n _hx_class_name = \"%s\"" p_name end; if has_feature ctx "python._hx_constructs" then begin let fix = match enum_constructs with [] -> "" | _ -> "\"" in let enum_constructs_str = fix ^ (String.concat ("\", \"") (List.map (fun ef -> ef.ef_name) enum_constructs)) ^ fix in print ctx "\n _hx_constructs = [%s]" enum_constructs_str; end; let const_constructors,param_constructors = List.partition (fun ef -> match follow ef.ef_type with | TFun(_,_) -> false | _ -> true ) enum_constructs in List.iter (fun ef -> match follow ef.ef_type with | TFun(args, _) -> let print_args args = let had_optional = ref false in let sl = List.map (fun (n,o,_) -> let name = handle_keywords n in let arg_value = if !had_optional then "= None" else if o then begin had_optional := true; " = None" end else "" in Printf.sprintf "%s%s" name arg_value ) args in String.concat "," sl in let f = handle_keywords ef.ef_name in let param_str = print_args args in let args_str = String.concat "," (List.map (fun (n,_,_) -> handle_keywords n) args) in newline ctx; newline ctx; print ctx " @staticmethod\n def %s(%s):\n" f param_str; print ctx " return %s(\"%s\", %i, [%s])" p ef.ef_name ef.ef_index args_str; | _ -> assert false ) param_constructors; List.iter (fun ef -> (* TODO: haxe source has api.quoteString for ef.ef_name *) let f = handle_keywords ef.ef_name in newline ctx; print ctx "%s.%s = %s(\"%s\", %i, list())" p f p ef.ef_name ef.ef_index ) const_constructors; if has_feature ctx "python._hx_class" then print ctx "\n%s._hx_class = %s" p p; if has_feature ctx "python._hx_classes" then print ctx "\n_hx_classes[\"%s\"] = %s" p_name p; gen_enum_metadata ctx en p let gen_abstract ctx a = newline ctx; newline ctx; newline ctx; let mt = (t_infos (TAbstractDecl a)) in let p = get_path mt in let p_name = get_full_name mt in print ctx "class %s:" p; let use_pass = ref true in if has_feature ctx "python._hx_class_name" then begin use_pass := false; print ctx "\n _hx_class_name = \"%s\"" p_name end; (match a.a_impl with | Some c -> List.iter (fun cf -> use_pass := false; if cf.cf_name = "_new" then gen_class_constructor ctx c cf else gen_class_field ctx c p cf ) c.cl_ordered_statics | None -> ()); if !use_pass then spr ctx "\n pass"; if has_feature ctx "python._hx_class" then print ctx "\n%s._hx_class = %s" p p; if has_feature ctx "python._hx_classes" then print ctx "\n_hx_classes[\"%s\"] = %s" p_name p let gen_type ctx mt = match mt with | TClassDecl c -> gen_class ctx c | TEnumDecl en when not en.e_extern -> gen_enum ctx en | TAbstractDecl {a_path = [],"UInt"} -> () | TAbstractDecl {a_path = [],"Enum"} -> () | TAbstractDecl {a_path = [],"EnumValue"} when not (has_feature ctx "has_enum") -> () | TAbstractDecl {a_path = [],"Void"} -> () | TAbstractDecl {a_path = [],"Int"} when not (has_feature ctx "Int.*") -> () | TAbstractDecl {a_path = [],"Float"} when not (has_feature ctx "Float.*") -> () | TAbstractDecl {a_path = [],"Class"} when not (has_feature ctx "Class.*") -> () | TAbstractDecl {a_path = [],"Dynamic"} when not (has_feature ctx "Dynamic.*") -> () | TAbstractDecl {a_path = [],"Bool"} when not (has_feature ctx "Bool.*") -> () | TAbstractDecl a when Meta.has Meta.CoreType a.a_meta -> gen_abstract ctx a | _ -> () (* Generator parts *) let gen_resources ctx = if Hashtbl.length ctx.com.resources > 0 then begin let slash_index = try (String.rindex ctx.com.file '/')+1 with Not_found -> 0 in let len = String.length ctx.com.file - slash_index in let file_name = String.sub ctx.com.file slash_index len in newline ctx; newline ctx; newline ctx; spr ctx "def _hx_resources__():"; spr ctx "\n import inspect"; spr ctx "\n import sys"; spr ctx "\n if not hasattr(sys.modules[__name__], '__file__'):"; print ctx "\n _file = '%s'" file_name; spr ctx "\n else:"; spr ctx "\n _file = __file__"; spr ctx "\n return {"; let first = ref true in Hashtbl.iter (fun k v -> let prefix = if !first then begin first := false; ""; end else "," in let k_enc = Codegen.escape_res_name k false in print ctx "%s\"%s\": open('%%s.%%s'%%(_file,'%s'),'rb').read()" prefix (Ast.s_escape k) k_enc; let f = open_out_bin (ctx.com.file ^ "." ^ k_enc) in output_string f v; close_out f ) ctx.com.resources; spr ctx "}" end let gen_imports ctx = let import path meta = if Meta.has Meta.PythonImport meta && is_directly_used ctx.com meta then begin let _, args, mp = Meta.get Meta.PythonImport meta in let class_name = match path with | [],name -> name | path,name -> (ExtString.String.join "_" path) ^ "_" ^ name in let import_type,ignore_error = match args with | [(EConst(String(module_name)), _)] | [(EConst(String(module_name)), _); (EBinop(OpAssign, (EConst(Ident("ignoreError")),_), (EConst(Ident("false")),_)),_)] -> IModule module_name, false | [(EConst(String(module_name)), _); (EBinop(OpAssign, (EConst(Ident("ignoreError")),_), (EConst(Ident("true")),_)),_)] -> IModule module_name,true | [(EConst(String(module_name)), _); (EConst(String(object_name)), _)] | [(EConst(String(module_name)), _); (EConst(String(object_name)), _); (EBinop(OpAssign, (EConst(Ident("ignoreError")),_), (EConst(Ident("false")),_)),_)] -> IObject (module_name,object_name), false | [(EConst(String(module_name)), _); (EConst(String(object_name)), _); (EBinop(OpAssign, (EConst(Ident("ignoreError")),_), (EConst(Ident("true")),_)),_)] -> IObject (module_name,object_name), true | _ -> abort "Unsupported @:pythonImport format" mp in let import = match import_type with | IModule module_name -> (* importing whole module *) if module_name = class_name then "import " ^ module_name else "import " ^ module_name ^ " as " ^ class_name | IObject (module_name,object_name) -> if String.contains object_name '.' then (* importing nested class *) "import " ^ module_name ^ " as _hx_temp_import; " ^ class_name ^ " = _hx_temp_import." ^ object_name ^ "; del _hx_temp_import" else (* importing a class from a module *) if object_name = class_name then "from " ^ module_name ^ " import " ^ object_name else "from " ^ module_name ^ " import " ^ object_name ^ " as " ^ class_name in newline ctx; if ignore_error then begin spr ctx "try:\n "; spr_line ctx import; spr ctx "except:\n pass" end else spr ctx import end in List.iter (fun mt -> match mt with | TClassDecl c when c.cl_extern -> import c.cl_path c.cl_meta | TEnumDecl e when e.e_extern -> import e.e_path e.e_meta | _ -> () ) ctx.com.types let gen_types ctx = let used_paths = Hashtbl.create 0 in let find_type path = Hashtbl.add used_paths path true; Utils.find_type ctx.com path in let need_anon_for_trace = (has_feature ctx "has_anon_trace") && (has_feature ctx "haxe.Log.trace") in if (has_feature ctx "has_anon") || (has_feature ctx "_hx_AnonObject") || (has_feature ctx "has_metadata") || need_anon_for_trace then begin let with_body = (has_feature ctx "has_anon") || (has_feature ctx "has_metadata") || need_anon_for_trace in newline ctx; newline ctx; newline ctx; spr ctx "class _hx_AnonObject:\n"; if with_body then begin spr ctx " def __init__(self, fields):\n"; spr ctx " self.__dict__ = fields" end else spr ctx " pass"; Hashtbl.add used_paths ([],"_hx_AnonObject") true; end; if has_feature ctx "python._hx_classes" then begin newline ctx; newline ctx; newline ctx; spr ctx "_hx_classes = {}"; end; if has_feature ctx "Boot.*" then gen_type ctx (find_type (["python"],"Boot")); if has_feature ctx "has_enum" || has_feature ctx "Enum.*" then gen_type ctx (find_type ([],"Enum")); if has_feature ctx "HxOverrides.*" then gen_type ctx (find_type ([],"HxOverrides")); List.iter (fun mt -> if not (Hashtbl.mem used_paths (t_infos mt).mt_path) then gen_type ctx mt ) ctx.com.types let gen_static_inits ctx = newline ctx; List.iter (fun f -> f()) (List.rev ctx.static_inits) let gen_class_inits ctx = newline ctx; List.iter (fun f -> f()) (List.rev ctx.class_inits) let gen_main ctx = match ctx.com.main with | None -> () | Some e -> newline ctx; newline ctx; match e.eexpr with | TBlock el -> List.iter (fun e -> gen_expr ctx e "" ""; newline ctx) el | _ -> gen_expr ctx e "" "" (* Entry point *) let run com = Transformer.init com; let ctx = mk_context com in Codegen.map_source_header com (fun s -> print ctx "# %s\n# coding: utf-8\n" s); if has_feature ctx "closure_Array" || has_feature ctx "closure_String" then spr ctx "from functools import partial as _hx_partial"; gen_imports ctx; gen_resources ctx; gen_types ctx; gen_class_inits ctx; gen_static_inits ctx; gen_main ctx; mkdir_from_path com.file; let ch = open_out_bin com.file in output_string ch (Buffer.contents ctx.buf); close_out ch end let generate com = Generator.run com haxe_3.4.4.orig/src/generators/genswf.ml0000664000175000017500000011740413166552354020206 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Swf open As3 open As3hl open Genswf9 open Type open Common open Ast open Globals let rec make_tpath = function | HMPath (pack,name) -> let pdyn = ref false in let pack, name = match pack, name with | [], "void" -> [], "Void" | [], "int" -> [], "Int" | [], "uint" -> [], "UInt" | [], "Number" -> [], "Float" | [], "Boolean" -> [], "Bool" | [], "Object" -> ["flash";"utils"], "Object" | [], "Function" -> ["flash";"utils"], "Function" | [], "Class" | [],"Array" -> pdyn := true; pack, name | [], "Error" -> ["flash";"errors"], "Error" | [] , "XML" -> ["flash";"xml"], "XML" | [] , "XMLList" -> ["flash";"xml"], "XMLList" | [] , "QName" -> ["flash";"utils"], "QName" | [] , "Namespace" -> ["flash";"utils"], "Namespace" | [] , "RegExp" -> ["flash";"utils"], "RegExp" | ["__AS3__";"vec"] , "Vector" -> ["flash"], "Vector" | _ -> pack, name in { tpackage = pack; tname = name; tparams = if !pdyn then [TPType (CTPath { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None; },null_pos)] else[]; tsub = None; } | HMName (id,ns) -> { tpackage = (match ns with | HNInternal (Some ns) -> ExtString.String.nsplit ns "." | HNPrivate (Some ns) -> (try let file, line = ExtString.String.split ns ".as$" in [file ^ "_" ^ line] with _ -> []) | _ -> []); tname = id; tparams = []; tsub = None; } | HMNSAny (id) -> { tpackage = []; tname = id; tparams = []; tsub = None; } | HMMultiName _ -> assert false | HMRuntimeName _ -> assert false | HMRuntimeNameLate -> assert false | HMMultiNameLate _ -> assert false | HMAttrib _ -> assert false | HMAny -> assert false | HMParams (t,params) -> let params = List.map (fun t -> TPType (CTPath (make_tpath t),null_pos)) params in { (make_tpath t) with tparams = params } let make_param cl p = { tpackage = fst cl; tname = snd cl; tparams = [TPType (CTPath { tpackage = fst p; tname = snd p; tparams = []; tsub = None },null_pos)]; tsub = None } let make_topt = function | None -> { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None } | Some t -> make_tpath t let make_type t = CTPath (make_topt t) let make_dyn_type t = match make_topt t with | { tpackage = ["flash";"utils"]; tname = ("Object"|"Function") } -> make_type None | o -> CTPath o let is_valid_path com pack name = let rec loop = function | [] -> false | load :: l -> match load (pack,name) null_pos with | None -> loop l | Some (file,(_,a)) -> true in let file = Printf.sprintf "%s/%s.hx" (String.concat "/" pack) name in loop com.load_extern_type || (try ignore(Common.find_file com file); true with Not_found -> false) let build_class com c file = let path = make_tpath c.hlc_name in let pos = { pfile = file ^ "@" ^ s_type_path (path.tpackage,path.tname); pmin = 0; pmax = 0 } in match path with | { tpackage = ["flash";"utils"]; tname = ("Object"|"Function") } -> let inf = { d_name = path.tname,null_pos; d_doc = None; d_params = []; d_meta = []; d_flags = []; d_data = CTPath { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None; },null_pos; } in (path.tpackage, [(ETypedef inf,pos)]) | _ -> (* make flags *) let flags = [HExtern] in let flags = if c.hlc_interface then HInterface :: flags else flags in let flags = (match c.hlc_super with | None | Some (HMPath ([],"Object")) -> flags | Some (HMPath ([],"Function")) -> flags (* found in AIR SDK *) | Some s -> HExtends (make_tpath s,null_pos) :: flags ) in let flags = List.map (fun i -> let i = (match i with | HMMultiName (Some id,ns) -> let rec loop = function | [] -> HMPath ([],id) | HNPublic (Some ns) :: _ when is_valid_path com (ExtString.String.nsplit ns ".") id -> HMPath (ExtString.String.nsplit ns ".",id) | _ :: l -> loop l in loop ns | HMPath _ -> i | _ -> assert false ) in if c.hlc_interface then HExtends (make_tpath i,null_pos) else HImplements (make_tpath i,null_pos) ) (Array.to_list c.hlc_implements) @ flags in let flags = if c.hlc_sealed || Common.defined com Define.FlashStrict then flags else HImplements (make_tpath (HMPath ([],"Dynamic")),null_pos) :: flags in (* make fields *) let getters = Hashtbl.create 0 in let setters = Hashtbl.create 0 in let override = Hashtbl.create 0 in let is_xml = (match path.tpackage, path.tname with | ["flash";"xml"], ("XML" | "XMLList") -> true | _ -> false ) in let make_field stat acc f = let meta = ref [] in let flags = (match f.hlf_name with | HMPath _ -> [APublic] | HMName (_,ns) -> (match ns with | HNPrivate _ | HNNamespace "http://www.adobe.com/2006/flex/mx/internal" -> [] | HNNamespace ns -> if not (c.hlc_interface || is_xml) then meta := (Meta.Ns,[String ns]) :: !meta; [APublic] | HNExplicit _ | HNInternal _ | HNPublic _ -> [APublic] | HNStaticProtected _ | HNProtected _ -> meta := (Meta.Protected,[]) :: !meta; [APrivate]) | _ -> [] ) in if flags = [] then acc else let flags = if stat then AStatic :: flags else flags in let name = (make_tpath f.hlf_name).tname in let mk_meta() = List.map (fun (s,cl) -> s, List.map (fun c -> EConst c,pos) cl, pos) (!meta) in let cf = { cff_name = name,null_pos; cff_doc = None; cff_pos = pos; cff_meta = mk_meta(); cff_access = flags; cff_kind = FVar (None,None); } in match f.hlf_kind with | HFVar v -> if v.hlv_const then cf.cff_kind <- FProp (("default",null_pos),("never",null_pos),Some (make_type v.hlv_type,null_pos),None) else cf.cff_kind <- FVar (Some (make_dyn_type v.hlv_type,null_pos),None); cf :: acc | HFMethod m when m.hlm_override -> Hashtbl.add override (name,stat) (); acc | HFMethod m -> (match m.hlm_kind with | MK3Normal -> let t = m.hlm_type in let p = ref 0 and pn = ref 0 in let make_type = if stat || name = "new" then make_dyn_type else make_type in let args = List.map (fun at -> let aname = (match t.hlmt_pnames with | None -> incr pn; "p" ^ string_of_int !pn | Some l -> match List.nth l !p with | None -> incr pn; "p" ^ string_of_int !pn | Some i -> i ) in let opt_val = (match t.hlmt_dparams with | None -> None | Some l -> try Some (List.nth l (!p - List.length t.hlmt_args + List.length l)) with _ -> None ) in incr p; let t = make_type at in let is_opt = ref false in let def_val = match opt_val with | None -> None | Some v -> let v = (match v with | HVNone | HVNull | HVNamespace _ | HVString _ -> is_opt := true; None | HVBool b -> Some (Ident (if b then "true" else "false")) | HVInt i | HVUInt i -> Some (Int (Int32.to_string i)) | HVFloat f -> Some (Float (float_repres f)) ) in match v with | None -> None | Some v -> (* add for --gen-hx-classes generation *) meta := (Meta.DefParam,[String aname;v]) :: !meta; Some (EConst v,pos) in ((aname,null_pos),!is_opt,[],Some (t,null_pos),def_val) ) t.hlmt_args in let args = if t.hlmt_var_args then args @ List.map (fun _ -> incr pn; (("p" ^ string_of_int !pn,null_pos),true,[],Some (make_type None,null_pos),None)) [1;2;3;4;5] else args in let f = { f_params = []; f_args = args; f_type = Some (make_type t.hlmt_ret,null_pos); f_expr = None; } in cf.cff_meta <- mk_meta(); cf.cff_kind <- FFun f; cf :: acc | MK3Getter -> Hashtbl.add getters (name,stat) m.hlm_type.hlmt_ret; acc | MK3Setter -> Hashtbl.add setters (name,stat) (match m.hlm_type.hlmt_args with [t] -> t | _ -> assert false); acc ) | _ -> acc in let fields = if c.hlc_interface then [] else make_field false [] { hlf_name = HMPath ([],"new"); hlf_slot = 0; hlf_metas = None; hlf_kind = HFMethod { hlm_type = { c.hlc_construct with hlmt_ret = Some (HMPath ([],"void")) }; hlm_final = false; hlm_override = false; hlm_kind = MK3Normal } } in let fields = Array.fold_left (make_field false) fields c.hlc_fields in let fields = Array.fold_left (make_field true) fields c.hlc_static_fields in let make_get_set name stat tget tset = let get, set, t = (match tget, tset with | None, None -> assert false | Some t, None -> true, false, t | None, Some t -> false, true, t | Some t1, Some t2 -> true, true, (if t1 <> t2 then None else t1) ) in let t = if name = "endian" then Some (HMPath (["flash";"utils"],"Endian")) else t in let flags = [APublic] in let flags = if stat then AStatic :: flags else flags in { cff_name = name,null_pos; cff_pos = pos; cff_doc = None; cff_access = flags; cff_meta = []; cff_kind = if get && set then FVar (Some (make_dyn_type t,null_pos), None) else FProp (((if get then "default" else "never"),null_pos),((if set then "default" else "never"),null_pos),Some (make_dyn_type t,null_pos),None); } in let fields = Hashtbl.fold (fun (name,stat) t acc -> if Hashtbl.mem override (name,stat) then acc else make_get_set name stat (Some t) (try Some (Hashtbl.find setters (name,stat)) with Not_found -> None) :: acc ) getters fields in let fields = Hashtbl.fold (fun (name,stat) t acc -> if Hashtbl.mem getters (name,stat) || Hashtbl.mem override (name,stat) then acc else make_get_set name stat None (Some t) :: acc ) setters fields in try (* If the class only contains static String constants, make it an enum *) let real_type = ref "" in let rec loop = function | [] -> [] | f :: l -> match f.cff_kind with | FVar (Some (CTPath { tpackage = []; tname = ("String" | "Int" | "UInt") as tname },null_pos),None) | FProp (("default",_),("never",_),Some (CTPath { tpackage = []; tname = ("String" | "Int" | "UInt") as tname },null_pos),None) when List.mem AStatic f.cff_access -> if !real_type = "" then real_type := tname else if !real_type <> tname then raise Exit; { ec_name = f.cff_name; ec_pos = pos; ec_args = []; ec_params = []; ec_meta = []; ec_doc = None; ec_type = None; } :: loop l | FFun { f_args = [] } when fst f.cff_name = "new" -> loop l | _ -> raise Exit in List.iter (function HExtends _ | HImplements _ -> raise Exit | _ -> ()) flags; let constr = loop fields in let name = "fakeEnum:" ^ String.concat "." (path.tpackage @ [path.tname]) in if not (Common.raw_defined com name) then raise Exit; let enum_data = { d_name = path.tname,null_pos; d_doc = None; d_params = []; d_meta = [(Meta.FakeEnum,[EConst (Ident !real_type),pos],pos)]; d_flags = [EExtern]; d_data = constr; } in (path.tpackage, [(EEnum enum_data,pos)]) with Exit -> let class_data = { d_name = path.tname,null_pos; d_doc = None; d_params = []; d_meta = if c.hlc_final && List.exists (fun f -> fst f.cff_name <> "new" && not (List.mem AStatic f.cff_access)) fields then [Meta.Final,[],pos] else []; d_flags = flags; d_data = fields; } in (path.tpackage, [(EClass class_data,pos)]) let extract_data (_,tags) = let t = Common.timer ["read";"swf"] in let h = Hashtbl.create 0 in let rec loop_field f = match f.hlf_kind with | HFClass c -> let path = make_tpath f.hlf_name in (match path with | { tpackage = []; tname = "Float" | "Bool" | "Int" | "UInt" | "Dynamic" } -> () | { tpackage = _; tname = "MethodClosure" } -> () | _ -> Hashtbl.add h (path.tpackage,path.tname) c) | _ -> () in List.iter (fun t -> match t.tdata with | TActionScript3 (_,as3) -> List.iter (fun i -> Array.iter loop_field i.hls_fields) (As3hlparse.parse as3) | _ -> () ) tags; t(); h let remove_debug_infos as3 = let hl = As3hlparse.parse as3 in let methods = Hashtbl.create 0 in let rec loop_field f = { f with hlf_kind = (match f.hlf_kind with | HFMethod m -> HFMethod { m with hlm_type = loop_method m.hlm_type } | HFFunction f -> HFFunction (loop_method f) | HFVar v -> HFVar v | HFClass c -> HFClass (loop_class c)) } and loop_class c = (* mutate in order to preserve sharing *) c.hlc_construct <- loop_method c.hlc_construct; c.hlc_fields <- Array.map loop_field c.hlc_fields; c.hlc_static_construct <- loop_method c.hlc_static_construct; c.hlc_static_fields <- Array.map loop_field c.hlc_static_fields; c and loop_static s = { hls_method = loop_method s.hls_method; hls_fields = Array.map loop_field s.hls_fields; } and loop_method m = try Hashtbl.find methods m.hlmt_index with Not_found -> let m2 = { m with hlmt_debug_name = None; hlmt_pnames = None } in Hashtbl.add methods m.hlmt_index m2; m2.hlmt_function <- (match m.hlmt_function with None -> None | Some f -> Some (loop_function f)); m2 and loop_function f = let cur = ref 0 in let positions = MultiArray.map (fun op -> let p = !cur in (match op with | HDebugReg _ | HDebugLine _ | HDebugFile _ | HBreakPointLine _ | HTimestamp -> () | _ -> incr cur); p ) f.hlf_code in MultiArray.add positions (!cur); let code = MultiArray.create() in MultiArray.iteri (fun pos op -> match op with | HDebugReg _ | HDebugLine _ | HDebugFile _ | HBreakPointLine _ | HTimestamp -> () | _ -> let p delta = MultiArray.get positions (pos + delta) - MultiArray.length code in let op = (match op with | HJump (j,delta) -> HJump (j, p delta) | HSwitch (d,deltas) -> HSwitch (p d,List.map p deltas) | HFunction m -> HFunction (loop_method m) | HCallStatic (m,args) -> HCallStatic (loop_method m,args) | HClassDef c -> HClassDef c (* mutated *) | _ -> op) in MultiArray.add code op ) f.hlf_code; f.hlf_code <- code; f.hlf_trys <- Array.map (fun t -> { t with hltc_start = MultiArray.get positions t.hltc_start; hltc_end = MultiArray.get positions t.hltc_end; hltc_handle = MultiArray.get positions t.hltc_handle; } ) f.hlf_trys; f in As3hlparse.flatten (List.map loop_static hl) let parse_swf com file = let t = Common.timer ["read";"swf"] in let is_swc = file_extension file = "swc" || file_extension file = "ane" in let file = (try Common.find_file com file with Not_found -> failwith ((if is_swc then "SWC" else "SWF") ^ " Library not found : " ^ file)) in let ch = if is_swc then begin let zip = Zip.open_in file in try let entry = Zip.find_entry zip "library.swf" in let ch = IO.input_string (Zip.read_entry zip entry) in Zip.close_in zip; ch with _ -> Zip.close_in zip; failwith ("The input swc " ^ file ^ " is corrupted") end else IO.input_channel (open_in_bin file) in let h, tags = try Swf.parse ch with Out_of_memory -> failwith ("Out of memory while parsing " ^ file) | _ -> failwith ("The input swf " ^ file ^ " is corrupted") in IO.close_in ch; List.iter (fun t -> match t.tdata with | TActionScript3 (id,as3) when not com.debug && not com.display.DisplayMode.dms_display -> t.tdata <- TActionScript3 (id,remove_debug_infos as3) | _ -> () ) tags; t(); (h,tags) let add_swf_lib com file extern = let swf_data = ref None in let swf_classes = ref None in let getSWF = (fun() -> match !swf_data with | None -> let d = parse_swf com file in swf_data := Some d; d | Some d -> d ) in let extract = (fun() -> match !swf_classes with | None -> let d = extract_data (getSWF()) in swf_classes := Some d; d | Some d -> d ) in let build cl p = match (try Some (Hashtbl.find (extract()) cl) with Not_found -> None) with | None -> None | Some c -> Some (file, build_class com c file) in com.load_extern_type <- com.load_extern_type @ [build]; if not extern then com.swf_libs <- (file,getSWF,extract) :: com.swf_libs (* ------------------------------- *) let tag ?(ext=false) d = { tid = 0; textended = ext; tdata = d; } let convert_header com (w,h,fps,bg) = let high = (max w h) * 20 in let rec loop b = if 1 lsl b > high then b else loop (b + 1) in let bits = loop 0 in { h_version = Common.flash_version_tag com.flash_version; h_size = { rect_nbits = bits + 1; left = 0; top = 0; right = w * 20; bottom = h * 20; }; h_frame_count = 1; h_fps = to_float16 (if fps > 127.0 then 127.0 else fps); h_compressed = not (Common.defined com Define.NoSwfCompress); } , bg let default_header com = convert_header com (400,300,30.,0xFFFFFF) type dependency_kind = | DKInherit | DKExpr | DKType let build_dependencies t = let h = ref PMap.empty in let add_path p k = h := PMap.add (p,k) () !h; in let rec add_type_rec l t = if List.memq t l then () else match t with | TEnum (e,pl) -> add_path e.e_path DKType; List.iter (add_type_rec (t::l)) pl; | TInst (c,pl) -> (match c.cl_kind with KTypeParameter _ -> () | _ -> add_path c.cl_path DKType); List.iter (add_type_rec (t::l)) pl; | TAbstract (a,pl) -> if Meta.has Meta.CoreType a.a_meta then add_path a.a_path DKType; List.iter (add_type_rec (t::l)) pl; | TFun (pl,t2) -> List.iter (fun (_,_,t2) -> add_type_rec (t::l) t2) pl; add_type_rec (t::l) t2; | TAnon a -> PMap.iter (fun _ f -> add_type_rec (t::l) f.cf_type) a.a_fields | TDynamic t2 -> add_type_rec (t::l) t2; | TLazy f -> add_type_rec l ((!f)()) | TMono r -> (match !r with | None -> () | Some t -> add_type_rec l t) | TType (tt,pl) -> add_type_rec (t::l) tt.t_type; List.iter (add_type_rec (t::l)) pl and add_type t = add_type_rec [] t and add_expr e = match e.eexpr with | TTypeExpr t -> add_path (Type.t_path t) DKExpr | TNew (c,pl,el) -> add_path c.cl_path DKExpr; List.iter add_type pl; List.iter add_expr el; | TFunction f -> List.iter (fun (v,_) -> add_type v.v_type) f.tf_args; add_type f.tf_type; add_expr f.tf_expr; | TFor (v,e1,e2) -> add_type v.v_type; add_expr e1; add_expr e2; | TVar (v,eo) -> add_type v.v_type; begin match eo with | None -> () | Some e -> add_expr e end | _ -> Type.iter add_expr e and add_field f = add_type f.cf_type; match f.cf_expr with | None -> () | Some e -> add_expr e in let add_inherit (c,pl) = add_path c.cl_path DKInherit; List.iter add_type pl; in (match t with | TClassDecl c when not c.cl_extern -> List.iter add_field c.cl_ordered_fields; List.iter add_field c.cl_ordered_statics; (match c.cl_constructor with | None -> () | Some f -> add_field f; if c.cl_path <> (["flash"],"Boot") then add_path (["flash"],"Boot") DKExpr; ); (match c.cl_init with | None -> () | Some e -> add_expr e); (match c.cl_super with | None -> add_path ([],"Object") DKInherit; | Some x -> add_inherit x); List.iter (fun (_,t) -> (* add type-parameters constraints dependencies *) match follow t with | TInst (c,_) -> List.iter add_inherit c.cl_implements | _ -> () ) c.cl_params; List.iter add_inherit c.cl_implements; | TEnumDecl e when not e.e_extern -> PMap.iter (fun _ f -> add_type f.ef_type) e.e_constrs; | _ -> ()); h := PMap.remove (([],"Int"),DKType) (!h); h := PMap.remove (([],"Int"),DKExpr) (!h); h := PMap.remove (([],"Void"),DKType) (!h); PMap.foldi (fun (c,k) () acc -> (c,k) :: acc) (!h) [] let build_swc_catalog com types = let node x att l = Xml.Element (x,att,l) in let make_path t sep = let path, name = t_path t in String.concat sep (path @ [name]) in let make_id path = match Genswf9.real_path path with | [],n -> n | l,n -> (String.concat "." l) ^ ":" ^ n in let build_script t = let deps = build_dependencies t in node "script" [("name",make_path t "/");("mod","0")] ([ node "def" ["id",make_id (t_path t)] []; node "dep" [("id","AS3");("type","n")] []; ] @ List.map (fun (p,k) -> let t = (match k with | DKInherit -> "i" | DKExpr -> (match p with "flash" :: _ :: _ , _ -> "i" | _ -> "e") | DKType -> "s" ) in node "dep" [("id",make_id p);("type",t)] [] ) deps) in let x = node "swc" ["xmlns","http://www.adobe.com/flash/swccatalog/9"] [ node "versions" [] [ node "swc" ["version","1.2"] []; node "haxe" ["version",Printf.sprintf "%d.%.2d" (com.version/10000) (com.version mod 10000)] []; ]; node "features" [] [ node "feature-script-deps" [] []; node "feature-files" [] []; ]; node "libraries" [] [ node "library" ["path","library.swf"] (List.map build_script types) ]; node "files" [] []; ] in "\n" ^ Xml.to_string_fmt x let remove_classes toremove lib hcl = let lib = lib() in match !toremove with | [] -> lib | _ -> let hcl = hcl() in match List.filter (fun c -> Hashtbl.mem hcl c) (!toremove) with | [] -> lib | classes -> let rec tags = function | [] -> [] | t :: l -> match t.tdata with | TActionScript3 (h,data) -> let data = As3hlparse.parse data in let rec loop f = match f.hlf_kind with | HFClass _ -> let path = make_tpath f.hlf_name in not (List.mem (path.tpackage,path.tname) classes) | _ -> true in let data = List.map (fun s -> { s with hls_fields = Array.of_list (List.filter loop (Array.to_list s.hls_fields)) }) data in let data = List.filter (fun s -> Array.length s.hls_fields > 0) data in (if data = [] then tags l else { t with tdata = TActionScript3 (h,As3hlparse.flatten data) } :: tags l) | _ -> t :: tags l in toremove := List.filter (fun p -> not (List.mem p classes)) !toremove; fst lib, tags (snd lib) type file_format = | BJPG | BPNG | BGIF | SWAV | SMP3 let detect_format data p = match (try data.[0],data.[1],data.[2] with _ -> '\x00','\x00','\x00') with | '\xFF', '\xD8', _ -> BJPG | '\x89', 'P', 'N' -> BPNG | 'R', 'I', 'F' -> SWAV | 'I', 'D', '3' -> SMP3 | '\xFF', i, _ when (int_of_char i) land 0xE2 = 0xE2 -> SMP3 | 'G', 'I', 'F' -> BGIF | _ -> abort "Unknown file format" p open TTFData let build_swf9 com file swc = let boot_name = if swc <> None || Common.defined com Define.HaxeBoot then "haxe" else "boot_" ^ (String.sub (Digest.to_hex (Digest.string (Filename.basename file))) 0 4) in let code = Genswf9.generate com boot_name in let code = (match swc with | Some cat -> cat := build_swc_catalog com (List.map (fun (t,_,_) -> t) code); List.map (fun (t,m,f) -> let path = (match t_path t with | [], name -> name | path, name -> String.concat "/" path ^ "/" ^ name ) in let init = { hls_method = m; hls_fields = [|f|]; } in tag (TActionScript3 (Some (1,path),As3hlparse.flatten [init])) ) code | None -> let inits = List.map (fun (_,m,f) -> { hls_method = m; hls_fields = [|f|]; } ) code in [tag (TActionScript3 ((if Common.defined com Define.SwfUseDoAbc then Some(1,boot_name) else None), As3hlparse.flatten inits))] ) in let cid = ref 0 in let classes = ref [{ f9_cid = None; f9_classname = boot_name }] in let res = Hashtbl.fold (fun name data acc -> incr cid; classes := { f9_cid = Some !cid; f9_classname = s_type_path (Genswf9.resource_path name) } :: !classes; tag (TBinaryData (!cid,data)) :: acc ) com.resources [] in let load_file_data file p = let file = try Common.find_file com file with Not_found -> file in if String.length file > 5 && String.sub file 0 5 = "data:" then String.sub file 5 (String.length file - 5) else (try Std.input_file ~bin:true file with Invalid_argument("String.create") -> abort "File is too big (max 16MB allowed)" p | _ -> abort "File not found" p) in let bmp = List.fold_left (fun acc t -> match t with | TClassDecl c -> let rec loop = function | [] -> acc | (Meta.Font,(EConst (String file),p) :: args,_) :: l -> let file = try Common.find_file com file with Not_found -> file in let ch = try open_in_bin file with _ -> abort "File not found" p in let ttf = try TTFParser.parse ch with e -> abort ("Error while parsing font " ^ file ^ " : " ^ Printexc.to_string e) p in close_in ch; let get_string e = match fst e with | EConst (String s) -> Some s | _ -> raise Not_found in let ttf_config = { ttfc_range_str = ""; ttfc_font_name = None; } in begin match args with | (EConst (String str),_) :: _ -> ttf_config.ttfc_range_str <- str; | _ -> () end; begin match args with | _ :: [e] -> begin match fst e with | EObjectDecl fl -> begin try ttf_config.ttfc_font_name <- get_string (Expr.field_assoc "fontName" fl) with Not_found -> () end | _ -> () end | _ -> () end; let ttf_swf = TTFSwfWriter.to_swf ttf ttf_config in let ch = IO.output_string () in let b = IO.output_bits ch in TTFSwfWriter.write_font2 ch b ttf_swf; let data = IO.close_out ch in incr cid; classes := { f9_cid = Some !cid; f9_classname = s_type_path c.cl_path } :: !classes; tag (TFont3 { cd_id = !cid; cd_data = data; }) :: loop l | (Meta.Bitmap,[EConst (String file),p],_) :: l -> let data = load_file_data file p in incr cid; classes := { f9_cid = Some !cid; f9_classname = s_type_path c.cl_path } :: !classes; let raw() = tag (TBitsJPEG2 { bd_id = !cid; bd_data = data; bd_table = None; bd_alpha = None; bd_deblock = Some 0 }) in let t = (match detect_format data p with | BPNG -> (* There is a bug in Flash PNG decoder for 24-bits PNGs : Color such has 0xFF00FF is decoded as 0xFE00FE. In that particular case, we will then embed the decoded PNG bytes instead. *) (try let png = Png.parse (IO.input_string data) in let h = Png.header png in (match h.Png.png_color with | Png.ClTrueColor (Png.TBits8,Png.NoAlpha) -> if h.Png.png_width * h.Png.png_height * 4 > Sys.max_string_length then begin com.warning "Flash will loose some color information for this file, add alpha channel to preserve it" p; raise Exit; end; let data = Extc.unzip (Png.data png) in let raw_data = Png.filter png data in let cmp_data = Extc.zip raw_data in tag ~ext:true (TBitsLossless2 { bll_id = !cid; bll_format = 5; bll_width = h.Png.png_width; bll_height = h.Png.png_height; bll_data = cmp_data }) | _ -> raw()) with Exit -> raw() | _ -> com.error ("Failed to decode this PNG " ^ file) p; raw(); ) | _ -> raw() ) in t :: loop l | (Meta.Bitmap,[EConst (String dfile),p1;EConst (String afile),p2],_) :: l -> let ddata = load_file_data dfile p1 in let adata = load_file_data afile p2 in (match detect_format ddata p1 with | BJPG -> () | _ -> abort "RGB channel must be a JPG file" p1); (match detect_format adata p2 with | BPNG -> () | _ -> abort "Alpha channel must be a PNG file" p2); let png = Png.parse (IO.input_string adata) in let h = Png.header png in let amask = (match h.Png.png_color with | Png.ClTrueColor (Png.TBits8,Png.HaveAlpha) -> let data = Extc.unzip (Png.data png) in let raw_data = Png.filter png data in let alpha = String.make (h.Png.png_width * h.Png.png_height) '\000' in for i = 0 to String.length alpha do String.unsafe_set alpha i (String.unsafe_get raw_data (i lsl 2)); done; Extc.zip alpha | _ -> abort "PNG file must contain 8 bit alpha channel" p2 ) in incr cid; classes := { f9_cid = Some !cid; f9_classname = s_type_path c.cl_path } :: !classes; tag (TBitsJPEG3 { bd_id = !cid; bd_data = ddata; bd_table = None; bd_alpha = Some amask; bd_deblock = Some 0 }) :: loop l | (Meta.File,[EConst (String file),p],_) :: l -> let data = load_file_data file p in incr cid; classes := { f9_cid = Some !cid; f9_classname = s_type_path c.cl_path } :: !classes; tag (TBinaryData (!cid,data)) :: loop l | (Meta.Sound,[EConst (String file),p],_) :: l -> let data = load_file_data file p in let make_flags fmt mono freq bits = let fbits = (match freq with 5512 when fmt <> 2 -> 0 | 11025 -> 1 | 22050 -> 2 | 44100 -> 3 | _ -> failwith ("Unsupported frequency " ^ string_of_int freq)) in let bbits = (match bits with 8 -> 0 | 16 -> 1 | _ -> failwith ("Unsupported bits " ^ string_of_int bits)) in (fmt lsl 4) lor (fbits lsl 2) lor (bbits lsl 1) lor (if mono then 0 else 1) in let flags, samples, data = (match detect_format data p with | SWAV -> (try let i = IO.input_string data in if IO.nread i 4 <> "RIFF" then raise Exit; ignore(IO.nread i 4); (* size *) if IO.nread i 4 <> "WAVE" || IO.nread i 4 <> "fmt " then raise Exit; let chunk_size = IO.read_i32 i in if not (chunk_size = 0x10 || chunk_size = 0x12 || chunk_size = 0x40) then failwith ("Unsupported chunk size " ^ string_of_int chunk_size); if IO.read_ui16 i <> 1 then failwith "Not a PCM file"; let chan = IO.read_ui16 i in if chan > 2 then failwith "Too many channels"; let freq = IO.read_i32 i in ignore(IO.read_i32 i); ignore(IO.read_i16 i); let bits = IO.read_ui16 i in if chunk_size <> 0x10 then ignore(IO.nread i (chunk_size - 0x10)); if IO.nread i 4 <> "data" then raise Exit; let data_size = IO.read_i32 i in let data = IO.nread i data_size in make_flags 0 (chan = 1) freq bits, (data_size * 8 / (chan * bits)), data with Exit | IO.No_more_input | IO.Overflow _ -> abort "Invalid WAV file" p | Failure msg -> abort ("Invalid WAV file (" ^ msg ^ ")") p ) | SMP3 -> (try let sampling = ref 0 in let mono = ref false in let samples = ref 0 in let i = IO.input_string data in let rec read_frame() = match (try IO.read_byte i with IO.No_more_input -> -1) with | -1 -> () | 0x49 -> (* ID3 *) if IO.nread i 2 <> "D3" then raise Exit; ignore(IO.read_ui16 i); (* version *) ignore(IO.read_byte i); (* flags *) let size = IO.read_byte i land 0x7F in let size = size lsl 7 lor (IO.read_byte i land 0x7F) in let size = size lsl 7 lor (IO.read_byte i land 0x7F) in let size = size lsl 7 lor (IO.read_byte i land 0x7F) in ignore(IO.nread i size); (* id3 data *) read_frame() | 0x54 -> (* TAG and TAG+ *) if IO.nread i 3 = "AG+" then ignore(IO.nread i 223) else ignore(IO.nread i 124); read_frame() | 0xFF -> let infos = IO.read_byte i in let ver = (infos lsr 3) land 3 in sampling := [|11025;0;22050;44100|].(ver); let layer = (infos lsr 1) land 3 in let bits = IO.read_byte i in let bitrate = (if ver = 3 then [|0;32;40;48;56;64;80;96;112;128;160;192;224;256;320;-1|] else [|0;8;16;24;32;40;48;56;64;80;96;112;128;144;160;-1|]).(bits lsr 4) in let srate = [| [|11025;12000;8000;-1|]; [|-1;-1;-1;-1|]; [|22050;24000;16000;-1|]; [|44100;48000;32000;-1|]; |].(ver).((bits lsr 2) land 3) in let pad = (bits lsr 1) land 1 in mono := (IO.read_byte i) lsr 6 = 3; let bpp = (if ver = 3 then 144 else 72) in let size = ((bpp * bitrate * 1000) / srate) + pad - 4 in ignore(IO.nread i size); samples := !samples + (if layer = 3 then 384 else 1152); read_frame() | _ -> raise Exit in read_frame(); make_flags 2 !mono !sampling 16, (!samples), ("\x00\x00" ^ data) with Exit | IO.No_more_input | IO.Overflow _ -> abort "Invalid MP3 file" p | Failure msg -> abort ("Invalid MP3 file (" ^ msg ^ ")") p ) | _ -> abort "Sound extension not supported (only WAV or MP3)" p ) in incr cid; classes := { f9_cid = Some !cid; f9_classname = s_type_path c.cl_path } :: !classes; tag (TSound { so_id = !cid; so_flags = flags; so_samples = samples; so_data = data }) :: loop l | _ :: l -> loop l in loop c.cl_meta | _ -> acc ) [] com.types in let clips = [tag (TF9Classes (List.rev !classes))] in res @ bmp @ code @ clips let merge com file priority (h1,tags1) (h2,tags2) = (* prioritize header+bgcolor for first swf *) let header = if priority then { h2 with h_version = max h2.h_version (Common.flash_version_tag com.flash_version) } else h1 in let tags1 = if priority then List.filter (function { tdata = TSetBgColor _ } -> false | _ -> true) tags1 else tags1 in (* remove unused tags *) let use_stage = priority && Common.defined com Define.FlashUseStage in let classes = ref [] in let nframe = ref 0 in let tags2 = List.filter (fun t -> match t.tdata with | TPlaceObject2 _ | TPlaceObject3 _ | TRemoveObject2 _ | TRemoveObject _ -> use_stage | TShowFrame -> incr nframe; use_stage | TFilesAttributes _ | TEnableDebugger2 _ | TScenes _ -> false | TMetaData _ -> not (Common.defined com Define.SwfMetadata) | TSetBgColor _ -> priority | TExport el when !nframe = 0 && com.flash_version >= 9. -> let el = List.filter (fun e -> let path = parse_path e.exp_name in let b = List.exists (fun t -> t_path t = path) com.types in if not b && fst path = [] then List.iter (fun t -> if snd (t_path t) = snd path then abort ("Linkage name '" ^ snd path ^ "' in '" ^ file ^ "' should be '" ^ s_type_path (t_path t) ^"'") (t_infos t).mt_pos; ) com.types; b ) el in classes := !classes @ List.map (fun e -> { f9_cid = Some e.exp_id; f9_classname = e.exp_name }) el; false | TF9Classes el when !nframe = 0 -> classes := !classes @ List.filter (fun e -> e.f9_cid <> None) el; false | _ -> true ) tags2 in (* rebuild character ids *) let max_id = ref (-1) in List.iter (SwfParser.scan (fun id -> if id > !max_id then max_id := id; id) (fun id -> id)) tags1; incr max_id; let rec loop t = SwfParser.scan (fun id -> id + !max_id) (fun id -> id + !max_id) t; match t.tdata with | TClip c -> List.iter loop c.c_tags | _ -> () in List.iter loop tags2; let classes = List.map (fun e -> match e.f9_cid with None -> e | Some id -> { e with f9_cid = Some (id + !max_id) }) !classes in (* merge timelines *) let rec loop l1 l2 = match l1, l2 with | ({ tdata = TSetBgColor _ } as t) :: l1, _ | ({ tdata = TEnableDebugger2 _ } as t) :: l1, _ | ({ tdata = TFilesAttributes _ } as t) :: l1, _ -> t :: loop l1 l2 | _, ({ tdata = TSetBgColor _ } as t) :: l2 -> t :: loop l1 l2 | { tdata = TShowFrame } :: l1, { tdata = TShowFrame } :: l2 -> tag TShowFrame :: loop l1 l2 | { tdata = TF9Classes el } :: l1, _ -> (* merge all classes together *) tag (TF9Classes (classes @ el)) :: loop l1 l2 | x :: l1, { tdata = TShowFrame } :: _ -> (* wait until we finish frame on other swf *) x :: loop l1 l2 | _ , x :: l2 -> x :: loop l1 l2 | x :: l1, [] -> x :: loop l1 l2 | [], [] -> [] in let tags = loop tags1 tags2 in header, tags let generate swf_header com = let swc = if Common.defined com Define.Swc then Some (ref "") else None in let file , codeclip = (try let f , c = ExtString.String.split com.file "@" in f, Some c with _ -> com.file , None) in (* list exports *) let exports = Hashtbl.create 0 in let toremove = ref [] in List.iter (fun (file,lib,_) -> let _, tags = lib() in List.iter (fun t -> match t.tdata with | TExport l -> List.iter (fun e -> Hashtbl.add exports e.exp_name ()) l | TF9Classes el -> List.iter (fun e -> if e.f9_cid <> None then List.iter (fun t -> let extern = (match t with | TClassDecl c -> c.cl_extern | TEnumDecl e -> e.e_extern | TAbstractDecl a -> false | TTypeDecl t -> false ) in if not extern && s_type_path (t_path t) = e.f9_classname then match t with | TClassDecl c -> if Meta.has Meta.Bind c.cl_meta then toremove := (t_path t) :: !toremove else abort ("Class already exists in '" ^ file ^ "', use @:bind to redefine it") (t_infos t).mt_pos | _ -> abort ("Invalid redefinition of class defined in '" ^ file ^ "'") (t_infos t).mt_pos ) com.types; ) el | _ -> () ) tags; ) com.swf_libs; (* build haxe swf *) let tags = build_swf9 com file swc in let header, bg = (match swf_header with None -> default_header com | Some h -> convert_header com h) in let bg = tag (TSetBgColor { cr = bg lsr 16; cg = (bg lsr 8) land 0xFF; cb = bg land 0xFF }) in let scene = tag ~ext:true (TScenes ([(0,"Scene1")],[])) in let swf_debug_password = try Digest.to_hex(Digest.string (Common.defined_value com Define.SwfDebugPassword)) with Not_found -> "" in let debug = (if Common.defined com Define.Fdb then [tag (TEnableDebugger2 (0, swf_debug_password))] else []) in let meta_data = try let file = Common.defined_value com Define.SwfMetadata in let file = try Common.find_file com file with Not_found -> file in let data = try Std.input_file ~bin:true file with Sys_error _ -> failwith ("Metadata resource file not found : " ^ file) in [tag(TMetaData (data))] with Not_found -> [] in let fattr = (if com.flash_version < 8. then [] else [tag (TFilesAttributes { fa_network = Common.defined com Define.NetworkSandbox; fa_as3 = true; fa_metadata = meta_data <> []; fa_gpu = com.flash_version > 9. && Common.defined com Define.SwfGpu; fa_direct_blt = com.flash_version > 9. && Common.defined com Define.SwfDirectBlit; })] ) in let fattr = if Common.defined com Define.AdvancedTelemetry then fattr @ [tag (TUnknown (0x5D,"\x00\x00"))] else fattr in let swf_script_limits = try let s = Common.defined_value com Define.SwfScriptTimeout in let i = try int_of_string s with _ -> abort "Argument to swf_script_timeout must be an integer" null_pos in [tag(TScriptLimits (256, if i < 0 then 0 else if i > 65535 then 65535 else i))] with Not_found -> [] in let swf = header, fattr @ meta_data @ bg :: scene :: debug @ swf_script_limits @ tags @ [tag TShowFrame] in (* merge swf libraries *) let priority = ref (swf_header = None) in let swf = List.fold_left (fun swf (file,lib,cl) -> let swf = merge com file !priority swf (remove_classes toremove lib cl) in priority := false; swf ) swf com.swf_libs in let swf = match swf with | header,tags when Common.defined com Define.SwfPreloaderFrame -> let rec loop l = match l with | ({tdata = TFilesAttributes _ | TUnknown (0x5D,"\x00\x00") | TMetaData _ | TSetBgColor _ | TEnableDebugger2 _ | TScriptLimits _} as t) :: l -> t :: loop l | t :: l -> tag TShowFrame :: t :: l | [] -> [] in {header with h_frame_count = header.h_frame_count + 1},loop tags | _ -> swf in (* write swf/swc *) let t = Common.timer ["write";"swf"] in let level = (try int_of_string (Common.defined_value com Define.SwfCompressLevel) with Not_found -> 9) in SwfParser.init Extc.input_zip (Extc.output_zip ~level); (match swc with | Some cat -> let ch = IO.output_strings() in Swf.write ch swf; let swf = IO.close_out ch in let z = Zip.open_out file in Zip.add_entry (!cat) z "catalog.xml"; Zip.add_entry (match swf with [s] -> s | _ -> failwith "SWF too big for SWC") z ~level:0 "library.swf"; Zip.close_out z | None -> let ch = IO.output_channel (open_out_bin file) in Swf.write ch swf; IO.close_out ch; ); t() ;; SwfParser.init Extc.input_zip Extc.output_zip; Swf.warnings := false; haxe_3.4.4.orig/src/generators/genswf9.ml0000664000175000017500000021372213166552354020277 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open Ast open Type open As3 open As3hl open Common type read = Read type write = Unused__ | Write type tkind = | KInt | KUInt | KFloat | KBool | KType of hl_name | KDynamic | KNone type register = { rid : int; rtype : tkind; mutable rused : bool; mutable rinit : bool; mutable rcond : bool; } type 'a access = | VReg of register | VId of hl_name | VCast of hl_name * tkind | VGlobal of hl_name | VArray | VScope of hl_slot | VVolatile of hl_name * tkind option | VSuper of hl_name type local = | LReg of register | LScope of hl_slot | LGlobal of hl_name type code_infos = { mutable iregs : register DynArray.t; mutable ipos : int; mutable istack : int; mutable imax : int; mutable iscopes : int; mutable imaxscopes : int; mutable iloop : int; mutable icond : bool; } type try_infos = { tr_pos : int; tr_end : int; tr_catch_pos : int; tr_type : t; } type context = { (* globals *) com : Common.context; debugger : bool; swc : bool; boot : path; swf_protected : bool; need_ctor_skip : bool; mutable cur_class : tclass; mutable debug : bool; mutable last_line : int; mutable last_file : string; (* per-function *) mutable locals : (int,tvar * local) PMap.t; mutable code : hl_opcode DynArray.t; mutable infos : code_infos; mutable trys : try_infos list; mutable breaks : (unit -> unit) list; mutable continues : (int -> unit) list; mutable in_static : bool; mutable block_vars : (hl_slot * string * hl_name option) list; mutable try_scope_reg : register option; mutable for_call : bool; } let rec follow t = match Type.follow t with | TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> follow (Abstract.get_underlying_type a tl) | t -> t let invalid_expr p = abort "Invalid expression" p let stack_error p = abort "Stack error" p let index_int (x : int) : 'a index = Obj.magic (x + 1) let index_nz_int (x : int) : 'a index_nz = Obj.magic x let tid (x : 'a index) : int = Obj.magic x let ethis = mk (TConst TThis) (mk_mono()) null_pos let dynamic_prop = HMMultiNameLate [HNPublic (Some "")] let is_special_compare e1 e2 = match e1.eexpr, e2.eexpr with | TConst TNull, _ | _ , TConst TNull -> None | _ -> match follow e1.etype, follow e2.etype with | TInst ({ cl_path = ["flash"],"NativeXml" } as c,_) , _ | _ , TInst ({ cl_path = ["flash"],"NativeXml" } as c,_) -> Some c | _ -> None let write ctx op = DynArray.add ctx.code op; ctx.infos.ipos <- ctx.infos.ipos + 1; let s = ctx.infos.istack + As3hlparse.stack_delta op in ctx.infos.istack <- s; if s > ctx.infos.imax then ctx.infos.imax <- s; match op with | HScope -> let n = ctx.infos.iscopes + 1 in ctx.infos.iscopes <- n; if n > ctx.infos.imaxscopes then ctx.infos.imaxscopes <- n | HPopScope -> ctx.infos.iscopes <- ctx.infos.iscopes - 1 | _ -> () let jump ctx cond = let op = DynArray.length ctx.code in let p = ctx.infos.ipos in write ctx (HJump (cond,0)); (fun () -> let delta = ctx.infos.ipos - p in DynArray.set ctx.code op (HJump (cond,delta)) ) let jump_back ctx = let p = ctx.infos.ipos in write ctx HLabel; (fun cond -> let delta = p - ctx.infos.ipos in write ctx (HJump (cond,delta)) ) let real_path = function | [] , "Int" -> [] , "int" | [] , "UInt" -> [] , "uint" | [] , "Float" -> [] , "Number" | [] , "Bool" -> [] , "Boolean" | [] , "Enum" -> [] , "Class" | [] , "EnumValue" -> [] , "Object" | ["flash";"xml"], "XML" -> [], "XML" | ["flash";"xml"], "XMLList" -> [], "XMLList" | ["flash";"utils"], "QName" -> [] , "QName" | ["flash";"utils"], "Namespace" -> [] , "Namespace" | ["flash";"utils"], "Object" -> [] , "Object" | ["flash";"utils"], "Function" -> [] , "Function" | ["flash"] , "FlashXml__" -> [] , "Xml" | ["flash";"errors"] , "Error" -> [], "Error" | ["flash"] , "Vector" -> ["__AS3__";"vec"], "Vector" | path -> path let type_path ctx path = let pack, name = real_path path in HMPath (pack,name) let rec follow_basic t = match t with | TMono r -> (match !r with | Some t -> follow_basic t | _ -> t) | TLazy f -> follow_basic (!f()) | TType ({ t_path = [],"Null" },[tp]) -> (match follow_basic tp with | TMono _ | TFun _ | TAbstract ({ a_path = ([],"Int") },[]) | TAbstract ({ a_path = ([],"Float") },[]) | TAbstract ({ a_path = [],"UInt" },[]) | TAbstract ({ a_path = ([],"Bool") },[]) | TInst ({ cl_path = (["haxe"],"Int32") },[]) -> t | t -> t) | TType ({ t_path = ["flash";"utils"],"Object" },[]) | TType ({ t_path = ["flash";"utils"],"Function" },[]) | TType ({ t_path = [],"UInt" },[]) -> t | TType (t,tl) -> follow_basic (apply_params t.t_params tl t.t_type) | TAbstract (a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> follow_basic (apply_params a.a_params pl a.a_this) | _ -> t let rec type_id ctx t = match follow_basic t with | TInst ({ cl_path = ["haxe"],"Int32" },_) -> type_path ctx ([],"Int") | TInst ({ cl_path = ["flash"],"Vector" } as c,pl) -> let def() = HMParams (type_path ctx c.cl_path,List.map (type_id ctx) pl) in (match pl with | [t] -> (match follow t with | TInst({cl_kind = KTypeParameter _},_) -> type_path ctx ([],"Object") | _ -> def()) | _ -> def()) | TInst (c,_) -> (match c.cl_kind with | KTypeParameter l -> (match l with | [t] -> type_id ctx t | _ -> type_path ctx ([],"Object")) | _ -> type_path ctx c.cl_path) | TAbstract (a,_) -> type_path ctx a.a_path | TFun _ | TType ({ t_path = ["flash";"utils"],"Function" },[]) -> type_path ctx ([],"Function") | TType ({ t_path = ([],"UInt") as path },_) -> type_path ctx path | TEnum ({ e_path = ["flash"],"XmlType"; e_extern = true },_) -> HMPath ([],"String") | TEnum (e,_) -> let rec loop = function | [] -> type_path ctx e.e_path | (Meta.FakeEnum,[Ast.EConst (Ast.Ident n),_],_) :: _ -> type_path ctx ([],n) | _ :: l -> loop l in loop e.e_meta | _ -> HMPath ([],"Object") let type_opt ctx t = match follow_basic t with | TDynamic _ | TMono _ -> None | _ -> Some (type_id ctx t) let type_void ctx t = match follow t with | TEnum ({ e_path = [],"Void" },_) | TAbstract ({ a_path = [],"Void" },_) -> Some (HMPath ([],"void")) | _ -> type_opt ctx t let classify ctx t = match follow_basic t with | TAbstract ({ a_path = [],"Int" },_) | TInst ({ cl_path = [],"Int" },_) | TInst ({ cl_path = ["haxe"],"Int32" },_) -> KInt | TAbstract ({ a_path = [],"Float" },_) | TInst ({ cl_path = [],"Float" },_) -> KFloat | TAbstract ({ a_path = [],"Bool" },_) | TEnum ({ e_path = [],"Bool" },_) -> KBool | TAbstract ({ a_path = [],"Void" },_) | TEnum ({ e_path = [],"Void" },_) -> KDynamic | TEnum ({ e_path = ["flash"],"XmlType"; e_extern = true },_) -> KType (HMPath ([],"String")) | TEnum (e,_) -> let rec loop = function | [] -> KType (type_id ctx t) | (Meta.FakeEnum,[Ast.EConst (Ident n),_],_) :: _ -> (match n with | "Int" -> KInt | "UInt" -> KUInt | "String" -> KType (HMPath ([],"String")) | _ -> assert false) | _ :: l -> loop l in loop e.e_meta | TAbstract ({ a_path = [],"UInt" },_) | TType ({ t_path = [],"UInt" },_) -> KUInt | TFun _ | TType ({ t_path = ["flash";"utils"],"Function" },[]) -> KType (HMPath ([],"Function")) | TAnon a -> (match !(a.a_status) with | Statics _ -> KNone | _ -> KDynamic) | TType ({ t_path = ["flash";"utils"],"Object" },[]) -> KType (HMPath ([],"Object")) | TInst _ | TAbstract _ -> KType (type_id ctx t) | TMono _ | TType _ | TDynamic _ -> KDynamic | TLazy _ -> assert false (* some field identifiers might cause issues with SWC *) let reserved i = match i with | "int" -> "_" ^ i | _ -> i let ident i = HMPath ([],reserved i) let as3 p = HMName (p,HNNamespace "http://adobe.com/AS3/2006/builtin") let property ctx p t = match follow t with | TInst ({ cl_path = [],"Array" },_) -> (match p with | "length" -> ident p, Some KInt, false (* UInt in the spec *) | "map" | "filter" when Common.defined ctx.com Define.NoFlashOverride -> ident (p ^ "HX"), None, true | "copy" | "insert" | "remove" | "iterator" | "toString" | "map" | "filter" -> ident p , None, true | _ -> as3 p, None, false); | TInst ({ cl_path = ["flash"],"Vector" },_) -> (match p with | "length" -> ident p, Some KInt, false (* UInt in the spec *) | "fixed" | "toString" -> ident p, None, false | "iterator" -> ident p, None, true | _ -> as3 p, None, false); | TInst ({ cl_path = [],"String" },_) -> (match p with | "length" (* Int in AS3/Haxe *) -> ident p, None, false | "charCodeAt" when Common.defined ctx.com Define.NoFlashOverride -> ident (p ^ "HX"), None, true | "charCodeAt" (* use Haxe version *) -> ident p, None, true | "cca" -> as3 "charCodeAt", None, false | _ -> as3 p, None, false); | TInst ({ cl_path = [],"Date" },_) -> (match p with | "toString" when Common.defined ctx.com Define.NoFlashOverride -> ident (p ^ "HX"), None, true | _ -> ident p, None, false) | TAnon a -> (match !(a.a_status) with | Statics { cl_path = [], "Math" } -> (match p with | "POSITIVE_INFINITY" | "NEGATIVE_INFINITY" | "NaN" -> ident p, Some KFloat, false | "floor" | "ceil" | "round" when ctx.for_call -> ident p, Some KInt, false | "ffloor" | "fceil" | "fround" -> ident (String.sub p 1 (String.length p - 1)), None, false | _ -> ident p, None, false) | _ -> ident p, None, false) | TInst ({ cl_interface = true } as c,_) -> (* lookup the interface in which the field was actually declared *) let rec loop c = try (match PMap.find p c.cl_fields with | { cf_kind = Var _ | Method MethDynamic } -> raise Exit (* no vars in interfaces in swf9 *) | _ -> c) with Not_found -> let rec loop2 = function | [] -> raise Not_found | (i,_) :: l -> try loop i with Not_found -> loop2 l in loop2 c.cl_implements in (try let c = loop c in let ns = HMName (reserved p, HNNamespace (match c.cl_path with [],n -> n | l,n -> String.concat "." l ^ ":" ^ n)) in ns, None, false with Not_found | Exit -> ident p, None, false) | _ -> ident p, None, false let default_infos() = { ipos = 0; istack = 0; imax = 0; iregs = DynArray.create(); iscopes = 0; imaxscopes = 0; iloop = -1; icond = false; } let alloc_reg ctx k = let regs = ctx.infos.iregs in try let p = DynArray.index_of (fun r -> not r.rused && k = r.rtype) regs in let r = DynArray.unsafe_get regs p in r.rused <- true; r.rinit <- false; r with Not_found -> let r = { rid = DynArray.length regs + 1; rused = true; rinit = false; rtype = k; rcond = false; } in DynArray.add regs r; r let coerce ctx t = (* it would be useful to know if we don't already have this type on the stack (as detected by the bytecode verifier)... maybe this get removed at JIT, so it's only useful to reduce codesize *) if t <> KNone then write ctx (match t with | KInt -> HToInt | KUInt -> HToUInt | KFloat -> HToNumber | KBool -> HToBool | KType t -> HCast t | KDynamic -> HAsAny | KNone -> assert false ) let set_reg ctx r = if not r.rinit then begin r.rinit <- true; if ctx.infos.icond then r.rcond <- true; end; coerce ctx r.rtype; write ctx (HSetReg r.rid) let set_reg_dup ctx r = if not r.rinit then begin r.rinit <- true; if ctx.infos.icond then r.rcond <- true; end; coerce ctx r.rtype; write ctx HDup; write ctx (HSetReg r.rid) let free_reg ctx r = r.rused <- false let pop ctx n = let rec loop n = if n > 0 then begin write ctx HPop; loop (n - 1) end in if n < 0 then assert false; let old = ctx.infos.istack in loop n; ctx.infos.istack <- old let is_member ctx name = let rec loop c = PMap.mem name c.cl_fields || (match c.cl_super with None -> false | Some (c,_) -> loop c) in loop ctx.cur_class let rename_block_var ctx v = (* we need to rename it since slots are accessed on a by-name basis *) let rec loop i = let name = v.v_name ^ string_of_int i in if List.exists (fun(_,x,_) -> name = x) ctx.block_vars || is_member ctx name then loop (i + 1) else v.v_name <- name in loop 1 let define_local ctx ?(init=false) v p = let name = v.v_name in let t = v.v_type in let l = (if v.v_capture then begin let topt = type_opt ctx t in if List.exists (fun (_,x,_) -> name = x) ctx.block_vars || is_member ctx name then rename_block_var ctx v; let pos = List.length ctx.block_vars + 1 in ctx.block_vars <- (pos,v.v_name,topt) :: ctx.block_vars; LScope pos end else let r = alloc_reg ctx (classify ctx t) in if ctx.debug then write ctx (HDebugReg (name, r.rid, ctx.last_line)); r.rinit <- init; LReg r ) in ctx.locals <- PMap.add v.v_id (v,l) ctx.locals let is_set v = (Obj.magic v) = Write let gen_local_access ctx v p (forset : 'a) : 'a access = match snd (try PMap.find v.v_id ctx.locals with Not_found -> abort ("Unbound variable " ^ v.v_name) p) with | LReg r -> VReg r | LScope n -> write ctx (HGetScope 1); VScope n | LGlobal p -> if is_set forset then write ctx (HFindProp p); VGlobal p let get_local_register ctx v = match (try snd (PMap.find v.v_id ctx.locals) with Not_found -> LScope 0) with | LReg r -> Some r | _ -> None let rec setvar ctx (acc : write access) kret = match acc with | VReg r -> if kret <> None then set_reg_dup ctx r else set_reg ctx r; | VGlobal _ | VId _ | VCast _ | VArray | VScope _ when kret <> None -> let r = alloc_reg ctx (match kret with None -> assert false | Some k -> k) in set_reg_dup ctx r; setvar ctx acc None; write ctx (HReg r.rid); free_reg ctx r | VGlobal g -> write ctx (HSetProp g) | VId id | VCast (id,_) -> write ctx (HInitProp id) | VVolatile (id,_) -> write ctx (HArray 1); write ctx (HInitProp id) | VArray -> write ctx (HSetProp dynamic_prop); ctx.infos.istack <- ctx.infos.istack - 1 | VScope n -> write ctx (HSetSlot n) | VSuper id -> write ctx (HSetSuper id) let getvar ctx (acc : read access) = match acc with | VReg r -> if not r.rinit then begin r.rinit <- true; r.rcond <- true; end; write ctx (HReg r.rid) | VId id -> write ctx (HGetProp id) | VVolatile (id,t) -> write ctx (HGetProp id); write ctx (HSmallInt 0); write ctx (HGetProp dynamic_prop); ctx.infos.istack <- ctx.infos.istack - 1; (match t with | None -> () | Some t -> coerce ctx t) | VCast (id,t) -> write ctx (HGetProp id); coerce ctx t | VGlobal g -> write ctx (HGetLex g); | VArray -> write ctx (HGetProp dynamic_prop); ctx.infos.istack <- ctx.infos.istack - 1 | VScope n -> write ctx (HGetSlot n) | VSuper id -> write ctx (HGetSuper id) let open_block ctx retval = let old_stack = ctx.infos.istack in let old_regs = DynArray.map (fun r -> r.rused) ctx.infos.iregs in let old_locals = ctx.locals in (fun() -> if ctx.infos.istack <> old_stack + (if retval then 1 else 0) then assert false; let rcount = DynArray.length old_regs + 1 in DynArray.iter (fun r -> if r.rid < rcount then r.rused <- DynArray.unsafe_get old_regs (r.rid - 1) else r.rused <- false ) ctx.infos.iregs; ctx.locals <- old_locals; ) let begin_branch ctx = if ctx.infos.icond then (fun() -> ()) else begin ctx.infos.icond <- true; (fun() -> ctx.infos.icond <- false) end let begin_switch ctx = let branch = begin_branch ctx in let switch_index = DynArray.length ctx.code in let switch_pos = ctx.infos.ipos in write ctx (HSwitch (0,[])); let constructs = ref [] in let max = ref 0 in let ftag tag = if tag > !max then max := tag; constructs := (tag,ctx.infos.ipos) :: !constructs; in let fend() = let cases = Array.create (!max + 1) 1 in List.iter (fun (tag,pos) -> Array.set cases tag (pos - switch_pos)) !constructs; DynArray.set ctx.code switch_index (HSwitch (1,Array.to_list cases)); branch(); in fend, ftag let debug_infos ?(is_min=true) ctx p = if ctx.debug then begin let line = Lexer.get_error_line (if is_min then p else { p with pmin = p.pmax }) in if ctx.last_file <> p.pfile then begin write ctx (HDebugFile (if ctx.debugger then Path.get_full_path p.pfile else p.pfile)); ctx.last_file <- p.pfile; ctx.last_line <- -1; end; if ctx.last_line <> line then begin write ctx (HDebugLine line); ctx.last_line <- line; end end let to_utf8 str = try UTF8.validate str; str; with UTF8.Malformed_code -> let b = UTF8.Buf.create 0 in String.iter (fun c -> UTF8.Buf.add_char b (UChar.of_char c)) str; UTF8.Buf.contents b let gen_constant ctx c t p = match c with | TInt i -> let unsigned = classify ctx t = KUInt in if Int32.compare i (-128l) > 0 && Int32.compare i 128l < 0 then begin write ctx (HSmallInt (Int32.to_int i)); if unsigned then write ctx HToUInt; end else write ctx (if unsigned then HUIntRef i else HIntRef i) | TFloat f -> let f = float_of_string f in write ctx (HFloat f); | TString s -> write ctx (HString (to_utf8 s)); | TBool b -> write ctx (if b then HTrue else HFalse); | TNull -> write ctx HNull; coerce ctx (classify ctx t) | TThis -> write ctx HThis | TSuper -> assert false let end_fun ctx args dparams tret = { hlmt_index = 0; hlmt_ret = type_void ctx tret; hlmt_args = List.map (fun (v,_) -> type_opt ctx v.v_type) args; hlmt_native = false; hlmt_var_args = false; hlmt_debug_name = None; hlmt_dparams = dparams; hlmt_pnames = if ctx.swc || ctx.debugger then Some (List.map (fun (v,_) -> Some v.v_name) args) else None; hlmt_new_block = false; hlmt_unused_flag = false; hlmt_arguments_defined = false; hlmt_uses_dxns = false; hlmt_function = None; } let begin_fun ctx args tret el stat p = let old_locals = ctx.locals in let old_code = ctx.code in let old_infos = ctx.infos in let old_trys = ctx.trys in let old_bvars = ctx.block_vars in let old_static = ctx.in_static in let last_line = ctx.last_line in let old_treg = ctx.try_scope_reg in ctx.infos <- default_infos(); ctx.code <- DynArray.create(); ctx.trys <- []; ctx.block_vars <- []; ctx.in_static <- stat; ctx.last_line <- -1; ctx.last_file <- ""; debug_infos ctx p; let rec find_this e = match e.eexpr with | TFunction _ -> () | TConst TThis | TConst TSuper -> raise Exit | _ -> Type.iter find_this e in let this_reg = try List.iter find_this el; false with Exit -> true in ctx.locals <- PMap.foldi (fun _ (v,l) acc -> match l with | LReg _ -> acc | LScope _ -> PMap.add v.v_id (v,LGlobal (ident v.v_name)) acc | LGlobal _ -> PMap.add v.v_id (v,l) acc ) ctx.locals PMap.empty; let dparams = ref None in let make_constant_value r c t = let v = (match classify ctx t, c with | _, None -> HVNone | (KInt | KFloat | KUInt | KBool) as kind, Some c -> (match c with | TInt i -> if kind = KUInt then HVUInt i else HVInt i | TFloat s -> HVFloat (float_of_string s) | TBool b -> HVBool b | TNull -> abort ("In Flash9, null can't be used as basic type " ^ s_type (print_context()) t) p | _ -> assert false) | _, Some TNull -> HVNone | k, Some c -> write ctx (HReg r.rid); write ctx HNull; let j = jump ctx J3Neq in gen_constant ctx c t p; coerce ctx k; write ctx (HSetReg r.rid); j(); HVNone ) in match !dparams with | None -> if c <> None then dparams := Some [v] | Some l -> dparams := Some (v :: l) in let args, varargs = (match List.rev args with | (({ v_name = "__arguments__"; v_type = t } as v),_) :: l -> (match follow t with | TInst ({ cl_path = ([],"Array") },_) -> List.rev l, Some (v,true) | _ -> List.rev l, Some(v,false)) | _ -> args, None ) in List.iter (fun (v,c) -> let t = v.v_type in define_local ctx v ~init:true p; match gen_local_access ctx v null_pos Write with | VReg r -> make_constant_value r c t | acc -> let r = alloc_reg ctx (classify ctx t) in make_constant_value r c t; write ctx (HReg r.rid); setvar ctx acc None ) args; (match varargs with | None -> () | Some (v,_) -> define_local ctx v ~init:true p; ignore(alloc_reg ctx (classify ctx v.v_type))); let dparams = (match !dparams with None -> None | Some l -> Some (List.rev l)) in let is_not_rethrow (_,e) = match e.eexpr with | TBlock [{ eexpr = TThrow { eexpr = TNew (_,_,[]) } }] -> false | _ -> true in let rec loop_try e = match e.eexpr with | TFunction _ -> () | TTry (_,catches) when List.exists is_not_rethrow catches -> raise Exit | _ -> Type.iter loop_try e in ctx.try_scope_reg <- (try List.iter loop_try el; None with Exit -> Some (alloc_reg ctx KDynamic)); (fun () -> let hasblock = ctx.block_vars <> [] || ctx.try_scope_reg <> None in let code = DynArray.to_list ctx.code in let extra = ( if hasblock then begin let scope = (match ctx.try_scope_reg with | None -> [HScope] | Some r -> [HDup; HSetReg r.rid; HScope] ) in HThis :: HScope :: HNewBlock :: scope end else if this_reg then [HThis; HScope] else [] ) in (* add dummy registers initialization *) let extra = extra @ List.concat (List.map (fun r -> if not r.rcond then [] else let s = [HSetReg r.rid] in match r.rtype with | KInt -> HSmallInt 0 :: s | KUInt -> HSmallInt 0 :: HToUInt :: s | KFloat -> HNaN :: s | KBool -> HFalse :: s | KType t -> HNull :: HAsType t :: s | KDynamic -> HNull :: HAsAny :: s | KNone -> HNull :: HAsType (HMPath ([],"Class")) :: s ) (DynArray.to_list ctx.infos.iregs)) in let delta = List.length extra in let f = { hlf_stack_size = (if ctx.infos.imax = 0 && (hasblock || this_reg) then 1 else ctx.infos.imax); hlf_nregs = DynArray.length ctx.infos.iregs + 1; hlf_init_scope = 1; hlf_max_scope = ctx.infos.imaxscopes + 1 + (if hasblock then 2 else if this_reg then 1 else 0); hlf_code = MultiArray.of_array (Array.of_list (extra @ code)); hlf_trys = Array.of_list (List.map (fun t -> { hltc_start = t.tr_pos + delta; hltc_end = t.tr_end + delta; hltc_handle = t.tr_catch_pos + delta; hltc_type = type_opt ctx t.tr_type; hltc_name = None; } ) (List.rev ctx.trys)); hlf_locals = Array.of_list (List.map (fun (id,name,t) -> ident name, t, id, false) ctx.block_vars); } in let mt = { (end_fun ctx args dparams tret) with hlmt_var_args = (match varargs with Some (_,true) -> true | _ -> false); hlmt_arguments_defined = (match varargs with Some (_,false) -> true | _ -> false); hlmt_new_block = hasblock; hlmt_function = Some f; } in ctx.locals <- old_locals; ctx.code <- old_code; ctx.infos <- old_infos; ctx.trys <- old_trys; ctx.block_vars <- old_bvars; ctx.in_static <- old_static; ctx.last_line <- last_line; ctx.try_scope_reg <- old_treg; mt ) let empty_method ctx p = let f = begin_fun ctx [] ctx.com.basic.tvoid [] true p in write ctx HRetVoid; f() let begin_loop ctx = let old_loop = ctx.infos.iloop in let old_breaks = ctx.breaks in let old_conts = ctx.continues in ctx.infos.iloop <- ctx.infos.istack; ctx.breaks <- []; ctx.continues <- []; (fun cont_pos -> if ctx.infos.istack <> ctx.infos.iloop then assert false; List.iter (fun j -> j()) ctx.breaks; List.iter (fun j -> j cont_pos) ctx.continues; ctx.infos.iloop <- old_loop; ctx.breaks <- old_breaks; ctx.continues <- old_conts; ) let no_value ctx retval = (* does not push a null but still increment the stack like if a real value was pushed *) if retval then ctx.infos.istack <- ctx.infos.istack + 1 let pop_value ctx retval = (* if we have multiple branches, make sure to forget about previous branch value *) if retval then ctx.infos.istack <- ctx.infos.istack - 1 let gen_expr_ref = ref (fun _ _ _ -> assert false) let gen_expr ctx e retval = (!gen_expr_ref) ctx e retval let rec gen_access ctx e (forset : 'a) : 'a access = match e.eexpr with | TLocal v -> gen_local_access ctx v e.epos forset | TField ({ eexpr = TConst TSuper } as e1,f) -> let f = field_name f in let id, _, _ = property ctx f e1.etype in write ctx HThis; VSuper id | TEnumParameter (e1,_,i) -> gen_expr ctx true e1; write ctx (HGetProp (ident "params")); write ctx (HSmallInt i); VArray | TField (e1,fa) -> let f = field_name fa in let id, k, closure = property ctx f e1.etype in if closure && not ctx.for_call then abort "In Flash9, this method cannot be accessed this way : please define a local function" e1.epos; (match e1.eexpr with | TConst (TThis|TSuper) when not ctx.in_static -> write ctx (HFindProp id) | _ -> gen_expr ctx true e1); (match k with | Some t -> VCast (id,t) | None -> match follow e1.etype, follow e.etype with | _ , TFun _ when not ctx.for_call -> VCast(id,classify ctx e.etype) | TEnum _, _ -> VId id | TInst (_,tl), et -> let is_type_parameter_field = match fa with | FInstance(_,_,cf) -> (match follow cf.cf_type with TInst({cl_kind = KTypeParameter _},_) -> true | _ -> false) | _ -> List.exists (fun t -> follow t == et) tl in (* if the return type is one of the type-parameters, then we need to cast it *) if is_type_parameter_field then VCast (id, classify ctx e.etype) else if Codegen.is_volatile e.etype then VVolatile (id,None) else VId id | TAnon a, _ when (match !(a.a_status) with Statics _ | EnumStatics _ -> true | _ -> false) -> if Codegen.is_volatile e.etype then VVolatile (id,None) else VId id | _ -> if Codegen.is_volatile e.etype then VVolatile (id,Some (classify ctx e.etype)) else VCast (id,classify ctx e.etype) ) | TArray ({ eexpr = TLocal { v_name = "__global__" } },{ eexpr = TConst (TString s) }) -> let path = parse_path s in let id = type_path ctx path in if is_set forset then write ctx HGetGlobalScope; VGlobal id | TArray (e,eindex) -> gen_expr ctx true e; gen_expr ctx true eindex; VArray | TTypeExpr t -> let id = type_path ctx (t_path t) in if is_set forset then write ctx HGetGlobalScope; VGlobal id | _ -> invalid_expr e.epos let gen_expr_twice ctx e = match e.eexpr with | TLocal v -> (match get_local_register ctx v with | Some r -> write ctx (HReg r.rid); write ctx (HReg r.rid); | None -> gen_expr ctx true e; write ctx HDup) | TConst _ -> gen_expr ctx true e; gen_expr ctx true e; | _ -> gen_expr ctx true e; write ctx HDup let gen_access_rw ctx e : (read access * write access) = match e.eexpr with | TArray ({ eexpr = TLocal _ }, { eexpr = TConst _ }) | TArray ({ eexpr = TLocal _ }, { eexpr = TLocal _ }) | TField ({ eexpr = TLocal _ },_) | TField ({ eexpr = TConst _ },_) -> let w = gen_access ctx e Write in let r = gen_access ctx e Read in r, w | TArray (e,eindex) -> let r = (match e.eexpr with TLocal v -> get_local_register ctx v | _ -> None) in (match r with | None -> let r = alloc_reg ctx (classify ctx e.etype) in gen_expr ctx true e; set_reg ctx r; write ctx (HReg r.rid); gen_expr_twice ctx eindex; write ctx (HReg r.rid); write ctx HSwap; free_reg ctx r; | Some r -> write ctx (HReg r.rid); gen_expr_twice ctx eindex; write ctx (HReg r.rid); write ctx HSwap; ); VArray, VArray | TField _ -> let w = gen_access ctx e Write in write ctx HDup; Obj.magic w, w | _ -> let w = gen_access ctx e Write in let r = gen_access ctx e Read in r, w let rec gen_type ctx t = match t with | HMParams (t,tl) -> write ctx (HGetLex t); List.iter (gen_type ctx) tl; write ctx (HApplyType (List.length tl)); | _ -> write ctx (HGetLex t) let rec gen_expr_content ctx retval e = match e.eexpr with | TConst c -> gen_constant ctx c e.etype e.epos | TThrow e -> ctx.infos.icond <- true; if has_feature ctx.com "haxe.CallStack.exceptionStack" then begin getvar ctx (VGlobal (type_path ctx (["flash"],"Boot"))); let id = type_path ctx (["flash";"errors"],"Error") in write ctx (HFindPropStrict id); write ctx (HConstructProperty (id,0)); setvar ctx (VId (ident "lastError")) None; end; gen_expr ctx true e; write ctx HThrow; no_value ctx retval; | TParenthesis e | TMeta (_,e) -> gen_expr ctx retval e | TObjectDecl fl -> List.iter (fun (name,e) -> write ctx (HString (reserved name)); gen_expr ctx true e ) fl; write ctx (HObject (List.length fl)) | TArrayDecl el -> List.iter (gen_expr ctx true) el; write ctx (HArray (List.length el)) | TBlock el -> let rec loop = function | [] -> if retval then write ctx HNull | [e] -> gen_expr ctx retval e | e :: l -> gen_expr ctx false e; loop l in let b = open_block ctx retval in loop el; b(); | TVar (v,ei) -> define_local ctx v e.epos; (match ei with | None -> () | Some e -> let acc = gen_local_access ctx v e.epos Write in gen_expr ctx true e; setvar ctx acc None) | TReturn None -> write ctx HRetVoid; ctx.infos.icond <- true; no_value ctx retval | TReturn (Some e) -> gen_expr ctx true e; write ctx HRet; ctx.infos.icond <- true; no_value ctx retval | TField _ | TLocal _ | TTypeExpr _ -> getvar ctx (gen_access ctx e Read) (* both accesses return dynamic so let's cast them to the real type *) | TEnumParameter _ | TArray _ -> getvar ctx (gen_access ctx e Read); coerce ctx (classify ctx e.etype) | TBinop (op,e1,e2) -> gen_binop ctx retval op e1 e2 e.etype e.epos | TCall (f,el) -> gen_call ctx retval f el e.etype | TNew ({ cl_path = [],"Array" },_,[]) -> (* it seems that [] is 4 time faster than new Array() *) write ctx (HArray 0) | TNew ({ cl_path = ["flash"],"Vector" },[t],_) when (match follow t with TInst({ cl_kind = KTypeParameter _ },_) -> true | _ -> false) -> write ctx (HString "Cannot create Vector without knowing runtime type"); write ctx HThrow; no_value ctx retval | TNew (c,tl,pl) -> let id = type_id ctx (TInst (c,tl)) in (match id with | HMParams _ -> gen_type ctx id; List.iter (gen_expr ctx true) pl; write ctx (HConstruct (List.length pl)) | _ -> write ctx (HFindPropStrict id); List.iter (gen_expr ctx true) pl; write ctx (HConstructProperty (id,List.length pl)) ); | TFunction f -> write ctx (HFunction (generate_function ctx f true)) | TIf (e0,e1,e2) -> let j = jump_expr ctx e0 false in let branch = begin_branch ctx in gen_expr ctx retval e1; let t = classify ctx e.etype in if retval && classify ctx e1.etype <> t then coerce ctx t; (match e2 with | None -> j() | Some e -> (* two expresssions, but one per branch *) pop_value ctx retval; let jend = jump ctx J3Always in j(); gen_expr ctx retval e; if retval && classify ctx e.etype <> t then coerce ctx t; jend()); branch(); | TWhile (econd,e,flag) -> let jstart = jump ctx J3Always in let end_loop = begin_loop ctx in let branch = begin_branch ctx in let loop = jump_back ctx in if flag = DoWhile then jstart(); gen_expr ctx false e; if flag = NormalWhile then jstart(); let continue_pos = ctx.infos.ipos in let _ = jump_expr_gen ctx econd true (fun j -> loop j; (fun() -> ())) in branch(); end_loop continue_pos; if retval then write ctx HNull | TUnop (op,flag,e) -> gen_unop ctx retval op flag e | TTry (e2,cases) -> if ctx.infos.istack <> 0 then abort "Cannot compile try/catch as a right-side expression in Flash9" e.epos; let branch = begin_branch ctx in let p = ctx.infos.ipos in gen_expr ctx retval e2; let pend = ctx.infos.ipos in let jend = jump ctx J3Always in let rec loop ncases = function | [] -> [] | (v,e) :: l -> let b = open_block ctx retval in let t = v.v_type in ctx.trys <- { tr_pos = p; tr_end = pend; tr_catch_pos = ctx.infos.ipos; tr_type = t; } :: ctx.trys; ctx.infos.istack <- ctx.infos.istack + 1; if ctx.infos.imax < ctx.infos.istack then ctx.infos.imax <- ctx.infos.istack; write ctx HThis; write ctx HScope; (match ctx.try_scope_reg with | None -> () | Some r -> write ctx (HReg r.rid); write ctx HScope); (* store the exception into local var, using a tmp register if needed *) define_local ctx v e.epos; let r = (match snd (try PMap.find v.v_id ctx.locals with Not_found -> assert false) with | LReg _ -> None | _ -> let r = alloc_reg ctx (classify ctx t) in set_reg ctx r; Some r ) in let acc = gen_local_access ctx v e.epos Write in (match r with None -> () | Some r -> write ctx (HReg r.rid)); setvar ctx acc None; (* ----- *) let rec call_loop e = match e.eexpr with | TCall _ | TNew _ -> raise Exit | TFunction _ -> () | _ -> Type.iter call_loop e in let has_call = (try call_loop e; false with Exit -> true) in if has_call && has_feature ctx.com "haxe.CallStack.exceptionStack" then begin getvar ctx (gen_local_access ctx v e.epos Read); write ctx (HAsType (type_path ctx (["flash";"errors"],"Error"))); let j = jump ctx J3False in getvar ctx (VGlobal (type_path ctx (["flash"],"Boot"))); getvar ctx (gen_local_access ctx v e.epos Read); setvar ctx (VId (ident "lastError")) None; j(); end; gen_expr ctx retval e; b(); if retval then ctx.infos.istack <- ctx.infos.istack - 1; match l with | [] -> [] | _ -> let j = jump ctx J3Always in j :: loop (ncases + 1) l in let loops = loop (List.length ctx.trys) cases in List.iter (fun j -> j()) loops; branch(); jend() | TFor (v,it,e) -> gen_expr ctx true it; let r = alloc_reg ctx KDynamic in set_reg ctx r; let branch = begin_branch ctx in let b = open_block ctx retval in define_local ctx v e.epos; let end_loop = begin_loop ctx in let continue_pos = ctx.infos.ipos in let start = jump_back ctx in write ctx (HReg r.rid); write ctx (HCallProperty (ident "hasNext",0)); let jend = jump ctx J3False in let acc = gen_local_access ctx v e.epos Write in write ctx (HReg r.rid); write ctx (HCallProperty (ident "next",0)); setvar ctx acc None; gen_expr ctx false e; start J3Always; end_loop continue_pos; jend(); if retval then getvar ctx (gen_local_access ctx v e.epos Read); b(); branch(); free_reg ctx r; | TBreak -> pop ctx (ctx.infos.istack - ctx.infos.iloop); ctx.breaks <- jump ctx J3Always :: ctx.breaks; no_value ctx retval | TContinue -> pop ctx (ctx.infos.istack - ctx.infos.iloop); let op = DynArray.length ctx.code in let p = ctx.infos.ipos in write ctx (HJump (J3Always,0)); ctx.continues <- (fun target -> DynArray.set ctx.code op (HJump (J3Always,target - p))) :: ctx.continues; no_value ctx retval | TSwitch (e0,el,eo) -> let t = classify ctx e.etype in (try let t0 = classify ctx e0.etype in (* generate optimized int switch *) if t0 <> KInt && t0 <> KUInt then raise Exit; let rec get_int e = match e.eexpr with | TConst (TInt n) -> if n < 0l || n > 512l then raise Exit; Int32.to_int n | TParenthesis e | TBlock [e] | TMeta (_,e) -> get_int e | _ -> raise Not_found in List.iter (fun (vl,_) -> List.iter (fun v -> try ignore (get_int v) with _ -> raise Exit ) vl) el; gen_expr ctx true e0; if t0 <> KInt then write ctx HToInt; let switch, case = begin_switch ctx in (match eo with | None -> if retval then begin write ctx HNull; coerce ctx t; end; | Some e -> gen_expr ctx retval e; if retval && classify ctx e.etype <> t then coerce ctx t); let jends = List.map (fun (vl,e) -> let j = jump ctx J3Always in List.iter (fun v -> case (get_int v)) vl; pop_value ctx retval; gen_expr ctx retval e; if retval && classify ctx e.etype <> t then coerce ctx t; j ) el in List.iter (fun j -> j()) jends; switch(); with Exit -> let r = alloc_reg ctx (classify ctx e0.etype) in gen_expr ctx true e0; set_reg ctx r; let branch = begin_branch ctx in let prev = ref (fun () -> ()) in let jend = List.map (fun (vl,e) -> (!prev)(); let rec loop = function | [] -> assert false | [v] -> write ctx (HReg r.rid); gen_expr ctx true v; prev := jump ctx J3Neq; | v :: l -> write ctx (HReg r.rid); gen_expr ctx true v; let j = jump ctx J3Eq in loop l; j() in loop vl; gen_expr ctx retval e; pop_value ctx retval; if retval && classify ctx e.etype <> t then coerce ctx t; jump ctx J3Always ) el in (!prev)(); free_reg ctx r; (match eo with | None -> if retval then begin write ctx HNull; coerce ctx t; end; | Some e -> gen_expr ctx retval e; if retval && classify ctx e.etype <> t then coerce ctx t; ); List.iter (fun j -> j()) jend; branch()); | TCast (e1,t) -> gen_expr ctx retval e1; if retval then begin match t with | None -> (* no error if cast failure *) let t1 = classify ctx e1.etype in let t = classify ctx e.etype in if t1 <> t then coerce ctx t; | Some t -> (* manual cast *) let tid = (match gen_access ctx (mk (TTypeExpr t) t_dynamic e.epos) Read with | VGlobal id -> id | _ -> assert false ) in match classify ctx e.etype with | KType n when (match n with HMPath ([],"String") -> false | _ -> true) -> (* for normal classes, we can use native cast *) write ctx (HCast tid) | KInt | KUInt -> (* allow any number to be cast to int (will coerce) *) write ctx HDup; write ctx (HIsType (HMPath([],"Number"))); let j = jump ctx J3True in write ctx (HString "Class cast error"); write ctx HThrow; j(); write ctx (HCast tid) | _ -> (* we need to check with "is" first, to prevent convertion *) write ctx HDup; write ctx (HIsType tid); let j = jump ctx J3True in write ctx (HString "Class cast error"); write ctx HThrow; j(); write ctx (HCast tid) end and gen_call ctx retval e el r = match e.eexpr , el with | TLocal { v_name = "__is__" }, [e;t] -> gen_expr ctx true e; gen_expr ctx true t; write ctx (HOp A3OIs) | TField (_,FStatic ({ cl_path = [],"Std" },{ cf_name = "is" })),[e;{ eexpr = TTypeExpr (TClassDecl _) } as t] -> (* fast inlining of Std.is with known values *) gen_expr ctx true e; gen_expr ctx true t; write ctx (HOp A3OIs) | TLocal { v_name = "__as__" }, [e;t] -> gen_expr ctx true e; gen_expr ctx true t; write ctx (HOp A3OAs) | TLocal { v_name = "__int__" }, [e] -> gen_expr ctx true e; write ctx HToInt | TLocal { v_name = "__float__" }, [e] -> gen_expr ctx true e; write ctx HToNumber | TLocal { v_name = "__foreach__" }, [obj;counter] -> gen_expr ctx true obj; gen_expr ctx true counter; write ctx HForEach | TLocal { v_name = "__forin__" }, [obj;counter] -> gen_expr ctx true obj; gen_expr ctx true counter; write ctx HForIn | TLocal { v_name = "__has_next__" }, [obj;counter] -> let oreg = match gen_access ctx obj Read with VReg r -> r | _ -> abort "Must be a local variable" obj.epos in let creg = match gen_access ctx counter Read with VReg r -> r | _ -> abort "Must be a local variable" obj.epos in write ctx (HNext (oreg.rid,creg.rid)) | TLocal { v_name = "__hkeys__" }, [e2] | TLocal { v_name = "__foreach__" }, [e2] | TLocal { v_name = "__keys__" }, [e2] -> let racc = alloc_reg ctx (KType (type_path ctx ([],"Array"))) in let rcounter = alloc_reg ctx KInt in let rtmp = alloc_reg ctx KDynamic in write ctx (HSmallInt 0); set_reg ctx rcounter; write ctx (HArray 0); set_reg ctx racc; gen_expr ctx true e2; set_reg ctx rtmp; let start = jump ctx J3Always in let loop = jump_back ctx in write ctx (HReg racc.rid); write ctx (HReg rtmp.rid); write ctx (HReg rcounter.rid); (match e.eexpr with | TLocal { v_name = "__foreach__" } -> write ctx HForEach | TLocal { v_name = "__hkeys__" } -> write ctx HForIn; write ctx (HSmallInt 1); write ctx (HCallProperty (as3 "substr",1)); | _ -> write ctx HForIn); write ctx (HCallPropVoid (as3 "push",1)); start(); write ctx (HNext (rtmp.rid,rcounter.rid)); loop J3True; write ctx (HReg racc.rid); free_reg ctx rtmp; free_reg ctx rcounter; free_reg ctx racc; | TLocal { v_name = "__new__" }, e :: el -> gen_expr ctx true e; List.iter (gen_expr ctx true) el; write ctx (HConstruct (List.length el)) | TLocal { v_name = "__delete__" }, [o;f] -> gen_expr ctx true o; gen_expr ctx true f; write ctx (HDeleteProp dynamic_prop); | TLocal { v_name = "__unprotect__" }, [e] -> write ctx (HGetLex (type_path ctx (["flash"],"Boot"))); gen_expr ctx true e; write ctx (HCallProperty (ident "__unprotect__",1)); | TLocal { v_name = "__typeof__" }, [e] -> gen_expr ctx true e; write ctx HTypeof | TLocal { v_name = "__in__" }, [e; f] -> gen_expr ctx true e; gen_expr ctx true f; write ctx (HOp A3OIn) | TLocal { v_name = "__resources__" }, [] -> let count = ref 0 in Hashtbl.iter (fun name data -> incr count; write ctx (HString "name"); write ctx (HString name); write ctx (HObject 1); ) ctx.com.resources; write ctx (HArray !count) | TLocal { v_name = "__vmem_set__" }, [{ eexpr = TConst (TInt code) };e1;e2] -> gen_expr ctx true e2; gen_expr ctx true e1; write ctx (HOp (match code with | 0l -> A3OMemSet8 | 1l -> A3OMemSet16 | 2l -> A3OMemSet32 | 3l -> A3OMemSetFloat | 4l -> A3OMemSetDouble | _ -> assert false )) | TLocal { v_name = "__vmem_get__" }, [{ eexpr = TConst (TInt code) };e] -> gen_expr ctx true e; write ctx (HOp (match code with | 0l -> A3OMemGet8 | 1l -> A3OMemGet16 | 2l -> A3OMemGet32 | 3l -> A3OMemGetFloat | 4l -> A3OMemGetDouble | _ -> assert false )) | TLocal { v_name = "__vmem_sign__" }, [{ eexpr = TConst (TInt code) };e] -> gen_expr ctx true e; write ctx (HOp (match code with | 0l -> A3OSign1 | 1l -> A3OSign8 | 2l -> A3OSign16 | _ -> assert false )) | TLocal { v_name = "__vector__" }, [ep] -> gen_type ctx (type_id ctx r); write ctx HGetGlobalScope; gen_expr ctx true ep; write ctx (HCallStack 1) | TArray ({ eexpr = TLocal { v_name = "__global__" } },{ eexpr = TConst (TString s) }), _ -> (match gen_access ctx e Read with | VGlobal id -> write ctx (HFindPropStrict id); List.iter (gen_expr ctx true) el; write ctx (HCallProperty (id,List.length el)); | _ -> assert false) | TConst TSuper , _ -> write ctx HThis; List.iter (gen_expr ctx true) el; write ctx (HConstructSuper (List.length el)); | TField ({ eexpr = TConst TSuper },f) , _ -> let id = ident (field_name f) in write ctx (HFindPropStrict id); List.iter (gen_expr ctx true) el; write ctx (HCallSuper (id,List.length el)); coerce ctx (classify ctx r); | TField ({ eexpr = TConst TThis },f) , _ when not ctx.in_static -> let id = ident (field_name f) in write ctx (HFindProp id); List.iter (gen_expr ctx true) el; if retval then begin write ctx (HCallProperty (id,List.length el)); coerce ctx (classify ctx r); end else write ctx (HCallPropVoid (id,List.length el)) | TField (e1,f) , _ -> let old = ctx.for_call in ctx.for_call <- true; gen_expr ctx true e1; let id , _, _ = property ctx (field_name f) e1.etype in ctx.for_call <- old; List.iter (gen_expr ctx true) el; if retval then begin write ctx (HCallProperty (id,List.length el)); coerce ctx (classify ctx r); end else write ctx (HCallPropVoid (id,List.length el)) | _ -> gen_expr ctx true e; write ctx HGetGlobalScope; List.iter (gen_expr ctx true) el; write ctx (HCallStack (List.length el)); coerce ctx (classify ctx r) and gen_unop ctx retval op flag e = let k = classify ctx e.etype in match op with | Not -> gen_expr ctx true e; write ctx (HOp A3ONot); | Neg -> gen_expr ctx true e; write ctx (HOp (if k = KInt then A3OINeg else A3ONeg)); | NegBits -> gen_expr ctx true e; write ctx (HOp A3OBitNot); | Increment | Decrement -> let incr = (op = Increment) in let r = (match e.eexpr with TLocal v -> get_local_register ctx v | _ -> None) in match r with | Some r when r.rtype = KInt -> if not r.rinit then r.rcond <- true; if retval && flag = Postfix then getvar ctx (VReg r); write ctx (if incr then HIncrIReg r.rid else HDecrIReg r.rid); if retval && flag = Prefix then getvar ctx (VReg r); | _ -> let acc_read, acc_write = gen_access_rw ctx e in let op = (match k, incr with | KInt, true -> A3OIIncr | KInt, false -> A3OIDecr | _ , true -> A3OIncr | _ , false -> A3ODecr ) in getvar ctx acc_read; match flag with | Postfix when retval -> let r = alloc_reg ctx k in write ctx HDup; set_reg ctx r; write ctx (HOp op); setvar ctx acc_write None; write ctx (HReg r.rid); free_reg ctx r | Postfix | Prefix -> write ctx (HOp op); setvar ctx acc_write (if retval then Some k else None) and check_binop ctx e1 e2 = let invalid = (match classify ctx e1.etype, classify ctx e2.etype with | KInt, KUInt | KUInt, KInt -> (match e1.eexpr, e2.eexpr with TConst (TInt i) , _ | _ , TConst (TInt i) -> i < 0l | _ -> true) | _ -> false) in if invalid then abort "Comparison of Int and UInt might lead to unexpected results" (punion e1.epos e2.epos); and gen_binop ctx retval op e1 e2 t p = let write_op op = let iop = (match op with | OpAdd -> Some A3OIAdd | OpSub -> Some A3OISub | OpMult -> Some A3OIMul | _ -> None ) in let op = (match op with | OpAdd -> A3OAdd | OpSub -> A3OSub | OpMult -> A3OMul | OpDiv -> A3ODiv | OpAnd -> A3OAnd | OpOr -> A3OOr | OpXor -> A3OXor | OpShl -> A3OShl | OpShr -> A3OShr | OpUShr -> A3OUShr | OpMod -> A3OMod | _ -> assert false ) in match iop with | Some iop -> let k1 = classify ctx e1.etype in let k2 = classify ctx e2.etype in (match k1, k2 with | KInt, KInt | KUInt, KUInt | KInt, KUInt | KUInt, KInt -> write ctx (HOp iop); let ret = classify ctx t in if ret <> KInt then coerce ctx ret | _ -> write ctx (HOp op); (* add is a generic operation, so let's make sure we don't loose our type in the process *) if op = A3OAdd then coerce ctx (classify ctx t)) | _ -> write ctx (HOp op); if op = A3OMod && classify ctx e1.etype = KInt && classify ctx e2.etype = KInt then coerce ctx (classify ctx t); in let gen_op o = check_binop ctx e1 e2; gen_expr ctx true e1; gen_expr ctx true e2; write ctx (HOp o) in let gen_eq() = match is_special_compare e1 e2 with | None -> gen_op A3OEq | Some c -> let f = FStatic (c,try PMap.find "compare" c.cl_statics with Not_found -> assert false) in gen_expr ctx true (mk (TCall (mk (TField (mk (TTypeExpr (TClassDecl c)) t_dynamic p,f)) t_dynamic p,[e1;e2])) ctx.com.basic.tbool p); in match op with | OpAssign -> let acc = gen_access ctx e1 Write in gen_expr ctx true e2; setvar ctx acc (if retval then Some (classify ctx e1.etype) else None) | OpBoolAnd -> write ctx HFalse; let j = jump_expr ctx e1 false in let b = begin_branch ctx in write ctx HPop; gen_expr ctx true e2; coerce ctx KBool; j(); b(); | OpBoolOr -> write ctx HTrue; let j = jump_expr ctx e1 true in let b = begin_branch ctx in write ctx HPop; gen_expr ctx true e2; coerce ctx KBool; j(); b(); | OpAssignOp op -> let racc, wacc = gen_access_rw ctx e1 in getvar ctx racc; gen_expr ctx true e2; write_op op; setvar ctx wacc (if retval then Some (classify ctx e1.etype) else None) | OpAdd | OpMult | OpDiv | OpSub | OpAnd | OpOr | OpXor | OpMod -> gen_expr ctx true e1; gen_expr ctx true e2; write_op op | OpShl | OpShr | OpUShr -> gen_expr ctx true e1; gen_expr ctx true e2; write_op op; coerce ctx (classify ctx e1.etype) | OpEq -> gen_eq() | OpNotEq -> gen_eq(); write ctx (HOp A3ONot) | OpGt -> gen_op A3OGt | OpGte -> gen_op A3OGte | OpLt -> gen_op A3OLt | OpLte -> gen_op A3OLte | OpInterval | OpArrow -> assert false and gen_expr ctx retval e = let old = ctx.infos.istack in debug_infos ctx e.epos; gen_expr_content ctx retval e; if old <> ctx.infos.istack then begin if old + 1 <> ctx.infos.istack then stack_error e.epos; if not retval then write ctx HPop; end else if retval then stack_error e.epos and generate_function ctx fdata stat = let f = begin_fun ctx fdata.tf_args fdata.tf_type [fdata.tf_expr] stat fdata.tf_expr.epos in gen_expr ctx false fdata.tf_expr; (match follow fdata.tf_type with | TEnum ({ e_path = [],"Void" },[]) | TAbstract ({ a_path = [],"Void" },[]) -> debug_infos ctx ~is_min:false fdata.tf_expr.epos; write ctx HRetVoid | _ -> (* check that we have a return that can be accepted by Flash9 VM *) let rec loop e = match e.eexpr with | TBlock [] -> false | TBlock l -> loop (List.hd (List.rev l)) | TReturn None -> true | TReturn (Some e) -> let rec inner_loop e = match e.eexpr with | TSwitch _ | TFor _ | TWhile _ | TTry _ -> false | TIf _ -> loop e | TParenthesis e | TMeta(_,e) -> inner_loop e | _ -> true in inner_loop e | TIf (_,e1,Some e2) -> loop e1 && loop e2 | TParenthesis e | TMeta(_,e) -> loop e | _ -> false in if not (loop fdata.tf_expr) then write ctx HRetVoid; ); f() and jump_expr_gen ctx e jif jfun = match e.eexpr with | TParenthesis e | TMeta(_,e) -> jump_expr_gen ctx e jif jfun | TBinop (op,e1,e2) -> let j t f = check_binop ctx e1 e2; gen_expr ctx true e1; gen_expr ctx true e2; jfun (if jif then t else f) in (match op with | OpEq when is_special_compare e1 e2 = None -> j J3Eq J3Neq | OpNotEq when is_special_compare e1 e2 = None -> j J3Neq J3Eq | OpGt -> j J3Gt J3NotGt | OpGte -> j J3Gte J3NotGte | OpLt -> j J3Lt J3NotLt | OpLte -> j J3Lte J3NotLte | _ -> gen_expr ctx true e; jfun (if jif then J3True else J3False)) | _ -> gen_expr ctx true e; jfun (if jif then J3True else J3False) and jump_expr ctx e jif = jump_expr_gen ctx e jif (jump ctx) let do_debug ctx meta = let old = ctx.debug in ctx.debug <- (old || Meta.has Meta.Debug meta) && not (Meta.has Meta.NoDebug meta); (fun() -> ctx.debug <- old) let generate_method ctx fdata stat fmeta = let old = do_debug ctx fmeta in let m = generate_function ctx fdata stat in old(); m let generate_construct ctx fdata c = (* make all args optional to allow no-param constructor *) let cargs = if not ctx.need_ctor_skip then fdata.tf_args else List.map (fun (v,c) -> let c = (match c with Some _ -> c | None -> Some (match classify ctx v.v_type with | KInt | KUInt -> TInt 0l | KFloat -> TFloat "0" | KBool -> TBool false | KType _ | KDynamic | KNone -> TNull) ) in v,c ) fdata.tf_args in let f = begin_fun ctx cargs fdata.tf_type [ethis;fdata.tf_expr] false fdata.tf_expr.epos in (* if skip_constructor, then returns immediatly *) if ctx.need_ctor_skip then (match c.cl_kind with | KGenericInstance _ -> () | _ when not (Codegen.constructor_side_effects fdata.tf_expr) -> () | _ -> let id = ident "skip_constructor" in getvar ctx (VGlobal (type_path ctx (["flash"],"Boot"))); getvar ctx (VId id); let j = jump ctx J3False in write ctx HRetVoid; j()); (* --- *) PMap.iter (fun _ f -> match f.cf_expr, f.cf_kind with | Some { eexpr = TFunction fdata }, Method MethDynamic -> let id = ident f.cf_name in write ctx (HFindProp id); write ctx (HGetProp id); let j = jump ctx J3True in write ctx (HFindProp id); write ctx (HFunction (generate_method ctx fdata false [])); write ctx (HInitProp id); j(); | _ -> () ) c.cl_fields; gen_expr ctx false fdata.tf_expr; debug_infos ctx ~is_min:false fdata.tf_expr.epos; write ctx HRetVoid; f() , List.length fdata.tf_args let rec is_const e = match e.eexpr with | TConst _ -> true | TArrayDecl el | TBlock el -> List.for_all is_const el | TObjectDecl fl -> List.for_all (fun (_,e) -> is_const e) fl | TParenthesis e | TMeta(_,e) -> is_const e | TFunction _ -> true | _ -> false let generate_class_statics ctx c const = List.iter (fun f -> match f.cf_expr with | Some { eexpr = TFunction _ } when (match f.cf_kind with Method (MethNormal | MethInline) -> true | _ -> false) -> () | Some e when is_const e = const -> write ctx (HGetLex (type_path ctx c.cl_path)); gen_expr ctx true e; if Codegen.is_volatile f.cf_type then write ctx (HArray 1); write ctx (HInitProp (ident f.cf_name)); | _ -> () ) c.cl_ordered_statics let need_init ctx c = not ctx.swc && not c.cl_extern && List.exists (fun f -> match f.cf_expr with Some e -> not (is_const e) | _ -> false) c.cl_ordered_statics let generate_extern_inits ctx = List.iter (fun t -> match t with | TClassDecl c when c.cl_extern -> (match c.cl_init with | None -> () | Some e -> gen_expr ctx false e); | _ -> () ) ctx.com.types let generate_inits ctx = let finit = begin_fun ctx [] ctx.com.basic.tvoid [] true null_pos in if not ctx.swc then generate_extern_inits ctx; List.iter (fun t -> match t with | TClassDecl c when need_init ctx c -> let id = ident "init__" in getvar ctx (VGlobal (type_path ctx c.cl_path)); getvar ctx (VId id); let j = jump ctx J3True in getvar ctx (VGlobal (type_path ctx c.cl_path)); write ctx HTrue; setvar ctx (VId id) None; let branch = begin_branch ctx in generate_class_statics ctx c false; branch(); j() | _ -> () ) ctx.com.types; (match ctx.com.main with | None -> () | Some e -> gen_expr ctx false e); write ctx HRetVoid; finit() let generate_class_init ctx c hc = write ctx HGetGlobalScope; if c.cl_interface then write ctx HNull else begin let path = (match c.cl_super with None -> ([],"Object") | Some (sup,_) -> sup.cl_path) in write ctx (HGetLex (type_path ctx path)); write ctx HScope; write ctx (HGetLex (type_path ctx path)); end; write ctx (HClassDef hc); List.iter (fun f -> match f.cf_expr, f.cf_kind with | Some { eexpr = TFunction fdata }, Method MethDynamic -> write ctx HDup; write ctx (HFunction (generate_method ctx fdata true f.cf_meta)); write ctx (HInitProp (ident f.cf_name)); | _ -> () ) c.cl_ordered_statics; if not c.cl_interface then write ctx HPopScope; write ctx (HInitProp (type_path ctx c.cl_path)); if ctx.swc && c.cl_path = ctx.boot then generate_extern_inits ctx; (match c.cl_init with | None -> () | Some e -> gen_expr ctx false e; if ctx.block_vars <> [] then abort "You can't have a local variable referenced from a closure inside __init__ (FP 10.1.53 crash)" e.epos; ); generate_class_statics ctx c true; if ctx.swc then begin generate_class_statics ctx c false; if ctx.block_vars <> [] then abort "You can't have a local variable referenced from a closure inside a static (FP 10.1.53 crash)" c.cl_pos; end let generate_enum_init ctx e hc meta = let path = ([],"Object") in let name_id = type_path ctx e.e_path in write ctx HGetGlobalScope; write ctx (HGetLex (type_path ctx path)); write ctx HScope; write ctx (HGetLex (type_path ctx path)); write ctx (HClassDef hc); write ctx HPopScope; write ctx (HInitProp name_id); PMap.iter (fun _ f -> match f.ef_type with | TFun _ -> () | _ -> write ctx (HGetLex name_id); write ctx (HFindPropStrict name_id); write ctx (HString f.ef_name); write ctx (HInt f.ef_index); write ctx HNull; write ctx (HConstructProperty (name_id,3)); write ctx (HInitProp (ident f.ef_name)); ) e.e_constrs; write ctx (HGetLex name_id); List.iter (fun n -> write ctx (HString n)) e.e_names; write ctx (HArray (List.length e.e_names)); write ctx (HInitProp (ident "__constructs__")); match meta with | None -> () | Some e -> write ctx (HGetLex name_id); gen_expr ctx true e; write ctx (HInitProp (ident "__meta__")) let extract_meta meta = let rec loop = function | [] -> [] | (Meta.Meta,[ECall ((EConst (Ident n),_),args),_],_) :: l -> let mk_arg (a,p) = match a with | EConst (String s) -> (None, s) | EBinop (OpAssign,(EConst (Ident n),_),(EConst (String s),_)) -> (Some n, s) | _ -> abort "Invalid meta definition" p in { hlmeta_name = n; hlmeta_data = Array.of_list (List.map mk_arg args) } :: loop l | _ :: l -> loop l in match loop meta with | [] -> None | l -> Some (Array.of_list l) let generate_field_kind ctx f c stat = let method_kind() = let rec loop = function | [] -> f.cf_name, MK3Normal | (Meta.Getter,[EConst (Ident f),_],_) :: _ -> f, MK3Getter | (Meta.Setter,[EConst (Ident f),_],_) :: _ -> f, MK3Setter | _ :: l -> loop l in loop f.cf_meta in if is_extern_field f then None else match f.cf_expr with | Some { eexpr = TFunction fdata } -> let rec loop c name = match c.cl_super with | None -> false | Some (c,_) -> PMap.exists name c.cl_fields || loop c name in (match f.cf_kind with | Method MethDynamic when List.memq f c.cl_overrides -> None | Var _ | Method MethDynamic -> Some (HFVar { hlv_type = Some (type_path ctx ([],"Function")); hlv_value = HVNone; hlv_const = false; }) | _ -> let name, kind = method_kind() in let m = generate_method ctx fdata stat f.cf_meta in Some (HFMethod { hlm_type = m; hlm_final = stat || (Meta.has Meta.Final f.cf_meta); hlm_override = not stat && (loop c name || loop c f.cf_name); hlm_kind = kind; }) ); | _ when c.cl_interface && not stat -> (match follow f.cf_type, f.cf_kind with | TFun (args,tret), Method (MethNormal | MethInline) -> let dparams = ref None in List.iter (fun (_,o,t) -> match !dparams with | None -> if o then dparams := Some [HVNone] | Some l -> dparams := Some (HVNone :: l) ) args; let dparams = (match !dparams with None -> None | Some l -> Some (List.rev l)) in Some (HFMethod { hlm_type = end_fun ctx (List.map (fun (a,opt,t) -> alloc_var a t f.cf_pos, (if opt then Some TNull else None)) args) dparams tret; hlm_final = false; hlm_override = false; hlm_kind = snd (method_kind()); }) | _ -> None) | _ -> Some (HFVar { hlv_type = if Codegen.is_volatile f.cf_type then Some (type_path ctx ([],"Array")) else type_opt ctx f.cf_type; hlv_value = HVNone; hlv_const = false; }) let check_constructor ctx c f = (* check that we don't assign a super Float var before we call super() : will result in NaN *) let rec loop e = Type.iter loop e; match e.eexpr with | TCall ({ eexpr = TConst TSuper },_) -> raise Exit | TBinop (OpAssign,{ eexpr = TField({ eexpr = TConst TThis },FInstance (cc,_,cf)) },_) when c != cc && (match classify ctx cf.cf_type with KFloat | KDynamic -> true | _ -> false) -> abort "You cannot assign some super class vars before calling super() in flash, this will reset them to default value" e.epos | _ -> () in (* only do so if we have a call to super() *) let rec has_super e = Type.iter has_super e; match e.eexpr with | TCall ({ eexpr = TConst TSuper },_) -> raise Exit | _ -> () in try has_super f.tf_expr with Exit -> try loop f.tf_expr with Exit -> () let generate_class ctx c = let name = type_path ctx c.cl_path in ctx.cur_class <- c; let cid , cnargs = (match c.cl_constructor with | None -> if c.cl_interface then { (empty_method ctx null_pos) with hlmt_function = None }, 0 else generate_construct ctx { tf_args = []; tf_type = ctx.com.basic.tvoid; tf_expr = { eexpr = TBlock []; etype = ctx.com.basic.tvoid; epos = null_pos; } } c | Some f -> match f.cf_expr with | Some { eexpr = TFunction fdata } -> let old = do_debug ctx f.cf_meta in let m = generate_construct ctx fdata c in check_constructor ctx c fdata; old(); m | _ -> assert false ) in let has_protected = ref None in let make_name f stat = let rec find_meta c = try let f = PMap.find f.cf_name (if stat then c.cl_statics else c.cl_fields) in if List.memq f c.cl_overrides then raise Not_found; f.cf_meta with Not_found -> match c.cl_super with | None -> [] | Some _ when stat -> [] | Some (c,_) -> find_meta c in let protect() = let p = (match c.cl_path with [], n -> n | p, n -> String.concat "." p ^ ":" ^ n) in has_protected := Some p; HMName (f.cf_name,HNProtected p) in let rec loop_meta = function | [] -> if not f.cf_public && ctx.swf_protected then protect() else ident f.cf_name | x :: l -> match x with | ((Meta.Getter | Meta.Setter),[EConst (Ident f),_],_) -> ident f | (Meta.Ns,[EConst (String ns),_],_) -> HMName (f.cf_name,HNNamespace ns) | (Meta.Protected,[],_) -> protect() | _ -> loop_meta l in if c.cl_interface then HMName (reserved f.cf_name, HNNamespace (match c.cl_path with [],n -> n | l,n -> String.concat "." l ^ ":" ^ n)) else loop_meta (find_meta c) in let generate_prop f acc alloc_slot = match f.cf_kind with | Method _ -> acc | Var v -> (* let p = f.cf_pos in *) (* let ethis = mk (TConst TThis) (TInst (c,[])) p in *) acc in let fields = PMap.fold (fun f acc -> let acc = generate_prop f acc (fun() -> 0) in match generate_field_kind ctx f c false with | None -> acc | Some k -> { hlf_name = make_name f false; hlf_slot = 0; hlf_kind = k; hlf_metas = extract_meta f.cf_meta; } :: acc ) c.cl_fields [] in let fields = if c.cl_path <> ctx.boot then fields else begin { hlf_name = make_name { cf_name = "init"; cf_public = ctx.swc && ctx.swf_protected; cf_meta = []; cf_doc = None; cf_pos = c.cl_pos; cf_name_pos = null_pos; cf_type = TFun ([],t_dynamic); cf_params = []; cf_expr = None; cf_expr_unoptimized = None; cf_kind = Method MethNormal; cf_overloads = []; } false; hlf_slot = 0; hlf_kind = (HFMethod { hlm_type = generate_inits ctx; hlm_final = false; hlm_override = true; hlm_kind = MK3Normal; }); hlf_metas = None; } :: fields end in let st_field_count = ref 0 in let st_meth_count = ref 0 in let statics = List.rev (List.fold_left (fun acc f -> let acc = generate_prop f acc (fun() -> incr st_meth_count; !st_meth_count) in match generate_field_kind ctx f c true with | None -> acc | Some k -> let count = (match k with HFMethod _ -> st_meth_count | HFVar _ -> st_field_count | _ -> assert false) in incr count; { hlf_name = make_name f true; hlf_slot = !count; hlf_kind = k; hlf_metas = extract_meta f.cf_meta; } :: acc ) [] c.cl_ordered_statics) in let statics = if not (need_init ctx c) then statics else { hlf_name = ident "init__"; hlf_slot = (incr st_field_count; !st_field_count); hlf_kind = HFVar { hlv_type = (Some (type_id ctx ctx.com.basic.tbool)); hlv_value = HVNone; hlv_const = false; }; hlf_metas = None; } :: statics in let rec is_dynamic c = if c.cl_dynamic <> None || c.cl_array_access <> None then true else match c.cl_super with | None -> false | Some (c,_) -> is_dynamic c in { hlc_index = 0; hlc_name = name; hlc_super = (if c.cl_interface then None else Some (type_path ctx (match c.cl_super with None -> [],"Object" | Some (c,_) -> c.cl_path))); hlc_sealed = not (is_dynamic c); hlc_final = Meta.has Meta.Final c.cl_meta; hlc_interface = c.cl_interface; hlc_namespace = (match !has_protected with None -> None | Some p -> Some (HNProtected p)); hlc_implements = Array.of_list (List.map (fun (c,_) -> if not c.cl_interface then abort "Can't implement class in Flash9" c.cl_pos; let pack, name = real_path c.cl_path in HMMultiName (Some name,[HNPublic (Some (String.concat "." pack))]) ) c.cl_implements); hlc_construct = cid; hlc_fields = Array.of_list fields; hlc_static_construct = empty_method ctx c.cl_pos; hlc_static_fields = Array.of_list statics; } let generate_enum ctx e meta = let name_id = type_path ctx e.e_path in let api = ctx.com.basic in let f = begin_fun ctx [alloc_var "tag" api.tstring e.e_pos, None;alloc_var "index" api.tint e.e_pos, None;alloc_var "params" (api.tarray (mk_mono())) e.e_pos, None] api.tvoid [ethis] false e.e_pos in let tag_id = ident "tag" in let index_id = ident "index" in let params_id = ident "params" in write ctx (HFindProp tag_id); write ctx (HReg 1); write ctx (HInitProp tag_id); write ctx (HFindProp index_id); write ctx (HReg 2); write ctx (HInitProp index_id); write ctx (HFindProp params_id); write ctx (HReg 3); write ctx (HInitProp params_id); write ctx HRetVoid; let construct = f() in let f = begin_fun ctx [] api.tstring [] true e.e_pos in write ctx (HGetLex (type_path ctx (["flash"],"Boot"))); write ctx HThis; write ctx (HCallProperty (ident "enum_to_string",1)); write ctx HRet; let tostring = f() in let st_field_count = ref 0 in let st_meth_count = ref 0 in let constrs = PMap.fold (fun f acc -> let st_count = (match f.ef_type with TFun _ -> st_meth_count | _ -> st_field_count) in incr st_count; { hlf_name = ident f.ef_name; hlf_slot = !st_count; hlf_kind = (match f.ef_type with | TFun (args,_) -> let fdata = begin_fun ctx (List.map (fun (a,opt,t) -> alloc_var a t e.e_pos, (if opt then Some TNull else None)) args) (TEnum (e,[])) [] true f.ef_pos in write ctx (HFindPropStrict name_id); write ctx (HString f.ef_name); write ctx (HInt f.ef_index); let n = ref 0 in List.iter (fun _ -> incr n; write ctx (HReg !n)) args; write ctx (HArray (!n)); write ctx (HConstructProperty (name_id,3)); write ctx HRet; let fid = fdata() in HFMethod { hlm_type = fid; hlm_final = true; hlm_override = false; hlm_kind = MK3Normal; } | _ -> HFVar { hlv_type = (Some name_id); hlv_value = HVNone; hlv_const = false; } ); hlf_metas = None; } :: acc ) e.e_constrs [] in let constrs = (match meta with | None -> constrs | Some _ -> incr st_field_count; { hlf_name = ident "__meta__"; hlf_slot = !st_field_count; hlf_kind = HFVar { hlv_type = None; hlv_value = HVNone; hlv_const = false; }; hlf_metas = None; } :: constrs ) in { hlc_index = 0; hlc_name = name_id; hlc_super = Some (type_path ctx ([],"Object")); hlc_sealed = true; hlc_final = true; hlc_interface = false; hlc_namespace = None; hlc_implements = [||]; hlc_construct = construct; hlc_fields = [| { hlf_name = tag_id; hlf_slot = 0; hlf_kind = HFVar { hlv_type = Some (HMPath ([],"String")); hlv_value = HVNone; hlv_const = false; }; hlf_metas = None }; { hlf_name = index_id; hlf_slot = 0; hlf_kind = HFVar { hlv_type = Some (HMPath ([],"int")); hlv_value = HVNone; hlv_const = false; }; hlf_metas = None }; { hlf_name = params_id; hlf_slot = 0; hlf_kind = HFVar { hlv_type = Some (HMPath ([],"Array")); hlv_value = HVNone; hlv_const = false; }; hlf_metas = None }; { hlf_name = ident "__enum__"; hlf_slot = 0; hlf_kind = HFVar { hlv_type = Some (HMPath ([],"Boolean")); hlv_value = HVBool true; hlv_const = true }; hlf_metas = None }; { hlf_name = ident "toString"; hlf_slot = 0; hlf_kind = HFMethod { hlm_type = tostring; hlm_final = true; hlm_override = false; hlm_kind = MK3Normal; }; hlf_metas = None; }; |]; hlc_static_construct = empty_method ctx e.e_pos; hlc_static_fields = Array.of_list (List.rev ({ hlf_name = ident "__isenum"; hlf_slot = !st_field_count + 2; hlf_kind = HFVar { hlv_type = Some (HMPath ([],"Boolean")); hlv_value = HVBool true; hlv_const = true; }; hlf_metas = None; } :: { hlf_name = ident "__constructs__"; hlf_slot = !st_field_count + 1; hlf_kind = HFVar { hlv_type = Some (HMPath ([],"Array")); hlv_value = HVNone; hlv_const = false; }; hlf_metas = None; } :: constrs)); } let rec generate_type ctx t = match t with | TClassDecl c -> if c.cl_path = (["flash";"_Boot"],"RealBoot") then c.cl_path <- ctx.boot; if c.cl_extern && (c.cl_path <> ([],"Dynamic") || Meta.has Meta.RealPath c.cl_meta) then None else let debug = do_debug ctx c.cl_meta in let hlc = generate_class ctx c in let init = begin_fun ctx [] ctx.com.basic.tvoid [ethis] false c.cl_pos in generate_class_init ctx c hlc; write ctx HRetVoid; debug(); Some (init(), { hlf_name = type_path ctx c.cl_path; hlf_slot = 0; hlf_kind = HFClass hlc; hlf_metas = extract_meta c.cl_meta; }) | TEnumDecl e -> if e.e_extern then None else let meta = Codegen.build_metadata ctx.com t in let hlc = generate_enum ctx e meta in let init = begin_fun ctx [] ctx.com.basic.tvoid [ethis] false e.e_pos in generate_enum_init ctx e hlc meta; write ctx HRetVoid; Some (init(), { hlf_name = type_path ctx e.e_path; hlf_slot = 0; hlf_kind = HFClass hlc; hlf_metas = extract_meta e.e_meta; }) | TAbstractDecl ({ a_path = [],"Dynamic" } as a) -> generate_type ctx (TClassDecl (mk_class a.a_module a.a_path a.a_pos null_pos)) | TTypeDecl _ | TAbstractDecl _ -> None let resource_path name = (["_res"],"_" ^ String.concat "_" (ExtString.String.nsplit name ".")) let generate_resource ctx name = let c = mk_class null_module (resource_path name) null_pos null_pos in c.cl_super <- Some (mk_class null_module (["flash";"utils"],"ByteArray") null_pos null_pos,[]); let t = TClassDecl c in match generate_type ctx t with | Some (m,f) -> (t,m,f) | None -> assert false let generate com boot_name = let ctx = { com = com; need_ctor_skip = Common.has_feature com "Type.createEmptyInstance"; debug = com.Common.debug; cur_class = null_class; boot = ([],boot_name); debugger = Common.defined com Define.Fdb; swc = Common.defined com Define.Swc; swf_protected = Common.defined com Define.SwfProtected; code = DynArray.create(); locals = PMap.empty; infos = default_infos(); trys = []; breaks = []; continues = []; block_vars = []; in_static = false; last_line = -1; last_file = ""; try_scope_reg = None; for_call = false; } in let types = if ctx.swc && com.main_class = None then (* make sure that both Boot and RealBoot are the first two classes in the SWC this way initializing RealBoot will also run externs __init__ blocks before another class static is defined *) let hd = ref [] in let types = List.fold_left (fun acc t -> match t_path t with | ["flash";"_Boot"],"RealBoot" -> hd := !hd @ [t]; acc | ["flash"], "Boot" -> hd := t :: !hd; acc | _ -> t :: acc ) [] com.types in !hd @ List.rev types else com.types in let res = Hashtbl.fold (fun name _ acc -> generate_resource ctx name :: acc) com.resources [] in let classes = List.fold_left (fun acc t -> match generate_type ctx t with | None -> acc | Some (m,f) -> (t,m,f) :: acc ) res types in List.rev classes ;; Random.self_init(); gen_expr_ref := gen_expr haxe_3.4.4.orig/src/generators/genxml.ml0000664000175000017500000004431113166552354020203 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open Ast open Type open Common open ExtString type xml = | Node of string * (string * string) list * xml list | PCData of string | CData of string let tag name = Node (name,[],[]) let xml name att = Node (name,att,[]) let node name att childs = Node (name,att,childs) let pcdata s = PCData s let cdata s = CData s let pmap f m = PMap.fold (fun x acc -> f x :: acc) m [] let gen_path (p,n) priv = ("path",String.concat "." (p @ [n])) let gen_string s = if String.contains s '<' || String.contains s '>' || String.contains s '&' then cdata s else pcdata s let gen_doc s = (* remove trailing space and convert newlines *) let s = ExtString.String.strip s in let s = String.concat "\n" (ExtString.String.nsplit (String.concat "\n" (ExtString.String.nsplit s "\r\n")) "\r") in node "haxe_doc" [] [gen_string s] let gen_doc_opt d = match d with | None -> [] | Some s -> [gen_doc s] let gen_arg_name (name,opt,_) = (if opt then "?" else "") ^ name let real_path path meta = let rec loop = function | [] -> path | (Meta.RealPath,[(Ast.EConst (Ast.String s),_)],_) :: _ -> parse_path s | _ :: l -> loop l in loop meta let tpath t = let i = t_infos t in real_path i.mt_path i.mt_meta let rec follow_param t = match t with | TMono r -> (match !r with | Some t -> follow_param t | _ -> t) | TType ({ t_path = [],"Null" } as t,tl) -> follow_param (apply_params t.t_params tl t.t_type) | _ -> t let gen_meta meta = let meta = List.filter (fun (m,_,_) -> match m with Meta.Used | Meta.MaybeUsed | Meta.RealPath | Meta.Pure -> false | _ -> true) meta in match meta with | [] -> [] | _ -> let nodes = List.map (fun (m,el,_) -> node "m" ["n",Meta.to_string m] (List.map (fun e -> node "e" [] [gen_string (Ast.s_expr e)]) el) ) meta in [node "meta" [] nodes] let rec gen_type ?(values=None) t = match t with | TMono m -> (match !m with None -> tag "unknown" | Some t -> gen_type t) | TEnum (e,params) -> gen_type_decl "e" (TEnumDecl e) params | TInst (c,params) -> gen_type_decl "c" (TClassDecl c) params | TAbstract (a,params) -> gen_type_decl "x" (TAbstractDecl a) params | TType (t,params) -> gen_type_decl "t" (TTypeDecl t) params | TFun (args,r) -> let names = String.concat ":" (List.map gen_arg_name args) in let values = match values with | None -> [] | Some values -> let has_value = ref false in let values = List.map (fun (n,_,_) -> try let e = PMap.find n values in has_value := true; let s = Ast.s_expr e in s with Not_found -> "" ) args in if !has_value then ["v",String.concat ":" values] else [] in let args = List.map (fun (_,opt,t) -> if opt then follow_param t else t ) args in node "f" (("a",names) :: values) (List.map gen_type (args @ [r])) | TAnon a -> node "a" [] (pmap (fun f -> gen_field [] { f with cf_public = false }) a.a_fields) | TDynamic t2 -> node "d" [] (if t == t2 then [] else [gen_type t2]) | TLazy f -> gen_type (!f()) and gen_type_decl n t pl = let i = t_infos t in node n [gen_path (tpath t) i.mt_private] (List.map gen_type pl) and gen_field att f = let add_get_set acc name att = match acc with | AccNormal | AccResolve | AccRequire _ -> att | AccNo | AccNever -> (name, "null") :: att | AccCall -> (name,"accessor") :: att | AccInline -> (name,"inline") :: att in let att = (match f.cf_expr with None -> att | Some e -> ("line",string_of_int (Lexer.get_error_line e.epos)) :: att) in let att,values = (match f.cf_kind with | Var v -> let att = try begin match Meta.get Meta.Value f.cf_meta with | (_,[e],_) -> ("expr",Ast.s_expr e) :: att | _ -> att end with Not_found -> att in add_get_set v.v_read "get" (add_get_set v.v_write "set" att),PMap.empty | Method m -> let att = match m with | MethNormal | MethMacro -> ("set", "method") :: att | MethDynamic -> ("set", "dynamic") :: att | MethInline -> ("get", "inline") :: ("set","null") :: att in att,get_value_meta f.cf_meta ) in let att = (match f.cf_params with [] -> att | l -> ("params", String.concat ":" (List.map (fun (n,_) -> n) l)) :: att) in let overloads = match List.map (gen_field []) f.cf_overloads with | [] -> [] | nl -> [node "overloads" [] nl] in let field_name cf = try begin match Meta.get Meta.RealPath cf.cf_meta with | _,[EConst (String (s)),_],_ -> s | _ -> raise Not_found end; with Not_found -> cf.cf_name in node (field_name f) (if f.cf_public then ("public","1") :: att else att) (gen_type ~values:(Some values) f.cf_type :: gen_meta f.cf_meta @ gen_doc_opt f.cf_doc @ overloads) let gen_constr e = let doc = gen_doc_opt e.ef_doc in let args, t = (match follow e.ef_type with | TFun (args,_) -> ["a",String.concat ":" (List.map gen_arg_name args)] , List.map (fun (_,opt,t) -> gen_type (if opt then follow_param t else t)) args @ doc | _ -> [] , doc ) in node e.ef_name args (t @ gen_meta e.ef_meta) let gen_ordered_constr e = let rec loop el = match el with | n :: el -> gen_constr (PMap.find n e.e_constrs) :: loop el | [] -> [] in loop e.e_names let gen_type_params ipos priv path params pos m = let mpriv = (if priv then [("private","1")] else []) in let mpath = (if m.m_path <> path then [("module",snd (gen_path m.m_path false))] else []) in let file = (if ipos && pos <> null_pos then [("file",pos.pfile)] else []) in gen_path path priv :: ("params", String.concat ":" (List.map fst params)) :: (file @ mpriv @ mpath) let gen_class_path name (c,pl) = node name [("path",s_type_path (tpath (TClassDecl c)))] (List.map gen_type pl) let rec exists f c = PMap.exists f.cf_name c.cl_fields || match c.cl_super with | None -> false | Some (csup,_) -> exists f csup let rec gen_type_decl com pos t = let m = (t_infos t).mt_module in match t with | TClassDecl c -> let stats = List.filter (fun cf -> cf.cf_name <> "__meta__" && not (Meta.has Meta.GenericInstance cf.cf_meta) ) c.cl_ordered_statics in let stats = List.map (gen_field ["static","1"]) stats in let fields = List.filter (fun cf -> not (Meta.has Meta.GenericInstance cf.cf_meta) ) c.cl_ordered_fields in let fields = (match c.cl_super with | None -> List.map (fun f -> f,[]) fields | Some (csup,_) -> List.map (fun f -> if exists f csup then (f,["override","1"]) else (f,[])) fields ) in let fields = List.map (fun (f,att) -> gen_field att f) fields in let constr = (match c.cl_constructor with None -> [] | Some f -> [gen_field [] f]) in let impl = List.map (gen_class_path (if c.cl_interface then "extends" else "implements")) c.cl_implements in let tree = (match c.cl_super with | None -> impl | Some x -> gen_class_path "extends" x :: impl ) in let doc = gen_doc_opt c.cl_doc in let meta = gen_meta c.cl_meta in let ext = (if c.cl_extern then [("extern","1")] else []) in let interf = (if c.cl_interface then [("interface","1")] else []) in let dynamic = (match c.cl_dynamic with | None -> [] | Some t -> [node "haxe_dynamic" [] [gen_type t]] ) in node "class" (gen_type_params pos c.cl_private (tpath t) c.cl_params c.cl_pos m @ ext @ interf) (tree @ stats @ fields @ constr @ doc @ meta @ dynamic) | TEnumDecl e -> let doc = gen_doc_opt e.e_doc in let meta = gen_meta e.e_meta in node "enum" (gen_type_params pos e.e_private (tpath t) e.e_params e.e_pos m) (gen_ordered_constr e @ doc @ meta) | TTypeDecl t -> let doc = gen_doc_opt t.t_doc in let meta = gen_meta t.t_meta in let tt = gen_type t.t_type in node "typedef" (gen_type_params pos t.t_private t.t_path t.t_params t.t_pos m) (tt :: doc @ meta) | TAbstractDecl a -> let doc = gen_doc_opt a.a_doc in let meta = gen_meta a.a_meta in let mk_cast t = node "icast" [] [gen_type t] in let mk_field_cast (t,cf) = node "icast" ["field",cf.cf_name] [gen_type t] in let sub = (match a.a_from,a.a_from_field with [],[] -> [] | l1,l2 -> [node "from" [] ((List.map mk_cast l1) @ (List.map mk_field_cast l2))]) in let super = (match a.a_to,a.a_to_field with [],[] -> [] | l1,l2 -> [node "to" [] ((List.map mk_cast l1) @ (List.map mk_field_cast l2))]) in let impl = (match a.a_impl with None -> [] | Some c -> [node "impl" [] [gen_type_decl com pos (TClassDecl c)]]) in let this = [node "this" [] [gen_type a.a_this]] in node "abstract" (gen_type_params pos a.a_private (tpath t) a.a_params a.a_pos m) (sub @ this @ super @ doc @ meta @ impl) let escape_entities s = Xml.to_string (Xml.PCData s) let att_str att = String.concat "" (List.map (fun (a,v) -> Printf.sprintf " %s=\"%s\"" a (escape_entities v)) att) let rec write_xml ch tabs x = match x with | Node (name,att,[]) -> IO.printf ch "%s<%s%s/>" tabs name (att_str att) | Node (name,att,[x]) -> IO.printf ch "%s<%s%s>" tabs name (att_str att); write_xml ch "" x; IO.printf ch "" name; | Node (name,att,childs) -> IO.printf ch "%s<%s%s>\n" tabs name (att_str att); List.iter (fun x -> write_xml ch (tabs ^ "\t") x; IO.printf ch "\n"; ) childs; IO.printf ch "%s" tabs name | PCData s -> IO.printf ch "%s" s | CData s -> IO.printf ch "" s let generate com file = let t = Common.timer ["generate";"xml"] in let x = node "haxe" [] (List.map (gen_type_decl com true) (List.filter (fun t -> not (Meta.has Meta.NoDoc (t_infos t).mt_meta)) com.types)) in t(); let t = Common.timer ["write";"xml"] in let ch = IO.output_channel (open_out_bin file) in write_xml ch "" x; IO.close_out ch; t() let gen_type_string ctx t = let x = gen_type_decl ctx false t in let ch = IO.output_string() in write_xml ch "" x; IO.close_out ch (* -------------------------------------------------------------------------- *) (* PRINT HX FROM TYPE *) let rec create_dir acc = function | [] -> () | d :: l -> let path = acc ^ "/" ^ d in (try Unix.mkdir path 0o777 with _ -> ()); create_dir path l let conv_path p = match List.rev (fst p) with | x :: l when x.[0] = '_' -> List.rev (("priv" ^ x) :: l), snd p | _ -> p let get_real_path meta path = try let real_path = match Meta.get Meta.RealPath meta with | (_,[(EConst(String s),_)],_) -> s | _ -> raise Not_found in match List.rev (String.nsplit real_path ".") with | name :: pack -> (List.rev pack), name | _ -> raise Not_found with | Not_found -> path let generate_type com t = let base_path = "hxclasses" in let pack, name = let info = t_infos t in get_real_path info.mt_meta info.mt_path in create_dir "." (base_path :: pack); match pack, name with | ["flash";"net"], "NetStreamPlayTransitions" | ["flash";"filters"], "BitmapFilterQuality" | ["flash";"display"], ("BitmapDataChannel" | "GraphicsPathCommand") -> () | _ -> let f = open_out_bin (base_path ^ "/" ^ (match pack with [] -> "" | l -> String.concat "/" l ^ "/") ^ name ^ ".hx") in let ch = IO.output_channel f in let p fmt = IO.printf ch fmt in if pack <> [] then IO.printf ch "package %s;\n\n" (String.concat "." pack); let rec notnull t = match t with | TMono r -> (match !r with | None -> t | Some t -> notnull t) | TLazy f -> notnull ((!f)()) | TType ({ t_path = [],"Null" },[t]) -> t | _ -> t in let rec path meta p tl = let p = conv_path (get_real_path meta p) in (if fst p = pack then snd p else s_type_path p) ^ (match tl with [] -> "" | _ -> "<" ^ String.concat "," (List.map stype tl) ^ ">") and stype t = match t with | TMono r -> (match !r with | None -> "Unknown" | Some t -> stype t) | TInst ({ cl_kind = KTypeParameter _ } as c,tl) -> path [] ([],snd c.cl_path) tl | TInst (c,tl) -> path c.cl_meta c.cl_path tl | TEnum (e,tl) -> path e.e_meta e.e_path tl | TType (t,tl) -> path t.t_meta t.t_path tl | TAbstract (a,tl) -> path a.a_meta a.a_path tl | TAnon a -> let fields = PMap.fold (fun f acc -> (f.cf_name ^ " : " ^ stype f.cf_type) :: acc) a.a_fields [] in "{" ^ String.concat ", " fields ^ "}" | TLazy f -> stype ((!f)()) | TDynamic t2 -> if t == t2 then "Dynamic" else "Dynamic<" ^ stype t2 ^ ">" | TFun ([],ret) -> "Void -> " ^ ftype ret | TFun (args,ret) -> String.concat " -> " (List.map (fun (_,_,t) -> ftype t) args) ^ " -> " ^ ftype ret and ftype t = match t with | TMono r -> (match !r with | None -> stype t | Some t -> ftype t) | TLazy f -> ftype ((!f)()) | TFun _ -> "(" ^ stype t ^ ")" | _ -> stype t in let sparam (n,v,t) = match v with | None -> n ^ " : " ^ stype t | Some (Ident "null") -> if is_nullable (notnull t) then "?" ^ n ^ " : " ^ stype (notnull t) else (* we have not found a default value stored in metadata, let's generate it *) n ^ " : " ^ stype t ^ " = " ^ (match follow t with | TAbstract ({ a_path = [],("Int"|"Float"|"UInt") },_) -> "0" | TAbstract ({ a_path = [],"Bool" },_) -> "false" | _ -> "null") | Some v -> n ^ " : " ^ stype t ^ " = " ^ (match s_constant v with "nan" -> "0./*NaN*/" | v -> v) in let print_meta ml = List.iter (fun (m,pl,_) -> match m with | Meta.DefParam | Meta.CoreApi | Meta.Used | Meta.MaybeUsed | Meta.FlatEnum | Meta.Value | Meta.DirectlyUsed -> () | _ -> match pl with | [] -> p "@%s " (Meta.to_string m) | l -> p "@%s(%s) " (Meta.to_string m) (String.concat "," (List.map Ast.s_expr pl)) ) ml in let access is_read a = s_access is_read a in let rec print_field stat f = p "\t"; print_meta f.cf_meta; if stat then p "static "; let name = try (match Meta.get Meta.RealPath f.cf_meta with | (Meta.RealPath, [EConst( String s ), _], _) -> s | _ -> raise Not_found) with Not_found -> f.cf_name in (match f.cf_kind with | Var v -> p "var %s" name; if v.v_read <> AccNormal || v.v_write <> AccNormal then p "(%s,%s)" (access true v.v_read) (access false v.v_write); p " : %s" (stype f.cf_type); | Method m -> let params, ret = (match follow f.cf_type with | TFun (args,ret) -> List.map (fun (a,o,t) -> let rec loop = function | [] -> Ident "null" | (Meta.DefParam,[(EConst (String p),_);(EConst v,_)],_) :: _ when p = a -> (match v with | Float "1.#QNAN" -> Float "0./*NaN*/" | Float "4294967295." -> Int "0xFFFFFFFF" | Int "16777215" -> Int "0xFFFFFF" | Float x -> (try let f = float_of_string x in let s = string_of_int (int_of_float f) in if s ^ "." = x then Int s else v with _ -> v) | _ -> v) | _ :: l -> loop l in a,(if o then Some (loop f.cf_meta) else None ),t ) args, ret | _ -> assert false ) in let tparams = (match f.cf_params with [] -> "" | l -> "<" ^ String.concat "," (List.map fst l) ^ ">") in p "function %s%s(%s) : %s" name tparams (String.concat ", " (List.map sparam params)) (stype ret); ); p ";\n"; if Meta.has Meta.Overload f.cf_meta then List.iter (fun f -> print_field stat f) f.cf_overloads in (match t with | TClassDecl c -> print_meta c.cl_meta; p "extern %s %s" (if c.cl_interface then "interface" else "class") (stype (TInst (c,List.map snd c.cl_params))); let ext = (match c.cl_super with | None -> [] | Some (c,pl) -> [" extends " ^ stype (TInst (c,pl))] ) in let ext = List.fold_left (fun acc (i,pl) -> ((if c.cl_interface then " extends " else " implements ") ^ stype (TInst (i,pl))) :: acc) ext c.cl_implements in let ext = (match c.cl_dynamic with | None -> ext | Some t -> (match c.cl_path with | ["flash";"errors"], _ -> ext | _ when t == t_dynamic -> " implements Dynamic" :: ext | _ -> (" implements Dynamic<" ^ stype t ^ ">") :: ext) ) in let ext = (match c.cl_path with | ["flash";"utils"], "ByteArray" -> " implements ArrayAccess" :: ext | ["flash";"utils"], "Dictionary" -> [" implements ArrayAccess"] | ["flash";"xml"], "XML" -> [" implements Dynamic"] | ["flash";"xml"], "XMLList" -> [" implements ArrayAccess"] | ["flash";"display"],"MovieClip" -> [" extends Sprite #if !flash_strict implements Dynamic #end"] | ["flash";"errors"], "Error" -> [" #if !flash_strict implements Dynamic #end"] | _ -> ext ) in p "%s" (String.concat "" (List.rev ext)); p " {\n"; let sort l = let a = Array.of_list (List.filter (fun f -> f.cf_public && not (List.memq f c.cl_overrides)) l) in let name = function "new" -> "" | n -> n in Array.sort (fun f1 f2 -> match f1.cf_kind, f2.cf_kind with | Var _, Var _ | Method _ , Method _ -> compare (name f1.cf_name) (name f2.cf_name) | Var _, _ -> -1 | _ -> 1 ) a; Array.to_list a in List.iter (print_field false) (sort (match c.cl_constructor with None -> c.cl_ordered_fields | Some f -> f :: c.cl_ordered_fields)); List.iter (print_field true) (sort c.cl_ordered_statics); p "}\n"; | TEnumDecl e -> print_meta e.e_meta; p "extern enum %s {\n" (stype (TEnum(e,List.map snd e.e_params))); let sort l = let a = Array.of_list l in Array.sort compare a; Array.to_list a in List.iter (fun n -> let c = PMap.find n e.e_constrs in p "\t%s" c.ef_name; (match follow c.ef_type with | TFun (args,_) -> p "(%s)" (String.concat ", " (List.map sparam (List.map (fun (a,o,t) -> a,(if o then Some (Ident "null") else None),t) args))) | _ -> ()); p ";\n"; ) (if Meta.has Meta.FakeEnum e.e_meta then sort e.e_names else e.e_names); p "}\n" | TTypeDecl t -> print_meta t.t_meta; p "typedef %s = " (stype (TType (t,List.map snd t.t_params))); p "%s" (stype t.t_type); p "\n"; | TAbstractDecl a -> print_meta a.a_meta; p "abstract %s {}" (stype (TAbstract (a,List.map snd a.a_params))); ); IO.close_out ch let generate_hx com = List.iter (generate_type com) com.types haxe_3.4.4.orig/src/generators/hl2c.ml0000664000175000017500000013273313166552354017547 0ustar andyandy00000000000000(* * Copyright (C)2005-2017 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 Hlcode type comparison = | CEq | CNeq | CLt | CGt | CLte | CGte type output_options = | OOLabel | OOCase of int | OODefault | OOIncreaseIndent | OODecreaseIndent | OOBeginBlock | OOEndBlock type function_entry = { mutable fe_name : string; mutable fe_decl : fundecl option; mutable fe_args : ttype list; mutable fe_ret : ttype; } type context = { version : int; out : Buffer.t; mutable tabs : string; hash_cache : (int, int32) Hashtbl.t; hlcode : code; dir : string; mutable curfile : string; mutable cfiles : string list; ftable : function_entry array; htypes : (ttype, int) PMap.t; } let sprintf = Printf.sprintf let keywords = let c_kwds = [ "auto";"break";"case";"char";"const";"continue";"default";"do";"double";"else";"enum";"extern";"float";"for";"goto"; "if";"int";"long";"register";"return";"short";"signed";"sizeof";"static";"struct";"switch";"typedef";"union";"unsigned"; "void";"volatile";"while"; (* MS specific *) "__asm";"dllimport2";"__int8";"naked2";"__based1";"__except";"__int16";"__stdcall";"__cdecl";"__fastcall";"__int32"; "thread2";"__declspec";"__finally";"__int64";"__try";"dllexport2";"__inline";"__leave";"asm"; (* reserved by HLC *) "t"; (* C11 *) "_Alignas";"_Alignof";"_Atomic";"_Bool";"_Complex";"_Generic";"_Imaginary";"_Noreturn";"_Static_assert";"_Thread_local";"_Pragma"; "inline";"restrict" ] in let h = Hashtbl.create 0 in List.iter (fun i -> Hashtbl.add h i ()) c_kwds; h let ident i = if Hashtbl.mem keywords i then "_" ^ i else i let s_comp = function | CLt -> "<" | CGt -> ">" | CEq -> "==" | CLte -> "<=" | CGte -> ">=" | CNeq -> "!=" let core_types = let vp = { vfields = [||]; vindex = PMap.empty } in let ep = { ename = ""; eid = 0; eglobal = None; efields = [||] } in [HVoid;HUI8;HUI16;HI32;HF32;HF64;HBool;HBytes;HDyn;HFun ([],HVoid);HObj null_proto;HArray;HType;HRef HVoid;HVirtual vp;HDynObj;HAbstract ("",0);HEnum ep;HNull HVoid] let tname str = let n = String.concat "__" (ExtString.String.nsplit str ".") in if Hashtbl.mem keywords ("_" ^ n) then "__" ^ n else n let is_gc_ptr = function | HVoid | HUI8 | HUI16 | HI32 | HF32 | HF64 | HBool | HType | HRef _ -> false | HBytes | HDyn | HFun _ | HObj _ | HArray | HVirtual _ | HDynObj | HAbstract _ | HEnum _ | HNull _ -> true let is_ptr = function | HVoid | HUI8 | HUI16 | HI32 | HF32 | HF64 | HBool -> false | _ -> true let rec ctype_no_ptr = function | HVoid -> "void",0 | HUI8 -> "unsigned char",0 | HUI16 -> "unsigned short",0 | HI32 -> "int",0 | HF32 -> "float",0 | HF64 -> "double",0 | HBool -> "bool",0 | HBytes -> "vbyte",1 | HDyn -> "vdynamic",1 | HFun _ -> "vclosure",1 | HObj p -> tname p.pname,0 | HArray -> "varray",1 | HType -> "hl_type",1 | HRef t -> let s,i = ctype_no_ptr t in s,i + 1 | HVirtual _ -> "vvirtual",1 | HDynObj -> "vdynobj",1 | HAbstract (name,_) -> name,1 | HEnum _ -> "venum",1 | HNull _ -> "vdynamic",1 let ctype t = let t, nptr = ctype_no_ptr t in if nptr = 0 then t else t ^ String.make nptr '*' let cast_fun s args t = sprintf "((%s (*)(%s))%s)" (ctype t) (String.concat "," (List.map ctype args)) s let dyn_value_field t = "->v." ^ match t with | HUI8 -> "ui8" | HUI16 -> "ui16" | HI32 -> "i" | HF32 -> "f" | HF64 -> "d" | HBool -> "b" | _ -> "ptr" let type_id t = match t with | HVoid -> "HVOID" | HUI8 -> "HUI8" | HUI16 -> "HUI16" | HI32 -> "HI32" | HF32 -> "HF32" | HF64 -> "HF64" | HBool -> "HBOOL" | HBytes -> "HBYTES" | HDyn -> "HDYN" | HFun _ -> "HFUN" | HObj _ -> "HOBJ" | HArray -> "HARRAY" | HType -> "HTYPE" | HRef _ -> "HREF" | HVirtual _ -> "HVIRTUAL" | HDynObj -> "HDYNOBJ" | HAbstract _ -> "HABSTRACT" | HEnum _ -> "HENUM" | HNull _ -> "HNULL" let var_type n t = ctype t ^ " " ^ ident n let block ctx = ctx.tabs <- ctx.tabs ^ "\t" let unblock ctx = ctx.tabs <- String.sub ctx.tabs 0 (String.length ctx.tabs - 1) let hash ctx sid = try Hashtbl.find ctx.hash_cache sid with Not_found -> let h = hl_hash ctx.hlcode.strings.(sid) in Hashtbl.add ctx.hash_cache sid h; h let type_value ctx t = let index = (try PMap.find t ctx.htypes with Not_found -> assert false) in "&type$" ^ string_of_int index let enum_constr_type ctx e i = let cname,_, tl = e.efields.(i) in if Array.length tl = 0 then "venum" else let name = if e.eid = 0 then let index = (try PMap.find (HEnum e) ctx.htypes with Not_found -> assert false) in "Enum$" ^ string_of_int index else String.concat "_" (ExtString.String.nsplit e.ename ".") in if cname = "" then name else name ^ "_" ^ cname let output ctx str = Buffer.add_string ctx.out str let output_char ctx c = Buffer.add_char ctx.out c let line ctx str = output ctx ctx.tabs; output ctx str; output_char ctx '\n' let expr ctx str = output ctx ctx.tabs; output ctx str; output ctx ";\n" let unamed_field fid = "$_f" ^ string_of_int fid let obj_field fid name = if name = "" then unamed_field fid else ident name let close_file ctx = let str = Buffer.contents ctx.out in Buffer.reset ctx.out; let fpath = ctx.dir ^ "/" ^ ctx.curfile in if String.sub ctx.curfile (String.length ctx.curfile - 2) 2 = ".c" then ctx.cfiles <- ctx.curfile :: ctx.cfiles; ctx.curfile <- ""; let fcontent = (try Std.input_file ~bin:true fpath with _ -> "") in if fcontent <> str then begin Common.mkdir_recursive "" (ExtString.String.nsplit (Filename.dirname fpath) "/"); let ch = open_out_bin fpath in output_string ch str; close_out ch; end let open_file ctx file = if ctx.curfile <> "" then close_file ctx; let version_major = ctx.version / 1000 in let version_minor = (ctx.version mod 1000) / 100 in let version_revision = (ctx.version mod 100) in if file <> "hlc.json" then line ctx (sprintf "// Generated by HLC %d.%d.%d (HL v%d)" version_major version_minor version_revision ctx.hlcode.version); ctx.curfile <- file let string_data_limit = 64 let string ctx sid = let s = ctx.hlcode.strings.(sid) in if String.length s < string_data_limit then sprintf "USTR(\"%s\")" (Ast.s_escape ~hex:false s) else sprintf "string$%d" sid let generate_reflection ctx = let line = line ctx and expr = expr ctx in let sline fmt = Printf.ksprintf line fmt and sexpr fmt = Printf.ksprintf expr fmt in let funByArgs = Hashtbl.create 0 in let type_kind t = match t with | HVoid | HF32 | HF64 -> t | HBool | HUI8 | HUI16 | HI32 -> HI32 | HBytes | HDyn | HFun _ | HObj _ | HArray | HType | HRef _ | HVirtual _ | HDynObj | HAbstract _ | HEnum _ | HNull _ -> HDyn in let type_kind_id t = match t with | HVoid -> 0 | HBool | HUI8 | HUI16 | HI32 -> 1 (* same int representation *) | HF32 -> 2 | HF64 -> 3 | _ -> 4 in let add_fun args t = let nargs = List.length args in let kargs = List.map type_kind args in let kt = type_kind t in let h = try Hashtbl.find funByArgs nargs with Not_found -> let h = Hashtbl.create 0 in Hashtbl.add funByArgs nargs h; h in Hashtbl.replace h (kargs,kt) () in Array.iter (fun f -> Array.iter (fun op -> match op with | OSafeCast (dst,_) | ODynGet (dst,_,_) -> (match f.regs.(dst) with | HFun (args, t) -> add_fun args t | _ -> ()) | _ -> () ) f.code ) ctx.hlcode.functions; Array.iter (fun f -> add_fun f.fe_args f.fe_ret) ctx.ftable; let argsCounts = List.sort compare (Hashtbl.fold (fun i _ acc -> i :: acc) funByArgs []) in sexpr "static int TKIND[] = {%s}" (String.concat "," (List.map (fun t -> string_of_int (type_kind_id (type_kind t))) core_types)); line ""; line "void *hlc_static_call( void *fun, hl_type *t, void **args, vdynamic *out ) {"; block ctx; sexpr "int chk = TKIND[t->fun->ret->kind]"; sexpr "vdynamic *d"; line "switch( t->fun->nargs ) {"; List.iter (fun nargs -> sline "case %d:" nargs; block ctx; if nargs > 9 then sexpr "hl_fatal(\"Too many arguments, TODO:use more bits\")" else begin for i = 0 to nargs-1 do sexpr "chk |= TKIND[t->fun->args[%d]->kind] << %d" i ((i + 1) * 3); done; line "switch( chk ) {"; Hashtbl.iter (fun (args,t) _ -> let s = ref (-1) in let chk = List.fold_left (fun chk t -> incr s; chk lor ((type_kind_id t) lsl (!s * 3))) 0 (t :: args) in sline "case %d:" chk; block ctx; let idx = ref (-1) in let vargs = List.map (fun t -> incr idx; if is_ptr t then sprintf "(%s)args[%d]" (ctype t) !idx else sprintf "*(%s*)args[%d]" (ctype t) !idx ) args in let call = sprintf "%s(%s)" (cast_fun "fun" args t) (String.concat "," vargs) in if is_ptr t then sexpr "return %s" call else if t = HVoid then begin expr call; expr "return NULL"; end else begin sexpr "out%s = %s" (dyn_value_field t) call; sexpr "return &out%s" (dyn_value_field t); end; unblock ctx; ) (Hashtbl.find funByArgs nargs); sline "}"; expr "break"; end; unblock ctx; ) argsCounts; line "}"; sexpr "hl_fatal(\"Unsupported dynamic call\")"; sexpr "return NULL"; unblock ctx; line "}"; line ""; let wrap_char = function | HVoid -> "v" | HUI8 | HUI16 | HBool | HI32 -> "i" | HF32 -> "f" | HF64 -> "d" | _ -> "p" in let make_wrap_name args t = String.concat "" (List.map wrap_char args) ^ "_" ^ wrap_char t in List.iter (fun nargs -> Hashtbl.iter (fun (args,t) _ -> let name = make_wrap_name args t in sline "static %s wrap_%s(void *value%s) {" (ctype t) name (String.concat "" (list_mapi (fun i t -> "," ^ var_type ("p" ^ string_of_int i) t) args)); block ctx; if args <> [] then sexpr "void *args[] = {%s}" (String.concat "," (list_mapi (fun i t -> if not (is_ptr t) then sprintf "&p%d" i else sprintf "p%d" i ) args)); let vargs = if args = [] then "NULL" else "args" in if t = HVoid then sexpr "hl_wrapper_call(value,%s,NULL)" vargs else if is_ptr t then sexpr "return hl_wrapper_call(value,%s,NULL)" vargs else begin expr "vdynamic ret"; sexpr "hl_wrapper_call(value,%s,&ret)" vargs; sexpr "return ret.v.%s" (wrap_char t); end; unblock ctx; line "}"; ) (Hashtbl.find funByArgs nargs); ) argsCounts; line ""; line "void *hlc_get_wrapper( hl_type *t ) {"; block ctx; sexpr "int chk = TKIND[t->fun->ret->kind]"; line "switch( t->fun->nargs ) {"; List.iter (fun nargs -> sline "case %d:" nargs; block ctx; if nargs > 9 then sexpr "hl_fatal(\"Too many arguments, TODO:use more bits\")" else begin for i = 0 to nargs-1 do sexpr "chk |= TKIND[t->fun->args[%d]->kind] << %d" i ((i + 1) * 3); done; line "switch( chk ) {"; Hashtbl.iter (fun (args,t) _ -> let s = ref (-1) in let chk = List.fold_left (fun chk t -> incr s; chk lor ((type_kind_id t) lsl (!s * 3))) 0 (t :: args) in sexpr "case %d: return wrap_%s" chk (make_wrap_name args t); ) (Hashtbl.find funByArgs nargs); sline "}"; expr "break"; end; unblock ctx; ) argsCounts; line "}"; sexpr "return NULL"; unblock ctx; line "}"; line "" let generate_function ctx f = let line = line ctx and expr = expr ctx in let sline fmt = Printf.ksprintf line fmt and sexpr fmt = Printf.ksprintf expr fmt in let block() = block ctx and unblock() = unblock ctx in let type_value = type_value ctx in let code = ctx.hlcode in let rid = ref (-1) in let reg id = "r" ^ string_of_int id in let label id = "label$" ^ string_of_int f.findex ^ "$" ^ string_of_int id in let rtype r = f.regs.(r) in let funname fid = ctx.ftable.(fid).fe_name in let rcast r t = if tsame (rtype r) t then (reg r) else Printf.sprintf "((%s)%s)" (ctype t) (reg r) in let rfun r args t = cast_fun (reg r ^ "->fun") args t in let rassign r t = let rt = rtype r in if t = HVoid then "" else let assign = reg r ^ " = " in if tsame t rt then assign else if not (safe_cast t rt) then assert false else assign ^ "(" ^ ctype rt ^ ")" in let ocall r fid args = let ft = ctx.ftable.(fid) in let rstr = rassign r ft.fe_ret in sexpr "%s%s(%s)" rstr ft.fe_name (String.concat "," (List.map2 rcast args ft.fe_args)) in let dyn_prefix = function | HUI8 | HUI16 | HI32 | HBool -> "i" | HF32 -> "f" | HF64 -> "d" | _ -> "p" in let type_value_opt t = match t with HF32 | HF64 -> "" | _ -> "," ^ type_value t in let dyn_call r f pl = line "{"; block(); if pl <> [] then sexpr "vdynamic *args[] = {%s}" (String.concat "," (List.map (fun p -> match rtype p with | HDyn -> reg p | t -> if is_dynamic t then sprintf "(vdynamic*)%s" (reg p) else sprintf "hl_make_dyn(&%s,%s)" (reg p) (type_value t) ) pl)); let rt = rtype r in let ret = if rt = HVoid then "" else if is_dynamic rt then sprintf "%s = (%s)" (reg r) (ctype rt) else "vdynamic *ret = " in sexpr "%shl_dyn_call((vclosure*)%s,%s,%d)" ret (reg f) (if pl = [] then "NULL" else "args") (List.length pl); if rt <> HVoid && not (is_dynamic rt) then sexpr "%s = (%s)hl_dyn_cast%s(&ret,&hlt_dyn%s)" (reg r) (ctype rt) (dyn_prefix rt) (type_value_opt rt); unblock(); line "}"; in let mcall r fid = function | [] -> assert false | o :: args -> match rtype o with | HObj _ -> let vfun = cast_fun (sprintf "%s->$type->vobj_proto[%d]" (reg o) fid) (rtype o :: List.map rtype args) (rtype r) in sexpr "%s%s(%s)" (rassign r (rtype r)) vfun (String.concat "," (List.map reg (o::args))) | HVirtual vp -> let rt = rtype r in let meth = sprintf "hl_vfields(%s)[%d]" (reg o) fid in let meth = cast_fun meth (HDyn :: List.map rtype args) rt in sline "if( hl_vfields(%s)[%d] ) %s%s(%s); else {" (reg o) fid (rassign r rt) meth (String.concat "," ((reg o ^ "->value") :: List.map reg args)); block(); if args <> [] then sexpr "void *args[] = {%s}" (String.concat "," (List.map (fun p -> let t = rtype p in if is_ptr t then reg p else sprintf "&%s" (reg p) ) args)); let rt = rtype r in let ret = if rt = HVoid then "" else if is_ptr rt then sprintf "%s = (%s)" (reg r) (ctype rt) else begin sexpr "vdynamic ret"; ""; end in let fname, fid, ft = vp.vfields.(fid) in sexpr "%shl_dyn_call_obj(%s->value,%s,%ld/*%s*/,%s,%s)" ret (reg o) (type_value ft) (hash ctx fid) fname (if args = [] then "NULL" else "args") (if is_ptr rt || rt == HVoid then "NULL" else "&ret"); if rt <> HVoid && not (is_ptr rt) then sexpr "%s = (%s)ret.v.%s" (reg r) (ctype rt) (dyn_prefix rt); unblock(); sline "}" | _ -> assert false in let set_field obj fid v = match rtype obj with | HObj o -> let name, t = resolve_field o fid in sexpr "%s->%s = %s" (reg obj) (obj_field fid name) (rcast v t) | HVirtual vp -> let name, nid, t = vp.vfields.(fid) in let dset = sprintf "hl_dyn_set%s(%s->value,%ld/*%s*/%s,%s)" (dyn_prefix t) (reg obj) (hash ctx nid) name (type_value_opt (rtype v)) (reg v) in (match t with | HFun _ -> expr dset | _ -> sexpr "if( hl_vfields(%s)[%d] ) *(%s*)(hl_vfields(%s)[%d]) = (%s)%s; else %s" (reg obj) fid (ctype t) (reg obj) fid (ctype t) (reg v) dset) | _ -> assert false in let get_field r obj fid = match rtype obj with | HObj o -> let name, t = resolve_field o fid in sexpr "%s%s->%s" (rassign r t) (reg obj) (obj_field fid name) | HVirtual v -> let name, nid, t = v.vfields.(fid) in let dget = sprintf "(%s)hl_dyn_get%s(%s->value,%ld/*%s*/%s)" (ctype t) (dyn_prefix t) (reg obj) (hash ctx nid) name (type_value_opt t) in (match t with | HFun _ -> sexpr "%s%s" (rassign r t) dget | _ -> sexpr "%shl_vfields(%s)[%d] ? (*(%s*)(hl_vfields(%s)[%d])) : %s" (rassign r t) (reg obj) fid (ctype t) (reg obj) fid dget) | _ -> assert false in let fret = (match f.ftype with | HFun (args,t) -> sline "%s %s(%s) {" (ctype t) (funname f.findex) (String.concat "," (List.map (fun t -> incr rid; var_type (reg !rid) t) args)); t | _ -> assert false ) in block(); let var_map = Hashtbl.create 0 in Array.iteri (fun i t -> if i <= !rid || t = HVoid then () else let key = ctype_no_ptr t in Hashtbl.replace var_map key (try (reg i) :: Hashtbl.find var_map key with Not_found -> [reg i]) ) f.regs; Hashtbl.iter (fun (s,i) il -> let prefix = String.make i '*' in let il = List.rev_map (fun s -> prefix ^ s) il in sexpr "%s %s" s (String.concat ", " il) ) var_map; let output_options = Array.make (Array.length f.code + 1) [] in let output_at i oo = output_options.(i) <- oo :: output_options.(i) in let output_at2 i ool = List.iter (output_at i) ool in let has_label i = List.exists (function OOLabel -> true | _ -> false) output_options.(i) in let trap_depth = ref 0 in let max_trap_depth = ref 0 in Array.iter (fun op -> match op with | OTrap _ -> incr trap_depth; if !trap_depth > !max_trap_depth then max_trap_depth := !trap_depth | OEndTrap true -> decr trap_depth | _ -> () ) f.code; for i = 0 to !max_trap_depth - 1 do sexpr "hl_trap_ctx trap$%d" i; done; let flush_options i = match output_options.(i) with | [] -> () | opts -> (* put label after } *) let opts = if has_label i && List.mem OOEndBlock opts then OOLabel :: List.filter (fun i -> i <> OOLabel) opts else opts in let opts = List.rev opts in List.iter (function | OOLabel -> sline "%s:" (label i) | OOCase i -> sline "case %i:" i | OODefault -> line "default:" | OOIncreaseIndent -> block() | OODecreaseIndent -> unblock() | OOBeginBlock -> line "{" | OOEndBlock -> line "}" ) opts in Array.iteri (fun i op -> flush_options i; let label delta = let addr = delta + i + 1 in let label = label addr in if not (has_label addr) then output_at addr OOLabel; label in let todo() = sexpr "hl_fatal(\"%s\")" (ostr (fun id -> "f" ^ string_of_int id) op) in let rec compare_op op a b d = let phys_compare() = sexpr "if( %s %s %s ) goto %s" (reg a) (s_comp op) (rcast b (rtype a)) (label d) in (* safe_cast is already checked two ways (same type) for eq one way for comparisons *) match rtype a, rtype b with | (HUI8 | HUI16 | HI32 | HF32 | HF64 | HBool), (HUI8 | HUI16 | HI32 | HF32 | HF64 | HBool) -> phys_compare() | HType, HType -> sexpr "if( hl_same_type(%s,%s) %s 0 ) {} else goto %s" (reg a) (reg b) (s_comp op) (label d) | HNull t, HNull _ -> let field = dyn_value_field t in let pcompare = sprintf "(%s%s %s %s%s)" (reg a) field (s_comp op) (reg b) field in if op = CEq then sexpr "if( %s == %s || (%s && %s && %s) ) goto %s" (reg a) (reg b) (reg a) (reg b) pcompare (label d) else if op = CNeq then sexpr "if( %s != %s && (!%s || !%s || %s) ) goto %s" (reg a) (reg b) (reg a) (reg b) pcompare (label d) else sexpr "if( %s && %s && %s ) goto %s" (reg a) (reg b) pcompare (label d) | HDyn , _ | _, HDyn -> let inv = if op = CGt || op = CGte then "&& i != hl_invalid_comparison " else "" in sexpr "{ int i = hl_dyn_compare((vdynamic*)%s,(vdynamic*)%s); if( i %s 0 %s) goto %s; }" (reg a) (reg b) (s_comp op) inv (label d) | HObj oa, HObj _ -> (try let fid = PMap.find "__compare" oa.pfunctions in if op = CEq then sexpr "if( %s == %s || (%s && %s && %s(%s,%s) == 0) ) goto %s" (reg a) (reg b) (reg a) (reg b) (funname fid) (reg a) (reg b) (label d) else if op = CNeq then sexpr "if( %s != %s && (!%s || !%s || %s(%s,%s) != 0) ) goto %s" (reg a) (reg b) (reg a) (reg b) (funname fid) (reg a) (reg b) (label d) else sexpr "if( %s && %s && %s(%s,%s) %s 0 ) goto %s" (reg a) (reg b) (funname fid) (reg a) (reg b) (s_comp op) (label d) with Not_found -> phys_compare()) | HVirtual _, HVirtual _ -> if op = CEq then sexpr "if( %s == %s || (%s && %s && %s->value && %s->value && %s->value == %s->value) ) goto %s" (reg a) (reg b) (reg a) (reg b) (reg a) (reg b) (reg a) (reg b) (label d) else if op = CNeq then sexpr "if( %s != %s && (!%s || !%s || !%s->value || !%s->value || %s->value != %s->value) ) goto %s" (reg a) (reg b) (reg a) (reg b) (reg a) (reg b) (reg a) (reg b) (label d) else assert false | HEnum _, HEnum _ | HDynObj, HDynObj -> phys_compare() | HVirtual _, HObj _-> if op = CEq then sexpr "if( %s ? (%s && %s->value == (vdynamic*)%s) : (%s == NULL) ) goto %s" (reg a) (reg b) (reg a) (reg b) (reg b) (label d) else if op = CNeq then sexpr "if( %s ? (%s == NULL || %s->value != (vdynamic*)%s) : (%s != NULL) ) goto %s" (reg a) (reg b) (reg a) (reg b) (reg b) (label d) else assert false | HObj _, HVirtual _ -> compare_op op b a d | HFun _, HFun _ -> phys_compare() | ta, tb -> failwith ("Don't know how to compare " ^ tstr ta ^ " and " ^ tstr tb ^ " (hlc)") in match op with | OMov (r,v) -> if rtype r <> HVoid then sexpr "%s = %s" (reg r) (rcast v (rtype r)) | OInt (r,idx) -> if code.ints.(idx) = 0x80000000l then sexpr "%s = 0x80000000" (reg r) else sexpr "%s = %ld" (reg r) code.ints.(idx) | OFloat (r,idx) -> sexpr "%s = %.19g" (reg r) code.floats.(idx) | OBool (r,b) -> sexpr "%s = %s" (reg r) (if b then "true" else "false") | OBytes (r,idx) -> sexpr "%s = bytes$%d" (reg r) idx | OString (r,idx) -> sexpr "%s = (vbyte*)%s" (reg r) (string ctx idx) | ONull r -> sexpr "%s = NULL" (reg r) | OAdd (r,a,b) -> sexpr "%s = %s + %s" (reg r) (reg a) (reg b) | OSub (r,a,b) -> sexpr "%s = %s - %s" (reg r) (reg a) (reg b) | OMul (r,a,b) -> sexpr "%s = %s * %s" (reg r) (reg a) (reg b) | OSDiv (r,a,b) -> (match rtype r with | HUI8 | HUI16 | HI32 -> sexpr "%s = %s == 0 ? 0 : %s / %s" (reg r) (reg b) (reg a) (reg b) | _ -> sexpr "%s = %s / %s" (reg r) (reg a) (reg b)) | OUDiv (r,a,b) -> sexpr "%s = %s == 0 ? 0 : ((unsigned)%s) / ((unsigned)%s)" (reg r) (reg b) (reg a) (reg b) | OSMod (r,a,b) -> (match rtype r with | HUI8 | HUI16 | HI32 -> sexpr "%s = %s == 0 ? 0 : %s %% %s" (reg r) (reg b) (reg a) (reg b) | HF32 -> sexpr "%s = fmodf(%s,%s)" (reg r) (reg a) (reg b) | HF64 -> sexpr "%s = fmod(%s,%s)" (reg r) (reg a) (reg b) | _ -> assert false) | OUMod (r,a,b) -> sexpr "%s = %s == 0 ? 0 : ((unsigned)%s) %% ((unsigned)%s)" (reg r) (reg b) (reg a) (reg b) | OShl (r,a,b) -> sexpr "%s = %s << %s" (reg r) (reg a) (reg b) | OSShr (r,a,b) -> sexpr "%s = %s >> %s" (reg r) (reg a) (reg b) | OUShr (r,a,b) -> sexpr "%s = ((unsigned)%s) >> %s" (reg r) (reg a) (reg b) | OAnd (r,a,b) -> sexpr "%s = %s & %s" (reg r) (reg a) (reg b) | OOr (r,a,b) -> sexpr "%s = %s | %s" (reg r) (reg a) (reg b) | OXor (r,a,b) -> sexpr "%s = %s ^ %s" (reg r) (reg a) (reg b) | ONeg (r,v) -> sexpr "%s = -%s" (reg r) (reg v) | ONot (r,v) -> sexpr "%s = !%s" (reg r) (reg v) | OIncr r -> sexpr "++%s" (reg r) | ODecr r -> sexpr "--%s" (reg r) | OCall0 (r,fid) -> ocall r fid [] | OCall1 (r,fid,a) -> ocall r fid [a] | OCall2 (r,fid,a,b) -> ocall r fid [a;b] | OCall3 (r,fid,a,b,c) -> ocall r fid [a;b;c] | OCall4 (r,fid,a,b,c,d) -> ocall r fid [a;b;c;d] | OCallN (r,fid,rl) -> ocall r fid rl | OCallMethod (r,fid,pl) -> mcall r fid pl | OCallThis (r,fid,pl) -> mcall r fid (0 :: pl) | OCallClosure (r,cl,pl) -> (match rtype cl with | HDyn -> dyn_call r cl pl | HFun (args,ret) -> let sargs = String.concat "," (List.map2 rcast pl args) in sexpr "%s%s->hasValue ? %s((vdynamic*)%s->value%s) : %s(%s)" (rassign r ret) (reg cl) (rfun cl (HDyn :: args) ret) (reg cl) (if sargs = "" then "" else "," ^ sargs) (rfun cl args ret) sargs | _ -> assert false) | OStaticClosure (r,fid) -> sexpr "%s = &cl$%d" (reg r) fid | OInstanceClosure (r,fid,ptr) -> let ft = ctx.ftable.(fid) in sexpr "%s = hl_alloc_closure_ptr(%s,%s,%s)" (reg r) (type_value (HFun (ft.fe_args,ft.fe_ret))) (funname fid) (reg ptr) | OVirtualClosure (r,o,m) -> (match rtype o with | HObj p -> let ft = ctx.ftable.(p.pvirtuals.(m)) in let s = sprintf "%s->$type->vobj_proto[%d]" (reg o) m in sexpr "%s = hl_alloc_closure_ptr(%s,%s,%s)" (reg r) (type_value (HFun(ft.fe_args,ft.fe_ret))) s (reg o) | _ -> todo()) | OGetGlobal (r,g) -> sexpr "%s = (%s)global$%d" (reg r) (ctype (rtype r)) g | OSetGlobal (g,r) -> sexpr "global$%d = (%s)%s" g (ctype code.globals.(g)) (reg r) | ORet r -> if rtype r = HVoid then expr "return" else sexpr "return %s" (rcast r fret) | OJTrue (r,d) | OJNotNull (r,d) -> sexpr "if( %s ) goto %s" (reg r) (label d) | OJFalse (r,d) | OJNull (r,d) -> sexpr "if( !%s ) goto %s" (reg r) (label d) | OJSLt (a,b,d) -> compare_op CLt a b d | OJSGte (a,b,d) -> compare_op CGte a b d | OJSGt (a,b,d) -> compare_op CGt a b d | OJSLte (a,b,d) -> compare_op CLte a b d | OJULt (a,b,d) -> sexpr "if( ((unsigned)%s) < ((unsigned)%s) ) goto %s" (reg a) (reg b) (label d) | OJUGte (a,b,d) -> sexpr "if( ((unsigned)%s) >= ((unsigned)%s) ) goto %s" (reg a) (reg b) (label d) | OJEq (a,b,d) -> compare_op CEq a b d | OJNotEq (a,b,d) -> compare_op CNeq a b d | OJAlways d -> sexpr "goto %s" (label d) | OLabel _ -> if not (has_label i) then sline "%s:" (label (-1)) | OToDyn (r,v) -> if is_ptr (rtype v) then begin sline "if( %s == NULL ) %s = NULL; else {" (reg v) (reg r); block(); end; sexpr "%s = hl_alloc_dynamic(%s)" (reg r) (type_value (rtype v)); (match rtype v with | HUI8 | HUI16 | HI32 | HBool -> sexpr "%s->v.i = %s" (reg r) (reg v) | HF32 -> sexpr "%s->v.f = %s" (reg r) (reg v) | HF64 -> sexpr "%s->v.d = %s" (reg r) (reg v) | _ -> sexpr "%s->v.ptr = %s" (reg r) (reg v)); if is_ptr (rtype v) then begin unblock(); line "}"; end; | OToSFloat (r,v) -> sexpr "%s = (%s)%s" (reg r) (ctype (rtype r)) (reg v) | OToUFloat (r,v) -> sexpr "%s = (%s)(unsigned)%s" (reg r) (ctype (rtype r)) (reg v) | OToInt (r,v) -> sexpr "%s = (int)%s" (reg r) (reg v) | ONew r -> (match rtype r with | HObj o -> sexpr "%s = (%s)hl_alloc_obj(%s)" (reg r) (tname o.pname) (tname o.pname ^ "__val") | HDynObj -> sexpr "%s = hl_alloc_dynobj()" (reg r) | HVirtual _ as t -> sexpr "%s = hl_alloc_virtual(%s)" (reg r) (type_value t) | _ -> assert false) | OField (r,obj,fid) -> get_field r obj fid | OSetField (obj,fid,v) -> set_field obj fid v | OGetThis (r,fid) -> get_field r 0 fid | OSetThis (fid,r) -> set_field 0 fid r | OThrow r -> sexpr "hl_throw((vdynamic*)%s)" (reg r) | ORethrow r -> sexpr "hl_rethrow((vdynamic*)%s)" (reg r) | OGetUI8 (r,b,idx) -> sexpr "%s = *(unsigned char*)(%s + %s)" (reg r) (reg b) (reg idx) | OGetUI16 (r,b,idx) -> sexpr "%s = *(unsigned short*)(%s + %s)" (reg r) (reg b) (reg idx) | OGetI32 (r,b,idx) -> sexpr "%s = *(int*)(%s + %s)" (reg r) (reg b) (reg idx) | OGetF32 (r,b,idx) -> sexpr "%s = *(float*)(%s + %s)" (reg r) (reg b) (reg idx) | OGetF64 (r,b,idx) -> sexpr "%s = *(double*)(%s + %s)" (reg r) (reg b) (reg idx) | OGetArray (r, arr, idx) -> sexpr "%s = ((%s*)(%s + 1))[%s]" (reg r) (ctype (rtype r)) (reg arr) (reg idx) | OSetUI8 (b,idx,r) -> sexpr "*(unsigned char*)(%s + %s) = (unsigned char)%s" (reg b) (reg idx) (reg r) | OSetUI16 (b,idx,r) -> sexpr "*(unsigned short*)(%s + %s) = (unsigned short)%s" (reg b) (reg idx) (reg r) | OSetI32 (b,idx,r) -> sexpr "*(int*)(%s + %s) = %s" (reg b) (reg idx) (reg r) | OSetF32 (b,idx,r) -> sexpr "*(float*)(%s + %s) = (float)%s" (reg b) (reg idx) (reg r) | OSetF64 (b,idx,r) -> sexpr "*(double*)(%s + %s) = %s" (reg b) (reg idx) (reg r) | OSetArray (arr,idx,v) -> sexpr "((%s*)(%s + 1))[%s] = %s" (ctype (rtype v)) (reg arr) (reg idx) (reg v) | OSafeCast (r,v) -> let tsrc = rtype v in let t = rtype r in if tsrc = HNull t then sexpr "%s = %s ? %s%s : 0" (reg r) (reg v) (reg v) (dyn_value_field t) else sexpr "%s = (%s)hl_dyn_cast%s(&%s,%s%s)" (reg r) (ctype t) (dyn_prefix t) (reg v) (type_value (rtype v)) (type_value_opt t) | OUnsafeCast (r,v) -> sexpr "%s = (%s)%s" (reg r) (ctype (rtype r)) (reg v) | OArraySize (r,a) -> sexpr "%s = %s->size" (reg r) (reg a) | OType (r,t) -> sexpr "%s = %s" (reg r) (type_value t) | OGetType (r,v) -> sexpr "%s = %s ? ((vdynamic*)%s)->t : &hlt_void" (reg r) (reg v) (reg v) | OGetTID (r,v) -> sexpr "%s = %s->kind" (reg r) (reg v) | ORef (r,v) -> sexpr "%s = &%s" (reg r) (reg v) | OUnref (r,v) -> sexpr "%s = *%s" (reg r) (reg v) | OSetref (r,v) -> sexpr "*%s = %s" (reg r) (reg v) | OToVirtual (r,v) -> sexpr "%s = hl_to_virtual(%s,(vdynamic*)%s)" (reg r) (type_value (rtype r)) (reg v) | ODynGet (r,o,sid) -> let t = rtype r in let h = hash ctx sid in sexpr "%s = (%s)hl_dyn_get%s((vdynamic*)%s,%ld/*%s*/%s)" (reg r) (ctype t) (dyn_prefix t) (reg o) h code.strings.(sid) (type_value_opt t) | ODynSet (o,sid,v) -> let h = hash ctx sid in sexpr "hl_dyn_set%s((vdynamic*)%s,%ld/*%s*/%s,%s)" (dyn_prefix (rtype v)) (reg o) h code.strings.(sid) (type_value_opt (rtype v)) (reg v) | OMakeEnum (r,cid,rl) -> let e, et = (match rtype r with HEnum e -> e, enum_constr_type ctx e cid | _ -> assert false) in let has_ptr = List.exists (fun r -> is_gc_ptr (rtype r)) rl in let need_tmp = List.mem r rl in let tmp = if not need_tmp then reg r else begin sexpr "{ venum *tmp"; "tmp" end in sexpr "%s = (venum*)hl_gc_alloc%s(sizeof(%s))" tmp (if has_ptr then "" else "_noptr") et; sexpr "%s->index = %d" tmp cid; let _,_,tl = e.efields.(cid) in list_iteri (fun i v -> sexpr "((%s*)%s)->p%d = %s" et tmp i (rcast v tl.(i)) ) rl; if need_tmp then sexpr "%s = tmp; }" (reg r) | OEnumAlloc (r,cid) -> let et, (_,_,tl) = (match rtype r with HEnum e -> enum_constr_type ctx e cid, e.efields.(cid) | _ -> assert false) in let has_ptr = List.exists is_gc_ptr (Array.to_list tl) in sexpr "%s = (venum*)hl_gc_alloc%s(sizeof(%s))" (reg r) (if has_ptr then "" else "_noptr") et; sexpr "memset(%s,0,sizeof(%s))" (reg r) et; if cid <> 0 then sexpr "%s->index = %d" (reg r) cid | OEnumIndex (r,v) -> (match rtype v with | HEnum _ -> sexpr "%s = %s->index" (reg r) (reg v) | HDyn -> sexpr "%s = ((venum*)%s->v.ptr)->index" (reg r) (reg v) | _ -> assert false) | OEnumField (r,e,cid,pid) -> let tname,(_,_,tl) = (match rtype e with HEnum e -> enum_constr_type ctx e cid, e.efields.(cid) | _ -> assert false) in sexpr "%s((%s*)%s)->p%d" (rassign r tl.(pid)) tname (reg e) pid | OSetEnumField (e,pid,r) -> let tname, (_,_,tl) = (match rtype e with HEnum e -> enum_constr_type ctx e 0, e.efields.(0) | _ -> assert false) in sexpr "((%s*)%s)->p%d = (%s)%s" tname (reg e) pid (ctype tl.(pid)) (reg r) | OSwitch (r,idx,eend) -> sline "switch(%s) {" (reg r); block(); output_at2 (i + 1) [OODefault;OOIncreaseIndent]; Array.iteri (fun k delta -> output_at2 (delta + i + 1) [OODecreaseIndent;OOCase k;OOIncreaseIndent]) idx; let pend = i+1+eend in (* insert at end if we have another switch case here *) let old = output_options.(pend) in output_options.(pend) <- []; output_at2 pend ([OODecreaseIndent;OODecreaseIndent;OOEndBlock] @ List.rev old); | ONullCheck r -> sexpr "if( %s == NULL ) hl_null_access()" (reg r) | OTrap (r,d) -> sexpr "hl_trap(trap$%d,%s,%s)" !trap_depth (reg r) (label d); incr trap_depth | OEndTrap b -> sexpr "hl_endtrap(trap$%d)" (!trap_depth - 1); if b then decr trap_depth; | ONop _ -> () ) f.code; flush_options (Array.length f.code); unblock(); line "}"; line "" let write_c com file (code:code) = let all_types, htypes = gather_types code in let ctx = { version = com.Common.version; out = Buffer.create 1024; tabs = ""; hlcode = code; hash_cache = Hashtbl.create 0; dir = (match Filename.dirname file with "" -> "." | dir -> String.concat "/" (ExtString.String.nsplit dir "\\")); curfile = ""; cfiles = []; ftable = Array.init (Array.length code.functions + Array.length code.natives) (fun _ -> { fe_args = []; fe_ret = HVoid; fe_name = ""; fe_decl = None; }); htypes = htypes; } in let line = line ctx and expr = expr ctx in let sline fmt = Printf.ksprintf line fmt and sexpr fmt = Printf.ksprintf expr fmt in open_file ctx "hl/code.h"; line "#ifndef HL_CODE_H"; line "#define HL_CODE_H"; line ""; line "#define HLC_BOOT"; line "#include "; line "#include \"typedefs.h\""; line "#include \"types.h\""; line "#include \"functions.h\""; line "#include \"globals.h\""; line "#include \"natives.h\""; line ""; line "#endif"; let used_closures = Hashtbl.create 0 in let bytes_strings = Hashtbl.create 0 in Array.iter (fun f -> Array.iteri (fun i op -> match op with | OStaticClosure (_,fid) -> Hashtbl.replace used_closures fid () | OBytes (_,sid) -> Hashtbl.replace bytes_strings sid () | _ -> () ) f.code ) code.functions; open_file ctx "hl/typedefs.h"; line "// Types definitions"; Array.iter (fun t -> match t with | HObj o -> let name = tname o.pname in expr ("typedef struct _" ^ name ^ " *" ^ name); | HAbstract (name,_) -> expr ("typedef struct _" ^ name ^ " " ^ name); | _ -> () ) all_types; line ""; line "// Types implementation"; Array.iter (fun t -> match t with | HObj o -> let name = tname o.pname in line ("struct _" ^ name ^ " {"); block ctx; let rec loop o = (match o.psuper with | None -> expr ("hl_type *$type"); | Some c -> loop c); Array.iteri (fun i (n,_,t) -> let rec abs_index p v = match p with | None -> v | Some o -> abs_index o.psuper (Array.length o.pfields + v) in expr (var_type (if n = "" then unamed_field (abs_index o.psuper i) else n) t) ) o.pfields; in loop o; unblock ctx; expr "}"; | HEnum e -> Array.iteri (fun i (_,_,pl) -> if Array.length pl <> 0 then begin line ("typedef struct {"); block ctx; expr "int index"; Array.iteri (fun i t -> expr (var_type ("p" ^ string_of_int i) t) ) pl; unblock ctx; sexpr "} %s" (enum_constr_type ctx e i); end; ) e.efields | _ -> () ) all_types; open_file ctx "hl/types.h"; line "// Types values declaration"; Array.iteri (fun i t -> sexpr "extern hl_type type$%d" i; match t with | HObj o -> sline "#define %s__val &type$%d" (tname o.pname) i | _ -> () ) all_types; line ""; sexpr "void hl_init_types( hl_module_context *ctx )"; open_file ctx "hl/natives.h"; line "// Natives functions"; let native_libs = Hashtbl.create 0 in Array.iter (fun (lib,name,t,idx) -> match t with | HFun (args,t) -> let fname = let lib = code.strings.(lib) in Hashtbl.replace native_libs lib (); let lib = if lib = "std" then "hl" else lib in lib ^ "_" ^ code.strings.(name) in sexpr "HL_API %s %s(%s)" (ctype t) fname (String.concat "," (List.map ctype args)); let ft = ctx.ftable.(idx) in ft.fe_name <- fname; ft.fe_args <- args; ft.fe_ret <- t; | _ -> assert false ) code.natives; open_file ctx "hl/functions.h"; line "// Functions declaration"; Array.iter (fun f -> match f.ftype with | HFun (args,t) -> let fname = String.concat "_" (ExtString.String.nsplit (fundecl_name f) ".") in sexpr "%s %s(%s)" (ctype t) fname (String.concat "," (List.map ctype args)); let ft = ctx.ftable.(f.findex) in ft.fe_name <- fname; ft.fe_args <- args; ft.fe_ret <- t; ft.fe_decl <- Some f; | _ -> assert false ) code.functions; line ""; sexpr "extern void *hl_functions_ptrs[]"; sexpr "extern hl_type *hl_functions_types[]"; open_file ctx "hl/globals.h"; line "// Globals"; Array.iteri (fun i t -> let name = "global$" ^ string_of_int i in sexpr "extern %s" (var_type name t) ) code.globals; Array.iteri (fun i str -> if Hashtbl.mem bytes_strings i then sexpr "extern vbyte bytes$%d[]" i else if String.length str >= string_data_limit then sexpr "vbyte string$%d[]" i ) code.strings; Hashtbl.iter (fun fid _ -> sexpr "extern vclosure cl$%d" fid) used_closures; line ""; sexpr "void hl_init_roots()"; open_file ctx "hl/globals.c"; line "#include "; line "// Globals"; Array.iteri (fun i t -> let name = "global$" ^ string_of_int i in sexpr "%s = 0" (var_type name t) ) code.globals; line ""; line "void hl_init_roots() {"; block ctx; Array.iteri (fun i t -> if is_ptr t then sexpr "hl_add_root((void**)&global$%d)" i; ) code.globals; unblock ctx; line "}"; Array.iteri (fun i str -> let rec loop s i = if i = String.length s then [] else let c = String.get s i in string_of_int (int_of_char c) :: loop s (i+1) in if Hashtbl.mem bytes_strings i then sexpr "vbyte bytes$%d[] = {%s}" i (String.concat "," (loop str 0)) else if String.length str >= string_data_limit then let s = utf8_to_utf16 str in sline "// %s..." (String.escaped (String.sub str 0 (string_data_limit-4))); sexpr "vbyte string$%d[] = {%s}" i (String.concat "," (loop s 0)) ) code.strings; Hashtbl.iter (fun fid _ -> let ft = ctx.ftable.(fid) in sexpr "vclosure cl$%d = { %s, %s, 0 }" fid (type_value ctx (HFun (ft.fe_args,ft.fe_ret))) ft.fe_name ) used_closures; open_file ctx "hl/types.c"; line "#include "; line "// Types values"; Array.iteri (fun i t -> sexpr "hl_type type$%d = { %s } /* %s */" i (type_id t) (tstr t); ) all_types; line ""; line "// Types values data"; Array.iteri (fun i t -> let field_value (_,name_id,t) = sprintf "{(const uchar*)%s, %s, %ld}" (string ctx name_id) (type_value ctx t) (hash ctx name_id) in match t with | HObj o -> let proto_value p = sprintf "{(const uchar*)%s, %d, %d, %ld}" (string ctx p.fid) p.fmethod (match p.fvirtual with None -> -1 | Some i -> i) (hash ctx p.fid) in let fields = if Array.length o.pfields = 0 then "NULL" else let name = sprintf "fields$%d" i in sexpr "static hl_obj_field %s[] = {%s}" name (String.concat "," (List.map field_value (Array.to_list o.pfields))); name in let proto = if Array.length o.pproto = 0 then "NULL" else let name = sprintf "proto$%d" i in sexpr "static hl_obj_proto %s[] = {%s}" name (String.concat "," (List.map proto_value (Array.to_list o.pproto))); name in let bindings = if o.pbindings = [] then "NULL" else let name = sprintf "bindings$%d" i in sexpr "static int %s[] = {%s}" name (String.concat "," (List.map (fun (fid,fidx) -> string_of_int fid ^ "," ^ string_of_int fidx) o.pbindings)); name in let ofields = [ string_of_int (Array.length o.pfields); string_of_int (Array.length o.pproto); string_of_int (List.length o.pbindings); sprintf "(const uchar*)%s" (string ctx o.pid); (match o.psuper with None -> "NULL" | Some c -> sprintf "%s__val" (tname c.pname)); fields; proto; bindings ] in sexpr "static hl_type_obj obj$%d = {%s}" i (String.concat "," ofields); | HEnum e -> let constr_name = sprintf "econstructs$%d" i in let constr_value cid (name,nid,tl) = let tval = if Array.length tl = 0 then "NULL" else let name = sprintf "econstruct$%d_%d" i cid in sexpr "static hl_type *%s[] = {%s}" name (String.concat "," (List.map (type_value ctx) (Array.to_list tl))); name in let size = if Array.length tl = 0 then "0" else sprintf "sizeof(%s)" (enum_constr_type ctx e cid) in let offsets = if Array.length tl = 0 then "NULL" else let name = sprintf "eoffsets$%d_%d" i cid in sexpr "static int %s[] = {%s}" name (String.concat "," (List.map (fun _ -> "0") (Array.to_list tl))); name in let has_ptr = List.exists is_gc_ptr (Array.to_list tl) in sprintf "{(const uchar*)%s, %d, %s, %s, %s, %s}" (string ctx nid) (Array.length tl) tval size (if has_ptr then "true" else "false") offsets in sexpr "static hl_enum_construct %s[] = {%s}" constr_name (String.concat "," (Array.to_list (Array.mapi constr_value e.efields))); let efields = [ if e.eid = 0 then "NULL" else sprintf "(const uchar*)%s" (string ctx e.eid); string_of_int (Array.length e.efields); constr_name ] in sexpr "static hl_type_enum enum$%d = {%s}" i (String.concat "," efields); | HVirtual v -> let fields_name = if Array.length v.vfields = 0 then "NULL" else let name = sprintf "vfields$%d" i in sexpr "static hl_obj_field %s[] = {%s}" name (String.concat "," (List.map field_value (Array.to_list v.vfields))); name in let vfields = [ fields_name; string_of_int (Array.length v.vfields) ] in sexpr "static hl_type_virtual virt$%d = {%s}" i (String.concat "," vfields); | HFun (args,t) -> let aname = if args = [] then "NULL" else let name = sprintf "fargs$%d" i in sexpr "static hl_type *%s[] = {%s}" name (String.concat "," (List.map (type_value ctx) args)); name in sexpr "static hl_type_fun tfun$%d = {%s,%s,%d}" i aname (type_value ctx t) (List.length args) | _ -> () ) all_types; line ""; line "void hl_init_types( hl_module_context *ctx ) {"; block ctx; Array.iteri (fun i t -> match t with | HObj o -> sexpr "obj$%d.m = ctx" i; (match o.pclassglobal with None -> () | Some g -> sexpr "obj$%d.global_value = (void**)&global$%d" i g); sexpr "type$%d.obj = &obj$%d" i i | HNull t | HRef t -> sexpr "type$%d.tparam = %s" i (type_value ctx t) | HEnum e -> sexpr "type$%d.tenum = &enum$%d" i i; (match e.eglobal with None -> () | Some g -> sexpr "enum$%d.global_value = (void**)&global$%d" i g); sexpr "hl_init_enum(&type$%d)" i; | HVirtual _ -> sexpr "type$%d.virt = &virt$%d" i i; sexpr "hl_init_virtual(&type$%d,ctx)" i; | HFun _ -> sexpr "type$%d.fun = &tfun$%d" i i | _ -> () ) all_types; unblock ctx; line "}"; open_file ctx "hl/reflect.c"; line "#include "; line "// Reflection helpers"; generate_reflection ctx; let gen_functions = Hashtbl.create 0 in let all_protos = Hashtbl.create 0 in Array.iter (fun t -> match t with | HObj o -> Hashtbl.add all_protos o.pname o | _ -> () ) all_types; Array.iter (fun t -> match t with | HObj o when Hashtbl.mem all_protos o.pname -> let file = ref false in let base_name, path = match List.rev (ExtString.String.nsplit o.pname ".") with | [] -> assert false | name :: acc -> (if name.[0] = '$' then String.sub name 1 (String.length name - 1) else name), List.rev acc in let generate fid = match ctx.ftable.(fid).fe_decl with | None -> () | Some f -> if not !file then begin file := true; let path = path @ [base_name] in let path = List.map (fun n -> if String.length n > 128 then Digest.to_hex (Digest.string n) else n) path in let path = (match path with [name] -> ["_std";name] | _ -> path) in open_file ctx (String.concat "/" path ^ ".c"); line "#include "; line ""; end; Hashtbl.replace gen_functions f.findex (); generate_function ctx f in let gen_proto name = try let full_name = String.concat "." (path @ [name]) in let o = Hashtbl.find all_protos full_name in Array.iter (fun p -> generate p.fmethod) o.pproto; List.iter (fun (_,mid) -> generate mid) o.pbindings; Hashtbl.remove all_protos full_name; with Not_found -> () in gen_proto base_name; gen_proto ("$" ^ base_name); | _ -> () ) all_types; open_file ctx "hl/functions.c"; line "#include "; line ""; sexpr "void *hl_functions_ptrs[] = {%s}" (String.concat "," (List.map (fun f -> f.fe_name) (Array.to_list ctx.ftable))); let rec loop i = if i = Array.length ctx.ftable then [] else let ft = ctx.ftable.(i) in (type_value ctx (HFun (ft.fe_args,ft.fe_ret))) :: loop (i + 1) in sexpr "hl_type *hl_functions_types[] = {%s}" (String.concat "," (loop 0)); line ""; Array.iter (fun f -> if not (Hashtbl.mem gen_functions f.findex) then generate_function ctx f; ) code.functions; open_file ctx "hl/hashes.c"; line "#include "; line ""; line "void hl_init_hashes() {"; block ctx; Hashtbl.iter (fun i _ -> sexpr "hl_hash((vbyte*)%s)" (string ctx i)) ctx.hash_cache; unblock ctx; line "}"; open_file ctx (Filename.basename file); line "#include "; line "#include "; line ""; line "#ifndef HL_MAKE"; List.iter (sline "# include <%s>") ctx.cfiles; line "#endif"; line ""; expr "void hl_init_hashes()"; line ""; line "// Entry point"; line "void hl_entry_point() {"; block ctx; expr "hl_module_context ctx"; expr "hl_alloc_init(&ctx.alloc)"; expr "ctx.functions_ptrs = hl_functions_ptrs"; expr "ctx.functions_types = hl_functions_types"; expr "hl_init_types(&ctx)"; expr "hl_init_hashes()"; expr "hl_init_roots()"; sexpr "%s()" ctx.ftable.(code.entrypoint).fe_name; unblock ctx; line "}"; line ""; open_file ctx "hlc.json"; line "{"; block ctx; sline "\"version\" : %d," ctx.version; sline "\"libs\" : [%s]," (String.concat "," (Hashtbl.fold (fun k _ acc -> sprintf "\"%s\"" k :: acc) native_libs [])); sline "\"defines\" : {%s\n\t}," (String.concat "," (PMap.foldi (fun k v acc -> sprintf "\n\t\t\"%s\" : \"%s\"" k v :: acc) com.Common.defines [])); sline "\"files\" : [%s\n\t]" (String.concat "," (List.map (sprintf "\n\t\t\"%s\"") ctx.cfiles)); unblock ctx; line "}"; close_file ctx haxe_3.4.4.orig/src/generators/hlcode.ml0000664000175000017500000005413513166552354020154 0ustar andyandy00000000000000(* * Copyright (C)2005-2017 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 reg = int type global = int type 'a index = int type functable type ttype = | HVoid | HUI8 | HUI16 | HI32 | HF32 | HF64 | HBool | HBytes | HDyn | HFun of ttype list * ttype | HObj of class_proto | HArray | HType | HRef of ttype | HVirtual of virtual_proto | HDynObj | HAbstract of string * string index | HEnum of enum_proto | HNull of ttype and class_proto = { pname : string; pid : int; mutable pclassglobal : int option; mutable psuper : class_proto option; mutable pvirtuals : int array; mutable pproto : field_proto array; mutable pnfields : int; mutable pfields : (string * string index * ttype) array; mutable pindex : (string, int * ttype) PMap.t; mutable pfunctions : (string, int) PMap.t; mutable pinterfaces : (ttype, int) PMap.t; mutable pbindings : (int * int) list; } and enum_proto = { ename : string; eid : int; mutable eglobal : int option; mutable efields : (string * string index * ttype array) array; } and field_proto = { fname : string; fid : int; fmethod : functable index; fvirtual : int option; } and virtual_proto = { mutable vfields : (string * string index * ttype) array; mutable vindex : (string, int) PMap.t; } type unused = int type field type opcode = (* register storing *) | OMov of reg * reg | OInt of reg * int index | OFloat of reg * float index | OBool of reg * bool | OBytes of reg * string index | OString of reg * string index | ONull of reg (* binops *) | OAdd of reg * reg * reg | OSub of reg * reg * reg | OMul of reg * reg * reg | OSDiv of reg * reg * reg | OUDiv of reg * reg * reg | OSMod of reg * reg * reg | OUMod of reg * reg * reg | OShl of reg * reg * reg | OSShr of reg * reg * reg | OUShr of reg * reg * reg | OAnd of reg * reg * reg | OOr of reg * reg * reg | OXor of reg * reg * reg (* unops *) | ONeg of reg * reg | ONot of reg * reg | OIncr of reg | ODecr of reg (* calls *) | OCall0 of reg * functable index | OCall1 of reg * functable index * reg | OCall2 of reg * functable index * reg * reg | OCall3 of reg * functable index * reg * reg * reg | OCall4 of reg * functable index * reg * reg * reg * reg | OCallN of reg * functable index * reg list | OCallMethod of reg * field index * reg list | OCallThis of reg * field index * reg list | OCallClosure of reg * reg * reg list (* closures *) | OStaticClosure of reg * functable index (* Class.method *) | OInstanceClosure of reg * functable index * reg (* instance.method *) | OVirtualClosure of reg * reg * field index (* instance.overriddenMethod *) (* field access *) | OGetGlobal of reg * global | OSetGlobal of global * reg | OField of reg * reg * field index | OSetField of reg * field index * reg | OGetThis of reg * field index | OSetThis of field index * reg | ODynGet of reg * reg * string index | ODynSet of reg * string index * reg (* jumps *) | OJTrue of reg * int | OJFalse of reg * int | OJNull of reg * int | OJNotNull of reg * int | OJSLt of reg * reg * int | OJSGte of reg * reg * int | OJSGt of reg * reg * int | OJSLte of reg * reg * int | OJULt of reg * reg * int | OJUGte of reg * reg * int | OJEq of reg * reg * int | OJNotEq of reg * reg * int | OJAlways of int (* coerce *) | OToDyn of reg * reg | OToSFloat of reg * reg | OToUFloat of reg * reg | OToInt of reg * reg | OSafeCast of reg * reg | OUnsafeCast of reg * reg | OToVirtual of reg * reg (* control flow *) | OLabel of unused | ORet of reg | OThrow of reg | ORethrow of reg | OSwitch of reg * int array * int | ONullCheck of reg | OTrap of reg * int | OEndTrap of bool (* memory access *) | OGetUI8 of reg * reg * reg | OGetUI16 of reg * reg * reg | OGetI32 of reg * reg * reg | OGetF32 of reg * reg * reg | OGetF64 of reg * reg * reg | OGetArray of reg * reg * reg | OSetUI8 of reg * reg * reg | OSetUI16 of reg * reg * reg | OSetI32 of reg * reg * reg | OSetF32 of reg * reg * reg | OSetF64 of reg * reg * reg | OSetArray of reg * reg * reg (* type operations *) | ONew of reg | OArraySize of reg * reg | OType of reg * ttype | OGetType of reg * reg | OGetTID of reg * reg (* references *) | ORef of reg * reg | OUnref of reg * reg | OSetref of reg * reg (* enums *) | OMakeEnum of reg * field index * reg list | OEnumAlloc of reg * field index | OEnumIndex of reg * reg | OEnumField of reg * reg * field index * int | OSetEnumField of reg * int * reg (* misc *) | ONop of string type fundecl = { fpath : string * string; findex : functable index; ftype : ttype; regs : ttype array; code : opcode array; debug : (int * int) array; } type code = { version : int; entrypoint : global; strings : string array; ints : int32 array; floats : float array; (* types : ttype array // only in bytecode, rebuilt on save() *) globals : ttype array; natives : (string index * string index * ttype * functable index) array; functions : fundecl array; debugfiles : string array; } let null_proto = { pname = ""; pid = 0; pclassglobal = None; psuper = None; pvirtuals = [||]; pproto = [||]; pfields = [||]; pnfields = 0; pindex = PMap.empty; pfunctions = PMap.empty; pinterfaces = PMap.empty; pbindings = []; } let list_iteri f l = let p = ref (-1) in List.iter (fun v -> incr p; f !p v) l let list_mapi f l = let p = ref (-1) in List.map (fun v -> incr p; f !p v) l (* does the runtime value can be set to null *) let is_nullable t = match t with | HBytes | HDyn | HFun _ | HObj _ | HArray | HVirtual _ | HDynObj | HAbstract _ | HEnum _ | HNull _ | HRef _ -> true | HUI8 | HUI16 | HI32 | HF32 | HF64 | HBool | HVoid | HType -> false let is_int = function | HUI8 | HUI16 | HI32 -> true | _ -> false let is_float = function | HF32 | HF64 -> true | _ -> false let is_number = function | HUI8 | HUI16 | HI32 | HF32 | HF64 -> true | _ -> false (* does the runtime value carry its type *) let is_dynamic t = match t with | HDyn | HFun _ | HObj _ | HArray | HVirtual _ | HDynObj | HNull _ -> true | _ -> false let rec tsame t1 t2 = if t1 == t2 then true else match t1, t2 with | HFun (args1,ret1), HFun (args2,ret2) when List.length args1 = List.length args2 -> List.for_all2 tsame args1 args2 && tsame ret2 ret1 | HObj p1, HObj p2 -> p1 == p2 | HEnum e1, HEnum e2 -> e1 == e2 | HAbstract (_,a1), HAbstract (_,a2) -> a1 == a2 | HVirtual v1, HVirtual v2 -> if v1 == v2 then true else if Array.length v1.vfields <> Array.length v2.vfields then false else let rec loop i = if i = Array.length v1.vfields then true else let _, i1, t1 = v1.vfields.(i) in let _, i2, t2 = v2.vfields.(i) in if i1 = i2 && tsame t1 t2 then loop (i + 1) else false in loop 0 | HNull t1, HNull t2 -> tsame t1 t2 | HRef t1, HRef t2 -> tsame t1 t2 | _ -> false (* can we use a value of t1 as t2 *) let rec safe_cast t1 t2 = if t1 == t2 then true else match t1, t2 with | _, HDyn -> is_dynamic t1 | HVirtual v1, HVirtual v2 when Array.length v2.vfields < Array.length v1.vfields -> let rec loop i = if i = Array.length v2.vfields then true else let n1, _, t1 = v1.vfields.(i) in let n2, _, t2 = v2.vfields.(i) in if n1 = n2 && tsame t1 t2 then loop (i + 1) else false in loop 0 | HObj p1, HObj p2 -> (* allow subtyping *) let rec loop p = p.pname = p2.pname || (match p.psuper with None -> false | Some p -> loop p) in loop p1 | HFun (args1,t1), HFun (args2,t2) when List.length args1 = List.length args2 -> List.for_all2 (fun t1 t2 -> safe_cast t2 t1 || (t1 = HDyn && is_dynamic t2)) args1 args2 && safe_cast t1 t2 | _ -> tsame t1 t2 let hl_hash b = let h = ref Int32.zero in let rec loop i = let c = if i = String.length b then 0 else int_of_char b.[i] in if c <> 0 then begin h := Int32.add (Int32.mul !h 223l) (Int32.of_int c); loop (i + 1) end else Int32.rem !h 0x1FFFFF7Bl in loop 0 let utf16_add buf c = let add c = Buffer.add_char buf (char_of_int (c land 0xFF)); Buffer.add_char buf (char_of_int (c lsr 8)); in if c >= 0 && c < 0x10000 then begin if c >= 0xD800 && c <= 0xDFFF then failwith ("Invalid unicode char " ^ string_of_int c); add c; end else if c < 0x110000 then begin let c = c - 0x10000 in add ((c asr 10) + 0xD800); add ((c land 1023) + 0xDC00); end else failwith ("Invalid unicode char " ^ string_of_int c) let utf8_to_utf16 str = let b = Buffer.create (String.length str * 2) in (try UTF8.iter (fun c -> utf16_add b (UChar.code c)) str with Invalid_argument _ | UChar.Out_of_range -> ()); (* if malformed *) utf16_add b 0; Buffer.contents b let rec get_index name p = try PMap.find name p.pindex with Not_found -> match p.psuper with | None -> raise Not_found | Some p -> get_index name p let resolve_field p fid = let rec loop pl p = let pl = p :: pl in match p.psuper with | None -> let rec fetch id = function | [] -> raise Not_found | p :: pl -> let d = id - Array.length p.pfields in if d < 0 then let name, _, t = p.pfields.(id) in name, t else fetch d pl in fetch fid pl | Some p -> loop pl p in loop [] p let gather_types (code:code) = let types = ref PMap.empty in let arr = DynArray.create() in let rec get_type t = (match t with HObj { psuper = Some p } -> get_type (HObj p) | _ -> ()); if PMap.mem t !types then () else let index = DynArray.length arr in DynArray.add arr t; types := PMap.add t index !types; match t with | HFun (args, ret) -> List.iter get_type args; get_type ret | HObj p -> Array.iter (fun (_,n,t) -> get_type t) p.pfields | HNull t | HRef t -> get_type t | HVirtual v -> Array.iter (fun (_,_,t) -> get_type t) v.vfields | HEnum e -> Array.iter (fun (_,_,tl) -> Array.iter get_type tl) e.efields | _ -> () in List.iter (fun t -> get_type t) [HVoid; HUI8; HUI16; HI32; HF32; HF64; HBool; HType; HDyn]; (* make sure all basic types get lower indexes *) Array.iter (fun g -> get_type g) code.globals; Array.iter (fun (_,_,t,_) -> get_type t) code.natives; Array.iter (fun f -> get_type f.ftype; Array.iter (fun r -> get_type r) f.regs; Array.iter (function | OType (_,t) -> get_type t | _ -> () ) f.code; ) code.functions; DynArray.to_array arr, !types let lookup_type types t = try PMap.find t types with Not_found -> assert false (* --------------------------------------------------------------------------------------------------------------------- *) (* DUMP *) let rec tstr ?(stack=[]) ?(detailed=false) t = match t with | HVoid -> "void" | HUI8 -> "ui8" | HUI16 -> "ui16" | HI32 -> "i32" | HF32 -> "f32" | HF64 -> "f64" | HBool -> "bool" | HBytes -> "bytes" | HDyn -> "dyn" | HFun (args,ret) -> "(" ^ String.concat "," (List.map (tstr ~stack ~detailed) args) ^ "):" ^ tstr ~stack ~detailed ret | HObj o when not detailed -> "#" ^ o.pname | HObj o -> let fields = "{" ^ String.concat "," (List.map (fun(s,_,t) -> s ^ " : " ^ tstr ~detailed:false t) (Array.to_list o.pfields)) ^ "}" in let proto = "{" ^ String.concat "," (List.map (fun p -> (match p.fvirtual with None -> "" | Some _ -> "virtual ") ^ p.fname ^ "@" ^ string_of_int p.fmethod) (Array.to_list o.pproto)) ^ "}" in "#" ^ o.pname ^ "[" ^ (match o.psuper with None -> "" | Some p -> ">" ^ p.pname ^ " ") ^ "fields=" ^ fields ^ " proto=" ^ proto ^ "]" | HArray -> "array" | HType -> "type" | HRef t -> "ref(" ^ tstr t ^ ")" | HVirtual v when List.memq v stack -> "..." | HVirtual v -> "virtual(" ^ String.concat "," (List.map (fun (f,_,t) -> f ^":"^tstr ~stack:(v::stack) t) (Array.to_list v.vfields)) ^ ")" | HDynObj -> "dynobj" | HAbstract (s,_) -> "abstract(" ^ s ^ ")" | HEnum e when e.eid = 0 -> let _,_,fl = e.efields.(0) in "enum(" ^ String.concat "," (List.map tstr (Array.to_list fl)) ^ ")" | HEnum e -> "enum(" ^ e.ename ^ ")" | HNull t -> "null(" ^ tstr t ^ ")" let ostr fstr o = match o with | OMov (a,b) -> Printf.sprintf "mov %d,%d" a b | OInt (r,i) -> Printf.sprintf "int %d,@%d" r i | OFloat (r,i) -> Printf.sprintf "float %d,@%d" r i | OString (r,s) -> Printf.sprintf "string %d,@%d" r s | OBytes (r,s) -> Printf.sprintf "bytes %d,@%d" r s | OBool (r,b) -> if b then Printf.sprintf "true %d" r else Printf.sprintf "false %d" r | ONull r -> Printf.sprintf "null %d" r | OAdd (r,a,b) -> Printf.sprintf "add %d,%d,%d" r a b | OSub (r,a,b) -> Printf.sprintf "sub %d,%d,%d" r a b | OMul (r,a,b) -> Printf.sprintf "mul %d,%d,%d" r a b | OSDiv (r,a,b) -> Printf.sprintf "sdiv %d,%d,%d" r a b | OUDiv (r,a,b) -> Printf.sprintf "udiv %d,%d,%d" r a b | OSMod (r,a,b) -> Printf.sprintf "smod %d,%d,%d" r a b | OUMod (r,a,b) -> Printf.sprintf "umod %d,%d,%d" r a b | OShl (r,a,b) -> Printf.sprintf "shl %d,%d,%d" r a b | OSShr (r,a,b) -> Printf.sprintf "sshr %d,%d,%d" r a b | OUShr (r,a,b) -> Printf.sprintf "ushr %d,%d,%d" r a b | OAnd (r,a,b) -> Printf.sprintf "and %d,%d,%d" r a b | OOr (r,a,b) -> Printf.sprintf "or %d,%d,%d" r a b | OXor (r,a,b) -> Printf.sprintf "xor %d,%d,%d" r a b | ONeg (r,v) -> Printf.sprintf "neg %d,%d" r v | ONot (r,v) -> Printf.sprintf "not %d,%d" r v | OIncr r -> Printf.sprintf "incr %d" r | ODecr r -> Printf.sprintf "decr %d" r | OCall0 (r,g) -> Printf.sprintf "call %d, %s()" r (fstr g) | OCall1 (r,g,a) -> Printf.sprintf "call %d, %s(%d)" r (fstr g) a | OCall2 (r,g,a,b) -> Printf.sprintf "call %d, %s(%d,%d)" r (fstr g) a b | OCall3 (r,g,a,b,c) -> Printf.sprintf "call %d, %s(%d,%d,%d)" r (fstr g) a b c | OCall4 (r,g,a,b,c,d) -> Printf.sprintf "call %d, %s(%d,%d,%d,%d)" r (fstr g) a b c d | OCallN (r,g,rl) -> Printf.sprintf "call %d, %s(%s)" r (fstr g) (String.concat "," (List.map string_of_int rl)) | OCallMethod (r,f,[]) -> "callmethod ???" | OCallMethod (r,f,o :: rl) -> Printf.sprintf "callmethod %d, %d[%d](%s)" r o f (String.concat "," (List.map string_of_int rl)) | OCallClosure (r,f,rl) -> Printf.sprintf "callclosure %d, %d(%s)" r f (String.concat "," (List.map string_of_int rl)) | OCallThis (r,f,rl) -> Printf.sprintf "callthis %d, [%d](%s)" r f (String.concat "," (List.map string_of_int rl)) | OStaticClosure (r,f) -> Printf.sprintf "staticclosure %d, %s" r (fstr f) | OInstanceClosure (r,f,v) -> Printf.sprintf "instanceclosure %d, %s(%d)" r (fstr f) v | OGetGlobal (r,g) -> Printf.sprintf "global %d, %d" r g | OSetGlobal (g,r) -> Printf.sprintf "setglobal %d, %d" g r | ORet r -> Printf.sprintf "ret %d" r | OJTrue (r,d) -> Printf.sprintf "jtrue %d,%d" r d | OJFalse (r,d) -> Printf.sprintf "jfalse %d,%d" r d | OJNull (r,d) -> Printf.sprintf "jnull %d,%d" r d | OJNotNull (r,d) -> Printf.sprintf "jnotnull %d,%d" r d | OJSLt (a,b,i) -> Printf.sprintf "jslt %d,%d,%d" a b i | OJSGte (a,b,i) -> Printf.sprintf "jsgte %d,%d,%d" a b i | OJSGt (r,a,b) -> Printf.sprintf "jsgt %d,%d,%d" r a b | OJSLte (r,a,b) -> Printf.sprintf "jslte %d,%d,%d" r a b | OJULt (a,b,i) -> Printf.sprintf "jult %d,%d,%d" a b i | OJUGte (a,b,i) -> Printf.sprintf "jugte %d,%d,%d" a b i | OJEq (a,b,i) -> Printf.sprintf "jeq %d,%d,%d" a b i | OJNotEq (a,b,i) -> Printf.sprintf "jnoteq %d,%d,%d" a b i | OJAlways d -> Printf.sprintf "jalways %d" d | OToDyn (r,a) -> Printf.sprintf "todyn %d,%d" r a | OToSFloat (r,a) -> Printf.sprintf "tosfloat %d,%d" r a | OToUFloat (r,a) -> Printf.sprintf "toufloat %d,%d" r a | OToInt (r,a) -> Printf.sprintf "toint %d,%d" r a | OLabel _ -> "label" | ONew r -> Printf.sprintf "new %d" r | OField (r,o,i) -> Printf.sprintf "field %d,%d[%d]" r o i | OVirtualClosure (r,o,m) -> Printf.sprintf "virtualclosure %d,%d[%d]" r o m | OSetField (o,i,r) -> Printf.sprintf "setfield %d[%d],%d" o i r | OGetThis (r,i) -> Printf.sprintf "getthis %d,[%d]" r i | OSetThis (i,r) -> Printf.sprintf "setthis [%d],%d" i r | OThrow r -> Printf.sprintf "throw %d" r | ORethrow r -> Printf.sprintf "rethrow %d" r | OGetUI8 (r,b,p) -> Printf.sprintf "getui8 %d,%d[%d]" r b p | OGetUI16 (r,b,p) -> Printf.sprintf "getui16 %d,%d[%d]" r b p | OGetI32 (r,b,p) -> Printf.sprintf "geti32 %d,%d[%d]" r b p | OGetF32 (r,b,p) -> Printf.sprintf "getf32 %d,%d[%d]" r b p | OGetF64 (r,b,p) -> Printf.sprintf "getf64 %d,%d[%d]" r b p | OGetArray (r,a,i) -> Printf.sprintf "getarray %d,%d[%d]" r a i | OSetUI8 (r,p,v) -> Printf.sprintf "setui8 %d,%d,%d" r p v | OSetUI16 (r,p,v) -> Printf.sprintf "setui16 %d,%d,%d" r p v | OSetI32 (r,p,v) -> Printf.sprintf "seti32 %d,%d,%d" r p v | OSetF32 (r,p,v) -> Printf.sprintf "setf32 %d,%d,%d" r p v | OSetF64 (r,p,v) -> Printf.sprintf "setf64 %d,%d,%d" r p v | OSetArray (a,i,v) -> Printf.sprintf "setarray %d[%d],%d" a i v | OSafeCast (r,v) -> Printf.sprintf "safecast %d,%d" r v | OUnsafeCast (r,v) -> Printf.sprintf "unsafecast %d,%d" r v | OArraySize (r,a) -> Printf.sprintf "arraysize %d,%d" r a | OType (r,t) -> Printf.sprintf "type %d,%s" r (tstr t) | OGetType (r,v) -> Printf.sprintf "gettype %d,%d" r v | OGetTID (r,v) -> Printf.sprintf "gettid %d,%d" r v | ORef (r,v) -> Printf.sprintf "ref %d,&%d" r v | OUnref (v,r) -> Printf.sprintf "unref %d,*%d" v r | OSetref (r,v) -> Printf.sprintf "setref *%d,%d" r v | OToVirtual (r,v) -> Printf.sprintf "tovirtual %d,%d" r v | ODynGet (r,o,f) -> Printf.sprintf "dynget %d,%d[@%d]" r o f | ODynSet (o,f,v) -> Printf.sprintf "dynset %d[@%d],%d" o f v | OMakeEnum (r,e,pl) -> Printf.sprintf "makeenum %d, %d(%s)" r e (String.concat "," (List.map string_of_int pl)) | OEnumAlloc (r,e) -> Printf.sprintf "enumalloc %d, %d" r e | OEnumIndex (r,e) -> Printf.sprintf "enumindex %d, %d" r e | OEnumField (r,e,i,n) -> Printf.sprintf "enumfield %d, %d[%d:%d]" r e i n | OSetEnumField (e,i,r) -> Printf.sprintf "setenumfield %d[%d], %d" e i r | OSwitch (r,idx,eend) -> Printf.sprintf "switch %d [%s] %d" r (String.concat "," (Array.to_list (Array.map string_of_int idx))) eend | ONullCheck r -> Printf.sprintf "nullcheck %d" r | OTrap (r,i) -> Printf.sprintf "trap %d, %d" r i | OEndTrap b -> Printf.sprintf "endtrap %b" b | ONop s -> if s = "" then "nop" else "nop " ^ s let fundecl_name f = if snd f.fpath = "" then "fun$" ^ (string_of_int f.findex) else (fst f.fpath) ^ "." ^ (snd f.fpath) let dump pr code = let all_protos = Hashtbl.create 0 in let funnames = Hashtbl.create 0 in let tstr t = (match t with | HObj p -> Hashtbl.replace all_protos p.pname p | _ -> ()); tstr t in let str idx = try code.strings.(idx) with _ -> "INVALID:" ^ string_of_int idx in let fstr fid = try Hashtbl.find funnames fid with _ -> Printf.sprintf "f@%X" fid in let debug_infos (fid,line) = (try code.debugfiles.(fid) with _ -> "???") ^ ":" ^ string_of_int line in pr ("hl v" ^ string_of_int code.version); pr ("entry @" ^ string_of_int code.entrypoint); pr (string_of_int (Array.length code.strings) ^ " strings"); Array.iteri (fun i s -> pr (" @" ^ string_of_int i ^ " : " ^ String.escaped s); ) code.strings; pr (string_of_int (Array.length code.ints) ^ " ints"); Array.iteri (fun i v -> pr (" @" ^ string_of_int i ^ " : " ^ Int32.to_string v); ) code.ints; pr (string_of_int (Array.length code.floats) ^ " floats"); Array.iteri (fun i f -> pr (" @" ^ string_of_int i ^ " : " ^ string_of_float f); ) code.floats; pr (string_of_int (Array.length code.globals) ^ " globals"); Array.iteri (fun i g -> pr (" @" ^ string_of_int i ^ " : " ^ tstr g); ) code.globals; pr (string_of_int (Array.length code.natives) ^ " natives"); Array.iter (fun (lib,name,t,fidx) -> pr (" @" ^ string_of_int fidx ^ " native " ^ str lib ^ "@" ^ str name ^ " " ^ tstr t); Hashtbl.add funnames fidx (str lib ^ "@" ^ str name) ) code.natives; Array.iter (fun f -> Hashtbl.add funnames f.findex (fundecl_name f)) code.functions; pr (string_of_int (Array.length code.functions) ^ " functions"); Array.iter (fun f -> pr (Printf.sprintf " fun@%d(%Xh) %s" f.findex f.findex (tstr f.ftype)); let fid, _ = f.debug.(0) in let cur_fid = ref fid in pr (Printf.sprintf " ; %s (%s)" (debug_infos f.debug.(0)) (fundecl_name f)); Array.iteri (fun i r -> pr (" r" ^ string_of_int i ^ " " ^ tstr r); ) f.regs; Array.iteri (fun i o -> let fid, line = f.debug.(i) in if fid <> !cur_fid then begin cur_fid := fid; pr (Printf.sprintf " ; %s" (debug_infos (fid,line))); end; pr (Printf.sprintf " .%-5d @%X %s" line i (ostr fstr o)) ) f.code; ) code.functions; let protos = Hashtbl.fold (fun _ p acc -> p :: acc) all_protos [] in pr (string_of_int (List.length protos) ^ " objects protos"); List.iter (fun p -> pr (" " ^ p.pname ^ " " ^ (match p.pclassglobal with None -> "no global" | Some i -> "@" ^ string_of_int i)); (match p.psuper with | None -> () | Some p -> pr (" extends " ^ p.pname)); pr (" " ^ string_of_int (Array.length p.pfields) ^ " fields"); let rec loop = function | None -> 0 | Some p -> Array.length p.pfields + loop p.psuper in let start_field = loop p.psuper in Array.iteri (fun i (_,id,t) -> pr (" @" ^ string_of_int (i + start_field) ^ " " ^ str id ^ " " ^ tstr t) ) p.pfields; pr (" " ^ string_of_int (Array.length p.pproto) ^ " methods"); Array.iteri (fun i f -> pr (" @" ^ string_of_int i ^ " " ^ str f.fid ^ " fun@" ^ string_of_int f.fmethod ^ (match f.fvirtual with None -> "" | Some p -> "[" ^ string_of_int p ^ "]")) ) p.pproto; pr (" " ^ string_of_int (List.length p.pbindings) ^ " bindings"); List.iter (fun (i,fidx) -> pr (" @" ^ string_of_int i ^ " fun@" ^ string_of_int fidx) ) p.pbindings; ) protos haxe_3.4.4.orig/src/generators/hlinterp.ml0000664000175000017500000027024013166552354020540 0ustar andyandy00000000000000(* * Copyright (C)2005-2017 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 Unix open Hlcode type value = | VNull | VInt of int32 | VFloat of float | VBool of bool | VDyn of value * ttype | VObj of vobject | VClosure of vfunction * value option | VBytes of string | VArray of value array * ttype | VUndef | VType of ttype | VRef of ref_value * ttype | VVirtual of vvirtual | VDynObj of vdynobj | VEnum of int * value array | VAbstract of vabstract | VVarArgs of vfunction * value option and ref_value = | RStack of int | RValue of value ref and vabstract = | AHashBytes of (string, value) Hashtbl.t | AHashInt of (int32, value) Hashtbl.t | AHashObject of (value * value) list ref | AReg of regexp | ARandom | APos of Globals.pos | ATDecl of Type.module_type | AUnsafe of Obj.t | ALazyType of ((unit -> Type.t) ref) * (unit -> value) and vfunction = | FFun of fundecl | FNativeFun of string * (value list -> value) * ttype and vobject = { oproto : vproto; ofields : value array; } and vproto = { pclass : class_proto; pmethods : vfunction array; } and vvirtual = { vtype : virtual_proto; mutable vindexes : vfield array; mutable vtable : value array; mutable vvalue : value; } and vdynobj = { dfields : (string, int) Hashtbl.t; mutable dtypes : ttype array; mutable dvalues : value array; mutable dvirtuals : vvirtual list; } and vfield = | VFNone | VFIndex of int and regexp = { r : Str.regexp; mutable r_string : string; mutable r_groups : (int * int) option array; } exception Return of value exception Runtime_error of string exception InterpThrow of value exception Sys_exit of int type context = { mutable t_globals : value array; mutable t_functions : vfunction array; mutable call_stack : (fundecl * int ref) list; mutable error_stack : (fundecl * int ref) list; mutable stack : value array; mutable stack_pos : int; mutable fcall : vfunction -> value list -> value; mutable code : code; mutable on_error : value -> (fundecl * int ref) list -> unit; mutable resolve_macro_api : string -> (value list -> value) option; checked : bool; cached_protos : (int, vproto * ttype array * (int * (value -> value)) list) Hashtbl.t; cached_strings : (int, string) Hashtbl.t; cached_hashes : (int32, string) Hashtbl.t; } let default t = match t with | HUI8 | HUI16 | HI32 -> VInt Int32.zero | HF32 | HF64 -> VFloat 0. | HBool -> VBool false | _ -> if is_nullable t then VNull else VUndef let get_type = function | VDyn (_,t) -> Some t | VObj o -> Some (HObj o.oproto.pclass) | VDynObj _ -> Some HDynObj | VVirtual v -> Some (HVirtual v.vtype) | VArray _ -> Some HArray | VClosure (f,None) -> Some (match f with FFun f -> f.ftype | FNativeFun (_,_,t) -> t) | VClosure (f,Some _) -> Some (match f with FFun { ftype = HFun(_::args,ret) } | FNativeFun (_,_,HFun(_::args,ret)) -> HFun (args,ret) | _ -> assert false) | VVarArgs _ -> Some (HFun ([],HDyn)) | _ -> None let v_dynamic = function | VNull | VDyn _ | VObj _ | VClosure _ | VArray _ | VVirtual _ | VDynObj _ | VVarArgs _ -> true | _ -> false let rec is_compatible v t = match v, t with | VInt _, (HUI8 | HUI16 | HI32) -> true | VFloat _, (HF32 | HF64) -> true | VBool _, HBool -> true | _, HVoid -> true | VNull, t -> is_nullable t | VObj o, HObj _ -> safe_cast (HObj o.oproto.pclass) t | VClosure _, HFun _ -> safe_cast (match get_type v with None -> assert false | Some t -> t) t | VBytes _, HBytes -> true | VDyn (_,t1), HNull t2 -> tsame t1 t2 | v, HNull t -> is_compatible v t | v, HDyn -> v_dynamic v | VType _, HType -> true | VArray _, HArray -> true | VDynObj _, HDynObj -> true | VVirtual v, HVirtual _ -> safe_cast (HVirtual v.vtype) t | VRef (_,t1), HRef t2 -> tsame t1 t2 | VAbstract _, HAbstract _ -> true | VEnum _, HEnum _ -> true | _ -> false type cast = | CNo | CDyn of ttype | CUnDyn of ttype | CCast of ttype * ttype let error msg = raise (Runtime_error msg) let get_function ctx f = ctx.t_functions.(f) let rec get_proto ctx p = try Hashtbl.find ctx.cached_protos p.pid with Not_found -> let fields, bindings = (match p.psuper with None -> [||],[] | Some p -> let _, fields, bindings = get_proto ctx p in fields, bindings) in let meths = Array.map (get_function ctx) p.pvirtuals in let fields = Array.append fields (Array.map (fun (_,_,t) -> t) p.pfields) in let bindings = List.fold_left (fun acc (fid,fidx) -> let f = get_function ctx fidx in let ft = (match f with FFun f -> f.ftype | FNativeFun _ -> assert false) in let need_closure = (match ft, fields.(fid) with HFun (args,_), HFun(args2,_) -> List.length args > List.length args2 | HFun _, HDyn -> false | _ -> assert false) in let acc = List.filter (fun (fid2,_) -> fid2 <> fid) acc in (fid, (fun v -> VClosure (f,if need_closure then Some v else None))) :: acc ) bindings p.pbindings in let proto = ({ pclass = p; pmethods = meths },fields,bindings) in Hashtbl.replace ctx.cached_protos p.pid proto; proto let alloc_obj ctx t = match t with | HDynObj -> VDynObj { dfields = Hashtbl.create 0; dvalues = [||]; dtypes = [||]; dvirtuals = []; } | HObj p -> let p, fields, bindings = get_proto ctx p in let ftable = Array.map default fields in let obj = VObj { oproto = p; ofields = ftable } in List.iter (fun (fid,mk) -> ftable.(fid) <- mk obj) bindings; obj | HVirtual v -> let o = { dfields = Hashtbl.create 0; dvalues = Array.map (fun (_,_,t) -> default t) v.vfields; dtypes = Array.map (fun (_,_,t) -> t) v.vfields; dvirtuals = []; } in Array.iteri (fun i (n,_,_) -> Hashtbl.add o.dfields n i) v.vfields; let v = { vtype = v; vvalue = VDynObj o; vtable = o.dvalues; vindexes = Array.mapi (fun i _ -> VFIndex i) v.vfields } in o.dvirtuals <- [v]; VVirtual v | _ -> assert false let float_to_string f = let s = string_of_float f in let len = String.length s in if String.unsafe_get s (len - 1) = '.' then String.sub s 0 (len - 1) else s let rec get_method p name = let m = ref None in Array.iter (fun p -> if p.fname = name then m := Some p.fmethod) p.pproto; match !m , p.psuper with | Some i, _ -> Some i | None, Some s -> get_method s name | None, None -> None let get_to_string ctx p = match get_method p "__string" with | Some f -> (match get_function ctx f with | (FFun { ftype = HFun([_],HBytes) } as f) -> Some f | _ -> None) | None -> None let set_i32 b p v = try String.set b p (char_of_int ((Int32.to_int v) land 0xFF)); String.set b (p+1) (char_of_int ((Int32.to_int (Int32.shift_right_logical v 8)) land 0xFF)); String.set b (p+2) (char_of_int ((Int32.to_int (Int32.shift_right_logical v 16)) land 0xFF)); String.set b (p+3) (char_of_int (Int32.to_int (Int32.shift_right_logical v 24))); with _ -> error "Set outside of bytes bounds" let get_i32 b p = let i = int_of_char (String.get b p) in let j = int_of_char (String.get b (p + 1)) in let k = int_of_char (String.get b (p + 2)) in let l = int_of_char (String.get b (p + 3)) in Int32.logor (Int32.of_int (i lor (j lsl 8) lor (k lsl 16))) (Int32.shift_left (Int32.of_int l) 24) let make_dyn v t = if v = VNull || is_dynamic t then v else VDyn (v,t) let get_ref ctx = function | RStack i -> ctx.stack.(i) | RValue r -> !r let set_ref ctx r v = match r with | RStack i -> ctx.stack.(i) <- v | RValue r -> r := v let fstr = function | FFun f -> "function@" ^ string_of_int f.findex | FNativeFun (s,_,_) -> "native[" ^ s ^ "]" let caml_to_hl str = utf8_to_utf16 str let hash ctx str = let h = hl_hash str in if not (Hashtbl.mem ctx.cached_hashes h) then Hashtbl.add ctx.cached_hashes h (String.sub str 0 (try String.index str '\000' with _ -> String.length str)); h let utf16_iter f s = let get v = int_of_char s.[v] in let rec loop p = if p = String.length s then () else let c = (get p) lor ((get (p+1)) lsl 8) in if c >= 0xD800 && c <= 0xDFFF then begin let c = c - 0xD800 in let c2 = ((get (p+2)) lor ((get(p+3)) lsl 8)) - 0xDC00 in f ((c2 lor (c lsl 10)) + 0x10000); loop (p + 4); end else begin f c; loop (p + 2); end; in loop 0 let utf16_char buf c = utf16_add buf (int_of_char c) let hl_to_caml str = let utf16_eof s = let get v = int_of_char s.[v] in let rec loop p = let c = (get p) lor ((get (p+1)) lsl 8) in if c = 0 then String.sub s 0 p else loop (p + 2); in loop 0 in let b = UTF8.Buf.create (String.length str / 2) in utf16_iter (fun c -> UTF8.Buf.add_char b (UChar.chr c)) (utf16_eof str); UTF8.Buf.contents b let null_access() = error "Null value bypass null pointer check" let throw ctx v = ctx.error_stack <- []; raise (InterpThrow v) let throw_msg ctx msg = throw ctx (VDyn (VBytes (caml_to_hl msg),HBytes)) let rec vstr_d ctx v = let vstr_d = vstr_d ctx in match v with | VNull -> "null" | VInt i -> Int32.to_string i ^ "i" | VFloat f -> string_of_float f ^ "f" | VBool b -> if b then "true" else "false" | VDyn (v,t) -> "dyn(" ^ vstr_d v ^ ":" ^ tstr t ^ ")" | VObj o -> let p = "#" ^ o.oproto.pclass.pname in (match get_to_string ctx o.oproto.pclass with | Some f -> p ^ ":" ^ vstr_d (ctx.fcall f [v]) | None -> p) | VBytes b -> "bytes(" ^ String.escaped b ^ ")" | VClosure (f,o) -> (match o with | None -> fstr f | Some v -> fstr f ^ "[" ^ vstr_d v ^ "]") | VArray (a,t) -> "array<" ^ tstr t ^ ">(" ^ String.concat "," (Array.to_list (Array.map vstr_d a)) ^ ")" | VUndef -> "undef" | VType t -> "type(" ^ tstr t ^ ")" | VRef (r,_) -> "ref(" ^ vstr_d (get_ref ctx r) ^ ")" | VVirtual v -> "virtual(" ^ vstr_d v.vvalue ^ ")" | VDynObj d -> "dynobj(" ^ String.concat "," (Hashtbl.fold (fun f i acc -> (f^":"^vstr_d d.dvalues.(i)) :: acc) d.dfields []) ^ ")" | VEnum (i,vals) -> "enum#" ^ string_of_int i ^ "(" ^ String.concat "," (Array.to_list (Array.map vstr_d vals)) ^ ")" | VAbstract _ -> "abstract" | VVarArgs _ -> "varargs" let rec to_virtual ctx v vp = match v with | VNull -> VNull | VObj o -> let indexes = Array.mapi (fun i (n,_,t) -> try let idx, ft = get_index n o.oproto.pclass in if idx < 0 || not (tsame t ft) then raise Not_found; VFIndex idx with Not_found -> VFNone (* most likely a method *) ) vp.vfields in let v = { vtype = vp; vindexes = indexes; vtable = o.ofields; vvalue = v; } in VVirtual v | VDynObj d -> (try VVirtual (List.find (fun v -> v.vtype == vp) d.dvirtuals) with Not_found -> let indexes = Array.mapi (fun i (n,_,t) -> try let idx = Hashtbl.find d.dfields n in if not (tsame t d.dtypes.(idx)) then raise Not_found; VFIndex idx with Not_found -> VFNone ) vp.vfields in let v = { vtype = vp; vindexes = indexes; vtable = d.dvalues; vvalue = v; } in d.dvirtuals <- v :: d.dvirtuals; VVirtual v ) | VVirtual vd -> if vd.vtype == vp then v else if vd.vvalue = VNull then assert false else to_virtual ctx vd.vvalue vp | _ -> throw_msg ctx ("Invalid ToVirtual " ^ vstr_d ctx v ^ " : " ^ tstr (HVirtual vp)) let rec dyn_cast ctx v t rt = let invalid() = throw_msg ctx ("Can't cast " ^ vstr_d ctx v ^ ":" ^ tstr t ^ " to " ^ tstr rt) in let default() = let v = default rt in if v = VUndef then invalid(); v in if safe_cast t rt then v else if v = VNull then default() else match t, rt with | (HUI8|HUI16|HI32), (HF32|HF64) -> (match v with VInt i -> VFloat (Int32.to_float i) | _ -> assert false) | (HF32|HF64), (HUI8|HUI16|HI32) -> (match v with VFloat f -> VInt (Int32.of_float f) | _ -> assert false) | (HUI8|HUI16|HI32|HF32|HF64), HNull ((HUI8|HUI16|HI32|HF32|HF64) as rt) -> let v = dyn_cast ctx v t rt in VDyn (v,rt) | HBool, HNull HBool -> VDyn (v,HBool) | _, HDyn -> make_dyn v t | _, HRef t2 when t = t2 -> VRef (RValue (ref v),t) | HFun (args1,t1), HFun (args2,t2) when List.length args1 = List.length args2 -> (match v with | VClosure (fn,farg) -> let get_conv t1 t2 = if safe_cast t1 t2 || (t2 = HDyn && is_dynamic t1) then CNo else if t2 = HDyn then CDyn t1 else if t1 = HDyn then CUnDyn t2 else CCast (t1,t2) in let conv = List.map2 get_conv args2 args1 in let rconv = get_conv t1 t2 in let convert v c = match c with | CNo -> v | CDyn t -> make_dyn v t | CUnDyn t -> dyn_cast ctx v HDyn t | CCast (t1,t2) -> dyn_cast ctx v t1 t2 in VClosure (FNativeFun ("~convert",(fun args -> let args = List.map2 convert args conv in let ret = ctx.fcall fn (match farg with None -> args | Some a -> a :: args) in convert ret rconv ),rt),None) | _ -> assert false) | HDyn, HFun (targs,tret) when (match v with VVarArgs _ -> true | _ -> false) -> VClosure (FNativeFun ("~varargs",(fun args -> dyn_call ctx v (List.map2 (fun v t -> (v,t)) args targs) tret ),rt),None) | HDyn, _ -> (match get_type v with | None -> assert false | Some t -> dyn_cast ctx (match v with VDyn (v,_) -> v | _ -> v) t rt) | HNull t, _ -> (match v with | VDyn (v,t) -> dyn_cast ctx v t rt | _ -> assert false) | HObj _, HObj b when safe_cast rt t && (match get_type v with Some t -> safe_cast t rt | None -> assert false) -> (* downcast *) v | (HObj _ | HDynObj | HVirtual _), HVirtual vp -> to_virtual ctx v vp | HVirtual _, _ -> (match v with | VVirtual v -> dyn_cast ctx v.vvalue (match get_type v.vvalue with None -> assert false | Some t -> t) rt | _ -> assert false) | HObj p, _ -> (match get_method p "__cast" with | None -> invalid() | Some f -> if v = VNull then VNull else let ret = ctx.fcall (get_function ctx f) [v;VType rt] in if ret <> VNull && (match get_type ret with None -> assert false | Some vt -> safe_cast vt rt) then ret else invalid()) | _ -> invalid() and dyn_call ctx v args tret = match v with | VClosure (f,a) -> let ft = (match f with FFun f -> f.ftype | FNativeFun (_,_,t) -> t) in let fargs, fret = (match ft with HFun (a,t) -> a, t | _ -> assert false) in let full_args = args and full_fargs = (match a with None -> fargs | Some _ -> List.tl fargs) in let rec loop args fargs = match args, fargs with | [], [] -> [] | _, [] -> throw_msg ctx (Printf.sprintf "Too many arguments (%s) != (%s)" (String.concat "," (List.map (fun (v,_) -> vstr_d ctx v) full_args)) (String.concat "," (List.map tstr full_fargs))) | (v,t) :: args, ft :: fargs -> dyn_cast ctx v t ft :: loop args fargs | [], _ :: fargs -> default ft :: loop args fargs in let vargs = loop args full_fargs in let v = ctx.fcall f (match a with None -> vargs | Some a -> a :: vargs) in dyn_cast ctx v fret tret | VNull -> null_access() | VVarArgs (f,a) -> let arr = VArray (Array.of_list (List.map (fun (v,t) -> make_dyn v t) args),HDyn) in dyn_call ctx (VClosure (f,a)) [arr,HArray] tret | _ -> throw_msg ctx (vstr_d ctx v ^ " cannot be called") let invalid_comparison = 255 let rec dyn_compare ctx a at b bt = if a == b && (match at with HF32 | HF64 -> false | _ -> true) then 0 else let fcompare (a:float) (b:float) = if a = b then 0 else if a > b then 1 else if a < b then -1 else invalid_comparison in match a, b with | VInt a, VInt b -> Int32.compare a b | VInt a, VFloat b -> fcompare (Int32.to_float a) b | VFloat a, VInt b -> fcompare a (Int32.to_float b) | VFloat a, VFloat b -> fcompare a b | VBool a, VBool b -> compare a b | VNull, VNull -> 0 | VType t1, VType t2 -> if tsame t1 t2 then 0 else 1 | VNull, _ -> 1 | _, VNull -> -1 | VObj oa, VObj ob -> if oa == ob then 0 else (match get_method oa.oproto.pclass "__compare" with | None -> invalid_comparison | Some f -> (match ctx.fcall (get_function ctx f) [a;b] with VInt i -> Int32.to_int i | _ -> assert false)); | VDyn (v,t), _ -> dyn_compare ctx v t b bt | _, VDyn (v,t) -> dyn_compare ctx a at v t | VVirtual v, _ -> dyn_compare ctx v.vvalue HDyn b bt | _, VVirtual v -> dyn_compare ctx a at v.vvalue HDyn | _ -> invalid_comparison let rec dyn_get_field ctx obj field rt = let get_with v t = dyn_cast ctx v t rt in match obj with | VDynObj d -> (try let idx = Hashtbl.find d.dfields field in get_with d.dvalues.(idx) d.dtypes.(idx) with Not_found -> default rt) | VObj o -> let default rt = match get_method o.oproto.pclass "__get_field" with | None -> default rt | Some f -> get_with (ctx.fcall (get_function ctx f) [obj; VInt (hash ctx field)]) HDyn in let rec loop p = try let fid = PMap.find field p.pfunctions in (match get_function ctx fid with | FFun fd as f -> get_with (VClosure (f,Some obj)) (match fd.ftype with HFun (_::args,t) -> HFun(args,t) | _ -> assert false) | FNativeFun _ -> assert false) with Not_found -> match p.psuper with | None -> default rt | Some p -> loop p in (try let idx, t = get_index field o.oproto.pclass in if idx < 0 then raise Not_found; get_with o.ofields.(idx) t with Not_found -> loop o.oproto.pclass) | VVirtual vp -> (match vp.vvalue with | VNull -> (try let idx = PMap.find field vp.vtype.vindex in match vp.vindexes.(idx) with | VFNone -> VNull | VFIndex i -> vp.vtable.(i) with Not_found -> VNull) | v -> dyn_get_field ctx v field rt) | VNull -> null_access() | _ -> throw_msg ctx "Invalid object access" let rebuild_virtuals ctx d = let old = d.dvirtuals in d.dvirtuals <- []; List.iter (fun v -> let v2 = (match to_virtual ctx (VDynObj d) v.vtype with VVirtual v -> v | _ -> assert false) in v.vindexes <- v2.vindexes; v.vtable <- d.dvalues; ) old; d.dvirtuals <- old let rec dyn_set_field ctx obj field v vt = let v, vt = (match vt with | HDyn -> (match get_type v with | None -> if v = VNull then VNull, HDyn else assert false | Some t -> (match v with VDyn (v,_) -> v | _ -> v), t) | t -> v, t ) in match obj with | VDynObj d -> (try let idx = Hashtbl.find d.dfields field in d.dvalues.(idx) <- v; if not (tsame d.dtypes.(idx) vt) then begin d.dtypes.(idx) <- vt; rebuild_virtuals ctx d; end; with Not_found -> let idx = Array.length d.dvalues in Hashtbl.add d.dfields field idx; let vals2 = Array.make (idx + 1) VNull in let types2 = Array.make (idx + 1) HVoid in Array.blit d.dvalues 0 vals2 0 idx; Array.blit d.dtypes 0 types2 0 idx; vals2.(idx) <- v; types2.(idx) <- vt; d.dvalues <- vals2; d.dtypes <- types2; rebuild_virtuals ctx d; ) | VObj o -> (try let idx, t = get_index field o.oproto.pclass in if idx < 0 then raise Not_found; o.ofields.(idx) <- dyn_cast ctx v vt t with Not_found -> throw_msg ctx (o.oproto.pclass.pname ^ " has no field " ^ field)) | VVirtual vp -> dyn_set_field ctx vp.vvalue field v vt | VNull -> null_access() | _ -> throw_msg ctx "Invalid object access" let make_stack ctx (f,pos) = let pos = !pos - 1 in try let fid, line = f.debug.(pos) in ctx.code.debugfiles.(fid), line with _ -> "???", 0 let stack_frame ctx (f,pos) = let file, line = make_stack ctx (f,pos) in Printf.sprintf "%s:%d: Called from fun@%d @x%X" file line f.findex (!pos - 1) let virt_make_val v = let hfields = Hashtbl.create 0 in let ftypes = DynArray.create() in let values = DynArray.create() in Array.iteri (fun i idx -> match idx with | VFNone -> () | VFIndex k -> let n, _, t = v.vtype.vfields.(i) in Hashtbl.add hfields n (DynArray.length values); DynArray.add values v.vtable.(k); DynArray.add ftypes t; ) v.vindexes; VDynObj { dfields = hfields; dtypes = DynArray.to_array ftypes; dvalues = DynArray.to_array values; dvirtuals = [v]; } let rec vstr ctx v t = let vstr = vstr ctx in match v with | VNull -> "null" | VInt i -> Int32.to_string i | VFloat f -> float_to_string f | VBool b -> if b then "true" else "false" | VDyn (v,t) -> vstr v t | VObj o -> (match get_to_string ctx o.oproto.pclass with | None -> "#" ^ o.oproto.pclass.pname | Some f -> vstr (ctx.fcall f [v]) HBytes) | VBytes b -> (try hl_to_caml b with _ -> "?" ^ String.escaped b) | VClosure (f,_) -> fstr f | VArray (a,t) -> "[" ^ String.concat ", " (Array.to_list (Array.map (fun v -> vstr v t) a)) ^ "]" | VUndef -> "undef" | VType t -> tstr t | VRef (r,t) -> "*" ^ (vstr (get_ref ctx r) t) | VVirtual v -> (match v.vvalue with | VNull -> vstr (virt_make_val v) HDyn | _ -> vstr v.vvalue HDyn) | VDynObj d -> (try let fid = Hashtbl.find d.dfields "__string" in (match d.dtypes.(fid) with HFun ([],HBytes) -> () | _ -> raise Not_found); vstr (dyn_call ctx d.dvalues.(fid) [] HBytes) HBytes with Not_found -> "{" ^ String.concat ", " (Hashtbl.fold (fun f i acc -> (f^":"^vstr d.dvalues.(i) d.dtypes.(i)) :: acc) d.dfields []) ^ "}") | VAbstract _ -> "abstract" | VEnum (i,vals) -> (match t with | HEnum e -> let n, _, pl = e.efields.(i) in if Array.length pl = 0 then n else let rec loop i = if i = Array.length pl then [] else let v = vals.(i) in vstr v pl.(i) :: loop (i + 1) in n ^ "(" ^ String.concat "," (loop 0) ^ ")" | _ -> assert false) | VVarArgs _ -> "varargs" let interp ctx f args = let func = get_function ctx in let spos = ctx.stack_pos in if spos + Array.length f.regs > Array.length ctx.stack then begin let nsize = spos + Array.length f.regs + 256 in let nstack = Array.make nsize VUndef in Array.blit ctx.stack 0 nstack 0 ctx.stack_pos; ctx.stack <- nstack; end; if ctx.checked then for i = 0 to Array.length f.regs - 1 do ctx.stack.(i + spos) <- VUndef; done; ctx.stack_pos <- spos + Array.length f.regs; let pos = ref 1 in ctx.call_stack <- (f,pos) :: ctx.call_stack; let fret = (match f.ftype with | HFun (fargs,fret) -> if ctx.checked && List.length fargs <> List.length args then error (Printf.sprintf "Invalid args: (%s) should be (%s)" (String.concat "," (List.map (vstr_d ctx) args)) (String.concat "," (List.map tstr fargs))); fret | _ -> assert false ) in let fcall = ctx.fcall in let rtype i = Array.unsafe_get f.regs i in let check v t id = if ctx.checked && not (is_compatible v t) then error (Printf.sprintf "Can't set %s(%s) with %s" (id()) (tstr t) (vstr_d ctx v)) in let cached_string idx = try Hashtbl.find ctx.cached_strings idx with Not_found -> let s = caml_to_hl ctx.code.strings.(idx) in Hashtbl.add ctx.cached_strings idx s; s in let check_obj v o fid = if ctx.checked then match o with | VObj o -> let _, fields, _ = get_proto ctx o.oproto.pclass in check v fields.(fid) (fun() -> "obj field") | VVirtual vp -> let _,_, t = vp.vtype.vfields.(fid) in check v t (fun() -> "virtual field") | _ -> () in let set r v = check v (rtype r) (fun() -> "register " ^ string_of_int r); Array.unsafe_set ctx.stack (r + spos) v in list_iteri set args; let get r = Array.unsafe_get ctx.stack (r + spos) in let global g = Array.unsafe_get ctx.t_globals g in let traps = ref [] in let numop iop fop a b = match rtype a with (* todo : sign-extend and mask after result for HUI8/16 *) | HUI8 | HUI16 | HI32 -> (match get a, get b with | VInt a, VInt b -> VInt (iop a b) | _ -> assert false) | HF32 | HF64 -> (match get a, get b with | VFloat a, VFloat b -> VFloat (fop a b) | _ -> assert false) | _ -> assert false in let iop f a b = match rtype a with (* todo : sign-extend and mask after result for HUI8/16 *) | HUI8 | HUI16 | HI32 -> (match get a, get b with | VInt a, VInt b -> VInt (f a b) | _ -> assert false) | _ -> assert false in let iunop iop r = match rtype r with | HUI8 | HUI16 | HI32 -> (match get r with | VInt a -> VInt (iop a) | _ -> assert false) | _ -> assert false in let ucompare a b = match a, b with | VInt a, VInt b -> let d = Int32.sub (Int32.shift_right_logical a 16) (Int32.shift_right_logical b 16) in Int32.to_int (if d = 0l then Int32.sub (Int32.logand a 0xFFFFl) (Int32.logand b 0xFFFFl) else d) | _ -> assert false in let vcompare ra rb op = let a = get ra in let b = get rb in let t = rtype ra in let r = dyn_compare ctx a t b t in if r = invalid_comparison then false else op r 0 in let ufloat v = if v < 0l then Int32.to_float v +. 4294967296. else Int32.to_float v in let rec loop() = let op = Array.unsafe_get f.code (!pos) in incr pos; (match op with | OMov (a,b) -> set a (get b) | OInt (r,i) -> set r (VInt ctx.code.ints.(i)) | OFloat (r,i) -> set r (VFloat (Array.unsafe_get ctx.code.floats i)) | OString (r,s) -> set r (VBytes (cached_string s)) | OBytes (r,s) -> set r (VBytes (ctx.code.strings.(s) ^ "\x00")) | OBool (r,b) -> set r (VBool b) | ONull r -> set r VNull | OAdd (r,a,b) -> set r (numop Int32.add ( +. ) a b) | OSub (r,a,b) -> set r (numop Int32.sub ( -. ) a b) | OMul (r,a,b) -> set r (numop Int32.mul ( *. ) a b) | OSDiv (r,a,b) -> set r (numop (fun a b -> if b = 0l then 0l else Int32.div a b) ( /. ) a b) | OUDiv (r,a,b) -> set r (iop (fun a b -> if b = 0l then 0l else Int32.of_float ((ufloat a) /. (ufloat b))) a b) | OSMod (r,a,b) -> set r (numop (fun a b -> if b = 0l then 0l else Int32.rem a b) mod_float a b) | OUMod (r,a,b) -> set r (iop (fun a b -> if b = 0l then 0l else Int32.of_float (mod_float (ufloat a) (ufloat b))) a b) | OShl (r,a,b) -> set r (iop (fun a b -> Int32.shift_left a (Int32.to_int b)) a b) | OSShr (r,a,b) -> set r (iop (fun a b -> Int32.shift_right a (Int32.to_int b)) a b) | OUShr (r,a,b) -> set r (iop (fun a b -> Int32.shift_right_logical a (Int32.to_int b)) a b) | OAnd (r,a,b) -> set r (iop Int32.logand a b) | OOr (r,a,b) -> set r (iop Int32.logor a b) | OXor (r,a,b) -> set r (iop Int32.logxor a b) | ONeg (r,v) -> set r (match get v with VInt v -> VInt (Int32.neg v) | VFloat f -> VFloat (-. f) | _ -> assert false) | ONot (r,v) -> set r (match get v with VBool b -> VBool (not b) | _ -> assert false) | OIncr r -> set r (iunop (fun i -> Int32.add i 1l) r) | ODecr r -> set r (iunop (fun i -> Int32.sub i 1l) r) | OCall0 (r,f) -> set r (fcall (func f) []) | OCall1 (r,f,r1) -> set r (fcall (func f) [get r1]) | OCall2 (r,f,r1,r2) -> set r (fcall (func f) [get r1;get r2]) | OCall3 (r,f,r1,r2,r3) -> set r (fcall (func f) [get r1;get r2;get r3]) | OCall4 (r,f,r1,r2,r3,r4) -> set r (fcall (func f) [get r1;get r2;get r3;get r4]) | OCallN (r,f,rl) -> set r (fcall (func f) (List.map get rl)) | OGetGlobal (r,g) -> set r (global g) | OSetGlobal (g,r) -> let v = get r in check v ctx.code.globals.(g) (fun() -> "global " ^ string_of_int g); Array.unsafe_set ctx.t_globals g v | OJTrue (r,i) -> if get r = VBool true then pos := !pos + i | OJFalse (r,i) -> if get r = VBool false then pos := !pos + i | ORet r -> raise (Return (get r)) | OJNull (r,i) -> if get r == VNull then pos := !pos + i | OJNotNull (r,i) -> if get r != VNull then pos := !pos + i | OJSLt (a,b,i) -> if vcompare a b (<) then pos := !pos + i | OJSGte (a,b,i) -> if vcompare a b (>=) then pos := !pos + i | OJSGt (a,b,i) -> if vcompare a b (>) then pos := !pos + i | OJSLte (a,b,i) -> if vcompare a b (<=) then pos := !pos + i | OJULt (a,b,i) -> if ucompare (get a) (get b) < 0 then pos := !pos + i | OJUGte (a,b,i) -> if ucompare (get a) (get b) >= 0 then pos := !pos + i | OJEq (a,b,i) -> if vcompare a b (=) then pos := !pos + i | OJNotEq (a,b,i) -> if not (vcompare a b (=)) then pos := !pos + i | OJAlways i -> pos := !pos + i | OToDyn (r,a) -> set r (make_dyn (get a) f.regs.(a)) | OToSFloat (r,a) -> set r (match get a with VInt v -> VFloat (Int32.to_float v) | VFloat _ as v -> v | _ -> assert false) | OToUFloat (r,a) -> set r (match get a with VInt v -> VFloat (ufloat v) | VFloat _ as v -> v | _ -> assert false) | OToInt (r,a) -> set r (match get a with VFloat v -> VInt (Int32.of_float v) | VInt _ as v -> v | _ -> assert false) | OLabel _ -> () | ONew r -> set r (alloc_obj ctx (rtype r)) | OField (r,o,fid) -> set r (match get o with | VObj v -> v.ofields.(fid) | VVirtual v as obj -> (match v.vindexes.(fid) with | VFNone -> dyn_get_field ctx obj (let n,_,_ = v.vtype.vfields.(fid) in n) (rtype r) | VFIndex i -> v.vtable.(i)) | VNull -> null_access() | _ -> assert false) | OSetField (o,fid,r) -> let rv = get r in let o = get o in (match o with | VObj v -> check_obj rv o fid; v.ofields.(fid) <- rv | VVirtual v -> (match v.vindexes.(fid) with | VFNone -> dyn_set_field ctx o (let n,_,_ = v.vtype.vfields.(fid) in n) rv (rtype r) | VFIndex i -> check_obj rv o fid; v.vtable.(i) <- rv) | VNull -> null_access() | _ -> assert false) | OGetThis (r, fid) -> set r (match get 0 with VObj v -> v.ofields.(fid) | _ -> assert false) | OSetThis (fid, r) -> (match get 0 with | VObj v as o -> let rv = get r in check_obj rv o fid; v.ofields.(fid) <- rv | _ -> assert false) | OCallMethod (r,m,rl) -> (match get (List.hd rl) with | VObj v -> set r (fcall v.oproto.pmethods.(m) (List.map get rl)) | VVirtual v -> let name, _, _ = v.vtype.vfields.(m) in (match v.vvalue with | VObj o as obj -> (try let m = PMap.find name o.oproto.pclass.pfunctions in set r (dyn_call ctx (VClosure (get_function ctx m,Some obj)) (List.map (fun r -> get r, rtype r) (List.tl rl)) (rtype r)) with Not_found -> assert false) | VDynObj _ -> set r (dyn_call ctx v.vvalue (List.map (fun r -> get r, rtype r) (List.tl rl)) (rtype r)) | _ -> assert false) | VNull -> null_access() | _ -> assert false) | OCallThis (r,m,rl) -> (match get 0 with | VObj v as o -> set r (fcall v.oproto.pmethods.(m) (o :: List.map get rl)) | _ -> assert false) | OCallClosure (r,v,rl) -> if rtype v = HDyn then set r (dyn_call ctx (get v) (List.map (fun r -> get r, rtype r) rl) (rtype r)) else (match get v with | VClosure (f,None) -> set r (fcall f (List.map get rl)) | VClosure (f,Some arg) -> set r (fcall f (arg :: List.map get rl)) | VNull -> null_access() | _ -> throw_msg ctx (vstr_d ctx (get v))) | OStaticClosure (r, fid) -> let f = get_function ctx fid in set r (VClosure (f,None)) | OInstanceClosure (r, fid, v) -> let f = get_function ctx fid in set r (VClosure (f,Some (get v))) | OVirtualClosure (r, o, m) -> let m = (match get o with | VObj v as obj -> VClosure (v.oproto.pmethods.(m), Some obj) | VNull -> null_access() | VVirtual v -> let name, _, _ = v.vtype.vfields.(m) in (match v.vvalue with | VObj o as obj -> (try let m = PMap.find name o.oproto.pclass.pfunctions in VClosure (get_function ctx m, Some obj) with Not_found -> VNull) | _ -> assert false) | _ -> assert false ) in set r (if m = VNull then m else dyn_cast ctx m (match get_type m with None -> assert false | Some v -> v) (rtype r)) | OThrow r -> throw ctx (get r) | ORethrow r -> ctx.call_stack <- List.rev ctx.error_stack @ ctx.call_stack; throw ctx (get r) | OGetUI8 (r,b,p) -> (match get b, get p with | VBytes b, VInt p -> set r (VInt (Int32.of_int (int_of_char (String.get b (Int32.to_int p))))) | _ -> assert false) | OGetUI16 (r,b,p) -> (match get b, get p with | VBytes b, VInt p -> let a = int_of_char (String.get b (Int32.to_int p)) in let b = int_of_char (String.get b (Int32.to_int p + 1)) in set r (VInt (Int32.of_int (a lor (b lsl 8)))) | _ -> assert false) | OGetI32 (r,b,p) -> (match get b, get p with | VBytes b, VInt p -> set r (VInt (get_i32 b (Int32.to_int p))) | _ -> assert false) | OGetF32 (r,b,p) -> (match get b, get p with | VBytes b, VInt p -> set r (VFloat (Int32.float_of_bits (get_i32 b (Int32.to_int p)))) | _ -> assert false) | OGetF64 (r,b,p) -> (match get b, get p with | VBytes b, VInt p -> let p = Int32.to_int p in let i64 = Int64.logor (Int64.logand (Int64.of_int32 (get_i32 b p)) 0xFFFFFFFFL) (Int64.shift_left (Int64.of_int32 (get_i32 b (p + 4))) 32) in set r (VFloat (Int64.float_of_bits i64)) | _ -> assert false) | OGetArray (r,a,i) -> (match get a, get i with | VArray (a,_), VInt i -> set r a.(Int32.to_int i) | _ -> assert false); | OSetUI8 (r,p,v) -> (match get r, get p, get v with | VBytes b, VInt p, VInt v -> String.set b (Int32.to_int p) (char_of_int ((Int32.to_int v) land 0xFF)) | _ -> assert false) | OSetUI16 (r,p,v) -> (match get r, get p, get v with | VBytes b, VInt p, VInt v -> String.set b (Int32.to_int p) (char_of_int ((Int32.to_int v) land 0xFF)); String.set b (Int32.to_int p + 1) (char_of_int (((Int32.to_int v) lsr 8) land 0xFF)) | _ -> assert false) | OSetI32 (r,p,v) -> (match get r, get p, get v with | VBytes b, VInt p, VInt v -> set_i32 b (Int32.to_int p) v | _ -> assert false) | OSetF32 (r,p,v) -> (match get r, get p, get v with | VBytes b, VInt p, VFloat v -> set_i32 b (Int32.to_int p) (Int32.bits_of_float v) | _ -> assert false) | OSetF64 (r,p,v) -> (match get r, get p, get v with | VBytes b, VInt p, VFloat v -> let p = Int32.to_int p in let v64 = Int64.bits_of_float v in set_i32 b p (Int64.to_int32 v64); set_i32 b (p + 4) (Int64.to_int32 (Int64.shift_right_logical v64 32)); | _ -> assert false) | OSetArray (a,i,v) -> (match get a, get i with | VArray (a,t), VInt i -> let v = get v in check v t (fun() -> "array"); a.(Int32.to_int i) <- v | _ -> assert false); | OSafeCast (r, v) -> set r (dyn_cast ctx (get v) (rtype v) (rtype r)) | OUnsafeCast (r,v) -> set r (get v) | OArraySize (r,a) -> (match get a with | VArray (a,_) -> set r (VInt (Int32.of_int (Array.length a))); | _ -> assert false) | OType (r,t) -> set r (VType t) | OGetType (r,v) -> let v = get v in let v = (match v with VVirtual { vvalue = VNull } -> assert false | VVirtual v -> v.vvalue | _ -> v) in set r (VType (if v = VNull then HVoid else match get_type v with None -> assert false | Some t -> t)); | OGetTID (r,v) -> set r (match get v with | VType t -> (VInt (Int32.of_int (match t with | HVoid -> 0 | HUI8 -> 1 | HUI16 -> 2 | HI32 -> 3 | HF32 -> 4 | HF64 -> 5 | HBool -> 6 | HBytes -> 7 | HDyn -> 8 | HFun _ -> 9 | HObj _ -> 10 | HArray -> 11 | HType -> 12 | HRef _ -> 13 | HVirtual _ -> 14 | HDynObj -> 15 | HAbstract _ -> 16 | HEnum _ -> 17 | HNull _ -> 18))) | _ -> assert false); | ORef (r,v) -> set r (VRef (RStack (v + spos),rtype v)) | OUnref (v,r) -> set v (match get r with | VRef (r,_) -> get_ref ctx r | _ -> assert false) | OSetref (r,v) -> (match get r with | VRef (r,t) -> let v = get v in check v t (fun() -> "ref"); set_ref ctx r v | _ -> assert false) | OToVirtual (r,rv) -> set r (to_virtual ctx (get rv) (match rtype r with HVirtual vp -> vp | _ -> assert false)) | ODynGet (r,o,f) -> set r (dyn_get_field ctx (get o) ctx.code.strings.(f) (rtype r)) | ODynSet (o,fid,vr) -> dyn_set_field ctx (get o) ctx.code.strings.(fid) (get vr) (rtype vr) | OMakeEnum (r,e,pl) -> set r (VEnum (e,Array.map get (Array.of_list pl))) | OEnumAlloc (r,f) -> (match rtype r with | HEnum e -> let _, _, fl = e.efields.(f) in let vl = Array.create (Array.length fl) VUndef in set r (VEnum (f, vl)) | _ -> assert false ) | OEnumIndex (r,v) -> (match get v with | VEnum (i,_) | VDyn (VEnum (i,_),_) -> set r (VInt (Int32.of_int i)) | _ -> assert false) | OEnumField (r, v, _, i) -> (match get v with | VEnum (_,vl) -> set r vl.(i) | _ -> assert false) | OSetEnumField (v, i, r) -> (match get v, rtype v with | VEnum (id,vl), HEnum e -> let rv = get r in let _, _, fields = e.efields.(id) in check rv fields.(i) (fun() -> "enumfield"); vl.(i) <- rv | _ -> assert false) | OSwitch (r, indexes, _) -> (match get r with | VInt i -> let i = Int32.to_int i in if i >= 0 && i < Array.length indexes then pos := !pos + indexes.(i) | _ -> assert false) | ONullCheck r -> if get r = VNull then throw_msg ctx "Null access" | OTrap (r,j) -> let target = !pos + j in traps := (r,target) :: !traps | OEndTrap _ -> traps := List.tl !traps | ONop _ -> () ); loop() in let rec exec() = try loop() with | Return v -> check v fret (fun() -> "return value"); ctx.call_stack <- List.tl ctx.call_stack; ctx.stack_pos <- spos; v | InterpThrow v -> match !traps with | [] -> ctx.error_stack <- List.hd ctx.call_stack :: ctx.error_stack; ctx.call_stack <- List.tl ctx.call_stack; raise (InterpThrow v) | (r,target) :: tl -> traps := tl; ctx.error_stack <- (f,ref !pos) :: ctx.error_stack; pos := target; ctx.stack_pos <- spos + Array.length f.regs; set r v; exec() in pos := 0; exec() let call_fun ctx f args = match f with | FFun f -> interp ctx f args | FNativeFun (_,f,_) -> try f args with InterpThrow v -> raise (InterpThrow v) | Failure msg -> throw_msg ctx msg | e -> throw_msg ctx (Printexc.to_string e) let call_wrap ?(final=(fun()->())) ctx f args = let old_st = ctx.call_stack in let old_pos = ctx.stack_pos in let restore() = ctx.call_stack <- old_st; ctx.stack_pos <- old_pos; in try let v = call_fun ctx f args in final(); v with | InterpThrow v -> restore(); final(); ctx.on_error v (List.rev ctx.error_stack); VNull | Runtime_error msg -> let stack = ctx.call_stack in restore(); final(); ctx.on_error (VBytes (caml_to_hl ("HL Interp error " ^ msg))) stack; VNull (* ------------------------------- HL RUNTIME ---------------------------------------------- *) let load_native ctx lib name t = let unresolved() = (fun args -> error ("Unresolved native " ^ lib ^ "@" ^ name)) in let int = Int32.to_int in let to_int i = VInt (Int32.of_int i) in let date d = Unix.localtime (Int32.to_float d) in let to_date d = let t, _ = Unix.mktime d in VInt (Int32.of_float t) in let hl_to_caml_sub str pos len = hl_to_caml (String.sub str pos len ^ "\x00\x00") in let no_virtual v = match v with | VVirtual v when v.vvalue <> VNull -> v.vvalue | _ -> v in let set_ref = set_ref ctx in let f = (match lib with | "std" -> (match name with | "alloc_bytes" -> (function | [VInt i] -> VBytes (String.create (int i)) | _ -> assert false) | "alloc_array" -> (function | [VType t;VInt i] -> VArray (Array.create (int i) (default t),t) | _ -> assert false) | "alloc_obj" -> (function | [VType t] -> alloc_obj ctx t | _ -> assert false) | "alloc_enum" -> (function | [VType (HEnum e); VInt idx; VArray (vl,vt); VInt len] -> let idx = int idx in let len = int len in let _, _, args = e.efields.(idx) in if Array.length args <> len then VNull else VDyn (VEnum (idx,Array.mapi (fun i v -> dyn_cast ctx v vt args.(i)) (Array.sub vl 0 len)),HEnum e) | vl -> assert false) | "array_blit" -> (function | [VArray (dst,_); VInt dp; VArray (src,_); VInt sp; VInt len] -> Array.blit src (int sp) dst (int dp) (int len); VUndef | _ -> assert false) | "bytes_blit" -> (function | [VBytes dst; VInt dp; VBytes src; VInt sp; VInt len] -> String.blit src (int sp) dst (int dp) (int len); VUndef | [(VBytes _ | VNull); VInt _; (VBytes _ | VNull); VInt _; VInt len] -> if len = 0l then VUndef else error "bytes_blit to NULL bytes"; | _ -> assert false) | "bsort_i32" -> (function | [VBytes b; VInt pos; VInt len; VClosure (f,c)] -> let pos = int pos and len = int len in let a = Array.init len (fun i -> get_i32 b (pos + i * 4)) in Array.stable_sort (fun a b -> match ctx.fcall f (match c with None -> [VInt a;VInt b] | Some v -> [v;VInt a;VInt b]) with | VInt i -> int i | _ -> assert false ) a; Array.iteri (fun i v -> set_i32 b (pos + i * 4) v) a; VUndef; | _ -> assert false) | "bsort_f64" -> (function | [VBytes b; VInt pos; VInt len; VClosure _] -> assert false | _ -> assert false) | "itos" -> (function | [VInt v; VRef (r,_)] -> let str = Int32.to_string v in set_ref r (to_int (String.length str)); VBytes (caml_to_hl str) | _ -> assert false); | "ftos" -> (function | [VFloat f; VRef (r,_)] -> let str = float_to_string f in set_ref r (to_int (String.length str)); VBytes (caml_to_hl str) | _ -> assert false); | "value_to_string" -> (function | [v; VRef (r,_)] -> let str = caml_to_hl (vstr ctx v HDyn) in set_ref r (to_int ((String.length str) lsr 1 - 1)); VBytes str | _ -> assert false); | "math_isnan" -> (function [VFloat f] -> VBool (classify_float f = FP_nan) | _ -> assert false) | "math_isfinite" -> (function [VFloat f] -> VBool (match classify_float f with FP_infinite | FP_nan -> false | _ -> true) | _ -> assert false) | "math_round" -> (function [VFloat f] -> VInt (Int32.of_float (floor (f +. 0.5))) | _ -> assert false) | "math_floor" -> (function [VFloat f] -> VInt (Int32.of_float (floor f)) | _ -> assert false) | "math_ceil" -> (function [VFloat f] -> VInt (Int32.of_float (ceil f)) | _ -> assert false) | "math_ffloor" -> (function [VFloat f] -> VFloat (floor f) | _ -> assert false) | "math_fceil" -> (function [VFloat f] -> VFloat (ceil f) | _ -> assert false) | "math_fround" -> (function [VFloat f] -> VFloat (floor (f +. 0.5)) | _ -> assert false) | "math_abs" -> (function [VFloat f] -> VFloat (abs_float f) | _ -> assert false) | "math_sqrt" -> (function [VFloat f] -> VFloat (if f < 0. then nan else sqrt f) | _ -> assert false) | "math_cos" -> (function [VFloat f] -> VFloat (cos f) | _ -> assert false) | "math_sin" -> (function [VFloat f] -> VFloat (sin f) | _ -> assert false) | "math_tan" -> (function [VFloat f] -> VFloat (tan f) | _ -> assert false) | "math_acos" -> (function [VFloat f] -> VFloat (acos f) | _ -> assert false) | "math_asin" -> (function [VFloat f] -> VFloat (asin f) | _ -> assert false) | "math_atan" -> (function [VFloat f] -> VFloat (atan f) | _ -> assert false) | "math_atan2" -> (function [VFloat a; VFloat b] -> VFloat (atan2 a b) | _ -> assert false) | "math_log" -> (function [VFloat f] -> VFloat (Pervasives.log f) | _ -> assert false) | "math_exp" -> (function [VFloat f] -> VFloat (exp f) | _ -> assert false) | "math_pow" -> (function [VFloat a; VFloat b] -> VFloat (a ** b) | _ -> assert false) | "parse_int" -> (function | [VBytes str; VInt pos; VInt len] -> (try let i = (match Interp.parse_int (hl_to_caml_sub str (int pos) (int len)) with | Interp.VInt v -> Int32.of_int v | Interp.VInt32 v -> v | _ -> assert false ) in VDyn (VInt i,HI32) with _ -> VNull) | l -> assert false) | "parse_float" -> (function | [VBytes str; VInt pos; VInt len] -> (try VFloat (Interp.parse_float (hl_to_caml_sub str (int pos) (int len))) with _ -> VFloat nan) | _ -> assert false) | "dyn_compare" -> (function | [a;b] -> to_int (dyn_compare ctx a HDyn b HDyn) | _ -> assert false) | "fun_compare" -> let ocompare o1 o2 = match o1, o2 with | None, None -> true | Some o1, Some o2 -> o1 == o2 | _ -> false in (function | [VClosure (FFun f1,o1);VClosure (FFun f2,o2)] -> VBool (f1 == f2 && ocompare o1 o2) | [VClosure (FNativeFun (f1,_,_),o1);VClosure (FNativeFun (f2,_,_),o2)] -> VBool (f1 = f2 && ocompare o1 o2) | _ -> VBool false) | "array_type" -> (function | [VArray (_,t)] -> VType t | _ -> assert false) | "value_cast" -> (function | [v;VType t] -> if is_compatible v t then v else throw_msg ctx ("Cannot cast " ^ vstr_d ctx v ^ " to " ^ tstr t); | _ -> assert false) | "hballoc" -> (function | [] -> VAbstract (AHashBytes (Hashtbl.create 0)) | _ -> assert false) | "hbset" -> (function | [VAbstract (AHashBytes h);VBytes b;v] -> Hashtbl.replace h (hl_to_caml b) v; VUndef | _ -> assert false) | "hbget" -> (function | [VAbstract (AHashBytes h);VBytes b] -> (try Hashtbl.find h (hl_to_caml b) with Not_found -> VNull) | _ -> assert false) | "hbvalues" -> (function | [VAbstract (AHashBytes h)] -> let values = Hashtbl.fold (fun _ v acc -> v :: acc) h [] in VArray (Array.of_list values, HDyn) | _ -> assert false) | "hbkeys" -> (function | [VAbstract (AHashBytes h)] -> let keys = Hashtbl.fold (fun s _ acc -> VBytes (caml_to_hl s) :: acc) h [] in VArray (Array.of_list keys, HBytes) | _ -> assert false) | "hbexists" -> (function | [VAbstract (AHashBytes h);VBytes b] -> VBool (Hashtbl.mem h (hl_to_caml b)) | _ -> assert false) | "hbremove" -> (function | [VAbstract (AHashBytes h);VBytes b] -> let m = Hashtbl.mem h (hl_to_caml b) in if m then Hashtbl.remove h (hl_to_caml b); VBool m | _ -> assert false) | "hialloc" -> (function | [] -> VAbstract (AHashInt (Hashtbl.create 0)) | _ -> assert false) | "hiset" -> (function | [VAbstract (AHashInt h);VInt i;v] -> Hashtbl.replace h i v; VUndef | _ -> assert false) | "higet" -> (function | [VAbstract (AHashInt h);VInt i] -> (try Hashtbl.find h i with Not_found -> VNull) | _ -> assert false) | "hivalues" -> (function | [VAbstract (AHashInt h)] -> let values = Hashtbl.fold (fun _ v acc -> v :: acc) h [] in VArray (Array.of_list values, HDyn) | _ -> assert false) | "hikeys" -> (function | [VAbstract (AHashInt h)] -> let keys = Hashtbl.fold (fun i _ acc -> VInt i :: acc) h [] in VArray (Array.of_list keys, HI32) | _ -> assert false) | "hiexists" -> (function | [VAbstract (AHashInt h);VInt i] -> VBool (Hashtbl.mem h i) | _ -> assert false) | "hiremove" -> (function | [VAbstract (AHashInt h);VInt i] -> let m = Hashtbl.mem h i in if m then Hashtbl.remove h i; VBool m | _ -> assert false) | "hoalloc" -> (function | [] -> VAbstract (AHashObject (ref [])) | _ -> assert false) | "hoset" -> (function | [VAbstract (AHashObject l);o;v] -> let o = no_virtual o in let rec replace l = match l with | [] -> [o,v] | (o2,_) :: l when o == o2 -> (o,v) :: l | p :: l -> p :: replace l in l := replace !l; VUndef | _ -> assert false) | "hoget" -> (function | [VAbstract (AHashObject l);o] -> (try List.assq (no_virtual o) !l with Not_found -> VNull) | _ -> assert false) | "hovalues" -> (function | [VAbstract (AHashObject l)] -> VArray (Array.of_list (List.map snd !l), HDyn) | _ -> assert false) | "hokeys" -> (function | [VAbstract (AHashObject l)] -> VArray (Array.of_list (List.map fst !l), HDyn) | _ -> assert false) | "hoexists" -> (function | [VAbstract (AHashObject l);o] -> VBool (List.mem_assq (no_virtual o) !l) | _ -> assert false) | "horemove" -> (function | [VAbstract (AHashObject rl);o] -> let rec loop acc = function | [] -> false | (o2,_) :: l when o == o2 -> rl := (List.rev acc) @ l; true | p :: l -> loop (p :: acc) l in VBool (loop [] !rl) | _ -> assert false) | "sys_print" -> (function | [VBytes str] -> print_string (hl_to_caml str); VUndef | _ -> assert false) | "sys_time" -> (function | [] -> VFloat (Unix.gettimeofday()) | _ -> assert false) | "sys_exit" -> (function | [VInt code] -> raise (Sys_exit (Int32.to_int code)) | _ -> assert false) | "sys_utf8_path" -> (function | [] -> VBool true | _ -> assert false) | "sys_string" -> let cached_sys_name = ref None in (function | [] -> VBytes (caml_to_hl (match Sys.os_type with | "Unix" -> (match !cached_sys_name with | Some n -> n | None -> let ic = Unix.open_process_in "uname" in let uname = (match input_line ic with | "Darwin" -> "Mac" | n -> n ) in close_in ic; cached_sys_name := Some uname; uname) | "Win32" | "Cygwin" -> "Windows" | s -> s)) | _ -> assert false) | "sys_is64" -> (function | [] -> VBool (Sys.word_size = 64) | _ -> assert false) | "hash" -> (function | [VBytes str] -> VInt (hash ctx (hl_to_caml str)) | _ -> assert false) | "type_safe_cast" -> (function | [VType a; VType b] -> VBool (safe_cast a b) | _ -> assert false) | "type_super" -> (function | [VType t] -> VType (match t with HObj { psuper = Some o } -> HObj o | _ -> HVoid) | _ -> assert false) | "type_args_count" -> (function | [VType t] -> to_int (match t with HFun (args,_) -> List.length args | _ -> 0) | _ -> assert false) | "type_get_global" -> (function | [VType t] -> (match t with | HObj c -> (match c.pclassglobal with None -> VNull | Some g -> ctx.t_globals.(g)) | HEnum e -> (match e.eglobal with None -> VNull | Some g -> ctx.t_globals.(g)) | _ -> VNull) | _ -> assert false) | "type_set_global" -> (function | [VType t; v] -> VBool (match t with | HObj c -> (match c.pclassglobal with None -> false | Some g -> ctx.t_globals.(g) <- v; true) | HEnum e -> (match e.eglobal with None -> false | Some g -> ctx.t_globals.(g) <- v; true) | _ -> false) | _ -> assert false) | "type_name" -> (function | [VType t] -> VBytes (caml_to_hl (match t with | HObj o -> o.pname | HEnum e -> e.ename | _ -> assert false)) | _ -> assert false) | "obj_fields" -> let rec get_fields v isRec = match v with | VDynObj o -> VArray (Array.of_list (Hashtbl.fold (fun n _ acc -> VBytes (caml_to_hl n) :: acc) o.dfields []), HBytes) | VObj o -> let rec loop p = let fields = Array.map (fun (n,_,_) -> VBytes (caml_to_hl n)) p.pfields in match p.psuper with Some p when isRec -> fields :: loop p | _ -> [fields] in VArray (Array.concat (loop o.oproto.pclass), HBytes) | VVirtual v -> get_fields v.vvalue isRec | _ -> VNull in (function | [v] -> get_fields v true | _ -> assert false) | "obj_copy" -> (function | [VDynObj d | VVirtual { vvalue = VDynObj d }] -> VDynObj { dfields = Hashtbl.copy d.dfields; dvalues = Array.copy d.dvalues; dtypes = Array.copy d.dtypes; dvirtuals = [] } | [_] -> VNull | _ -> assert false) | "enum_parameters" -> (function | [VDyn (VEnum (idx,pl),HEnum e)] -> let _,_, ptypes = e.efields.(idx) in VArray (Array.mapi (fun i v -> make_dyn v ptypes.(i)) pl,HDyn) | _ -> assert false) | "type_instance_fields" -> (function | [VType t] -> (match t with | HObj o -> let rec fields o = let sup = (match o.psuper with None -> [||] | Some o -> fields o) in Array.concat [ sup; Array.map (fun (s,_,_) -> VBytes (caml_to_hl s)) o.pfields; Array.of_list (Array.fold_left (fun acc f -> let is_override = (match o.psuper with None -> false | Some p -> try ignore(get_index f.fname p); true with Not_found -> false) in if is_override then acc else VBytes (caml_to_hl f.fname) :: acc ) [] o.pproto) ] in VArray (fields o,HBytes) | _ -> VNull) | _ -> assert false) | "type_enum_fields" -> (function | [VType t] -> (match t with | HEnum e -> VArray (Array.map (fun (f,_,_) -> VBytes (caml_to_hl f)) e.efields,HBytes) | _ -> VNull) | _ -> assert false) | "type_enum_values" -> (function | [VType (HEnum e as t)] -> VArray (Array.mapi (fun i (_,_,args) -> if Array.length args <> 0 then VNull else VDyn (VEnum (i,[||]),t)) e.efields,HDyn) | _ -> assert false) | "type_enum_eq" -> (function | [VDyn (VEnum _, HEnum _); VNull] | [VNull; VDyn (VEnum _, HEnum _)] -> VBool false | [VNull; VNull] -> VBool true | [VDyn (VEnum _ as v1, HEnum e1); VDyn (VEnum _ as v2, HEnum e2)] -> let rec loop v1 v2 e = match v1, v2 with | VEnum (t1,_), VEnum (t2,_) when t1 <> t2 -> false | VEnum (t,vl1), VEnum (_,vl2) -> let _, _, pl = e.efields.(t) in let rec chk i = if i = Array.length pl then true else (match pl.(i) with | HEnum e -> loop vl1.(i) vl2.(i) e | t -> dyn_compare ctx vl1.(i) t vl2.(i) t = 0) && chk (i + 1) in chk 0 | _ -> assert false in VBool (if e1 != e2 then false else loop v1 v2 e1) | _ -> assert false) | "obj_get_field" -> (function | [o;VInt hash] -> let f = (try Hashtbl.find ctx.cached_hashes hash with Not_found -> assert false) in (match o with | VObj _ | VDynObj _ | VVirtual _ -> dyn_get_field ctx o f HDyn | _ -> VNull) | _ -> assert false) | "obj_set_field" -> (function | [o;VInt hash;v] -> let f = (try Hashtbl.find ctx.cached_hashes hash with Not_found -> assert false) in dyn_set_field ctx o f v HDyn; VUndef | _ -> assert false) | "obj_has_field" -> (function | [o;VInt hash] -> let f = (try Hashtbl.find ctx.cached_hashes hash with Not_found -> assert false) in let rec loop o = match o with | VDynObj d -> Hashtbl.mem d.dfields f | VObj o -> let rec loop p = if PMap.mem f p.pindex then let idx, _ = PMap.find f p.pindex in idx >= 0 else match p.psuper with None -> false | Some p -> loop p in loop o.oproto.pclass | VVirtual v -> loop v.vvalue | _ -> false in VBool (loop o) | _ -> assert false) | "obj_delete_field" -> (function | [o;VInt hash] -> let f = (try Hashtbl.find ctx.cached_hashes hash with Not_found -> assert false) in let rec loop o = match o with | VDynObj d when Hashtbl.mem d.dfields f -> let idx = Hashtbl.find d.dfields f in let count = Array.length d.dvalues in Hashtbl.remove d.dfields f; let fields = Hashtbl.fold (fun name i acc -> (name,if i < idx then i else i - 1) :: acc) d.dfields [] in Hashtbl.clear d.dfields; List.iter (fun (n,i) -> Hashtbl.add d.dfields n i) fields; let vals2 = Array.make (count - 1) VNull in let types2 = Array.make (count - 1) HVoid in let len = count - idx - 1 in Array.blit d.dvalues 0 vals2 0 idx; Array.blit d.dvalues (idx + 1) vals2 idx len; Array.blit d.dtypes 0 types2 0 idx; Array.blit d.dtypes (idx + 1) types2 idx len; d.dvalues <- vals2; d.dtypes <- types2; rebuild_virtuals ctx d; true | VVirtual v -> loop v.vvalue | _ -> false in VBool (loop o) | _ -> assert false) | "get_virtual_value" -> (function | [VVirtual v] -> v.vvalue | _ -> assert false) | "ucs2length" -> (function | [VBytes s; VInt pos] -> let delta = int pos in let rec loop p = let c = int_of_char s.[p+delta] lor ((int_of_char s.[p+delta+1]) lsl 8) in if c = 0 then p lsr 1 else loop (p + 2) in to_int (loop 0) | _ -> assert false) | "utf8_to_utf16" -> (function | [VBytes s; VInt pos; VRef (r,HI32)] -> let s = String.sub s (int pos) (String.length s - (int pos)) in let u16 = caml_to_hl (try String.sub s 0 (String.index s '\000') with Not_found -> assert false) in set_ref r (to_int (String.length u16 - 2)); VBytes u16 | _ -> assert false) | "utf16_to_utf8" -> (function | [VBytes s; VInt pos; VRef (r,HI32)] -> let s = String.sub s (int pos) (String.length s - (int pos)) in let u8 = hl_to_caml s in set_ref r (to_int (String.length u8)); VBytes (u8 ^ "\x00") | _ -> assert false) | "ucs2_upper" -> (function | [VBytes s; VInt pos; VInt len] -> let buf = Buffer.create 0 in utf16_iter (fun c -> let c = if c >= int_of_char 'a' && c <= int_of_char 'z' then c + int_of_char 'A' - int_of_char 'a' else c in utf16_add buf c ) (String.sub s (int pos) ((int len) lsl 1)); utf16_add buf 0; VBytes (Buffer.contents buf) | _ -> assert false) | "ucs2_lower" -> (function | [VBytes s; VInt pos; VInt len] -> let buf = Buffer.create 0 in utf16_iter (fun c -> let c = if c >= int_of_char 'A' && c <= int_of_char 'Z' then c + int_of_char 'a' - int_of_char 'A' else c in utf16_add buf c ) (String.sub s (int pos) ((int len) lsl 1)); utf16_add buf 0; VBytes (Buffer.contents buf) | _ -> assert false) | "url_encode" -> (function | [VBytes s; VRef (r, HI32)] -> let s = hl_to_caml s in let buf = Buffer.create 0 in let hex = "0123456789ABCDEF" in for i = 0 to String.length s - 1 do let c = String.unsafe_get s i in match c with | 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' | '-' | '.' -> utf16_char buf c | _ -> utf16_char buf '%'; utf16_char buf (String.unsafe_get hex (int_of_char c lsr 4)); utf16_char buf (String.unsafe_get hex (int_of_char c land 0xF)); done; utf16_add buf 0; let str = Buffer.contents buf in set_ref r (to_int (String.length str lsr 1 - 1)); VBytes str | _ -> assert false) | "url_decode" -> (function | [VBytes s; VRef (r, HI32)] -> let s = hl_to_caml s in let b = Buffer.create 0 in let len = String.length s in let decode c = match c with | '0'..'9' -> Some (int_of_char c - int_of_char '0') | 'a'..'f' -> Some (int_of_char c - int_of_char 'a' + 10) | 'A'..'F' -> Some (int_of_char c - int_of_char 'A' + 10) | _ -> None in let rec loop i = if i = len then () else let c = String.unsafe_get s i in match c with | '%' -> let p1 = (try decode (String.get s (i + 1)) with _ -> None) in let p2 = (try decode (String.get s (i + 2)) with _ -> None) in (match p1, p2 with | Some c1, Some c2 -> Buffer.add_char b (char_of_int ((c1 lsl 4) lor c2)); loop (i + 3) | _ -> loop (i + 1)); | '+' -> Buffer.add_char b ' '; loop (i + 1) | c -> Buffer.add_char b c; loop (i + 1) in loop 0; let str = Buffer.contents b in set_ref r (to_int (UTF8.length str)); VBytes (caml_to_hl str) | _ -> assert false) | "call_method" -> (function | [f;VArray (args,HDyn)] -> dyn_call ctx f (List.map (fun v -> v,HDyn) (Array.to_list args)) HDyn | _ -> assert false) | "no_closure" -> (function | [VClosure (f,_)] -> VClosure (f,None) | _ -> assert false) | "get_closure_value" -> (function | [VClosure (_,None)] -> VNull | [VClosure (_,Some v)] -> v | _ -> assert false) | "make_var_args" -> (function | [VClosure (f,arg)] -> VVarArgs (f,arg) | _ -> assert false) | "bytes_find" -> (function | [VBytes src; VInt pos; VInt len; VBytes chk; VInt cpos; VInt clen; ] -> to_int (try int pos + ExtString.String.find (String.sub src (int pos) (int len)) (String.sub chk (int cpos) (int clen)) with ExtString.Invalid_string -> -1) | _ -> assert false) | "bytes_compare" -> (function | [VBytes a; VInt apos; VBytes b; VInt bpos; VInt len] -> to_int (String.compare (String.sub a (int apos) (int len)) (String.sub b (int bpos) (int len))) | _ -> assert false) | "bytes_fill" -> (function | [VBytes a; VInt pos; VInt len; VInt v] -> String.fill a (int pos) (int len) (char_of_int ((int v) land 0xFF)); VUndef | _ -> assert false) | "exception_stack" -> (function | [] -> VArray (Array.map (fun e -> VBytes (caml_to_hl (stack_frame ctx e))) (Array.of_list (List.rev ctx.error_stack)),HBytes) | _ -> assert false) | "date_new" -> (function | [VInt y; VInt mo; VInt d; VInt h; VInt m; VInt s] -> let t = Unix.localtime (Unix.time()) in let t = { t with tm_year = int y - 1900; tm_mon = int mo; tm_mday = int d; tm_hour = int h; tm_min = int m; tm_sec = int s; } in to_date t | _ -> assert false) | "date_now" -> (function | [] -> to_date (Unix.localtime (Unix.time())) | _ -> assert false) | "date_get_time" -> (function | [VInt v] -> VFloat (fst (Unix.mktime (date v)) *. 1000.) | _ -> assert false) | "date_from_time" -> (function | [VFloat f] -> to_date (Unix.localtime (f /. 1000.)) | _ -> assert false) | "date_get_inf" -> (function | [VInt d;year;month;day;hours;minutes;seconds;wday] -> let d = date d in let set r v = match r with | VNull -> () | VRef (r,HI32) -> set_ref r (to_int v) | _ -> assert false in set year (d.tm_year + 1900); set month d.tm_mon; set day d.tm_mday; set hours d.tm_hour; set minutes d.tm_min; set seconds d.tm_sec; set wday d.tm_wday; VUndef | _ -> assert false) | "date_to_string" -> (function | [VInt d; VRef (r,HI32)] -> let t = date d in let str = Printf.sprintf "%.4d-%.2d-%.2d %.2d:%.2d:%.2d" (t.tm_year + 1900) (t.tm_mon + 1) t.tm_mday t.tm_hour t.tm_min t.tm_sec in set_ref r (to_int (String.length str)); VBytes (caml_to_hl str) | _ -> assert false) | "rnd_init_system" -> (function | [] -> Random.self_init(); VAbstract ARandom | _ -> assert false) | "rnd_int" -> (function | [VAbstract ARandom] -> VInt (Int32.of_int (Random.bits())) | _ -> assert false) | "rnd_float" -> (function | [VAbstract ARandom] -> VFloat (Random.float 1.) | _ -> assert false) | "regexp_new_options" -> (function | [VBytes str; VBytes opt] -> let case_sensitive = ref true in List.iter (function | 'm' -> () (* always ON ? *) | 'i' -> case_sensitive := false | c -> failwith ("Unsupported regexp option '" ^ String.make 1 c ^ "'") ) (ExtString.String.explode (hl_to_caml opt)); let buf = Buffer.create 0 in let rec loop prev esc = function | [] -> () | c :: l when esc -> (match c with | 'n' -> Buffer.add_char buf '\n' | 'r' -> Buffer.add_char buf '\r' | 't' -> Buffer.add_char buf '\t' | 's' -> Buffer.add_string buf "[ \t\r\n]" | 'd' -> Buffer.add_string buf "[0-9]" | '\\' -> Buffer.add_string buf "\\\\" | '(' | ')' | '{' | '}' -> Buffer.add_char buf c | '1'..'9' | '+' | '$' | '^' | '*' | '?' | '.' | '[' | ']' -> Buffer.add_char buf '\\'; Buffer.add_char buf c; | _ -> Buffer.add_char buf c); loop c false l | c :: l -> match c with | '\\' -> loop prev true l | '(' | '|' | ')' -> Buffer.add_char buf '\\'; Buffer.add_char buf c; loop c false l | '?' when prev = '(' && (match l with ':' :: _ -> true | _ -> false) -> failwith "Non capturing groups '(?:' are not supported in macros" | '?' when prev = '*' -> failwith "Ungreedy *? are not supported in macros" | _ -> Buffer.add_char buf c; loop c false l in loop '\000' false (ExtString.String.explode (hl_to_caml str)); let str = Buffer.contents buf in let r = { r = if !case_sensitive then Str.regexp str else Str.regexp_case_fold str; r_string = ""; r_groups = [||]; } in VAbstract (AReg r) | _ -> assert false); | "regexp_match" -> (function | [VAbstract (AReg r);VBytes str;VInt pos;VInt len] -> let str = hl_to_caml str and pos = int pos and len = int len in let nstr, npos, delta = (if len = String.length str - pos then str, pos, 0 else String.sub str pos len, 0, pos) in (try ignore(Str.search_forward r.r nstr npos); let rec loop n = if n = 9 then [] else try (Some (Str.group_beginning n + delta, Str.group_end n + delta)) :: loop (n + 1) with Not_found -> None :: loop (n + 1) | Invalid_argument _ -> [] in r.r_string <- str; r.r_groups <- Array.of_list (loop 0); VBool true; with Not_found -> VBool false) | _ -> assert false); | "regexp_matched_pos" -> (function | [VAbstract (AReg r); VInt n; VRef (rr,HI32)] -> let n = int n in (match (try r.r_groups.(n) with _ -> failwith ("Invalid group " ^ string_of_int n)) with | None -> to_int (-1) | Some (pos,pend) -> set_ref rr (to_int (pend - pos)); to_int pos) | [VAbstract (AReg r); VInt n; VNull] -> let n = int n in (match (try r.r_groups.(n) with _ -> failwith ("Invalid group " ^ string_of_int n)) with | None -> to_int (-1) | Some (pos,pend) -> to_int pos) | _ -> assert false) | "make_macro_pos" -> (function | [VBytes file;VInt min;VInt max] -> VAbstract (APos { Globals.pfile = String.sub file 0 (String.length file - 1); pmin = Int32.to_int min; pmax = Int32.to_int max }) | _ -> assert false) | _ -> unresolved()) | "macro" -> (match ctx.resolve_macro_api name with | None -> unresolved() | Some f -> f) | _ -> unresolved() ) in FNativeFun (lib ^ "@" ^ name, f, t) let create checked = let ctx = { t_globals = [||]; t_functions = [||]; call_stack = []; error_stack = []; stack = [||]; stack_pos = 0; cached_protos = Hashtbl.create 0; cached_strings = Hashtbl.create 0; cached_hashes = Hashtbl.create 0; code = { functions = [||]; globals = [||]; natives = [||]; strings = [||]; ints = [||]; debugfiles = [||]; floats = [||]; entrypoint = 0; version = 0; }; checked = checked; fcall = (fun _ _ -> assert false); on_error = (fun _ _ -> assert false); resolve_macro_api = (fun _ -> None); } in ctx.on_error <- (fun msg stack -> failwith (vstr ctx msg HDyn ^ "\n" ^ String.concat "\n" (List.map (stack_frame ctx) stack))); ctx.fcall <- call_fun ctx; ctx let set_error_handler ctx e = ctx.on_error <- e let set_macro_api ctx f = ctx.resolve_macro_api <- f let add_code ctx code = (* expand global table *) let globals = Array.map default code.globals in Array.blit ctx.t_globals 0 globals 0 (Array.length ctx.t_globals); ctx.t_globals <- globals; (* expand function table *) let nfunctions = Array.length code.functions + Array.length code.natives in let functions = Array.create nfunctions (FNativeFun ("",(fun _ -> assert false),HDyn)) in Array.blit ctx.t_functions 0 functions 0 (Array.length ctx.t_functions); let rec loop i = if i = Array.length code.natives then () else let lib, name, t, idx = code.natives.(i) in functions.(idx) <- load_native ctx code.strings.(lib) code.strings.(name) t; loop (i + 1) in loop (Array.length ctx.code.natives); let rec loop i = if i = Array.length code.functions then () else let fd = code.functions.(i) in functions.(fd.findex) <- FFun fd; loop (i + 1) in loop (Array.length ctx.code.functions); ctx.t_functions <- functions; ctx.code <- code; (* call entrypoint *) ignore(call_wrap ctx functions.(code.entrypoint) []) (* ------------------------------- CHECK ---------------------------------------------- *) let check code macros = let ftypes = Array.create (Array.length code.natives + Array.length code.functions) HVoid in let is_native_fun = Hashtbl.create 0 in let check_fun f = let pos = ref 0 in let error msg = let dfile, dline = f.debug.(!pos) in let file = code.debugfiles.(dfile) in let msg = Printf.sprintf "Check failure at fun@%d @%X - %s" f.findex (!pos) msg in if macros then begin let low = dline land 0xFFFFF in let pos = { Globals.pfile = file; Globals.pmin = low; Globals.pmax = low + (dline lsr 20); } in Common.abort msg pos end else failwith (Printf.sprintf "\n%s:%d: %s" file dline msg) in let targs, tret = (match f.ftype with HFun (args,ret) -> args, ret | _ -> assert false) in let rtype i = try f.regs.(i) with _ -> HObj { null_proto with pname = "OUT_OF_BOUNDS:" ^ string_of_int i } in let check t1 t2 = if not (safe_cast t1 t2) then error (tstr t1 ^ " should be " ^ tstr t2) in let reg_inf r = "Register " ^ string_of_int r ^ "(" ^ tstr (rtype r) ^ ")" in let reg r t = if not (safe_cast (rtype r) t) then error (reg_inf r ^ " should be " ^ tstr t ^ " and not " ^ tstr (rtype r)) in let numeric r = match rtype r with | HUI8 | HUI16 | HI32 | HF32 | HF64 -> () | _ -> error (reg_inf r ^ " should be numeric") in let int r = match rtype r with | HUI8 | HUI16 | HI32 -> () | _ -> error (reg_inf r ^ " should be integral") in let float r = match rtype r with | HF32 | HF64 -> () | _ -> error (reg_inf r ^ " should be float") in let call f args r = match ftypes.(f) with | HFun (targs, tret) -> if List.length args <> List.length targs then error (tstr (HFun (List.map rtype args, rtype r)) ^ " should be " ^ tstr ftypes.(f)); List.iter2 reg args targs; check tret (rtype r) | _ -> assert false in let can_jump delta = if !pos + 1 + delta < 0 || !pos + 1 + delta >= Array.length f.code then error "Jump outside function bounds"; if delta < 0 && Array.get f.code (!pos + 1 + delta) <> OLabel 0 then error "Jump back without Label"; in let is_obj r = match rtype r with | HObj _ -> () | _ -> error (reg_inf r ^ " should be object") in let is_enum r = match rtype r with | HEnum _ -> () | _ -> error (reg_inf r ^ " should be enum") in let is_dyn r = if not (is_dynamic (rtype r)) then error (reg_inf r ^ " should be castable to dynamic") in let tfield o fid proto = if fid < 0 then error (reg_inf o ^ " does not have " ^ (if proto then "proto " else "") ^ "field " ^ string_of_int fid); match rtype o with | HObj p -> if proto then ftypes.(p.pvirtuals.(fid)) else (try snd (resolve_field p fid) with Not_found -> error (reg_inf o ^ " does not have field " ^ string_of_int fid)) | HVirtual v when not proto -> let _,_, t = v.vfields.(fid) in t | _ -> is_obj o; HVoid in list_iteri reg targs; Array.iteri (fun i op -> pos := i; match op with | OMov (a,b) -> reg b (rtype a) | OInt (r,i) -> ignore(code.ints.(i)); int r | OFloat (r,i) -> if rtype r <> HF32 then reg r HF64; if i < 0 || i >= Array.length code.floats then error "float outside range"; | OBool (r,_) -> reg r HBool | OString (r,i) | OBytes (r,i) -> reg r HBytes; if i < 0 || i >= Array.length code.strings then error "string outside range"; | ONull r -> let t = rtype r in if not (is_nullable t) then error (tstr t ^ " is not nullable") | OAdd (r,a,b) | OSub (r,a,b) | OMul (r,a,b) | OSDiv (r,a,b) | OUDiv (r,a,b) | OSMod (r,a,b) | OUMod(r,a,b) -> numeric r; reg a (rtype r); reg b (rtype r); | ONeg (r,a) -> numeric r; reg a (rtype r); | OShl (r,a,b) | OSShr (r,a,b) | OUShr (r,a,b) | OAnd (r,a,b) | OOr (r,a,b) | OXor (r,a,b) -> int r; reg a (rtype r); reg b (rtype r); | OIncr r -> int r | ODecr r -> int r | ONot (a,b) -> reg a HBool; reg b HBool; | OCall0 (r,f) -> call f [] r | OCall1 (r, f, a) -> call f [a] r | OCall2 (r, f, a, b) -> call f [a;b] r | OCall3 (r, f, a, b, c) -> call f [a;b;c] r | OCall4 (r, f, a, b, c, d) -> call f [a;b;c;d] r | OCallN (r,f,rl) -> call f rl r | OCallThis (r, m, rl) -> (match tfield 0 m true with | HFun (tobj :: targs, tret) when List.length targs = List.length rl -> reg 0 tobj; List.iter2 reg rl targs; check tret (rtype r) | t -> check t (HFun (rtype 0 :: List.map rtype rl, rtype r))); | OCallMethod (r, m, rl) -> (match rl with | [] -> assert false | obj :: rl2 -> let t, rl = (match rtype obj with | HVirtual v -> let _, _, t = v.vfields.(m) in t, rl2 | _ -> tfield obj m true, rl ) in match t with | HFun (targs, tret) when List.length targs = List.length rl -> List.iter2 reg rl targs; check tret (rtype r) | t -> check t (HFun (List.map rtype rl, rtype r))) | OCallClosure (r,f,rl) -> (match rtype f with | HFun (targs,tret) when List.length targs = List.length rl -> List.iter2 reg rl targs; check tret (rtype r) | HDyn -> List.iter (fun r -> ignore(rtype r)) rl; | _ -> reg f (HFun(List.map rtype rl,rtype r))) | OGetGlobal (r,g) -> if not (safe_cast code.globals.(g) (rtype r)) then reg r code.globals.(g) | OSetGlobal (g,r) -> reg r code.globals.(g) | ORet r -> reg r tret | OJTrue (r,delta) | OJFalse (r,delta) -> reg r HBool; can_jump delta | OJNull (r,delta) | OJNotNull (r,delta) -> ignore(rtype r); can_jump delta | OJUGte (a,b,delta) | OJULt (a,b,delta) | OJSGte (a,b,delta) | OJSLt (a,b,delta) | OJSGt (a,b,delta) | OJSLte (a,b,delta) -> if not (safe_cast (rtype a) (rtype b)) then reg b (rtype a); can_jump delta | OJEq (a,b,delta) | OJNotEq (a,b,delta) -> (match rtype a, rtype b with | (HObj _ | HVirtual _), (HObj _ | HVirtual _) -> () | ta, tb when safe_cast tb ta -> () | _ -> reg a (rtype b)); can_jump delta | OJAlways d -> can_jump d | OToDyn (r,a) -> (* we can still use OToDyn on nullable if we want to turn them into dynamic *) if is_dynamic (rtype a) then reg a HI32; (* don't wrap as dynamic types that can safely be cast to it *) if rtype r <> HDyn then reg r (HNull (rtype a)) | OToSFloat (a,b) | OToUFloat (a,b) -> float a; (match rtype b with HF32 | HF64 -> () | _ -> int b); | OToInt (a,b) -> int a; (match rtype b with HF32 | HF64 -> () | _ -> int b); | OLabel _ -> () | ONew r -> (match rtype r with | HDynObj | HVirtual _ -> () | _ -> is_obj r) | OField (r,o,fid) -> check (tfield o fid false) (rtype r) | OSetField (o,fid,r) -> reg r (tfield o fid false) | OGetThis (r,fid) -> check (tfield 0 fid false) (rtype r) | OSetThis(fid,r) -> reg r (tfield 0 fid false) | OStaticClosure (r,f) -> reg r ftypes.(f) | OVirtualClosure (r,o,fid) -> (match rtype o with | HObj _ -> (match tfield o fid true with | HFun (t :: tl, tret) -> reg o t; reg r (HFun (tl,tret)); | _ -> assert false) | HVirtual v -> let _,_, t = v.vfields.(fid) in reg r t; | _ -> is_obj o) | OInstanceClosure (r,f,arg) -> (match ftypes.(f) with | HFun (t :: tl, tret) -> reg arg t; if not (is_nullable t) then error (reg_inf r ^ " should be nullable"); reg r (HFun (tl,tret)); | _ -> assert false); | OThrow r -> reg r HDyn | ORethrow r -> reg r HDyn | OGetArray (v,a,i) -> reg a HArray; reg i HI32; ignore(rtype v); | OGetUI8 (r,b,p) | OGetI32 (r,b,p) | OGetUI16(r,b,p) -> reg r HI32; reg b HBytes; reg p HI32; | OGetF32 (r,b,p) -> reg r HF32; reg b HBytes; reg p HI32; | OGetF64 (r,b,p) -> reg r HF64; reg b HBytes; reg p HI32; | OSetUI8 (r,p,v) | OSetI32 (r,p,v) | OSetUI16 (r,p,v) -> reg r HBytes; reg p HI32; reg v HI32; | OSetF32 (r,p,v) -> reg r HBytes; reg p HI32; reg v HF32; | OSetF64 (r,p,v) -> reg r HBytes; reg p HI32; reg v HF64; | OSetArray (a,i,v) -> reg a HArray; reg i HI32; ignore(rtype v); | OUnsafeCast (a,b) -> is_dyn a; is_dyn b; | OSafeCast (a,b) -> ignore(rtype a); ignore(rtype b); | OArraySize (r,a) -> reg a HArray; reg r HI32 | OType (r,_) -> reg r HType | OGetType (r,v) -> reg r HType; is_dyn v; | OGetTID (r,v) -> reg r HI32; reg v HType; | OUnref (v,r) -> (match rtype r with | HRef t -> check t (rtype v) | _ -> reg r (HRef (rtype v))) | ORef (r,v) | OSetref (r,v) -> (match rtype r with HRef t -> reg v t | _ -> reg r (HRef (rtype v))) | OToVirtual (r,v) -> (match rtype r with | HVirtual _ -> () | _ -> reg r (HVirtual {vfields=[||];vindex=PMap.empty;})); (match rtype v with | HObj _ | HDynObj | HDyn | HVirtual _ -> () | _ -> reg v HDynObj) | ODynGet (v,r,f) | ODynSet (r,f,v) -> ignore(code.strings.(f)); ignore(rtype v); (match rtype r with | HObj _ | HDyn | HDynObj | HVirtual _ -> () | _ -> reg r HDynObj) | OMakeEnum (r,index,pl) -> (match rtype r with | HEnum e -> let _,_, fl = e.efields.(index) in if Array.length fl <> List.length pl then error ("MakeEnum has " ^ (string_of_int (List.length pl)) ^ " params while " ^ (string_of_int (Array.length fl)) ^ " are required"); List.iter2 (fun r t -> reg r t) pl (Array.to_list fl) | _ -> is_enum r) | OEnumAlloc (r,index) -> (match rtype r with | HEnum e -> ignore(e.efields.(index)) | _ -> is_enum r) | OEnumIndex (r,v) -> if rtype v <> HDyn then is_enum v; reg r HI32; | OEnumField (r,e,f,i) -> (match rtype e with | HEnum e -> let _, _, tl = e.efields.(f) in check tl.(i) (rtype r) | _ -> is_enum e) | OSetEnumField (e,i,r) -> (match rtype e with | HEnum e -> let _, _, tl = e.efields.(0) in check (rtype r) tl.(i) | _ -> is_enum e) | OSwitch (r,idx,eend) -> reg r HI32; Array.iter can_jump idx; if eend + 1 + i <> Array.length f.code then can_jump eend | ONullCheck r -> ignore(rtype r) | OTrap (r, idx) -> reg r HDyn; can_jump idx | OEndTrap _ -> () | ONop _ -> () ) f.code (* TODO : check that all path correctly initialize NULL values and reach a return *) in Array.iter (fun fd -> if fd.findex >= Array.length ftypes then failwith ("Invalid function index " ^ string_of_int fd.findex); if ftypes.(fd.findex) <> HVoid then failwith ("Duplicate function bind " ^ string_of_int fd.findex ^ " " ^ fundecl_name fd); ftypes.(fd.findex) <- fd.ftype; ) code.functions; Array.iter (fun (lib,name,t,idx) -> if idx >= Array.length ftypes then failwith ("Invalid native function index " ^ string_of_int idx ^ " for "^ code.strings.(lib) ^ "@" ^ code.strings.(name)); if ftypes.(idx) <> HVoid then failwith ("Duplicate native function bind " ^ string_of_int idx); Hashtbl.add is_native_fun idx true; ftypes.(idx) <- t ) code.natives; (* TODO : check that no object type has a virtual native in his proto *) Array.iter check_fun code.functions (* ------------------------------- SPEC ---------------------------------------------- *) open Hlopt type svalue = | SUndef | SArg of int | SInt of int32 | SFloat of float | SString of string | SBool of bool | SNull | SType of ttype | SOp of string * svalue * svalue | SUnop of string * svalue | SResult of string | SFun of int * svalue option | SMeth of svalue * int | SGlobal of int | SField of svalue * int | SDField of svalue * string | SConv of string * svalue | SCast of svalue * ttype | SMem of svalue * svalue * ttype | SEnum of int * svalue list | SEnumField of svalue * int * int | SUnion of svalue list | SRef of int | SRefResult of string | SUnreach | SExc | SDelayed of string * svalue list option ref type call_spec = | SFid of int | SMethod of int | SClosure of svalue type spec = | SCall of call_spec * svalue list | SGlobalSet of int * svalue | SFieldSet of svalue * int * svalue | SFieldDSet of svalue * string * svalue | SJEq of string * svalue | SJComp of string * svalue * svalue | SJump | SRet of svalue | SNullCheck of svalue | SThrow of svalue | SSwitch of svalue | SWriteMem of svalue * svalue * svalue * ttype | SSetRef of svalue * svalue | SSetEnumField of svalue * int * svalue | SStoreResult of string * spec | SNew of ttype * int | SVal of svalue let rec svalue_string v = let sval = svalue_string in match v with | SUndef -> "undef" | SArg i -> "arg" ^ string_of_int i | SInt i -> Int32.to_string i | SFloat f -> string_of_float f | SString s -> "\"" ^ s ^ "\"" | SBool b -> if b then "true" else "false" | SNull -> "null" | SRef _ -> "ref" | SRefResult s -> Printf.sprintf "refresult(%s)" s | SType t -> tstr t | SOp (op,a,b) -> Printf.sprintf "(%s %s %s)" (sval a) op (sval b) | SUnop (op,v) -> op ^ sval v | SResult i -> i | SFun (i,None) -> "fun" ^ string_of_int i | SFun (i,Some v) -> Printf.sprintf "fun%d(%s)" i (sval v) | SMeth (v,i) -> Printf.sprintf "meth%d(%s)" i (sval v) | SGlobal g -> Printf.sprintf "G[%d]" g | SField (o,i) -> Printf.sprintf "%s[%d]" (sval o) i | SDField (o,f) -> Printf.sprintf "%s.%s" (sval o) f | SConv (f,v) -> Printf.sprintf "%s(%s)" f (sval v) | SCast (v,t) -> Printf.sprintf "cast(%s,%s)" (sval v) (tstr t) | SMem (m,idx,t) -> Printf.sprintf "(%s*)%s[%s]" (tstr t) (sval m) (sval idx) | SEnum (i,vl) -> Printf.sprintf "enum%d(%s)" i (String.concat "," (List.map sval vl)) | SEnumField (v,k,i) -> Printf.sprintf "%s[%d:%d]" (sval v) k i | SUnion vl -> Printf.sprintf "union(%s)" (String.concat " | " (List.map sval vl)) | SUnreach -> "unreach" | SExc -> "exc" | SDelayed (str,_) -> str let svalue_iter f = function | SUndef | SArg _ | SInt _ | SFloat _ | SString _ | SBool _ | SNull | SType _ | SResult _ | SFun (_,None) | SGlobal _ | SRef _ | SRefResult _ | SUnreach | SExc | SDelayed _ -> () | SOp (_,a,b) | SMem (a,b,_) -> f a; f b | SUnop (_,a) | SFun (_,Some a) | SMeth (a,_) | SField (a,_) | SDField (a,_) | SConv (_,a) | SCast (a,_) | SEnumField (a,_,_) -> f a | SUnion vl | SEnum (_,vl) -> List.iter f vl let spec_iter fs fv = function | SCall (c,vl) -> (match c with SClosure v -> fv v | _ -> ()); List.iter fv vl | SVal v | SJEq (_,v) | SRet v | SNullCheck v | SThrow v | SSwitch v | SGlobalSet (_,v) -> fv v | SJComp (_,a,b) | SSetRef (a,b) | SSetEnumField (a,_,b) | SFieldDSet (a,_,b) | SFieldSet (a,_,b) -> fv a; fv b | SJump -> () | SWriteMem (m,a,b,_) -> fv m; fv a; fv b | SStoreResult (_,s) -> fs s | SNew _ -> () let rec svalue_same a b = let vsame = svalue_same in match a, b with | SType t1, SType t2 -> tsame t1 t2 | SOp (op1,a1,b1), SOp (op2,a2,b2) -> op1 = op2 && vsame a1 a2 && vsame b1 b2 | SUnop (op1,v1), SUnop (op2,v2) -> op1 = op2 && vsame v1 v2 | SFun (f1,Some v1), SFun (f2,Some v2) -> f1 = f2 && vsame v1 v2 | SMeth (v1,m1), SMeth (v2,m2) -> vsame v1 v2 && m1 = m2 | SField (v1,f1), SField (v2,f2) -> vsame v1 v2 && f1 = f2 | SDField (v1,f1), SDField (v2,f2) -> vsame v1 v2 && f1 = f2 | SConv (op1,v1), SConv (op2,v2) -> op1 = op2 && vsame v1 v2 | SCast (v1,t1), SCast (v2,t2) -> vsame v1 v2 && tsame t1 t2 | SMem (m1,i1,t1), SMem (m2,i2,t2) -> vsame m1 m2 && vsame i1 i2 && tsame t1 t2 | SEnum (i1,vl1), SEnum (i2,vl2) -> i1 = i2 && List.length vl1 = List.length vl2 && List.for_all2 vsame vl1 vl2 | SEnumField (v1,c1,i1), SEnumField (v2,c2,i2) -> vsame v1 v2 && c1 = c2 && i1 = i2 | SUnion vl1, SUnion vl2 -> List.length vl1 = List.length vl2 && List.for_all2 vsame vl1 vl2 | SDelayed (id1,_), SDelayed (id2,_) -> id1 = id2 | _ -> a = b let rec spec_string s = let sval = svalue_string in match s with | SCall (c,vl) -> let cstr = (match c with | SFid i -> Printf.sprintf "fun%d" i | SMethod i -> Printf.sprintf "meth%d" i | SClosure v -> Printf.sprintf "closure(%s)" (sval v) ) in Printf.sprintf "%s(%s)" cstr (String.concat "," (List.map sval vl)) | SGlobalSet (i,v) -> Printf.sprintf "G[%d] = %s" i (sval v) | SFieldSet (o,fid,v) | SSetEnumField (o,fid,v) -> Printf.sprintf "%s[%d] = %s" (sval o) fid (sval v) | SFieldDSet (o,f,v) -> Printf.sprintf "%s.%s = %s" (sval o) f (sval v) | SJEq (s,v) -> Printf.sprintf "j%s(%s)" s (sval v) | SJComp (s,a,b) -> Printf.sprintf "jump(%s %s %s)" (sval a) s (sval b) | SJump -> "jump" | SRet v -> "ret " ^ sval v | SNullCheck v -> "nullcheck " ^ sval v | SThrow v -> "throw " ^ sval v | SSwitch v -> "switch " ^ sval v | SWriteMem (m,idx,v,t) -> Printf.sprintf "(%s*)%s[%s] = %s" (tstr t) (sval m) (sval idx) (sval v) | SSetRef (r,v) -> Printf.sprintf "*%s = %s" (sval r) (sval v) | SStoreResult (r,s) -> r ^ " <- " ^ spec_string s | SNew (t,idx) -> Printf.sprintf "new %s(%d)" (tstr t) idx | SVal v -> sval v let make_spec (code:code) (f:fundecl) = let op = Array.get f.code in let out_spec = ref [] in let alloc_count = ref (-1) in let digest str = let d = Digest.to_hex (Digest.string str) in String.sub d 0 4 in let rec semit s = let rec loop_spec s = spec_iter loop_spec loop_val s and loop_val v = match v with | SDelayed (r,used) -> (match !used with | None -> () | Some vl -> used := None; semit (SStoreResult (r,SVal (SUnion vl)))) | _ -> svalue_iter loop_val v in loop_spec s; out_spec := s :: !out_spec in let emit (s:spec) = let d = digest (spec_string s) in semit (SStoreResult (d,s)); SResult d in let big_unions = Hashtbl.create 0 in let block_args = Hashtbl.create 0 in let rec get_args b = try Hashtbl.find block_args b.bstart with Not_found -> assert false and calc_spec b = let bprev = List.filter (fun b2 -> b2.bstart < b.bstart) b.bprev in let args = (match bprev with | [] -> let args = Array.make (Array.length f.regs) SUndef in (match f.ftype with | HFun (tl,_) -> list_iteri (fun i _ -> args.(i) <- SArg i) tl | _ -> assert false); args | b2 :: l -> let args = Array.copy (get_args b2) in List.iter (fun b2 -> let args2 = get_args b2 in for i = 0 to Array.length args - 1 do if not (svalue_same args.(i) args2.(i)) then begin let l1 = (match args.(i) with SUnion l -> l | v -> [v]) in let l2 = (match args2.(i) with SUnion l -> l | v -> [v]) in let l = l1 @ List.filter (fun v -> not (List.exists (svalue_same v) l1)) l2 in if List.length l > 10 then begin (try let ident, used = Hashtbl.find big_unions l in args.(i) <- SDelayed (ident, used); with Not_found -> let ident = digest (String.concat "," (List.map svalue_string l)) in let used = ref (Some l) in Hashtbl.replace big_unions l (ident,used); args.(i) <- SDelayed (ident, used)) end else args.(i) <- SUnion l; end done; ) l; if l = [] then (match op b2.bend with OTrap (r,_) -> args.(r) <- SExc | _ -> ()); args ) in let make_call c vl = let r = emit (SCall (c,vl)) in (match r with | SResult result -> List.iter (fun v -> match v with SRef r -> args.(r) <- SRefResult result | _ -> ()) vl | _ -> assert false); r in for i = b.bstart to b.bend do match op i with | OMov (d,r) -> args.(d) <- args.(r) | OInt (d,i) -> args.(d) <- SInt code.ints.(i) | OFloat (d,f) -> args.(d) <- SFloat code.floats.(f) | OBool (d,b) -> args.(d) <- SBool b | OBytes (d,s) | OString (d,s) -> args.(d) <- SString code.strings.(s) | ONull d -> args.(d) <- SNull | OAdd (d,a,b) -> args.(d) <- SOp ("+",args.(a),args.(b)) | OSub (d,a,b) -> args.(d) <- SOp ("-",args.(a),args.(b)) | OMul (d,a,b) -> args.(d) <- SOp ("*",args.(a),args.(b)) | OSDiv (d,a,b) -> args.(d) <- SOp ("/",args.(a),args.(b)) | OUDiv (d,a,b) -> args.(d) <- SOp ("//",args.(a),args.(b)) | OSMod (d,a,b) -> args.(d) <- SOp ("%",args.(a),args.(b)) | OUMod (d,a,b) -> args.(d) <- SOp ("%%",args.(a),args.(b)) | OShl (d,a,b) -> args.(d) <- SOp ("<<",args.(a),args.(b)) | OSShr (d,a,b) -> args.(d) <- SOp (">>",args.(a),args.(b)) | OUShr (d,a,b) -> args.(d) <- SOp (">>>",args.(a),args.(b)) | OAnd (d,a,b) -> args.(d) <- SOp ("&",args.(a),args.(b)) | OOr (d,a,b) -> args.(d) <- SOp ("|",args.(a),args.(b)) | OXor (d,a,b) -> args.(d) <- SOp ("^",args.(a),args.(b)) | ONeg (d,r) -> args.(d) <- SUnop ("-",args.(r)) | ONot (d,r) -> args.(d) <- SUnop ("!",args.(r)) | OIncr r -> args.(r) <- SUnop ("++",args.(r)) | ODecr r -> args.(r) <- SUnop ("++",args.(r)) | OCall0 (d,f) -> args.(d) <- make_call (SFid f) [] | OCall1 (d,f,a) -> args.(d) <- make_call (SFid f) [args.(a)] | OCall2 (d,f,a,b) -> args.(d) <- make_call (SFid f) [args.(a);args.(b)] | OCall3 (d,f,a,b,c) -> args.(d) <- make_call (SFid f) [args.(a);args.(b);args.(c)] | OCall4 (d,f,a,b,c,k) -> args.(d) <- make_call (SFid f) [args.(a);args.(b);args.(c);args.(k)] | OCallN (d,f,rl) -> args.(d) <- make_call (SFid f) (List.map (fun r -> args.(r)) rl) | OCallMethod (d,fid,rl) -> args.(d) <- make_call (SMethod fid) (List.map (fun r -> args.(r)) rl) | OCallThis (d,fid,rl) -> args.(d) <- make_call (SMethod fid) (List.map (fun r -> args.(r)) (0 :: rl)) | OCallClosure (d,r,rl) -> args.(d) <- make_call (SClosure args.(r)) (List.map (fun r -> args.(r)) rl) | OStaticClosure (d,fid) -> args.(d) <- SFun (fid,None) | OInstanceClosure (d,fid,r) -> args.(d) <- SFun (fid,Some args.(r)) | OVirtualClosure (d,r,index) -> args.(d) <- SMeth (args.(r),index) | OGetGlobal (d,g) -> args.(d) <- SGlobal g | OSetGlobal (g,r) -> semit (SGlobalSet (g,args.(r))) | OField (d,r,f) -> args.(d) <- SField (args.(r),f) | OSetField (o,f,r) -> semit (SFieldSet (args.(o),f,args.(r))) | OGetThis (d,fid) -> args.(d) <- SField (args.(0),fid) | OSetThis (f,r) -> semit (SFieldSet (args.(0),f,args.(r))) | ODynGet (d,o,f) -> args.(d) <- SDField (args.(o),code.strings.(f)) | ODynSet (o,f,v) -> semit (SFieldDSet (args.(o),code.strings.(f),args.(v))) | OJTrue (r,_) -> semit (SJEq ("true",args.(r))) | OJFalse (r,_) -> semit (SJEq ("false",args.(r))) | OJNull (r,_) -> semit (SJEq ("null",args.(r))) | OJNotNull (r,_) -> semit (SJEq ("not null",args.(r))) | OJSLt (a,b,_) -> semit (SJComp ("<",args.(a),args.(b))) | OJSGte (a,b,_) -> semit (SJComp (">=",args.(a),args.(b))) | OJSGt (a,b,_) -> semit (SJComp (">",args.(a),args.(b))) | OJSLte (a,b,_) -> semit (SJComp ("<=",args.(a),args.(b))) | OJULt (a,b,_) -> semit (SJComp (" semit (SJComp (">=!",args.(a),args.(b))) | OJEq (a,b,_) -> semit (SJComp ("==",args.(a),args.(b))) | OJNotEq (a,b,_) -> semit (SJComp ("!=",args.(a),args.(b))) | OJAlways _ -> semit SJump | OToDyn (d,r) -> args.(d) <- SConv ("dyn",args.(r)) | OToSFloat (d,r) -> args.(d) <- SConv ("sfloat",args.(r)) | OToUFloat (d,r) -> args.(d) <- SConv ("ufloat",args.(r)) | OToInt (d,r) -> args.(d) <- SConv ("int",args.(r)) | OSafeCast (d,r) -> args.(d) <- SCast (args.(r),f.regs.(d)) | OUnsafeCast (d,r) -> args.(d) <- SConv ("cast", args.(r)) | OToVirtual (d,r) -> args.(d) <- SConv ("virtual",args.(r)) | OLabel _ -> () | ORet r -> semit (SRet (if f.regs.(r) = HVoid then SUndef else args.(r))); if i < b.bend then for i = 0 to Array.length args - 1 do args.(i) <- SUnreach done | OThrow r | ORethrow r -> semit (SThrow args.(r)); if i < b.bend then for i = 0 to Array.length args - 1 do args.(i) <- SUnreach done | OSwitch (r,_,_) -> semit (SSwitch args.(r)) | ONullCheck r -> semit (SNullCheck args.(r)) | OTrap _ | OEndTrap _ -> () | OGetUI8 (d,b,i) -> args.(d) <- SMem (args.(b),args.(i),HUI8) | OGetUI16 (d,b,i) -> args.(d) <- SMem (args.(b),args.(i),HUI16) | OGetI32 (d,b,i) -> args.(d) <- SMem (args.(b),args.(i),HI32) | OGetF32 (d,b,i) -> args.(d) <- SMem (args.(b),args.(i),HF32) | OGetF64 (d,b,i) -> args.(d) <- SMem (args.(b),args.(i),HF64) | OGetArray (d,b,i) -> args.(d) <- SMem (args.(b),args.(i),HArray) | OSetUI8 (b,i,v) -> semit (SWriteMem (args.(b),args.(i),args.(v),HUI8)) | OSetUI16 (b,i,v) -> semit (SWriteMem (args.(b),args.(i),args.(v),HUI16)) | OSetI32 (b,i,v) -> semit (SWriteMem (args.(b),args.(i),args.(v),HI32)) | OSetF32 (b,i,v) -> semit (SWriteMem (args.(b),args.(i),args.(v),HF32)) | OSetF64 (b,i,v) -> semit (SWriteMem (args.(b),args.(i),args.(v),HF64)) | OSetArray (b,i,v) -> semit (SWriteMem (args.(b),args.(i),args.(v),HArray)) | ONew d -> incr alloc_count; args.(d) <- emit (SNew (f.regs.(d),!alloc_count)) | OArraySize (d,r) -> args.(d) <- SConv ("size",args.(r)) | OType (d,t) -> args.(d) <- SType t | OGetType (d,r) -> args.(d) <- SConv ("type",args.(r)) | OGetTID (d,r) -> args.(d) <- SConv ("tid",args.(r)) | ORef (d,r) -> args.(d) <- SRef r | OUnref (d,r) -> (match args.(r) with | SRef r -> args.(d) <- args.(r) | _ -> args.(d) <- SConv ("unref",args.(r))) | OSetref (r,v) -> (match args.(r) with | SRef r -> args.(r) <- args.(v) | _ -> ()); semit (SSetRef (args.(r),args.(v))) | OMakeEnum (d,fid,rl) -> args.(d) <- SEnum (fid, List.map (fun r -> args.(r)) rl) | OEnumAlloc (d,fid) -> args.(d) <- SEnum (fid, []) | OEnumIndex (d,r) -> args.(d) <- SConv ("index",args.(r)) | OEnumField (d,r,fid,cid) -> args.(d) <- SEnumField (args.(r),fid,cid) | OSetEnumField (e,fid,r) -> semit (SSetEnumField (args.(e),fid,args.(r))) | ONop _ -> () done; Hashtbl.add block_args b.bstart args in let all_blocks, _ = Hlopt.code_graph f in let rec loop i = if i = Array.length f.code then () else if not (Hashtbl.mem all_blocks i) then loop (i + 1) else (* unreachable code *) let b = try Hashtbl.find all_blocks i with Not_found -> failwith (Printf.sprintf "Missing block %s(%d)" (fundecl_name f) i) in calc_spec b; loop (b.bend + 1) in loop 0; List.rev !out_spec haxe_3.4.4.orig/src/generators/hlopt.ml0000664000175000017500000005536013166552354020045 0ustar andyandy00000000000000(* * Copyright (C)2005-2017 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 Hlcode module ISet = Set.Make(struct let compare = Pervasives.compare type t = int end) type cur_value = | VUndef | VReg of int type reg_state = { mutable rindex : int; mutable ralias : reg_state; mutable rbind : reg_state list; mutable rnullcheck : bool; } type block = { bstart : int; mutable bend : int; mutable bnext : block list; mutable bprev : block list; mutable bloop : bool; mutable bstate : reg_state array option; mutable bneed : ISet.t; mutable bneed_all : ISet.t option; mutable bwrite : (int, int) PMap.t; } type control = | CNo | CJCond of int | CJAlways of int | CTry of int | CSwitch of int array | CRet | CThrow | CLabel let control = function | OJTrue (_,d) | OJFalse (_,d) | OJNull (_,d) | OJNotNull (_,d) | OJSLt (_,_,d) | OJSGte (_,_,d) | OJSGt (_,_,d) | OJSLte (_,_,d) | OJULt (_,_,d) | OJUGte (_,_,d) | OJEq (_,_,d) | OJNotEq (_,_,d) -> CJCond d | OJAlways d -> CJAlways d | OLabel _ -> CLabel | ORet _ -> CRet | OThrow _ | ORethrow _ -> CThrow | OSwitch (_,cases,_) -> CSwitch cases | OTrap (_,d) -> CTry d | _ -> CNo let opcode_fx frw op = let read r = frw r true and write r = frw r false in match op with | OMov (d,a) | ONeg (d,a) | ONot (d,a) -> read a; write d | OInt (d,_) | OFloat (d,_) | OBool (d,_) | OBytes (d,_) | OString (d,_) | ONull d -> write d | OAdd (d,a,b) | OSub (d,a,b) | OMul (d,a,b) | OSDiv (d,a,b) | OUDiv (d,a,b) | OSMod (d,a,b)| OUMod (d,a,b) | OShl (d,a,b) | OSShr (d,a,b) | OUShr (d,a,b) | OAnd (d,a,b) | OOr (d,a,b) | OXor (d,a,b) -> read a; read b; write d | OIncr a | ODecr a -> read a; write a | OCall0 (d,_) -> write d | OCall1 (d,_,a) -> read a; write d | OCall2 (d,_,a,b) -> read a; read b; write d | OCall3 (d,_,a,b,c) -> read a; read b; read c; write d | OCall4 (d,_,a,b,c,k) -> read a; read b; read c; read k; write d | OCallN (d,_,rl) | OCallMethod (d,_,rl) | OCallThis (d,_,rl) -> List.iter read rl; write d | OCallClosure (d,f,rl) -> read f; List.iter read rl; write d | OStaticClosure (d,_) -> write d | OInstanceClosure (d, _, a) | OVirtualClosure (d,a,_) -> read a; write d | OGetGlobal (d,_) -> write d | OSetGlobal (_,a) -> read a; | OField (d,a,_) | ODynGet (d,a,_) -> read a; write d | OSetField (a,_,b) | ODynSet (a,_,b)-> read a; read b | OGetThis (d,_) -> write d | OSetThis (_,a) -> read a | OJTrue (r,_) | OJFalse (r,_) | OJNull (r,_) | OJNotNull (r,_) -> read r | OJSLt (a,b,_) | OJSGte (a,b,_) | OJSGt (a,b,_) | OJSLte (a,b,_) | OJULt (a,b,_) | OJUGte (a,b,_) | OJEq (a,b,_) | OJNotEq (a,b,_) -> read a; read b; | OJAlways _ | OLabel _ -> () | OToDyn (d, a) | OToSFloat (d,a) | OToUFloat (d,a) | OToInt (d,a) | OSafeCast (d,a) | OUnsafeCast (d,a) | OToVirtual (d,a) -> read a; write d | ORet r | OThrow r | ORethrow r | OSwitch (r,_,_) | ONullCheck r -> read r | OTrap (r,_) -> write r | OEndTrap _ -> () (* ??? *) | OGetUI8 (d,a,b) | OGetUI16 (d,a,b) | OGetI32 (d,a,b) | OGetF32 (d,a,b) | OGetF64 (d,a,b) | OGetArray (d,a,b) -> read a; read b; write d | OSetUI8 (a,b,c) | OSetUI16 (a,b,c) | OSetI32 (a,b,c) | OSetF32 (a,b,c) | OSetF64 (a,b,c) | OSetArray (a,b,c) -> read a; read b; read c | ONew d -> write d | OArraySize (d, a) | OGetType (d,a) | OGetTID (d,a) | ORef (d, a) | OUnref (d,a) | OSetref (d, a) | OEnumIndex (d, a) | OEnumField (d,a,_,_) -> read a; write d | OType (d,_) | OEnumAlloc (d,_) -> write d | OMakeEnum (d,_,rl) -> List.iter read rl; write d | OSetEnumField (a,_,b) -> read a; read b | ONop _ -> () let opcode_eq a b = match a, b with | OType (r1,t1), OType (r2,t2) -> r1 = r2 && t1 == t2 | _ -> a = b let opcode_map read write op = match op with | OMov (d,a) -> let a = read a in OMov (write d, a) | ONeg (d,a) -> let a = read a in ONeg (write d, a) | ONot (d,a) -> let a = read a in ONot (write d, a) | OInt (d,idx) -> OInt (write d, idx) | OFloat (d,idx) -> OFloat (write d, idx) | OBool (d,idx) -> OBool (write d, idx) | OBytes (d,idx) -> OBytes (write d, idx) | OString (d,idx) -> OString (write d, idx) | ONull d -> ONull (write d) | OAdd (d,a,b) -> let a = read a and b = read b in OAdd (write d, a, b) | OSub (d,a,b) -> let a = read a and b = read b in OSub (write d, a, b) | OMul (d,a,b) -> let a = read a and b = read b in OMul (write d, a, b) | OSDiv (d,a,b) -> let a = read a and b = read b in OSDiv (write d, a, b) | OUDiv (d,a,b) -> let a = read a and b = read b in OUDiv (write d, a, b) | OSMod (d,a,b) -> let a = read a and b = read b in OSMod (write d, a, b) | OUMod (d,a,b) -> let a = read a and b = read b in OUMod (write d, a, b) | OShl (d,a,b) -> let a = read a and b = read b in OShl (write d, a, b) | OSShr (d,a,b) -> let a = read a and b = read b in OSShr (write d, a, b) | OUShr (d,a,b) -> let a = read a and b = read b in OUShr (write d, a, b) | OAnd (d,a,b) -> let a = read a and b = read b in OAnd (write d, a, b) | OOr (d,a,b) -> let a = read a and b = read b in OOr (write d, a, b) | OXor (d,a,b) -> let a = read a and b = read b in OXor (write d, a, b) | OIncr a -> OIncr (write a) | ODecr a -> ODecr (write a) | OCall0 (d,f) -> OCall0 (write d, f) | OCall1 (d,f,a) -> let a = read a in OCall1 (write d, f, a) | OCall2 (d,f,a,b) -> let a = read a in let b = read b in OCall2 (write d, f, a, b) | OCall3 (d,f,a,b,c) -> let a = read a in let b = read b in let c = read c in OCall3 (write d, f, a, b, c) | OCall4 (w,f,a,b,c,d) -> let a = read a in let b = read b in let c = read c in let d = read d in OCall4 (write w, f, a, b, c, d) | OCallN (d,f,rl) -> let rl = List.map read rl in OCallN (write d, f, rl) | OCallMethod (d,f,rl) -> let rl = List.map read rl in OCallMethod (write d, f, rl) | OCallThis (d,f,rl) -> let rl = List.map read rl in OCallThis (write d, f, rl) | OCallClosure (d,f,rl) -> let f = read f in let rl = List.map read rl in OCallClosure (write d, f, rl) | OStaticClosure (d,f) -> OStaticClosure (write d, f) | OInstanceClosure (d, f, a) -> let a = read a in OInstanceClosure (write d, f, a) | OVirtualClosure (d,a,f) -> let a = read a in OVirtualClosure (write d, a, f) | OGetGlobal (d,g) -> OGetGlobal (write d, g) | OSetGlobal (g,r) -> OSetGlobal (g, read r) | OField (d,a,f) -> let a = read a in OField (write d, a, f) | ODynGet (d,a,f) -> let a = read a in ODynGet (write d, a, f) | OSetField (a,f,b) -> OSetField (read a, f, read b) | ODynSet (a,f,b) -> ODynSet (read a, f, read b) | OGetThis (d,f) -> OGetThis (write d, f) | OSetThis (f,a) -> OSetThis (f, read a) | OJTrue (r,d) -> OJTrue (read r, d) | OJFalse (r,d) -> OJFalse (read r, d) | OJNull (r,d) -> OJNull (read r, d) | OJNotNull (r,d) -> OJNotNull (read r, d) | OJSLt (a,b,d) -> OJSLt (read a, read b, d) | OJSGte (a,b,d) -> OJSGte (read a, read b, d) | OJSGt (a,b,d) -> OJSGt (read a, read b, d) | OJSLte (a,b,d) -> OJSLte (read a, read b, d) | OJULt (a,b,d) -> OJULt (read a, read b, d) | OJUGte (a,b,d) -> OJUGte (read a, read b, d) | OJEq (a,b,d) -> OJEq (read a, read b, d) | OJNotEq (a,b,d) -> OJNotEq (read a, read b, d) | OJAlways _ | OLabel _ -> op | OToDyn (d, a) -> let a = read a in OToDyn (write d, a) | OToSFloat (d,a) -> let a = read a in OToSFloat (write d, a) | OToUFloat (d,a) -> let a = read a in OToUFloat (write d, a) | OToInt (d,a) -> let a = read a in OToInt (write d, a) | OSafeCast (d,a) -> let a = read a in OSafeCast (write d, a) | OUnsafeCast (d,a) -> let a = read a in OUnsafeCast (write d, a) | OToVirtual (d,a) -> let a = read a in OToVirtual (write d, a) | ORet r -> ORet (read r) | OThrow r -> OThrow (read r) | ORethrow r -> ORethrow (read r) | OSwitch (r,cases,def) -> OSwitch (read r, cases, def) | ONullCheck r -> ONullCheck (read r) | OTrap (r,d) -> OTrap (write r, d) | OEndTrap _ -> op (* ??? *) | OGetUI8 (d,a,b) -> let a = read a and b = read b in OGetUI8 (write d, a, b) | OGetUI16 (d,a,b) -> let a = read a and b = read b in OGetUI16 (write d, a, b) | OGetI32 (d,a,b) -> let a = read a and b = read b in OGetI32 (write d, a, b) | OGetF32 (d,a,b) -> let a = read a and b = read b in OGetF32 (write d, a, b) | OGetF64 (d,a,b) -> let a = read a and b = read b in OGetF64 (write d, a, b) | OGetArray (d,a,b) -> let a = read a and b = read b in OGetArray (write d, a, b) | OSetUI8 (a,b,c) -> let a = read a and b = read b and c = read c in OSetUI8 (a, b, c) | OSetUI16 (a,b,c) -> let a = read a and b = read b and c = read c in OSetUI16 (a, b, c) | OSetI32 (a,b,c) -> let a = read a and b = read b and c = read c in OSetI32 (a, b, c) | OSetF32 (a,b,c) -> let a = read a and b = read b and c = read c in OSetF32 (a, b, c) | OSetF64 (a,b,c) -> let a = read a and b = read b and c = read c in OSetF64 (a, b, c) | OSetArray (a,b,c) -> let a = read a and b = read b and c = read c in OSetArray (a, b, c) | ONew d -> ONew (write d) | OArraySize (d, a) -> let a = read a in OArraySize (write d, a) | OGetType (d,a) -> let a = read a in OGetType (write d, a) | OGetTID (d,a) -> let a = read a in OGetTID (write d, a) | ORef (d, a) -> let a = read a in ORef (write d, a) | OUnref (d,a) -> let a = read a in OUnref (write d, a) | OSetref (d, a) -> let a = read a in OSetref (write d, a) | OEnumIndex (d, a) -> let a = read a in OEnumIndex (write d, a) | OEnumField (d,a,cs,idx) -> let a = read a in OEnumField (write d, a, cs, idx) | OType (d,t) -> OType (write d, t) | OEnumAlloc (d,e) -> OEnumAlloc (write d, e) | OMakeEnum (d,e,rl) -> let rl = List.map read rl in OMakeEnum (write d, e, rl) | OSetEnumField (a,f,b) -> OSetEnumField (read a, f, read b) | ONop _ -> op (* build code graph *) let code_graph (f:fundecl) = let op index = f.code.(index) in let blocks_pos = Hashtbl.create 0 in let all_blocks = Hashtbl.create 0 in for i = 0 to Array.length f.code - 1 do match control (op i) with | CJAlways d | CJCond d -> Hashtbl.replace all_blocks (i + 1 + d) true | _ -> () done; let rec make_block pos = try Hashtbl.find blocks_pos pos with Not_found -> let b = { bstart = pos; bend = 0; bnext = []; bprev = []; bloop = false; bstate = None; bneed = ISet.empty; bwrite = PMap.empty; bneed_all = None; } in Hashtbl.add blocks_pos pos b; let rec loop i = let goto d = let b2 = make_block (i + 1 + d) in b2.bprev <- b :: b2.bprev; b2 in if i > pos && Hashtbl.mem all_blocks i then begin b.bend <- i - 1; b.bnext <- [goto (-1)]; end else match control (op i) with | CNo -> loop (i + 1) | CRet | CThrow -> b.bend <- i | CJAlways d -> b.bend <- i; b.bnext <- [goto d]; | CSwitch pl -> b.bend <- i; b.bnext <- goto 0 :: Array.to_list (Array.map goto pl) | CJCond d | CTry d -> b.bend <- i; b.bnext <- [goto 0; goto d]; | CLabel -> b.bloop <- true; loop (i + 1) in loop pos; b in blocks_pos, make_block 0 let optimize dump (f:fundecl) = let nregs = Array.length f.regs in let old_code = match dump with None -> f.code | Some _ -> Array.copy f.code in let op index = f.code.(index) in let set_op index op = f.code.(index) <- op in let nop_count = ref 0 in let set_nop index r = f.code.(index) <- (ONop r); incr nop_count in let write str = match dump with None -> () | Some ch -> IO.nwrite ch (str ^ "\n") in let blocks_pos, root = code_graph f in let read_counts = Array.make nregs 0 in let write_counts = Array.make nregs 0 in let last_write = Array.make nregs (-1) in let bit_regs = 30 in let stride = (nregs + bit_regs - 1) / bit_regs in let live_bits = Array.make (Array.length f.code * stride) 0 in let set_live r min max = let offset = r / bit_regs in let mask = 1 lsl (r - offset * bit_regs) in if min < 0 || max >= Array.length f.code then assert false; for i=min to max do let p = i * stride + offset in Array.unsafe_set live_bits p ((Array.unsafe_get live_bits p) lor mask); done; in let is_live r i = let offset = r / bit_regs in let mask = 1 lsl (r - offset * bit_regs) in live_bits.(i * stride + offset) land mask <> 0 in let read_count r = read_counts.(r) <- read_counts.(r) + 1 in let write_count r = write_counts.(r) <- write_counts.(r) + 1 in let empty_state() = Array.init nregs (fun i -> let r = { rindex = i; ralias = Obj.magic 0; rbind = []; rnullcheck = false } in r.ralias <- r; r ) in let print_state i s = let state_str s = if s.ralias == s && s.rbind == [] then "" else Printf.sprintf "%d%s[%s]" s.rindex (if s.ralias == s then "" else "=" ^ string_of_int s.ralias.rindex) (String.concat "," (List.map (fun s -> string_of_int s.rindex) s.rbind)) in write (Printf.sprintf "@%X %s" i (String.concat " " (Array.to_list (Array.map state_str s)))) in let dstate = false in let rec propagate b = let state = if b.bloop then empty_state() else match b.bprev with | [] -> empty_state() | b2 :: l -> let s = get_state b2 in let s = (match b2.bnext with | [] -> assert false | [_] -> s (* reuse *) | _ :: l -> let s2 = empty_state() in for i = 0 to nregs - 1 do let sold = s.(i) and snew = s2.(i) in snew.ralias <- s2.(sold.ralias.rindex); snew.rbind <- List.map (fun b -> s2.(b.rindex)) sold.rbind; snew.rnullcheck <- sold.rnullcheck; done; s2 ) in List.iter (fun b2 -> let s2 = get_state b2 in for i = 0 to nregs - 1 do let s1 = s.(i) and s2 = s2.(i) in if s1.ralias.rindex <> s2.ralias.rindex then s1.ralias <- s1 done; for i = 0 to nregs - 1 do let s1 = s.(i) and s2 = s2.(i) in s1.rbind <- List.filter (fun s -> s.ralias == s1) s1.rbind; s1.rnullcheck <- s1.rnullcheck && s2.rnullcheck; (match s2.rbind with | [] -> () | l -> s1.rbind <- List.fold_left (fun acc sb2 -> let s = s.(sb2.rindex) in if s.ralias == s1 && not (List.memq s s1.rbind) then s :: acc else acc) s1.rbind s2.rbind) done; ) l; s in let unalias r = r.ralias.rbind <- List.filter (fun r2 -> r2 != r) r.ralias.rbind; r.ralias <- r in let rec loop i = let do_read r = let w = last_write.(r) in if w < b.bstart || w > i then begin last_write.(r) <- i; set_live r b.bstart i; b.bneed <- ISet.add r b.bneed; end else set_live r (w + 1) i; read_count r in let do_write r = let s = state.(r) in List.iter (fun s2 -> s2.ralias <- s2) s.rbind; s.rbind <- []; s.rnullcheck <- false; last_write.(r) <- i; b.bwrite <- PMap.add r i b.bwrite; write_count r; unalias s in if i > b.bend then () else let op = op i in if dstate then print_state i state; (match op with | OIncr r | ODecr r | ORef (_,r) -> unalias state.(r) | OCallClosure (_,r,_) when f.regs.(r) = HDyn && (match f.regs.(state.(r).ralias.rindex) with HFun (_,rt) -> not (is_dynamic rt) | HDyn -> false | _ -> true) -> unalias state.(r) (* Issue3218.hx *) | _ -> ()); let op = opcode_map (fun r -> let s = state.(r) in s.ralias.rindex ) (fun w -> w) op in set_op i op; (match op with | OMov (d, v) when d = v -> set_nop i "mov" | OMov (d, v) -> let sv = state.(v) in let sd = state.(d) in do_read v; do_write d; sd.ralias <- sv; sd.rnullcheck <- sv.rnullcheck; if not (List.memq sd sv.rbind) then sv.rbind <- sd :: sv.rbind; | OIncr r | ODecr r -> do_read r; do_write r; | ONullCheck r -> let s = state.(r) in if s.rnullcheck then set_nop i "nullcheck" else begin do_read r; s.rnullcheck <- true; end; | _ -> opcode_fx (fun r read -> if read then do_read r else do_write r ) op ); loop (i + 1) in loop b.bstart; b.bstate <- Some state; List.iter (fun b2 -> ignore (get_state b2)) b.bnext and get_state b = match b.bstate with | None -> (* recurse before calculating *) List.iter (fun b2 -> if b2.bstart < b.bstart then ignore(get_state b2)) b.bprev; (match b.bstate with | None -> propagate b; get_state b | Some b -> b); | Some state -> state in propagate root; (* unreachable code *) let rec loop i = if i = Array.length f.code then () else try let b = Hashtbl.find blocks_pos i in loop (b.bend + 1) with Not_found -> (match op i with | OEndTrap true -> () | _ -> set_nop i "unreach"); loop (i + 1) in loop 0; (* liveness *) let rec live b = match b.bneed_all with | Some a -> a | None -> let need_sub = List.fold_left (fun acc b2 -> (* loop : first pass does not recurse, second pass uses cache *) if b2.bloop && b2.bstart < b.bstart then (match b2.bneed_all with None -> acc | Some s -> ISet.union acc s) else ISet.union acc (live b2) ) ISet.empty b.bnext in let need_sub = ISet.filter (fun r -> try let w = PMap.find r b.bwrite in set_live r (w + 1) b.bend; false with Not_found -> set_live r b.bstart b.bend; true ) need_sub in let need = ISet.union b.bneed need_sub in b.bneed_all <- Some need; if b.bloop then begin (* if we are a loop, we need a second pass to perform fixed point first clear the cache within the loop from backward then rebuild the cache to make sure liveness ranges are correctly set *) let rec clear b2 = match b2.bneed_all with | Some _ when b2.bstart > b.bstart -> b2.bneed_all <- None; List.iter clear b2.bprev | _ -> () in List.iter (fun b2 -> if b2.bstart > b.bstart then clear b2) b.bprev; List.iter (fun b -> ignore(live b)) b.bnext; end; need in ignore(live root); (* nop *) for i=0 to Array.length f.code - 1 do (match op i with | OMov (d,r) when not (is_live d (i + 1)) -> let n = read_counts.(r) - 1 in read_counts.(r) <- n; write_counts.(d) <- write_counts.(d) - 1; set_nop i "unused" | _ -> ()); done; (* reg map *) let used_regs = ref 0 in let reg_map = read_counts in let nargs = (match f.ftype with HFun (args,_) -> List.length args | _ -> assert false) in for i=0 to nregs-1 do if read_counts.(i) > 0 || write_counts.(i) > 0 || i < nargs then begin reg_map.(i) <- !used_regs; incr used_regs; end else reg_map.(i) <- -1; done; let reg_remap = !used_regs <> nregs in (* done *) if dump <> None then begin let rec loop i block = if i = Array.length f.code then () else let block = try let b = Hashtbl.find blocks_pos i in write (Printf.sprintf "\t----- [%s] (%X)" (String.concat "," (List.map (fun b -> Printf.sprintf "%X" b.bstart) b.bnext)) b.bend ); let need = String.concat "," (List.map string_of_int (ISet.elements b.bneed)) in let wr = String.concat " " (List.rev (PMap.foldi (fun r p acc -> Printf.sprintf "r%d:%X" r p :: acc) b.bwrite [])) in write ("\t" ^ (if b.bloop then "LOOP " else "") ^ "NEED=" ^ need ^ "\tWRITE=" ^ wr); b with Not_found -> block in let old = old_code.(i) in let op = op i in let rec live_loop r l = if r = nregs then List.rev l else live_loop (r + 1) (if is_live r i then r :: l else l) in let live = "LIVE=" ^ String.concat "," (List.map string_of_int (live_loop 0 [])) in write (Printf.sprintf "\t@%-3X %-20s %-20s%s" i (ostr string_of_int old) (if opcode_eq old op then "" else ostr string_of_int op) live); loop (i + 1) block in write (Printf.sprintf "%s@%d" (fundecl_name f) f.findex); if reg_remap then begin for i=0 to nregs-1 do write (Printf.sprintf "\tr%-2d %-10s%s" i (tstr f.regs.(i)) (if reg_map.(i) < 0 then " unused" else if reg_map.(i) = i then "" else Printf.sprintf " r%-2d" reg_map.(i))) done; end; loop 0 root; write ""; write ""; (match dump with None -> () | Some ch -> IO.flush ch); end; (* remap *) let code = ref f.code in let regs = ref f.regs in let debug = ref f.debug in if !nop_count > 0 || reg_remap then begin let new_pos = Array.make (Array.length f.code) 0 in let jumps = ref [] in let out_pos = ref 0 in let out_code = Array.make (Array.length f.code - !nop_count) (ONop "") in let new_debug = Array.make (Array.length f.code - !nop_count) (0,0) in Array.iteri (fun i op -> Array.unsafe_set new_pos i !out_pos; match op with | ONop _ -> () | _ -> (match op with | OJTrue _ | OJFalse _ | OJNull _ | OJNotNull _ | OJSLt _ | OJSGte _ | OJSGt _ | OJSLte _ | OJULt _ | OJUGte _ | OJEq _ | OJNotEq _ | OJAlways _ | OSwitch _ | OTrap _ -> jumps := i :: !jumps | _ -> ()); let op = if reg_remap then opcode_map (fun r -> reg_map.(r)) (fun r -> reg_map.(r)) op else op in out_code.(!out_pos) <- op; new_debug.(!out_pos) <- f.debug.(i); incr out_pos ) f.code; List.iter (fun j -> let pos d = new_pos.(j + 1 + d) - new_pos.(j + 1) in let p = new_pos.(j) in out_code.(p) <- (match out_code.(p) with | OJTrue (r,d) -> OJTrue (r,pos d) | OJFalse (r,d) -> OJFalse (r,pos d) | OJNull (r,d) -> OJNull (r, pos d) | OJNotNull (r,d) -> OJNotNull (r, pos d) | OJSLt (a,b,d) -> OJSLt (a,b,pos d) | OJSGte (a,b,d) -> OJSGte (a,b,pos d) | OJSLte (a,b,d) -> OJSLte (a,b,pos d) | OJSGt (a,b,d) -> OJSGt (a,b,pos d) | OJULt (a,b,d) -> OJULt (a,b,pos d) | OJUGte (a,b,d) -> OJUGte (a,b,pos d) | OJEq (a,b,d) -> OJEq (a,b,pos d) | OJNotEq (a,b,d) -> OJNotEq (a,b,pos d) | OJAlways d -> OJAlways (pos d) | OSwitch (r,cases,send) -> OSwitch (r, Array.map pos cases, pos send) | OTrap (r,d) -> OTrap (r,pos d) | _ -> assert false) ) !jumps; code := out_code; debug := new_debug; if reg_remap then begin let new_regs = Array.make !used_regs HVoid in for i=0 to nregs-1 do let p = reg_map.(i) in if p >= 0 then new_regs.(p) <- f.regs.(i) done; regs := new_regs; end; end; { f with code = !code; regs = !regs; debug = !debug }haxe_3.4.4.orig/src/globals.ml0000664000175000017500000000220013166552354016152 0ustar andyandy00000000000000type pos = { pfile : string; pmin : int; pmax : int; } module IntMap = Map.Make(struct type t = int let compare a b = a - b end) module StringMap = Map.Make(struct type t = string let compare = String.compare end) type platform = | Cross | Js | Lua | Neko | Flash | Php | Cpp | Cs | Java | Python | Hl let version = 3404 let version_major = version / 1000 let version_minor = (version mod 1000) / 100 let version_revision = (version mod 100) let macro_platform = ref Neko let is_windows = Sys.os_type = "Win32" || Sys.os_type = "Cygwin" let s_version = Printf.sprintf "%d.%d.%d%s" version_major version_minor version_revision (match Version.version_extra with None -> "" | Some v -> " " ^ v) let platforms = [ Js; Lua; Neko; Flash; Php; Cpp; Cs; Java; Python; Hl; ] let platform_name = function | Cross -> "cross" | Js -> "js" | Lua -> "lua" | Neko -> "neko" | Flash -> "flash" | Php -> "php" | Cpp -> "cpp" | Cs -> "cs" | Java -> "java" | Python -> "python" | Hl -> "hl" let null_pos = { pfile = "?"; pmin = -1; pmax = -1 } let s_type_path (p,s) = match p with [] -> s | _ -> String.concat "." p ^ "." ^ shaxe_3.4.4.orig/src/json.ml0000664000175000017500000000503313166552354015507 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) type t = | JString of string | JFloat of float | JInt of int | JObject of (string * t) list | JArray of t list | JBool of bool | JNull let write_iter f_el f_sep l = let rec rest = function | [] -> () | v :: l -> f_sep(); f_el v; rest l in match l with | [] -> () | v :: l -> f_el v; rest l let write_sep w = w "," let rec write_json w v = match v with | JNull -> write_null w | JBool b -> write_bool w b | JString s -> write_string w s | JFloat f -> write_float w f | JInt i -> write_int w i | JObject o -> write_object w o | JArray a -> write_array w a and write_null w = w "null" and write_bool w b = w (if b then "true" else "false") and write_string w s = w "\""; let b = Buffer.create (String.length s) in for i = 0 to String.length s - 1 do match String.unsafe_get s i with | '"' -> Buffer.add_string b "\\\"" | '\t' -> Buffer.add_string b "\\t" | '\r' -> Buffer.add_string b "\\r" | '\b' -> Buffer.add_string b "\\b" | '\n' -> Buffer.add_string b "\\n" | '\012' -> Buffer.add_string b "\\f" | '\\' -> Buffer.add_string b "\\\\" | '\x00'..'\x1F' | '\x7F' as c -> Buffer.add_string b (Printf.sprintf "\\u%04X" (int_of_char c)) | c -> Buffer.add_char b c done; w (Buffer.contents b); w "\"" and write_int w i = w (string_of_int i) and write_float w f = match classify_float f with | FP_nan | FP_infinite -> failwith "NaN and infinity floats are unsupported in JSON" | _ -> let s = Printf.sprintf "%.16g" f in let s = if float_of_string s = f then s else Printf.sprintf "%.17g" f in w s and write_array w a = w "["; write_iter (write_json w) (fun() -> write_sep w) a; w "]" and write_object w o = let write_el (k, v) = write_string w k; w ":"; write_json w v in w "{"; write_iter write_el (fun() -> write_sep w) o; w "}" haxe_3.4.4.orig/src/macro/hlmacro.ml0000664000175000017500000004011613166552354017265 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open Type open Ast open Hlcode open Hlinterp open MacroApi type value = Hlinterp.value type context = { com : Common.context; (* macro one *) mutable gen : Genhl.context option; interp : Hlinterp.context; types : (Type.path,int) Hashtbl.t; cached_protos : (obj_type, (virtual_proto * vfield array)) Hashtbl.t; cached_enums : (enum_type, ttype) Hashtbl.t; mutable curapi : value MacroApi.compiler_api; mutable has_error : bool; } exception Error of string * Globals.pos list let debug = true (* TODO !!! set to false for speed++ ! *) let get_ctx_ref = ref (fun() -> assert false) let get_ctx() : context = (!get_ctx_ref)() let macro_lib = Hashtbl.create 0 let interp() = (get_ctx()).interp let setup get_api = let api = get_api (fun() -> (get_ctx()).curapi.get_com()) (fun() -> (get_ctx()).curapi) in List.iter (fun (n,v) -> Hashtbl.replace macro_lib n (match v with VClosure (FNativeFun (_,v,_),None) -> v | _ -> assert false)) api; Globals.macro_platform := Globals.Hl let select ctx = get_ctx_ref := (fun() -> ctx) let error_handler ctx v stack = let make_pos st = let file, line = Hlinterp.make_stack ctx.interp st in let low = line land 0xFFFFF in { Globals.pfile = file; Globals.pmin = low; Globals.pmax = low + (line lsr 20); } in (*let rec loop o = if o == ctx.error_proto then true else match o.oproto with None -> false | Some p -> loop p in (match v with | VObject o when loop o -> (match get_field o (hash "message"), get_field o (hash "pos") with | VObject msg, VAbstract (APos pos) -> (match get_field msg h_s with | VString msg -> raise (Error.Error (Error.Custom msg,pos)) | _ -> ()); | _ -> ()); | _ -> ());*) raise (Error (Hlinterp.vstr ctx.interp v Hlcode.HDyn,List.map make_pos stack)) let create com api = let ctx = { com = com; gen = None; interp = Hlinterp.create debug; curapi = api; types = Hashtbl.create 0; has_error = false; cached_protos = Hashtbl.create 0; cached_enums = Hashtbl.create 0; } in select ctx; Hlinterp.set_error_handler ctx.interp (error_handler ctx); Hlinterp.set_macro_api ctx.interp (fun name -> try Some (Hashtbl.find macro_lib name) with Not_found -> None); ctx let init ctx = if ctx.gen = None then ctx.gen <- Some (Genhl.create_context ctx.com true false) let set_error ctx e = ctx.has_error <- e let add_types ctx types ready = let types = List.filter (fun t -> match t with | TAbstractDecl a when not (Meta.has Meta.CoreType a.a_meta) -> (* A @:native on an abstract causes the implementation class and the abstract to have the same path. Let's skip all abstracts so this doesn't matter. *) false | _ -> let path = Type.t_path t in if Hashtbl.mem ctx.types path then false else begin Hashtbl.add ctx.types path (Type.t_infos t).mt_module.m_id; true; end ) types in List.iter ready types; if ctx.gen = None then init ctx; match ctx.gen with | None -> assert false | Some gen -> Genhl.add_types gen types; if debug then Genhl.check gen; let code = Genhl.build_code gen types None in if debug then begin try Hlinterp.check code true with Failure _ | Common.Abort _ as exn -> let ch = open_out_bin "hlcode.txt" in Hlcode.dump (fun s -> output_string ch (s ^ "\n")) code; close_out ch; raise exn end; Hlinterp.add_code ctx.interp code let do_reuse ctx api = ctx.curapi <- api let can_reuse ctx types = let has_old_version t = let inf = Type.t_infos t in try Hashtbl.find ctx.types inf.mt_path <> inf.mt_module.m_id with Not_found -> false in not (List.exists has_old_version types) let catch_errors ctx ?(final=(fun() -> ())) f = let prev = get_ctx() in (* switch context in case we have an older one, see #5676 *) select ctx; try let v = f() in final(); select prev; Some v with Error _ as e -> final(); select prev; raise e | Abort -> final(); select prev; None let call_path ctx cpath (f:string) args api = if ctx.has_error then None else let old = ctx.curapi in ctx.curapi <- api; let gid = Genhl.resolve_class_global (match ctx.gen with None -> assert false | Some ctx -> ctx) (String.concat "." cpath) in let gval = ctx.interp.Hlinterp.t_globals.(gid) in let fval = Hlinterp.dyn_get_field ctx.interp gval f Hlcode.HDyn in match fval with | Hlinterp.VClosure (f,None) -> catch_errors ~final:(fun() -> ctx.curapi <- old) ctx (fun() -> call_wrap ctx.interp f args) | _ -> prerr_endline (Hlinterp.vstr_d ctx.interp gval); assert false let vnull = VNull let vbool b = VBool b let vint i = VInt (Int32.of_int i) let vint32 i = VInt i let vfloat f = VFloat f let vfun0 f = let callb args = match args with [] -> f() | _ -> assert false in VClosure(FNativeFun ("fun0",callb,HVoid), None) let vfun1 f = let callb args = match args with [a] -> f a | _ -> assert false in VClosure(FNativeFun ("fun1",callb,HVoid), None) let vfun2 f = let callb args = match args with [a;b] -> f a b | _ -> assert false in VClosure(FNativeFun ("fun2",callb,HVoid), None) let vfun3 f = let callb args = match args with [a;b;c] -> f a b c | _ -> assert false in VClosure(FNativeFun ("fun3",callb,HVoid), None) let vfun4 f = let callb args = match args with [a;b;c;d] -> f a b c d | _ -> assert false in VClosure(FNativeFun ("fun4",callb,HVoid), None) let vfun5 f = let callb args = match args with [a;b;c;d;e] -> f a b c d e | _ -> assert false in VClosure(FNativeFun ("fun5",callb,HVoid), None) let exc_string msg = Hlinterp.throw_msg (interp()) msg let compiler_error msg pos = assert false (* TODO : raise haxe.macro.Error(msg,pos) *) let eval_expr ctx (e:texpr) = assert false let eval_delayed _ _ = assert false (* macro - in - macro *) let prepare_callback f n = assert false let encode_pos p = VAbstract (APos p) let decode_pos = function | VAbstract (APos p) -> p | _ -> raise Invalid_expr let last_enum_type = ref IExpr let encode_enum t pos tag pl = last_enum_type := t; match pos with | None -> VEnum (tag,Array.of_list pl) | Some p -> VEnum (tag,Array.of_list (List.rev (encode_pos p :: List.rev pl))) let decode_enum = function | VEnum (tag,arr) -> tag, Array.to_list arr | _ -> raise Invalid_expr let decode_enum_with_pos = function | VEnum (tag,arr) when Array.length arr > 0 && (match arr.(Array.length arr - 1) with VAbstract (APos _) -> true | _ -> false) -> let rec loop i = if i = Array.length arr - 1 then [] else arr.(i) :: loop (i + 1) in (tag, loop 0), decode_pos arr.(Array.length arr - 1) | e -> decode_enum e, Globals.null_pos let encode_tdecl t = VAbstract (ATDecl t) let encode_unsafe o = VAbstract (AUnsafe o) let decode_unsafe = function | VAbstract (AUnsafe v) -> v | _ -> raise Invalid_expr let decode_tdecl = function | VAbstract (ATDecl t) -> t | _ -> raise Invalid_expr let dec_int = function | VInt i -> Int32.to_int i | _ -> raise Invalid_expr let dec_i32 = function | VInt i -> i | _ -> raise Invalid_expr let dec_bool = function | VBool b -> b | _ -> raise Invalid_expr let field o n = match o with | VDynObj _ | VVirtual _ | VObj _ -> Hlinterp.dyn_get_field (interp()) o n HDyn | _ -> raise Invalid_expr let dec_string = function | VObj { ofields = [|VBytes s;VInt _|] } -> Hlinterp.hl_to_caml s | _ -> raise Invalid_expr let dec_array = function | VObj { ofields = [|VInt len;VArray (arr,_)|] } -> let len = Int32.to_int len in let rec loop i = if i = len then [] else arr.(i) :: loop (i+1) in loop 0 | v -> raise Invalid_expr let encode_lazytype f t = VAbstract (ALazyType (f,t)) let decode_lazytype = function | VAbstract (ALazyType (t,_)) -> t | _ -> raise Invalid_expr let enc_obj t fields = match t with | OMetaAccess -> let h = Hashtbl.create 0 in let rec loop i = function | [] -> () | (n,_) :: l -> Hashtbl.add h n i; loop (i + 1) l in loop 0 fields; let values = Array.of_list (List.map snd fields) in VDynObj { dfields = h; dvalues = values; dtypes = Array.make (Array.length values) HDyn; dvirtuals = []; } | _ -> let ctx = get_ctx() in let to_str (name,f) = match f with | None -> name | Some f -> name ^ "." ^ f in let vp, idx = try Hashtbl.find ctx.cached_protos t with Not_found -> let name, field = proto_name t in let gen = (match ctx.gen with None -> assert false | Some gen -> gen) in let vt = (try let t = Hashtbl.find gen.Genhl.macro_typedefs name in (match t, field with | _, None -> t | HVirtual v, Some f -> let idx = (try PMap.find f v.vindex with Not_found -> failwith (name ^ " has no field definition " ^ f)) in let _,_, t = v.vfields.(idx) in (match t with | HVirtual _ -> t | _ -> failwith ("Unexpected type " ^ tstr t ^ " for definition " ^ to_str (name,field))) | _ -> assert false ) with Not_found -> try let t = PMap.find (["haxe";"macro"],name) gen.Genhl.cached_types in (match t, field with | HEnum e, Some f -> let rec loop i = if i = Array.length e.efields then raise Not_found; let n, _, tl = e.efields.(i) in if n = f then tl.(0) else loop (i + 1) in loop 0 | _ -> failwith ("Unexpected type " ^ tstr t ^ " for definition " ^ to_str (name,field))) with Not_found -> failwith ("Macro definition missing " ^ to_str (name,field)) ) in match vt with | HVirtual vp -> let vindexes = Array.map (fun (n,_,_) -> let rec loop i = function | [] -> VFNone | (n2,_) :: _ when n = n2 -> VFIndex i | _ :: l -> loop (i + 1) l in loop 0 fields ) vp.vfields in Hashtbl.replace ctx.cached_protos t (vp, vindexes); vp, vindexes | _ -> failwith (to_str (name,field) ^ " returned invalid type " ^ tstr vt) in if debug then begin let farr = Array.of_list fields in Array.iteri (fun i idx -> let name, _ ,_ = vp.vfields.(i) in match idx with | VFNone -> if List.mem_assoc name fields then failwith ("Field " ^ name ^ " is present in " ^ to_str (proto_name t)) | VFIndex i when i >= Array.length farr -> failwith ("Missing field " ^ name ^ " of " ^ to_str (proto_name t)) | VFIndex i when fst farr.(i) <> name -> failwith ("Field " ^ name ^ " of " ^ to_str (proto_name t) ^ " is wrongly mapped on " ^ fst farr.(i)) | _ -> () ) idx; List.iter (fun (n,_) -> if n <> "name_pos" && not (PMap.mem n vp.vindex) then failwith ("Field " ^ n ^ " has data but is not part of type " ^ to_str (proto_name t)); ) fields; end; VVirtual { vtype = vp; vindexes = idx; vtable = Array.map snd (Array.of_list fields); vvalue = VNull; } let enc_inst path fields = let ctx = get_ctx() in let t = (match ctx.gen with None -> assert false | Some gen -> try Genhl.resolve_type gen path with Not_found -> assert false) in match t with | HObj o -> let proto, _, _ = Hlinterp.get_proto ctx.interp o in VObj { oproto = proto; ofields = fields } | _ -> assert false let enc_string s = enc_inst ([],"String") [|VBytes (caml_to_hl s);VInt (Int32.of_int (String.length s))|] let enc_array vl = let arr = Array.of_list (List.map (fun v -> match v with | VNull | VObj _ | VVirtual _ -> v | VEnum _ -> let ctx = get_ctx() in let et = !last_enum_type in let t = try Hashtbl.find ctx.cached_enums et with Not_found -> let name = enum_name et in let t = (match ctx.gen with | None -> assert false | Some gen -> try PMap.find (["haxe";"macro"],name) gen.Genhl.cached_types with Not_found -> failwith ("Missing enum type " ^ name) ) in Hashtbl.replace ctx.cached_enums et t; t in VDyn (v,t) | _ -> failwith "Invalid array value" ) vl) in enc_inst (["hl";"types"],"ArrayObj") [|VInt (Int32.of_int (Array.length arr));VArray (arr,HDyn)|] let encode_bytes s = enc_inst (["haxe";"io"],"Bytes") [|VInt (Int32.of_int (String.length s)); VBytes s|] let encode_string_map convert pmap = let h = Hashtbl.create 0 in PMap.iter (fun k v -> Hashtbl.add h k (convert v)) pmap; enc_inst (["haxe";"ds"],"StringMap") [|VAbstract (AHashBytes h)|] let decode_bytes = function | VObj { ofields = [|VInt _;VBytes s|] } -> s | _ -> raise Invalid_expr let encode_ref v convert tostr = let h = Hashtbl.create 0 in Hashtbl.add h "get" 0; Hashtbl.add h "__string" 1; Hashtbl.add h "toString" 2; Hashtbl.add h "$" 3; VDynObj { dfields = h; dvalues = [| vfun0 (fun() -> convert v); vfun0 (fun() -> VBytes (caml_to_hl (tostr()))); vfun0 (fun() -> enc_string (tostr())); VAbstract (AUnsafe (Obj.repr v)) |]; dtypes = [| HFun ([],HDyn); HFun ([],HBytes); HFun ([],HDyn); HDyn; |]; dvirtuals = []; } let decode_ref v : 'a = match field v "$" with | VAbstract (AUnsafe t) -> Obj.obj t | _ -> raise Invalid_expr let value_string v = Hlinterp.vstr (get_ctx()).interp v HDyn let value_signature v = failwith "signature() not supported in HL macros" let value_to_expr v p = let ctx = get_ctx() in let error v = failwith ("Unsupported value " ^ vstr ctx.interp v Hlcode.HDyn) in (* let h_enum = hash "__enum__" and h_et = hash "__et__" and h_ct = hash "__ct__" in let h_tag = hash "tag" and h_args = hash "args" in let h_length = hash "length" in let make_path t = let rec loop = function | [] -> assert false | [name] -> (Ast.EConst (Ast.Ident name),p) | name :: l -> (Ast.EField (loop l,name),p) in let t = t_infos t in loop (List.rev (if t.mt_module.m_path = t.mt_path then fst t.mt_path @ [snd t.mt_path] else fst t.mt_module.m_path @ [snd t.mt_module.m_path;snd t.mt_path])) in*) let rec loop = function | VNull -> (Ast.EConst (Ast.Ident "null"),p) | VBool b -> (Ast.EConst (Ast.Ident (if b then "true" else "false")),p) | VInt i -> (Ast.EConst (Ast.Int (Int32.to_string i)),p) | VFloat f -> let std = (Ast.EConst (Ast.Ident "std"), p) in let math = (Ast.EField (std, "Math"), p) in if (f = infinity) then (Ast.EField (math, "POSITIVE_INFINITY"), p) else if (f = neg_infinity) then (Ast.EField (math, "NEGATIVE_INFINITY"), p) else if (f <> f) then (Ast.EField (math, "NaN"), p) else (Ast.EConst (Ast.Float (Common.float_repres f)), p) | VAbstract (APos p) -> (Ast.EObjectDecl ( (("fileName",Globals.null_pos) , (Ast.EConst (Ast.String p.Globals.pfile) , p)) :: (("lineNumber",Globals.null_pos) , (Ast.EConst (Ast.Int (string_of_int (Lexer.get_error_line p))),p)) :: (("className",Globals.null_pos) , (Ast.EConst (Ast.String ("")),p)) :: [] ), p) | VObj { oproto = { pclass = { pname = "String" } }; ofields = [|VBytes content;VInt _|] } -> (Ast.EConst (Ast.String (hl_to_caml content)),p) | v -> error v (* | VObject o as v -> match o.oproto with | None -> (match get_field_opt o h_ct with | Some (VAbstract (ATDecl t)) -> make_path t | _ -> let fields = List.fold_left (fun acc (fid,v) -> ((field_name ctx fid,Globals.null_pos), loop v) :: acc) [] (Array.to_list o.ofields) in (Ast.EObjectDecl fields, p)) | Some proto -> match get_field_opt proto h_enum, get_field_opt o h_a, get_field_opt o h_s, get_field_opt o h_length with | _, Some (VArray a), _, Some (VInt len) -> (Ast.EArrayDecl (List.map loop (Array.to_list (Array.sub a 0 len))),p) | Some (VObject en), _, _, _ -> (match get_field en h_et, get_field o h_tag with | VAbstract (ATDecl t), VString tag -> let e = (Ast.EField (make_path t,tag),p) in (match get_field_opt o h_args with | Some (VArray args) -> let args = List.map loop (Array.to_list args) in (Ast.ECall (e,args),p) | _ -> e) | _ -> error v) | _ -> error v *) in loop v haxe_3.4.4.orig/src/macro/interp.ml0000664000175000017500000026053513166552354017152 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open Common open Nast open Unix open Type open MacroApi (* ---------------------------------------------------------------------- *) (* TYPES *) type value = | VNull | VBool of bool | VInt of int | VFloat of float | VString of string | VObject of vobject | VArray of value array | VAbstract of vabstract | VFunction of vfunction | VClosure of value list * (value list -> value list -> value) | VInt32 of int32 and vobject = { mutable ofields : (int * value) array; mutable oproto : vobject option; } and vabstract = | ADeallocated of int ref | AKind of vabstract | AHash of (value, value) Hashtbl.t | ARandom of Random.State.t ref | ABuffer of Buffer.t | APos of Globals.pos | AFRead of (in_channel * bool ref) | AFWrite of out_channel | AReg of regexp | AZipI of zlib | AZipD of zlib | AUtf8 of UTF8.Buf.buf | ASocket of Unix.file_descr | ATDecl of module_type | AUnsafe of Obj.t | ALazyType of ((unit -> Type.t) ref) * (unit -> value) | ANekoAbstract of Extc.value | ANekoBuffer of value | ACacheRef of value | AInt32Kind | ATls of value ref | AProcess of Process.process and vfunction = | Fun0 of (unit -> value) | Fun1 of (value -> value) | Fun2 of (value -> value -> value) | Fun3 of (value -> value -> value -> value) | Fun4 of (value -> value -> value -> value -> value) | Fun5 of (value -> value -> value -> value -> value -> value) | FunVar of (value list -> value) and regexp = { r : Pcre.regexp; mutable r_string : string; mutable r_groups : int array; } and zlib = { z : Extc.zstream; mutable z_flush : Extc.zflush; } type cmp = | CEq | CSup | CInf | CUndef type callstack = { cpos : pos; cthis : value; cstack : int; cenv : value array; } type context = { gen : Genneko.context; types : (Type.path,int) Hashtbl.t; prototypes : (string list, vobject) Hashtbl.t; fields_cache : (int,string) Hashtbl.t; mutable error : bool; mutable error_proto : vobject; mutable enums : (value * string) array array; mutable do_call : value -> value -> value list -> pos -> value; mutable do_string : value -> string; mutable do_loadprim : value -> value -> value; mutable do_compare : value -> value -> cmp; mutable loader : value; mutable exports : value; (* runtime *) mutable stack : value DynArray.t; mutable callstack : callstack list; mutable callsize : int; mutable exc : pos list; mutable vthis : value; mutable venv : value array; (* context *) mutable curapi : value MacroApi.compiler_api; (* eval *) mutable locals_map : (string, int) PMap.t; mutable locals_count : int; mutable locals_barrier : int; mutable locals_env : string DynArray.t; mutable globals : (string, value ref) PMap.t; } type access = | AccThis | AccLocal of int | AccGlobal of value ref | AccEnv of int | AccField of (unit -> value) * string | AccArray of (unit -> value) * (unit -> value) exception Runtime of value exception Builtin_error exception Error of string * Globals.pos list exception Continue exception Break of value exception Return of value exception Sys_exit of int (* ---------------------------------------------------------------------- *) (* UTILS *) let get_ctx_ref = ref (fun() -> assert false) let get_ctx() = (!get_ctx_ref)() let to_int f = Int32.of_float (mod_float f 2147483648.0) let need_32_bits i = Int32.compare (Int32.logand (Int32.add i 0x40000000l) 0x80000000l) Int32.zero <> 0 let best_int i = if need_32_bits i then VInt32 i else VInt (Int32.to_int i) let macro_lib = Hashtbl.create 0 let setup get_api = let api = get_api (fun() -> (get_ctx()).curapi.get_com()) (fun() -> (get_ctx()).curapi) in List.iter (fun (n,v) -> Hashtbl.replace macro_lib n (match v with VFunction v -> v | _ -> assert false)) api let make_pos p = let low = p.pline land 0xFFFFF in { Globals.pfile = p.psource; Globals.pmin = low; Globals.pmax = low + (p.pline lsr 20); } let warn ctx msg p = (ctx.curapi.get_com()).Common.warning msg (make_pos p) let rec pop ctx n = if n > 0 then begin DynArray.delete_last ctx.stack; pop ctx (n - 1); end let pop_ret ctx f n = let v = f() in pop ctx n; v let push ctx v = DynArray.add ctx.stack v let hash f = let h = ref 0 in for i = 0 to String.length f - 1 do h := !h * 223 + int_of_char (String.unsafe_get f i); done; if Sys.word_size = 64 then Int32.to_int (Int32.shift_right (Int32.shift_left (Int32.of_int !h) 1) 1) else !h let constants = let h = Hashtbl.create 0 in List.iter (fun f -> Hashtbl.add h (hash f) f) ["done";"read";"write";"min";"max";"file";"args";"loadprim";"loadmodule";"__a";"__s";"h"; "tag";"index";"length";"message";"pack";"name";"params";"sub";"doc";"kind";"meta";"access"; "constraints";"opt";"type";"value";"ret";"expr";"field";"values";"get";"__string";"toString"; "$";"add";"remove";"has";"__t";"module";"isPrivate";"isPublic";"isExtern";"isInterface";"exclude"; "constructs";"names";"superClass";"interfaces";"fields";"statics";"constructor";"init";"t"; "gid";"uid";"atime";"mtime";"ctime";"dev";"ino";"nlink";"rdev";"size";"mode";"pos";"len"; "binops";"unops";"from";"to";"array";"op";"isPostfix";"impl";"resolve"; "id";"capture";"extra";"v";"ids";"vars";"en";"overrides";"status";"overloads";"path";"namePos"]; h let h_get = hash "__get" and h_set = hash "__set" and h_add = hash "__add" and h_radd = hash "__radd" and h_sub = hash "__sub" and h_rsub = hash "__rsub" and h_mult = hash "__mult" and h_rmult = hash "__rmult" and h_div = hash "__div" and h_rdiv = hash "__rdiv" and h_mod = hash "__mod" and h_rmod = hash "__rmod" and h_string = hash "__string" and h_compare = hash "__compare" and h_constructs = hash "__constructs__" and h_a = hash "__a" and h_s = hash "__s" and h_class = hash "__class__" let exc v = raise (Runtime v) let exc_string str = exc (VString str) let select ctx = get_ctx_ref := (fun() -> ctx) let s_value_kind = function | VNull -> "VNull" | VBool _ -> "VBool" | VInt _ -> "VInt" | VFloat _ -> "VFloat" | VString _ -> "VString" | VObject _ -> "VObject" | VArray _ -> "VArray" | VAbstract _ -> "VAbstract" | VFunction _ -> "VFunction" | VClosure _ -> "VClosure" | VInt32 _ -> "VInt32" let hash_field ctx f = let h = hash f in (try let f2 = Hashtbl.find ctx.fields_cache h in if f <> f2 then exc (VString ("Field conflict between " ^ f ^ " and " ^ f2)); with Not_found -> Hashtbl.add ctx.fields_cache h f); h let field_name ctx fid = try Hashtbl.find ctx.fields_cache fid with Not_found -> "???" let obj hash fields = let fields = Array.of_list (List.map (fun (k,v) -> hash k, v) fields) in Array.sort (fun (k1,_) (k2,_) -> compare k1 k2) fields; { ofields = fields; oproto = None; } let parse_int s = let rec loop_hex i = if i = String.length s then s else match String.unsafe_get s i with | '0'..'9' | 'a'..'f' | 'A'..'F' -> loop_hex (i + 1) | _ -> String.sub s 0 i in let rec loop sp i = if i = String.length s then (if sp = 0 then s else String.sub s sp (i - sp)) else match String.unsafe_get s i with | '0'..'9' -> loop sp (i + 1) | ' ' when sp = i -> loop (sp + 1) (i + 1) | '-' when i = 0 -> loop sp (i + 1) | ('x' | 'X') when i = 1 && String.get s 0 = '0' -> loop_hex (i + 1) | _ -> String.sub s sp (i - sp) in best_int (Int32.of_string (loop 0 0)) let parse_float s = let rec loop sp i = if i = String.length s then (if sp = 0 then s else String.sub s sp (i - sp)) else match String.unsafe_get s i with | ' ' when sp = i -> loop (sp + 1) (i + 1) | '0'..'9' | '-' | '+' | 'e' | 'E' | '.' -> loop sp (i + 1) | _ -> String.sub s sp (i - sp) in float_of_string (loop 0 0) let find_sub str sub start = let sublen = String.length sub in if sublen = 0 then 0 else let found = ref 0 in let len = String.length str in try for i = start to len - sublen do let j = ref 0 in while String.unsafe_get str (i + !j) = String.unsafe_get sub !j do incr j; if !j = sublen then begin found := i; raise Exit; end; done; done; raise Not_found with Exit -> !found let nargs = function | Fun0 _ -> 0 | Fun1 _ -> 1 | Fun2 _ -> 2 | Fun3 _ -> 3 | Fun4 _ -> 4 | Fun5 _ -> 5 | FunVar _ -> -1 let rec get_field o fid = let rec loop min max = if min < max then begin let mid = (min + max) lsr 1 in let cid, v = Array.unsafe_get o.ofields mid in if cid < fid then loop (mid + 1) max else if cid > fid then loop min mid else v end else match o.oproto with | None -> VNull | Some p -> get_field p fid in loop 0 (Array.length o.ofields) let set_field o fid v = let rec loop min max = let mid = (min + max) lsr 1 in if min < max then begin let cid, _ = Array.unsafe_get o.ofields mid in if cid < fid then loop (mid + 1) max else if cid > fid then loop min mid else Array.unsafe_set o.ofields mid (cid,v) end else let fields = Array.make (Array.length o.ofields + 1) (fid,v) in Array.blit o.ofields 0 fields 0 mid; Array.blit o.ofields mid fields (mid + 1) (Array.length o.ofields - mid); o.ofields <- fields in loop 0 (Array.length o.ofields) let rec remove_field o fid = let rec loop min max = let mid = (min + max) lsr 1 in if min < max then begin let cid, v = Array.unsafe_get o.ofields mid in if cid < fid then loop (mid + 1) max else if cid > fid then loop min mid else begin let fields = Array.make (Array.length o.ofields - 1) (fid,VNull) in Array.blit o.ofields 0 fields 0 mid; Array.blit o.ofields (mid + 1) fields mid (Array.length o.ofields - mid - 1); o.ofields <- fields; true end end else false in loop 0 (Array.length o.ofields) let rec get_field_opt o fid = let rec loop min max = if min < max then begin let mid = (min + max) lsr 1 in let cid, v = Array.unsafe_get o.ofields mid in if cid < fid then loop (mid + 1) max else if cid > fid then loop min mid else Some v end else match o.oproto with | None -> None | Some p -> get_field_opt p fid in loop 0 (Array.length o.ofields) let catch_errors ctx ?(final=(fun() -> ())) f = let n = DynArray.length ctx.stack in let prev = get_ctx() in (* switch context in case we have an older one, see #5676 *) select ctx; try let v = f() in final(); select prev; Some v with Runtime v -> pop ctx (DynArray.length ctx.stack - n); final(); select prev; let rec loop o = if o == ctx.error_proto then true else match o.oproto with None -> false | Some p -> loop p in (match v with | VObject o when loop o -> (match get_field o (hash "message"), get_field o (hash "pos") with | VObject msg, VAbstract (APos pos) -> (match get_field msg h_s with | VString msg -> raise (Error.Error (Error.Custom msg,pos)) | _ -> ()); | _ -> ()); | _ -> ()); raise (Error (ctx.do_string v,List.map (fun s -> make_pos s.cpos) ctx.callstack)) | Abort -> pop ctx (DynArray.length ctx.stack - n); final(); select prev; None let make_library fl = let h = Hashtbl.create 0 in List.iter (fun (n,f) -> Hashtbl.add h n f) fl; h (* ---------------------------------------------------------------------- *) (* NEKO INTEROP *) type primitive = (string * Extc.value * int) type neko_context = { load : string -> int -> primitive; call : primitive -> value list -> value; } (* try to load dl in order *) let rec dlopen dls = let null = Extc.dlint 0 in match dls with | dl_path :: dls -> let dl = Extc.dlopen dl_path in if (Obj.magic dl) == null then dlopen dls else Some dl; | _ -> None (* ---------------------------------------------------------------------- *) (* BUILTINS *) let builtins = let p = { psource = ""; pline = 0 } in let error() = raise Builtin_error in let vint = function | VInt n -> n | _ -> error() in let varray = function | VArray a -> a | _ -> error() in let vstring = function | VString s -> s | _ -> error() in let vobj = function | VObject o -> o | _ -> error() in let vfun = function | VFunction f -> f | VClosure (cl,f) -> FunVar (f cl) | _ -> error() in let vhash = function | VAbstract (AHash h) -> h | _ -> error() in let build_stack sl = let make p = let p = make_pos p in VArray [|VString p.Globals.pfile;VInt (Lexer.get_error_line p)|] in VArray (Array.of_list (List.map make sl)) in let do_closure args args2 = match args with | f :: obj :: args -> (get_ctx()).do_call obj f (args @ args2) p | _ -> assert false in let funcs = [ (* array *) "array", FunVar (fun vl -> VArray (Array.of_list vl)); "amake", Fun1 (fun v -> VArray (Array.create (vint v) VNull)); "acopy", Fun1 (fun a -> VArray (Array.copy (varray a))); "asize", Fun1 (fun a -> VInt (Array.length (varray a))); "asub", Fun3 (fun a p l -> VArray (Array.sub (varray a) (vint p) (vint l))); "ablit", Fun5 (fun dst dstp src p l -> Array.blit (varray src) (vint p) (varray dst) (vint dstp) (vint l); VNull ); "aconcat", Fun1 (fun arr -> let arr = Array.map varray (varray arr) in VArray (Array.concat (Array.to_list arr)) ); (* string *) "string", Fun1 (fun v -> VString ((get_ctx()).do_string v)); "smake", Fun1 (fun l -> VString (String.make (vint l) '\000')); "ssize", Fun1 (fun s -> VInt (String.length (vstring s))); "scopy", Fun1 (fun s -> VString (String.copy (vstring s))); "ssub", Fun3 (fun s p l -> VString (String.sub (vstring s) (vint p) (vint l))); "sget", Fun2 (fun s p -> try VInt (int_of_char (String.get (vstring s) (vint p))) with Invalid_argument _ -> VNull ); "sset", Fun3 (fun s p c -> let c = char_of_int ((vint c) land 0xFF) in try String.set (vstring s) (vint p) c; VInt (int_of_char c) with Invalid_argument _ -> VNull); "sblit", Fun5 (fun dst dstp src p l -> String.blit (vstring src) (vint p) (vstring dst) (vint dstp) (vint l); VNull ); "sfind", Fun3 (fun src pos pat -> try VInt (find_sub (vstring src) (vstring pat) (vint pos)) with Not_found -> VNull ); (* object *) "new", Fun1 (fun o -> match o with | VNull -> VObject { ofields = [||]; oproto = None } | VObject o -> VObject { ofields = Array.copy o.ofields; oproto = o.oproto } | _ -> error() ); "objget", Fun2 (fun o f -> match o with | VObject o -> get_field o (vint f) | _ -> VNull ); "objset", Fun3 (fun o f v -> match o with | VObject o -> set_field o (vint f) v; v | _ -> VNull ); "objcall", Fun3 (fun o f pl -> match o with | VObject oo -> (get_ctx()).do_call o (get_field oo (vint f)) (Array.to_list (varray pl)) p | _ -> VNull ); "objfield", Fun2 (fun o f -> match o with | VObject o -> let p = o.oproto in o.oproto <- None; let v = get_field_opt o (vint f) in o.oproto <- p; VBool (v <> None) | _ -> VBool false ); "objremove", Fun2 (fun o f -> VBool (remove_field (vobj o) (vint f)) ); "objfields", Fun1 (fun o -> VArray (Array.map (fun (fid,_) -> VInt fid) (vobj o).ofields) ); "hash", Fun1 (fun v -> VInt (hash_field (get_ctx()) (vstring v))); "fasthash", Fun1 (fun v -> VInt (hash (vstring v))); "field", Fun1 (fun v -> try VString (Hashtbl.find (get_ctx()).fields_cache (vint v)) with Not_found -> VNull ); "objsetproto", Fun2 (fun o p -> let o = vobj o in (match p with | VNull -> o.oproto <- None | VObject p -> o.oproto <- Some p | _ -> error()); VNull; ); "objgetproto", Fun1 (fun o -> match (vobj o).oproto with | None -> VNull | Some p -> VObject p ); (* function *) "nargs", Fun1 (fun f -> VInt (nargs (vfun f)) ); "call", Fun3 (fun f o args -> (get_ctx()).do_call o f (Array.to_list (varray args)) p ); "closure", FunVar (fun vl -> match vl with | VFunction f :: _ :: _ -> VClosure (vl, do_closure) | _ -> exc (VString "Can't create closure : value is not a function") ); "apply", FunVar (fun vl -> match vl with | f :: args -> let f = vfun f in VFunction (FunVar (fun args2 -> (get_ctx()).do_call VNull (VFunction f) (args @ args2) p)) | _ -> exc (VString "Invalid closure arguments number") ); "varargs", Fun1 (fun f -> match f with | VFunction (FunVar _) | VFunction (Fun1 _) | VClosure _ -> VFunction (FunVar (fun vl -> (get_ctx()).do_call VNull f [VArray (Array.of_list vl)] p)) | _ -> error() ); (* numbers *) (* skip iadd, isub, idiv, imult *) "isnan", Fun1 (fun f -> match f with | VFloat f -> VBool (f <> f) | _ -> VBool false ); "isinfinite", Fun1 (fun f -> match f with | VFloat f -> VBool (f = infinity || f = neg_infinity) | _ -> VBool false ); "int", Fun1 (fun v -> match v with | VInt _ | VInt32 _ -> v | VFloat f -> best_int (to_int f) | VString s -> (try parse_int s with _ -> VNull) | _ -> VNull ); "float", Fun1 (fun v -> match v with | VInt i -> VFloat (float_of_int i) | VInt32 i -> VFloat (Int32.to_float i) | VFloat _ -> v | VString s -> (try VFloat (parse_float s) with _ -> VNull) | _ -> VNull ); (* abstract *) "getkind", Fun1 (fun v -> match v with | VAbstract a -> VAbstract (AKind a) | VInt32 _ -> VAbstract (AKind AInt32Kind) | _ -> error() ); "iskind", Fun2 (fun v k -> match v, k with | VAbstract a, VAbstract (AKind k) -> VBool (Obj.tag (Obj.repr a) = Obj.tag (Obj.repr k)) | VInt32 _, VAbstract (AKind AInt32Kind) -> VBool true | _, VAbstract (AKind _) -> VBool false | _ -> error() ); (* hash *) "hkey", Fun1 (fun v -> VInt (Hashtbl.hash v)); "hnew", Fun1 (fun v -> VAbstract (AHash (match v with | VNull -> Hashtbl.create 0 | VInt n -> Hashtbl.create n | _ -> error())) ); "hresize", Fun1 (fun v -> VNull); "hget", Fun3 (fun h k cmp -> if cmp <> VNull then assert false; (try Hashtbl.find (vhash h) k with Not_found -> VNull) ); "hmem", Fun3 (fun h k cmp -> if cmp <> VNull then assert false; VBool (Hashtbl.mem (vhash h) k) ); "hremove", Fun3 (fun h k cmp -> if cmp <> VNull then assert false; let h = vhash h in let old = Hashtbl.mem h k in if old then Hashtbl.remove h k; VBool old ); "hset", Fun4 (fun h k v cmp -> if cmp <> VNull then assert false; let h = vhash h in let old = Hashtbl.mem h k in Hashtbl.replace h k v; VBool (not old); ); "hadd", Fun3 (fun h k v -> let h = vhash h in let old = Hashtbl.mem h k in Hashtbl.add h k v; VBool (not old); ); "hiter", Fun2 (fun h f -> Hashtbl.iter (fun k v -> ignore ((get_ctx()).do_call VNull f [k;v] p)) (vhash h); VNull); "hcount", Fun1 (fun h -> VInt (Hashtbl.length (vhash h))); "hsize", Fun1 (fun h -> VInt (Hashtbl.length (vhash h))); (* misc *) "print", FunVar (fun vl -> List.iter (fun v -> let ctx = get_ctx() in let com = ctx.curapi.get_com() in com.print (ctx.do_string v) ) vl; VNull); "throw", Fun1 (fun v -> exc v); "rethrow", Fun1 (fun v -> let ctx = get_ctx() in ctx.callstack <- List.rev (List.map (fun p -> { cpos = p; cthis = ctx.vthis; cstack = DynArray.length ctx.stack; cenv = ctx.venv }) ctx.exc) @ ctx.callstack; exc v ); "istrue", Fun1 (fun v -> match v with | VNull | VInt 0 | VBool false | VInt32 0l -> VBool false | _ -> VBool true ); "not", Fun1 (fun v -> match v with | VNull | VInt 0 | VBool false | VInt32 0l -> VBool true | _ -> VBool false ); "typeof", Fun1 (fun v -> VInt (match v with | VNull -> 0 | VInt _ | VInt32 _ -> 1 | VFloat _ -> 2 | VBool _ -> 3 | VString _ -> 4 | VObject _ -> 5 | VArray _ -> 6 | VFunction _ | VClosure _ -> 7 | VAbstract _ -> 8) ); "compare", Fun2 (fun a b -> match (get_ctx()).do_compare a b with | CUndef -> VNull | CEq -> VInt 0 | CSup -> VInt 1 | CInf -> VInt (-1) ); "pcompare", Fun2 (fun a b -> assert false ); "excstack", Fun0 (fun() -> build_stack (get_ctx()).exc ); "callstack", Fun0 (fun() -> build_stack (List.map (fun s -> s.cpos) (get_ctx()).callstack) ); "version", Fun0 (fun() -> VInt 200 ); (* extra *) "use_neko_dll", Fun0 (fun() -> VBool false ); ] in let vals = [ "tnull", VInt 0; "tint", VInt 1; "tfloat", VInt 2; "tbool", VInt 3; "tstring", VInt 4; "tobject", VInt 5; "tarray", VInt 6; "tfunction", VInt 7; "tabstract", VInt 8; ] in let h = Hashtbl.create 0 in List.iter (fun (n,f) -> Hashtbl.add h n (VFunction f)) funcs; List.iter (fun (n,v) -> Hashtbl.add h n v) vals; h (* ---------------------------------------------------------------------- *) (* STD LIBRARY *) let free_abstract a = match a with | VAbstract vp -> Obj.set_tag (Obj.repr vp) 0 (* this will mute it as Deallocated *) | _ -> assert false let std_lib = let p = { psource = ""; pline = 0 } in let error() = raise Builtin_error in let make_list l = let rec loop acc = function | [] -> acc | x :: l -> loop (VArray [|x;acc|]) l in loop VNull (List.rev l) in let num = function | VInt i -> float_of_int i | VInt32 i -> Int32.to_float i | VFloat f -> f | _ -> error() in let make_date f = VInt32 (Int32.of_float f) in let date = function | VInt32 i -> Int32.to_float i | VInt i -> float_of_int i | _ -> error() in let make_i32 i = VInt32 i in let int32 = function | VInt i -> Int32.of_int i | VInt32 i -> i | _ -> error() in let vint = function | VInt n -> n | _ -> error() in let vstring = function | VString s -> s | _ -> error() in let int32_addr h = let base = Int32.to_int (Int32.logand h 0xFFFFFFl) in let str = Printf.sprintf "%ld.%d.%d.%d" (Int32.shift_right_logical h 24) (base lsr 16) ((base lsr 8) land 0xFF) (base land 0xFF) in Unix.inet_addr_of_string str in let int32_op op = Fun2 (fun a b -> make_i32 (op (int32 a) (int32 b))) in make_library ([ (* math *) "math_atan2", Fun2 (fun a b -> VFloat (atan2 (num a) (num b))); "math_pow", Fun2 (fun a b -> VFloat ((num a) ** (num b))); "math_abs", Fun1 (fun v -> match v with | VInt i -> VInt (abs i) | VInt32 i -> VInt32 (Int32.abs i) | VFloat f -> VFloat (abs_float f) | _ -> error() ); "math_ceil", Fun1 (fun v -> match v with VInt _ | VInt32 _ -> v | _ -> best_int (to_int (ceil (num v)))); "math_floor", Fun1 (fun v -> match v with VInt _ | VInt32 _ -> v | _ -> best_int (to_int (floor (num v)))); "math_round", Fun1 (fun v -> match v with VInt _ | VInt32 _ -> v | _ -> best_int (to_int (floor (num v +. 0.5)))); "math_pi", Fun0 (fun() -> VFloat (4.0 *. atan 1.0)); "math_sqrt", Fun1 (fun v -> let v = num v in VFloat (if v < 0. then nan else sqrt v)); "math_atan", Fun1 (fun v -> VFloat (atan (num v))); "math_cos", Fun1 (fun v -> VFloat (cos (num v))); "math_sin", Fun1 (fun v -> VFloat (sin (num v))); "math_tan", Fun1 (fun v -> VFloat (tan (num v))); "math_log", Fun1 (fun v -> VFloat (Pervasives.log (num v))); "math_exp", Fun1 (fun v -> VFloat (exp (num v))); "math_acos", Fun1 (fun v -> VFloat (acos (num v))); "math_asin", Fun1 (fun v -> VFloat (asin (num v))); "math_fceil", Fun1 (fun v -> VFloat (ceil (num v))); "math_ffloor", Fun1 (fun v -> VFloat (floor (num v))); "math_fround", Fun1 (fun v -> VFloat (floor (num v +. 0.5))); "math_int", Fun1 (fun v -> match v with | VInt _ | VInt32 _ -> v | VFloat f -> best_int (to_int (if f < 0. then ceil f else floor f)) | _ -> error() ); (* buffer *) "buffer_new", Fun0 (fun() -> VAbstract (ABuffer (Buffer.create 0)) ); "buffer_add", Fun2 (fun b v -> match b with | VAbstract (ABuffer b) -> Buffer.add_string b ((get_ctx()).do_string v); VNull | _ -> error() ); "buffer_add_char", Fun2 (fun b v -> match b, v with | VAbstract (ABuffer b), VInt n when n >= 0 && n < 256 -> Buffer.add_char b (char_of_int n); VNull | _ -> error() ); "buffer_add_sub", Fun4 (fun b s p l -> match b, s, p, l with | VAbstract (ABuffer b), VString s, VInt p, VInt l -> (try Buffer.add_substring b s p l; VNull with _ -> error()) | _ -> error() ); "buffer_string", Fun1 (fun b -> match b with | VAbstract (ABuffer b) -> VString (Buffer.contents b) | _ -> error() ); "buffer_reset", Fun1 (fun b -> match b with | VAbstract (ABuffer b) -> Buffer.reset b; VNull; | _ -> error() ); "buffer_get_length", Fun1 (fun b -> match b with | VAbstract (ABuffer b) -> VInt (Buffer.length b) | _ -> error() ); (* date *) "date_now", Fun0 (fun () -> make_date (Unix.time()) ); "date_new", Fun1 (fun v -> make_date (match v with | VNull -> Unix.time() | VString s -> (match String.length s with | 19 -> let r = Str.regexp "^\\([0-9][0-9][0-9][0-9]\\)-\\([0-9][0-9]\\)-\\([0-9][0-9]\\) \\([0-9][0-9]\\):\\([0-9][0-9]\\):\\([0-9][0-9]\\)$" in if not (Str.string_match r s 0) then exc (VString ("Invalid date format : " ^ s)); let t = Unix.localtime (Unix.time()) in let t = { t with tm_year = int_of_string (Str.matched_group 1 s) - 1900; tm_mon = int_of_string (Str.matched_group 2 s) - 1; tm_mday = int_of_string (Str.matched_group 3 s); tm_hour = int_of_string (Str.matched_group 4 s); tm_min = int_of_string (Str.matched_group 5 s); tm_sec = int_of_string (Str.matched_group 6 s); } in fst (Unix.mktime t) | 10 -> assert false | 8 -> assert false | _ -> exc (VString ("Invalid date format : " ^ s))); | _ -> error()) ); "date_set_hour", Fun4 (fun d h m s -> let d = date d in let t = Unix.localtime d in make_date (fst (Unix.mktime { t with tm_hour = vint h; tm_min = vint m; tm_sec = vint s })) ); "date_set_day", Fun4 (fun d y m da -> let d = date d in let t = Unix.localtime d in make_date (fst (Unix.mktime { t with tm_year = vint y - 1900; tm_mon = vint m - 1; tm_mday = vint da })) ); "date_format", Fun2 (fun d fmt -> match fmt with | VNull -> let t = Unix.localtime (date d) in VString (Printf.sprintf "%.4d-%.2d-%.2d %.2d:%.2d:%.2d" (t.tm_year + 1900) (t.tm_mon + 1) t.tm_mday t.tm_hour t.tm_min t.tm_sec) | VString "%w" -> (* week day *) let t = Unix.localtime (date d) in VString (string_of_int t.tm_wday) | VString _ -> exc (VString "Custom date format is not supported") (* use native Haxe implementation *) | _ -> error() ); "date_get_hour", Fun1 (fun d -> let t = Unix.localtime (date d) in let o = obj (hash_field (get_ctx())) [ "h", VInt t.tm_hour; "m", VInt t.tm_min; "s", VInt t.tm_sec; ] in VObject o ); "date_get_day", Fun1 (fun d -> let t = Unix.localtime (date d) in let o = obj (hash_field (get_ctx())) [ "d", VInt t.tm_mday; "m", VInt (t.tm_mon + 1); "y", VInt (t.tm_year + 1900); ] in VObject o ); (* string *) "string_split", Fun2 (fun s d -> make_list (match s, d with | VString "", VString _ -> [VString ""] | VString s, VString "" -> Array.to_list (Array.init (String.length s) (fun i -> VString (String.make 1 (String.get s i)))) | VString s, VString d -> List.map (fun s -> VString s) (ExtString.String.nsplit s d) | _ -> error()) ); "url_encode", Fun1 (fun s -> let s = vstring s in let b = Buffer.create 0 in let hex = "0123456789ABCDEF" in for i = 0 to String.length s - 1 do let c = String.unsafe_get s i in match c with | 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' | '-' | '.' -> Buffer.add_char b c | _ -> Buffer.add_char b '%'; Buffer.add_char b (String.unsafe_get hex (int_of_char c lsr 4)); Buffer.add_char b (String.unsafe_get hex (int_of_char c land 0xF)); done; VString (Buffer.contents b) ); "url_decode", Fun1 (fun s -> let s = vstring s in let b = Buffer.create 0 in let len = String.length s in let decode c = match c with | '0'..'9' -> Some (int_of_char c - int_of_char '0') | 'a'..'f' -> Some (int_of_char c - int_of_char 'a' + 10) | 'A'..'F' -> Some (int_of_char c - int_of_char 'A' + 10) | _ -> None in let rec loop i = if i = len then () else let c = String.unsafe_get s i in match c with | '%' -> let p1 = (try decode (String.get s (i + 1)) with _ -> None) in let p2 = (try decode (String.get s (i + 2)) with _ -> None) in (match p1, p2 with | Some c1, Some c2 -> Buffer.add_char b (char_of_int ((c1 lsl 4) lor c2)); loop (i + 3) | _ -> loop (i + 1)); | '+' -> Buffer.add_char b ' '; loop (i + 1) | c -> Buffer.add_char b c; loop (i + 1) in loop 0; VString (Buffer.contents b) ); "base_encode", Fun2 (fun s b -> match s, b with | VString s, VString "0123456789abcdef" when String.length s = 16 -> VString (Digest.to_hex s) | VString s, VString b -> if String.length b <> 64 then assert false; let tbl = Array.init 64 (String.unsafe_get b) in VString (Base64.str_encode ~tbl s) | _ -> error() ); "base_decode", Fun2 (fun s b -> let s = vstring s in let b = vstring b in if String.length b <> 64 then assert false; let tbl = Array.init 64 (String.unsafe_get b) in VString (Base64.str_decode ~tbl:(Base64.make_decoding_table tbl) s) ); "make_md5", Fun1 (fun s -> VString (Digest.string (vstring s)) ); (* sprintf *) (* int32 *) "int32_new", Fun1 (fun v -> match v with | VInt32 _ -> v | VInt i -> make_i32 (Int32.of_int i) | VFloat f -> make_i32 (Int32.of_float f) | _ -> error() ); "int32_to_int", Fun1 (fun v -> let v = int32 v in let i = Int32.to_int v in if Int32.compare (Int32.of_int i) v <> 0 then error(); VInt i ); "int32_to_float", Fun1 (fun v -> VFloat (Int32.to_float (int32 v)) ); "int32_compare", Fun2 (fun a b -> VInt (Int32.compare (int32 a) (int32 b)) ); "int32_add", int32_op Int32.add; "int32_sub", int32_op Int32.sub; "int32_mul", int32_op Int32.mul; "int32_div", int32_op Int32.div; "int32_shl", int32_op (fun a b -> Int32.shift_left a (Int32.to_int b)); "int32_shr", int32_op (fun a b -> Int32.shift_right a (Int32.to_int b)); "int32_ushr", int32_op (fun a b -> Int32.shift_right_logical a (Int32.to_int b)); "int32_mod", int32_op Int32.rem; "int32_or", int32_op Int32.logor; "int32_and", int32_op Int32.logand; "int32_xor", int32_op Int32.logxor; "int32_neg", Fun1 (fun v -> make_i32 (Int32.neg (int32 v))); "int32_complement", Fun1 (fun v -> make_i32 (Int32.lognot (int32 v))); (* misc *) "same_closure", Fun2 (fun a b -> VBool (match a, b with | VClosure (la,fa), VClosure (lb,fb) -> fa == fb && List.length la = List.length lb && List.for_all2 (fun a b -> (get_ctx()).do_compare a b = CEq) la lb | VFunction a, VFunction b -> a == b | _ -> false) ); "double_bytes", Fun2 (fun f big -> let f = (match f with VFloat f -> f | VInt i -> float_of_int i | _ -> error()) in match big with | VBool big -> let ch = IO.output_string() in if big then IO.BigEndian.write_double ch f else IO.write_double ch f; VString (IO.close_out ch) | _ -> error() ); "float_bytes", Fun2 (fun f big -> let f = (match f with VFloat f -> f | VInt i -> float_of_int i | _ -> error()) in match big with | VBool big -> let ch = IO.output_string() in let i = Int32.bits_of_float f in if big then IO.BigEndian.write_real_i32 ch i else IO.write_real_i32 ch i; VString (IO.close_out ch) | _ -> error() ); "double_of_bytes", Fun2 (fun s big -> match s, big with | VString s, VBool big when String.length s = 8 -> let ch = IO.input_string s in VFloat (if big then IO.BigEndian.read_double ch else IO.read_double ch) | _ -> error() ); "float_of_bytes", Fun2 (fun s big -> match s, big with | VString s, VBool big when String.length s = 4 -> let ch = IO.input_string s in VFloat (Int32.float_of_bits (if big then IO.BigEndian.read_real_i32 ch else IO.read_real_i32 ch)) | _ -> error() ); (* random *) "random_new", Fun0 (fun() -> VAbstract (ARandom (ref (Random.State.make_self_init())))); "random_set_seed", Fun2 (fun r s -> match r, s with | VAbstract (ARandom r), VInt seed -> r := Random.State.make [|seed|]; VNull | VAbstract (ARandom r), VInt32 seed -> r := Random.State.make [|Int32.to_int seed|]; VNull | _ -> error() ); "random_int", Fun2 (fun r s -> match r, s with | VAbstract (ARandom r), VInt max -> VInt (Random.State.int (!r) (if max <= 0 then 1 else max)) | _ -> error() ); "random_float", Fun1 (fun r -> match r with | VAbstract (ARandom r) -> VFloat (Random.State.float (!r) 1.0) | _ -> error() ); (* file *) "file_open", Fun2 (fun f r -> match f, r with | VString f, VString r -> let perms = 0o666 in VAbstract (match r with | "r" -> AFRead (open_in_gen [Open_rdonly] 0 f,ref false) | "rb" -> AFRead (open_in_gen [Open_rdonly;Open_binary] 0 f,ref false) | "w" -> AFWrite (open_out_gen [Open_wronly;Open_creat;Open_trunc] perms f) | "wb" -> AFWrite (open_out_gen [Open_wronly;Open_creat;Open_trunc;Open_binary] perms f) | "a" -> AFWrite (open_out_gen [Open_append;Open_creat] perms f) | "ab" -> AFWrite (open_out_gen [Open_append;Open_creat;Open_binary] perms f) | _ -> error()) | _ -> error() ); "file_close", Fun1 (fun vf -> (match vf with | VAbstract (AFRead (f,_)) -> close_in f; free_abstract vf; | VAbstract (AFWrite f) -> close_out f; free_abstract vf; | _ -> error()); VNull ); (* file_name *) "file_write", Fun4 (fun f s p l -> match f, s, p, l with | VAbstract (AFWrite f), VString s, VInt p, VInt l -> output f s p l; VInt l | _ -> error() ); "file_read", Fun4 (fun f s p l -> match f, s, p, l with | VAbstract (AFRead (f,r)), VString s, VInt p, VInt l -> let n = input f s p l in if n = 0 then begin r := true; exc (VArray [|VString "file_read"|]); end; VInt n | _ -> error() ); "file_write_char", Fun2 (fun f c -> match f, c with | VAbstract (AFWrite f), VInt c -> output_char f (char_of_int c); VNull | _ -> error() ); "file_read_char", Fun1 (fun f -> match f with | VAbstract (AFRead (f,r)) -> VInt (int_of_char (try input_char f with _ -> r := true; exc (VArray [|VString "file_read_char"|]))) | _ -> error() ); "file_seek", Fun3 (fun f pos mode -> match f, pos, mode with | VAbstract (AFRead (f,r)), VInt pos, VInt mode -> r := false; seek_in f (match mode with 0 -> pos | 1 -> pos_in f + pos | 2 -> in_channel_length f + pos | _ -> error()); VNull; | VAbstract (AFWrite f), VInt pos, VInt mode -> seek_out f (match mode with 0 -> pos | 1 -> pos_out f + pos | 2 -> out_channel_length f + pos | _ -> error()); VNull; | _ -> error() ); "file_tell", Fun1 (fun f -> match f with | VAbstract (AFRead (f,_)) -> VInt (pos_in f) | VAbstract (AFWrite f) -> VInt (pos_out f) | _ -> error() ); "file_eof", Fun1 (fun f -> match f with | VAbstract (AFRead (f,r)) -> VBool !r | _ -> error() ); "file_flush", Fun1 (fun f -> (match f with | VAbstract (AFWrite f) -> flush f | _ -> error()); VNull ); "file_contents", Fun1 (fun f -> match f with | VString f -> VString (Std.input_file ~bin:true f) | _ -> error() ); "file_stdin", Fun0 (fun() -> VAbstract (AFRead (Pervasives.stdin, ref false))); "file_stdout", Fun0 (fun() -> VAbstract (AFWrite Pervasives.stdout)); "file_stderr", Fun0 (fun() -> VAbstract (AFWrite Pervasives.stderr)); (* serialize *) (* TODO *) (* socket *) "socket_init", Fun0 (fun() -> VNull); "socket_new", Fun1 (fun v -> match v with | VBool b -> VAbstract (ASocket (Unix.socket PF_INET (if b then SOCK_DGRAM else SOCK_STREAM) 0)); | _ -> error() ); "socket_close", Fun1 (fun vs -> match vs with | VAbstract (ASocket s) -> Unix.close s; free_abstract vs; VNull | _ -> error() ); "socket_send_char", Fun2 (fun s c -> match s, c with | VAbstract (ASocket s), VInt c when c >= 0 && c <= 255 -> ignore(Unix.send s (String.make 1 (char_of_int c)) 0 1 []); VNull | _ -> error() ); "socket_send", Fun4 (fun s buf pos len -> match s, buf, pos, len with | VAbstract (ASocket s), VString buf, VInt pos, VInt len -> VInt (Unix.send s buf pos len []) | _ -> error() ); "socket_recv", Fun4 (fun s buf pos len -> match s, buf, pos, len with | VAbstract (ASocket s), VString buf, VInt pos, VInt len -> VInt (Unix.recv s buf pos len []) | _ -> error() ); "socket_recv_char", Fun1 (fun s -> match s with | VAbstract (ASocket s) -> let buf = String.make 1 '\000' in ignore(Unix.recv s buf 0 1 []); VInt (int_of_char (String.unsafe_get buf 0)) | _ -> error() ); "socket_write", Fun2 (fun s str -> match s, str with | VAbstract (ASocket s), VString str -> let pos = ref 0 in let len = ref (String.length str) in while !len > 0 do let k = Unix.send s str (!pos) (!len) [] in pos := !pos + k; len := !len - k; done; VNull | _ -> error() ); "socket_read", Fun1 (fun s -> match s with | VAbstract (ASocket s) -> let tmp = String.make 1024 '\000' in let buf = Buffer.create 0 in let rec loop() = let k = (try Unix.recv s tmp 0 1024 [] with Unix_error _ -> 0) in if k > 0 then begin Buffer.add_substring buf tmp 0 k; loop(); end in loop(); VString (Buffer.contents buf) | _ -> error() ); "host_resolve", Fun1 (fun s -> let h = (try Unix.gethostbyname (vstring s) with Not_found -> error()) in let addr = Unix.string_of_inet_addr h.h_addr_list.(0) in let a, b, c, d = Scanf.sscanf addr "%d.%d.%d.%d" (fun a b c d -> a,b,c,d) in VInt32 (Int32.logor (Int32.shift_left (Int32.of_int a) 24) (Int32.of_int (d lor (c lsl 8) lor (b lsl 16)))) ); "host_to_string", Fun1 (fun h -> match h with | VInt32 h -> VString (Unix.string_of_inet_addr (int32_addr h)); | _ -> error() ); "host_reverse", Fun1 (fun h -> match h with | VInt32 h -> VString (gethostbyaddr (int32_addr h)).h_name | _ -> error() ); "host_local", Fun0 (fun() -> VString (Unix.gethostname()) ); "socket_connect", Fun3 (fun s h p -> match s, h, p with | VAbstract (ASocket s), VInt32 h, VInt p -> Unix.connect s (ADDR_INET (int32_addr h,p)); VNull | _ -> error() ); "socket_listen", Fun2 (fun s l -> match s, l with | VAbstract (ASocket s), VInt l -> Unix.listen s l; VNull | _ -> error() ); "socket_set_timeout", Fun2 (fun s t -> match s with | VAbstract (ASocket s) -> let t = (match t with VNull -> 0. | VInt t -> float_of_int t | VFloat f -> f | _ -> error()) in Unix.setsockopt_float s SO_RCVTIMEO t; Unix.setsockopt_float s SO_SNDTIMEO t; VNull | _ -> error() ); "socket_shutdown", Fun3 (fun s r w -> match s, r, w with | VAbstract (ASocket s), VBool r, VBool w -> Unix.shutdown s (match r, w with true, true -> SHUTDOWN_ALL | true, false -> SHUTDOWN_RECEIVE | false, true -> SHUTDOWN_SEND | _ -> error()); VNull | _ -> error() ); (* TODO : select, bind, accept, peer, host *) (* poll_alloc, poll : not planned *) (* system *) "get_env", Fun1 (fun v -> try VString (Unix.getenv (vstring v)) with _ -> VNull ); "put_env", Fun2 (fun e v -> Unix.putenv (vstring e) (vstring v); VNull ); "sys_sleep", Fun1 (fun f -> match f with | VFloat f -> ignore(Unix.select [] [] [] f); VNull | _ -> error() ); "set_time_locale", Fun1 (fun l -> match l with | VString s -> VBool false (* always fail *) | _ -> error() ); "get_cwd", Fun0 (fun() -> let dir = Unix.getcwd() in let l = String.length dir in VString (if l = 0 then "./" else match dir.[l - 1] with '/' | '\\' -> dir | _ -> dir ^ "/") ); "set_cwd", Fun1 (fun s -> Unix.chdir (vstring s); VNull; ); "sys_string", ( let cached_sys_name = ref None in Fun0 (fun() -> VString (match Sys.os_type with | "Unix" -> (match !cached_sys_name with | Some n -> n | None -> let ic = Unix.open_process_in "uname" in let uname = (match input_line ic with | "Darwin" -> "Mac" | n -> n ) in close_in ic; cached_sys_name := Some uname; uname) | "Win32" | "Cygwin" -> "Windows" | s -> s) ) ); "sys_is64", Fun0 (fun() -> VBool (Sys.word_size = 64) ); "sys_command", Fun1 (fun cmd -> VInt (((get_ctx()).curapi.get_com()).run_command (vstring cmd)) ); "sys_exit", Fun1 (fun code -> if (get_ctx()).curapi.use_cache() then raise (Error.Fatal_error ("",Globals.null_pos)); raise (Sys_exit(vint code)); ); "sys_exists", Fun1 (fun file -> VBool (Sys.file_exists (vstring file)) ); "file_delete", Fun1 (fun file -> Sys.remove (vstring file); VNull; ); "sys_rename", Fun2 (fun file target -> Sys.rename (vstring file) (vstring target); VNull; ); "sys_stat", Fun1 (fun file -> let s = Unix.stat (vstring file) in VObject (obj (hash_field (get_ctx())) [ "gid", VInt s.st_gid; "uid", VInt s.st_uid; "atime", VInt32 (Int32.of_float s.st_atime); "mtime", VInt32 (Int32.of_float s.st_mtime); "ctime", VInt32 (Int32.of_float s.st_ctime); "dev", VInt s.st_dev; "ino", VInt s.st_ino; "nlink", VInt s.st_nlink; "rdev", VInt s.st_rdev; "size", VInt s.st_size; "mode", VInt s.st_perm; ]) ); "sys_file_type", Fun1 (fun file -> VString (match (Unix.stat (vstring file)).st_kind with | S_REG -> "file" | S_DIR -> "dir" | S_CHR -> "char" | S_BLK -> "block" | S_LNK -> "symlink" | S_FIFO -> "fifo" | S_SOCK -> "sock") ); "sys_create_dir", Fun2 (fun dir mode -> Unix.mkdir (vstring dir) (vint mode); VNull ); "sys_remove_dir", Fun1 (fun dir -> Unix.rmdir (vstring dir); VNull; ); "sys_time", Fun0 (fun() -> VFloat (Unix.gettimeofday()) ); "sys_cpu_time", Fun0 (fun() -> VFloat (Sys.time()) ); "sys_read_dir", Fun1 (fun dir -> let d = Sys.readdir (vstring dir) in let rec loop acc i = if i < 0 then acc else loop (VArray [|VString d.(i);acc|]) (i - 1) in loop VNull (Array.length d - 1) ); "file_full_path", Fun1 (fun file -> VString (try Extc.get_full_path (vstring file) with _ -> error()) ); "sys_exe_path", Fun0 (fun() -> VString (Sys.argv.(0)) ); "sys_program_path", Fun0 (fun() -> let ctx = get_ctx() in let com = ctx.curapi.get_com() in match com.main_class with | None -> error() | Some p -> match ctx.curapi.get_type (s_type_path p) with | Some(TInst (c, _)) -> VString (Extc.get_full_path c.cl_pos.Globals.pfile) | _ -> error(); ); "sys_env", Fun0 (fun() -> let env = Unix.environment() in let rec loop acc i = if i < 0 then acc else let e, v = ExtString.String.split env.(i) "=" in loop (VArray [|VString e;VString v;acc|]) (i - 1) in loop VNull (Array.length env - 1) ); "sys_getch", Fun1 (fun echo -> match echo with | VBool b -> VInt (Extc.getch b) | _ -> error() ); "sys_get_pid", Fun0 (fun() -> VInt (Unix.getpid()) ); (* utf8 *) "utf8_buf_alloc", Fun1 (fun v -> VAbstract (AUtf8 (UTF8.Buf.create (vint v))) ); "utf8_buf_add", Fun2 (fun b c -> match b with | VAbstract (AUtf8 buf) -> UTF8.Buf.add_char buf (UChar.chr_of_uint (vint c)); VNull | _ -> error() ); "utf8_buf_content", Fun1 (fun b -> match b with | VAbstract (AUtf8 buf) -> VString (UTF8.Buf.contents buf); | _ -> error() ); "utf8_buf_length", Fun1 (fun b -> match b with | VAbstract (AUtf8 buf) -> VInt (UTF8.length (UTF8.Buf.contents buf)); | _ -> error() ); "utf8_buf_size", Fun1 (fun b -> match b with | VAbstract (AUtf8 buf) -> VInt (String.length (UTF8.Buf.contents buf)); | _ -> error() ); "utf8_validate", Fun1 (fun s -> VBool (try UTF8.validate (vstring s); true with UTF8.Malformed_code -> false) ); "utf8_length", Fun1 (fun s -> VInt (UTF8.length (vstring s)) ); "utf8_sub", Fun3 (fun s p l -> let buf = UTF8.Buf.create 0 in let pos = ref (-1) in let p = vint p and l = vint l in UTF8.iter (fun c -> incr pos; if !pos >= p && !pos < p + l then UTF8.Buf.add_char buf c; ) (vstring s); VString (UTF8.Buf.contents buf) ); "utf8_get", Fun2 (fun s p -> VInt (UChar.uint_code (try UTF8.get (vstring s) (vint p) with _ -> error())) ); "utf8_iter", Fun2 (fun s f -> let ctx = get_ctx() in UTF8.iter (fun c -> ignore(ctx.do_call VNull f [VInt (UChar.uint_code c)] p); ) (vstring s); VNull; ); "utf8_compare", Fun2 (fun s1 s2 -> VInt (UTF8.compare (vstring s1) (vstring s2)) ); (* thread *) "thread_create", Fun2 (fun f p -> exc (VString "Can't create thread from within a macro"); ); "tls_create", Fun0 (fun() -> VAbstract (ATls (ref VNull)) ); "tls_get", Fun1 (fun t -> match t with | VAbstract (ATls r) -> !r | _ -> error(); ); "tls_set", Fun2 (fun t v -> match t with | VAbstract (ATls r) -> r := v; VNull | _ -> error(); ); (* lock, mutex, deque : not implemented *) (* process *) "process_run", (Fun2 (fun p args -> match p, args with | VString p, VArray args -> VAbstract (AProcess (Process.run p (Some (Array.map vstring args)))) | VString p, _ -> VAbstract (AProcess (Process.run p None)) | _ -> error() )); "process_stdout_read", (Fun4 (fun p str pos len -> match p, str, pos, len with | VAbstract (AProcess p), VString str, VInt pos, VInt len -> VInt (Process.read_stdout p str pos len) | _ -> error() )); "process_stderr_read", (Fun4 (fun p str pos len -> match p, str, pos, len with | VAbstract (AProcess p), VString str, VInt pos, VInt len -> VInt (Process.read_stderr p str pos len) | _ -> error() )); "process_stdin_write", (Fun4 (fun p str pos len -> match p, str, pos, len with | VAbstract (AProcess p), VString str, VInt pos, VInt len -> VInt (Process.write_stdin p str pos len) | _ -> error() )); "process_stdin_close", (Fun1 (fun p -> match p with | VAbstract (AProcess p) -> Process.close_stdin p; VNull | _ -> error() )); "process_exit", (Fun1 (fun p -> match p with | VAbstract (AProcess p) -> VInt (Process.exit p) | _ -> error() )); "process_pid", (Fun1 (fun p -> match p with | VAbstract (AProcess p) -> VInt (Process.pid p) | _ -> error() )); "process_close", (Fun1 (fun vp -> match vp with | VAbstract (AProcess p) -> Process.close p; free_abstract vp; VNull | _ -> error() )); "process_kill", (Fun1 (fun vp -> match vp with | VAbstract (AProcess p) -> Process.kill p; free_abstract vp; VNull | _ -> error() )); (* xml *) "parse_xml", (Fun2 (fun str o -> match str, o with | VString str, VObject events -> let ctx = get_ctx() in let p = { psource = "parse_xml"; pline = 0 } in let xml = get_field events (hash "xml") in let don = get_field events (hash "done") in let pcdata = get_field events (hash "pcdata") in (* Since we use the Xml parser, we don't have support for - CDATA - comments, prolog, doctype (allowed but skipped) let cdata = get_field events (hash "cdata") in let comment = get_field events (hash "comment") in *) let rec loop = function | Xml.Element (node, attribs, children) -> ignore(ctx.do_call o xml [VString node;VObject (obj (hash_field ctx) (List.map (fun (a,v) -> a, VString v) attribs))] p); List.iter loop children; ignore(ctx.do_call o don [] p); | Xml.PCData s -> ignore(ctx.do_call o pcdata [VString s] p); in let x = XmlParser.make() in XmlParser.check_eof x false; loop (try XmlParser.parse x (XmlParser.SString str) with Xml.Error e -> failwith ("Parser failure (" ^ Xml.error e ^ ")") | e -> failwith ("Parser failure (" ^ Printexc.to_string e ^ ")")); VNull | _ -> error()) ); (* memory, module : not planned *) ]) (* ---------------------------------------------------------------------- *) (* REGEXP LIBRARY *) let reg_lib = let error() = raise Builtin_error in let open Pcre in let string_of_pcre_error = function | BadPattern(s,i) -> Printf.sprintf "at %i: %s" i s | Partial -> "Partial" | BadPartial -> "BadPartial" | BadUTF8 -> "BadUTF8" | BadUTF8Offset -> "BadUTF8Offset" | MatchLimit -> "MatchLimit" | RecursionLimit -> "RecursionLimit" | InternalError s -> "InternalError: " ^ s in make_library [ "regexp_new_options", Fun2 (fun str opt -> match str,opt with | VString str,VString opt -> let flags = List.map (function | 'i' -> `CASELESS | 's' -> `DOTALL | 'm' -> `MULTILINE | 'u' -> `UTF8 | 'g' -> `UNGREEDY | c -> failwith ("Unsupported regexp option '" ^ String.make 1 c ^ "'") ) (ExtString.String.explode opt) in let r = try regexp ~flags str with Error error -> failwith (string_of_pcre_error error) in let pcre = { r = r; r_string = ""; r_groups = [||] } in VAbstract (AReg pcre) | _ -> error() ); "regexp_match", Fun4 (fun rex str pos len -> match rex, str, pos, len with | VAbstract (AReg rex),VString str,VInt pos,VInt len -> begin try (* A bit awkward, but the PCRE bindings don't seem to expose the len argument... *) if pos + len > String.length str then raise Not_found; let str = String.sub str 0 (pos + len) in let a = pcre_exec ~rex:rex.r ~pos str in rex.r_string <- str; rex.r_groups <- a; VBool true with Not_found -> VBool false end | _ -> error() ); "regexp_matched", Fun2 (fun r n -> match r, n with | VAbstract (AReg r),VInt n -> let pos = r.r_groups.(n * 2) in let len = r.r_groups.(n * 2 + 1) - pos in if pos = -1 then VNull else VString (String.sub r.r_string pos len) | _ -> error() ); "regexp_matched_pos", Fun2 (fun r n -> match r, n with | VAbstract (AReg r),VInt n -> let pos = r.r_groups.(n * 2) in let len = r.r_groups.(n * 2 + 1) - pos in VObject (obj (hash_field (get_ctx())) ["pos",VInt pos;"len",VInt len]) | _ -> error() ); ] (* ---------------------------------------------------------------------- *) (* ZLIB LIBRARY *) let z_lib = let error() = raise Builtin_error in make_library [ "inflate_init", Fun1 (fun f -> let z = Extc.zlib_inflate_init2 (match f with VNull -> 15 | VInt i -> i | _ -> error()) in VAbstract (AZipI { z = z; z_flush = Extc.Z_NO_FLUSH }) ); "deflate_init", Fun1 (fun f -> let z = Extc.zlib_deflate_init (match f with VInt i -> i | _ -> error()) in VAbstract (AZipD { z = z; z_flush = Extc.Z_NO_FLUSH }) ); "deflate_end", Fun1 (fun vz -> match vz with | VAbstract (AZipD z) -> Extc.zlib_deflate_end z.z; free_abstract vz; VNull; | _ -> error() ); "inflate_end", Fun1 (fun vz -> match vz with | VAbstract (AZipI z) -> Extc.zlib_inflate_end z.z; free_abstract vz; VNull; | _ -> error() ); "set_flush_mode", Fun2 (fun z f -> match z, f with | VAbstract (AZipI z | AZipD z), VString s -> z.z_flush <- (match s with | "NO" -> Extc.Z_NO_FLUSH | "SYNC" -> Extc.Z_SYNC_FLUSH | "FULL" -> Extc.Z_FULL_FLUSH | "FINISH" -> Extc.Z_FINISH | "BLOCK" -> Extc.Z_PARTIAL_FLUSH | _ -> error()); VNull; | _ -> error() ); "inflate_buffer", Fun5 (fun z src pos dst dpos -> match z, src, pos, dst, dpos with | VAbstract (AZipI z), VString src, VInt pos, VString dst, VInt dpos -> let r = Extc.zlib_inflate z.z src pos (String.length src - pos) dst dpos (String.length dst - dpos) z.z_flush in VObject (obj (hash_field (get_ctx())) [ "done", VBool r.Extc.z_finish; "read", VInt r.Extc.z_read; "write", VInt r.Extc.z_wrote; ]) | _ -> error() ); "deflate_buffer", Fun5 (fun z src pos dst dpos -> match z, src, pos, dst, dpos with | VAbstract (AZipD z), VString src, VInt pos, VString dst, VInt dpos -> let r = Extc.zlib_deflate z.z src pos (String.length src - pos) dst dpos (String.length dst - dpos) z.z_flush in VObject (obj (hash_field (get_ctx())) [ "done", VBool r.Extc.z_finish; "read", VInt r.Extc.z_read; "write", VInt r.Extc.z_wrote; ]) | _ -> error() ); "deflate_bound", Fun2 (fun z size -> match z, size with | VAbstract (AZipD z), VInt size -> VInt (size + 1024) | _ -> error() ); ] (* ---------------------------------------------------------------------- *) (* EVAL *) let throw ctx p msg = ctx.callstack <- { cpos = p; cthis = ctx.vthis; cstack = DynArray.length ctx.stack; cenv = ctx.venv } :: ctx.callstack; exc (VString msg) let declare ctx var = ctx.locals_map <- PMap.add var ctx.locals_count ctx.locals_map; ctx.locals_count <- ctx.locals_count + 1 let save_locals ctx = let old, oldcount = ctx.locals_map, ctx.locals_count in (fun() -> let n = ctx.locals_count - oldcount in ctx.locals_count <- oldcount; ctx.locals_map <- old; n; ) let get_ident ctx s = try let index = PMap.find s ctx.locals_map in if index >= ctx.locals_barrier then AccLocal (ctx.locals_count - index) else (try AccEnv (DynArray.index_of (fun s2 -> s = s2) ctx.locals_env) with Not_found -> let index = DynArray.length ctx.locals_env in DynArray.add ctx.locals_env s; AccEnv index ) with Not_found -> try AccGlobal (PMap.find s ctx.globals) with Not_found -> let g = ref VNull in ctx.globals <- PMap.add s g ctx.globals; AccGlobal g let no_env = [||] let rec eval_expr ctx e = let e = Genneko.gen_expr ctx.gen e in catch_errors ctx (fun() -> (eval ctx e)()) and eval ctx (e,p) = match e with | EConst c -> (match c with | True -> (fun() -> VBool true) | False -> (fun() -> VBool false) | Null -> (fun() -> VNull) | This -> (fun() -> ctx.vthis) | Int i -> (fun() -> VInt i) | Int32 i -> (fun() -> VInt32 i) | Float f -> let f = float_of_string f in (fun() -> VFloat f) | String s -> (fun() -> VString s) | Builtin "loader" -> (fun() -> ctx.loader) | Builtin "exports" -> (fun() -> ctx.exports) | Builtin s -> let b = (try Hashtbl.find builtins s with Not_found -> throw ctx p ("Builtin not found '" ^ s ^ "'")) in (fun() -> b) | Ident s -> acc_get ctx p (get_ident ctx s)) | EBlock el -> let old = save_locals ctx in let el = List.map (eval ctx) el in let n = old() in let rec loop = function | [] -> VNull | [e] -> e() | e :: l -> ignore(e()); loop l in (fun() -> let v = loop el in pop ctx n; v) | EParenthesis e -> eval ctx e | EField (e,f) -> let e = eval ctx e in let h = hash_field ctx f in (fun() -> match e() with | VObject o -> get_field o h | _ -> throw ctx p ("Invalid field access : " ^ f) ) | ECall ((EConst (Builtin "__mk_pos__"),_),[(ECall (_,[EConst (String file),_]),_);(EConst (Int min),_);(EConst (Int max),_)]) -> let pos = VAbstract (APos { Globals.pfile = file; Globals.pmin = min; Globals.pmax = max }) in (fun() -> pos) | ECall ((EConst (Builtin "typewrap"),_),[t]) -> (fun() -> VAbstract (ATDecl (Obj.magic t))) | ECall ((EConst (Builtin "__delayed_call__"),_),[EConst (Int index),_]) -> let f = ctx.curapi.delayed_macro index in let fbuild = ref None in let old = { ctx with gen = ctx.gen } in let compile_delayed_call() = let oldl, oldc, oldb, olde = ctx.locals_map, ctx.locals_count, ctx.locals_barrier, ctx.locals_env in ctx.locals_map <- old.locals_map; ctx.locals_count <- old.locals_count; ctx.locals_barrier <- old.locals_barrier; ctx.locals_env <- DynArray.copy old.locals_env; let save = save_locals ctx in let e = f() in let n = save() in let e = if DynArray.length ctx.locals_env = DynArray.length old.locals_env then e else let n = DynArray.get ctx.locals_env (DynArray.length ctx.locals_env - 1) in (fun() -> exc (VString ("Macro-in-macro call can't access to closure variable '" ^ n ^ "'"))) in ctx.locals_map <- oldl; ctx.locals_count <- oldc; ctx.locals_barrier <- oldb; ctx.locals_env <- olde; (fun() -> let v = e() in pop ctx n; v ) in (fun() -> let e = (match !fbuild with | Some e -> e | None -> let e = compile_delayed_call() in fbuild := Some e; e ) in e()) | ECall (e,el) -> let el = List.map (eval ctx) el in (match fst e with | EField (e,f) -> let e = eval ctx e in let h = hash_field ctx f in (fun() -> let pl = List.map (fun f -> f()) el in let o = e() in let f = (match o with | VObject o -> get_field o h | _ -> throw ctx p ("Invalid field access : " ^ f) ) in call ctx o f pl p ) | _ -> let e = eval ctx e in (fun() -> let pl = List.map (fun f -> f()) el in call ctx ctx.vthis (e()) pl p )) | EArray (e1,e2) -> let e1 = eval ctx e1 in let e2 = eval ctx e2 in let acc = AccArray (e1,e2) in acc_get ctx p acc | EVars vl -> let vl = List.map (fun (v,eo) -> let eo = (match eo with None -> (fun() -> VNull) | Some e -> eval ctx e) in declare ctx v; eo ) vl in (fun() -> List.iter (fun e -> push ctx (e())) vl; VNull ) | EWhile (econd,e,NormalWhile) -> let econd = eval ctx econd in let e = eval ctx e in let rec loop st = match econd() with | VBool true -> let v = (try ignore(e()); None with | Continue -> pop ctx (DynArray.length ctx.stack - st); None | Break v -> pop ctx (DynArray.length ctx.stack - st); Some v ) in (match v with | None -> loop st | Some v -> v) | _ -> VNull in (fun() -> try loop (DynArray.length ctx.stack) with Sys.Break -> throw ctx p "Ctrl+C") | EWhile (econd,e,DoWhile) -> let e = eval ctx e in let econd = eval ctx econd in let rec loop st = let v = (try ignore(e()); None with | Continue -> pop ctx (DynArray.length ctx.stack - st); None | Break v -> pop ctx (DynArray.length ctx.stack - st); Some v ) in match v with | Some v -> v | None -> match econd() with | VBool true -> loop st | _ -> VNull in (fun() -> loop (DynArray.length ctx.stack)) | EIf (econd,eif,eelse) -> let econd = eval ctx econd in let eif = eval ctx eif in let eelse = (match eelse with None -> (fun() -> VNull) | Some e -> eval ctx e) in (fun() -> match econd() with | VBool true -> eif() | _ -> eelse() ) | ETry (e,exc,ecatch) -> let old = save_locals ctx in let e = eval ctx e in let n1 = old() in declare ctx exc; let ecatch = eval ctx ecatch in let n2 = old() in (fun() -> let vthis = ctx.vthis in let venv = ctx.venv in let stack = ctx.callstack in let csize = ctx.callsize in let size = DynArray.length ctx.stack in try pop_ret ctx e n1 with Runtime v -> let rec loop n l = if n = 0 then List.map (fun s -> s.cpos) l else match l with | [] -> [] | _ :: l -> loop (n - 1) l in ctx.exc <- loop (List.length stack) (List.rev ctx.callstack); ctx.callstack <- stack; ctx.callsize <- csize; ctx.vthis <- vthis; ctx.venv <- venv; pop ctx (DynArray.length ctx.stack - size); push ctx v; pop_ret ctx ecatch n2 ) | EFunction (pl,e) -> let old = save_locals ctx in let oldb, oldenv = ctx.locals_barrier, ctx.locals_env in ctx.locals_barrier <- ctx.locals_count; ctx.locals_env <- DynArray.create(); List.iter (declare ctx) pl; let e = eval ctx e in ignore(old()); let env = ctx.locals_env in ctx.locals_barrier <- oldb; ctx.locals_env <- oldenv; let env = DynArray.to_array (DynArray.map (fun s -> acc_get ctx p (get_ident ctx s)) env ) in let init_env = if Array.length env = 0 then (fun() -> no_env) else (fun() -> Array.map (fun e -> e()) env) in (match pl with | [] -> (fun() -> let env = init_env() in VFunction (Fun0 (fun() -> ctx.venv <- env; e()))) | [a] -> (fun() -> let env = init_env() in VFunction (Fun1 (fun v -> ctx.venv <- env; push ctx v; e(); ))) | [a;b] -> (fun() -> let env = init_env() in VFunction (Fun2 (fun va vb -> ctx.venv <- env; push ctx va; push ctx vb; e(); ))) | [a;b;c] -> (fun() -> let env = init_env() in VFunction (Fun3 (fun va vb vc -> ctx.venv <- env; push ctx va; push ctx vb; push ctx vc; e(); ))) | [a;b;c;d] -> (fun() -> let env = init_env() in VFunction (Fun4 (fun va vb vc vd -> ctx.venv <- env; push ctx va; push ctx vb; push ctx vc; push ctx vd; e(); ))) | [a;b;c;d;pe] -> (fun() -> let env = init_env() in VFunction (Fun5 (fun va vb vc vd ve -> ctx.venv <- env; push ctx va; push ctx vb; push ctx vc; push ctx vd; push ctx ve; e(); ))) | _ -> (fun() -> let env = init_env() in VFunction (FunVar (fun vl -> if List.length vl != List.length pl then exc (VString "Invalid call"); ctx.venv <- env; List.iter (push ctx) vl; e(); ))) ) | EBinop (op,e1,e2) -> eval_op ctx op e1 e2 p | EReturn None -> (fun() -> raise (Return VNull)) | EReturn (Some e) -> let e = eval ctx e in (fun() -> raise (Return (e()))) | EBreak None -> (fun() -> raise (Break VNull)) | EBreak (Some e) -> let e = eval ctx e in (fun() -> raise (Break (e()))) | EContinue -> (fun() -> raise Continue) | ENext (e1,e2) -> let e1 = eval ctx e1 in let e2 = eval ctx e2 in (fun() -> ignore(e1()); e2()) | EObject fl -> let fl = List.map (fun (f,e) -> hash_field ctx f, eval ctx e) fl in let fields = Array.of_list (List.map (fun (f,_) -> f,VNull) fl) in Array.sort (fun (f1,_) (f2,_) -> compare f1 f2) fields; (fun() -> let o = { ofields = Array.copy fields; oproto = None; } in List.iter (fun (f,e) -> set_field o f (e())) fl; VObject o ) | ELabel l -> assert false | ESwitch (e1,el,eo) -> let e1 = eval ctx e1 in let el = List.map (fun (cond,e) -> cond, eval ctx cond, eval ctx e) el in let eo = (match eo with None -> (fun() -> VNull) | Some e -> eval ctx e) in let cases = (try let max = ref (-1) in let ints = List.map (fun (cond,_,e) -> match fst cond with | EConst (Int i) -> if i < 0 then raise Exit; if i > !max then max := i; i, e | _ -> raise Exit ) el in let a = Array.create (!max + 1) eo in List.iter (fun (i,e) -> a.(i) <- e) (List.rev ints); Some a; with Exit -> None ) in let def v = let rec loop = function | [] -> eo() | (_,c,e) :: l -> if ctx.do_compare v (c()) = CEq then e() else loop l in loop el in (match cases with | None -> (fun() -> def (e1())) | Some t -> (fun() -> match e1() with | VInt i -> if i >= 0 && i < Array.length t then t.(i)() else eo() | v -> def v )) | ENeko _ -> throw ctx p "Inline neko code unsupported" and eval_oop ctx p o field (params:value list) = match get_field_opt o field with | None -> None | Some f -> Some (call ctx (VObject o) f params p) and eval_access ctx (e,p) = match e with | EField (e,f) -> let v = eval ctx e in AccField (v,f) | EArray (e,eindex) -> let v = eval ctx e in let idx = eval ctx eindex in AccArray (v,idx) | EConst (Ident s) -> get_ident ctx s | EConst This -> AccThis | _ -> throw ctx p "Invalid assign" and eval_access_get_set ctx (e,p) = match e with | EField (e,f) -> let v = eval ctx e in let cache = ref VNull in AccField ((fun() -> cache := v(); !cache),f), AccField((fun() -> !cache), f) | EArray (e,eindex) -> let v = eval ctx e in let idx = eval ctx eindex in let vcache = ref VNull and icache = ref VNull in AccArray ((fun() -> vcache := v(); !vcache),(fun() -> icache := idx(); !icache)), AccArray ((fun() -> !vcache),(fun() -> !icache)) | EConst (Ident s) -> let acc = get_ident ctx s in acc, acc | EConst This -> AccThis, AccThis | _ -> throw ctx p "Invalid assign" and acc_get ctx p = function | AccField (v,f) -> let h = hash_field ctx f in (fun() -> match v() with | VObject o -> get_field o h | _ -> throw ctx p ("Invalid field access : " ^ f)) | AccArray (e,index) -> (fun() -> let e = e() in let index = index() in (match index, e with | VInt i, VArray a -> (try Array.get a i with _ -> VNull) | VInt32 _, VArray _ -> VNull | _, VObject o -> (match eval_oop ctx p o h_get [index] with | None -> throw ctx p "Invalid array access" | Some v -> v) | _ -> throw ctx p "Invalid array access")) | AccLocal i -> (fun() -> DynArray.get ctx.stack (DynArray.length ctx.stack - i)) | AccGlobal g -> (fun() -> !g) | AccThis -> (fun() -> ctx.vthis) | AccEnv i -> (fun() -> ctx.venv.(i)) and acc_set ctx p acc value = match acc with | AccField (v,f) -> let h = hash_field ctx f in (fun() -> let v = v() in let value = value() in match v with | VObject o -> set_field o h value; value | _ -> throw ctx p ("Invalid field access : " ^ f)) | AccArray (e,index) -> (fun() -> let e = e() in let index = index() in let value = value() in (match index, e with | VInt i, VArray a -> (try Array.set a i value; value with _ -> value) | VInt32 _, VArray _ -> value | _, VObject o -> (match eval_oop ctx p o h_set [index;value] with | None -> throw ctx p "Invalid array access" | Some _ -> value); | _ -> throw ctx p "Invalid array access")) | AccLocal i -> (fun() -> let value = value() in DynArray.set ctx.stack (DynArray.length ctx.stack - i) value; value) | AccGlobal g -> (fun() -> let value = value() in g := value; value) | AccThis -> (fun() -> let value = value() in ctx.vthis <- value; value) | AccEnv i -> (fun() -> let value = value() in ctx.venv.(i) <- value; value) and number_op ctx p sop iop fop oop rop v1 v2 = (fun() -> let v1 = v1() in let v2 = v2() in exc_number_op ctx p sop iop fop oop rop v1 v2) and exc_number_op ctx p sop iop fop oop rop v1 v2 = match v1, v2 with | VInt a, VInt b -> best_int (iop (Int32.of_int a) (Int32.of_int b)) | VInt32 a, VInt b -> best_int (iop a (Int32.of_int b)) | VInt a, VInt32 b -> best_int (iop (Int32.of_int a) b) | VFloat a, VInt b -> VFloat (fop a (float_of_int b)) | VFloat a, VInt32 b -> VFloat (fop a (Int32.to_float b)) | VInt a, VFloat b -> VFloat (fop (float_of_int a) b) | VInt32 a, VFloat b -> VFloat (fop (Int32.to_float a) b) | VFloat a, VFloat b -> VFloat (fop a b) | VInt32 a, VInt32 b -> best_int (iop a b) | VObject o, _ -> (match eval_oop ctx p o oop [v2] with | Some v -> v | None -> match v2 with | VObject o -> (match eval_oop ctx p o rop [v1] with | Some v -> v | None -> throw ctx p sop) | _ -> throw ctx p sop) | _ , VObject o -> (match eval_oop ctx p o rop [v1] with | Some v -> v | None -> throw ctx p sop) | _ -> throw ctx p sop and int_op ctx p op iop v1 v2 = (fun() -> let v1 = v1() in let v2 = v2() in match v1, v2 with | VInt a, VInt b -> best_int (iop (Int32.of_int a) (Int32.of_int b)) | VInt32 a, VInt b -> best_int (iop a (Int32.of_int b)) | VInt a, VInt32 b -> best_int (iop (Int32.of_int a) b) | VInt32 a, VInt32 b -> best_int (iop a b) | _ -> throw ctx p op) and base_op ctx op v1 v2 p = match op with | "+" -> (fun() -> let v1 = v1() in let v2 = v2() in match v1, v2 with | (VInt _ | VInt32 _), (VInt _ | VInt32 _) | (VInt _ | VInt32 _), VFloat _ | VFloat _ , (VInt _ | VInt32 _) | VFloat _ , VFloat _ | VObject _ , _ | _ , VObject _ -> exc_number_op ctx p op Int32.add (+.) h_add h_radd v1 v2 | VString a, _ -> VString (a ^ ctx.do_string v2) | _, VString b -> VString (ctx.do_string v1 ^ b) | _ -> throw ctx p op) | "-" -> number_op ctx p op Int32.sub (-.) h_sub h_rsub v1 v2 | "*" -> number_op ctx p op Int32.mul ( *. ) h_mult h_rmult v1 v2 | "/" -> (fun() -> let v1 = v1() in let v2 = v2() in match v1, v2 with | VInt i, VInt j -> VFloat ((float_of_int i) /. (float_of_int j)) | VInt i, VInt32 j -> VFloat ((float_of_int i) /. (Int32.to_float j)) | VInt32 i, VInt j -> VFloat ((Int32.to_float i) /. (float_of_int j)) | VInt32 i, VInt32 j -> VFloat ((Int32.to_float i) /. (Int32.to_float j)) | _ -> exc_number_op ctx p op Int32.div (/.) h_div h_rdiv v1 v2) | "%" -> number_op ctx p op (fun x y -> if y = 0l then throw ctx p op; Int32.rem x y) mod_float h_mod h_rmod v1 v2 | "&" -> int_op ctx p op Int32.logand v1 v2 | "|" -> int_op ctx p op Int32.logor v1 v2 | "^" -> int_op ctx p op Int32.logxor v1 v2 | "<<" -> int_op ctx p op (fun x y -> Int32.shift_left x (Int32.to_int y)) v1 v2 | ">>" -> int_op ctx p op (fun x y -> Int32.shift_right x (Int32.to_int y)) v1 v2 | ">>>" -> int_op ctx p op (fun x y -> Int32.shift_right_logical x (Int32.to_int y)) v1 v2 | _ -> throw ctx p op and eval_op ctx op e1 e2 p = match op with | "=" -> let acc = eval_access ctx e1 in let v = eval ctx e2 in acc_set ctx p acc v | "==" -> let v1 = eval ctx e1 in let v2 = eval ctx e2 in (fun() -> let v1 = v1() in let v2 = v2() in match ctx.do_compare v1 v2 with | CEq -> VBool true | _ -> VBool false) | "!=" -> let v1 = eval ctx e1 in let v2 = eval ctx e2 in (fun() -> let v1 = v1() in let v2 = v2() in match ctx.do_compare v1 v2 with | CEq -> VBool false | _ -> VBool true) | ">" -> let v1 = eval ctx e1 in let v2 = eval ctx e2 in (fun() -> let v1 = v1() in let v2 = v2() in match ctx.do_compare v1 v2 with | CSup -> VBool true | _ -> VBool false) | ">=" -> let v1 = eval ctx e1 in let v2 = eval ctx e2 in (fun() -> let v1 = v1() in let v2 = v2() in match ctx.do_compare v1 v2 with | CSup | CEq -> VBool true | _ -> VBool false) | "<" -> let v1 = eval ctx e1 in let v2 = eval ctx e2 in (fun() -> let v1 = v1() in let v2 = v2() in match ctx.do_compare v1 v2 with | CInf -> VBool true | _ -> VBool false) | "<=" -> let v1 = eval ctx e1 in let v2 = eval ctx e2 in (fun() -> let v1 = v1() in let v2 = v2() in match ctx.do_compare v1 v2 with | CInf | CEq -> VBool true | _ -> VBool false) | "+" | "-" | "*" | "/" | "%" | "|" | "&" | "^" | "<<" | ">>" | ">>>" -> let v1 = eval ctx e1 in let v2 = eval ctx e2 in base_op ctx op v1 v2 p | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "&=" | "^=" -> let aset, aget = eval_access_get_set ctx e1 in let v1 = acc_get ctx p aget in let v2 = eval ctx e2 in let v = base_op ctx (String.sub op 0 (String.length op - 1)) v1 v2 p in acc_set ctx p aset v | "&&" -> let e1 = eval ctx e1 in let e2 = eval ctx e2 in (fun() -> match e1() with | VBool true -> e2() | _ -> VBool false) | "||" -> let e1 = eval ctx e1 in let e2 = eval ctx e2 in (fun() -> match e1() with | VBool true as v -> v | _ -> e2()) | "++=" | "--=" -> let aset, aget = eval_access_get_set ctx e1 in let v1 = acc_get ctx p aget in let v2 = eval ctx e2 in let vcache = ref VNull in let v = base_op ctx (String.sub op 0 1) (fun() -> vcache := v1(); !vcache) v2 p in let set = acc_set ctx p aset v in (fun() -> ignore(set()); !vcache) | _ -> throw ctx p ("Unsupported " ^ op) and call ctx vthis vfun pl p = let oldthis = ctx.vthis in let stackpos = DynArray.length ctx.stack in let oldstack = ctx.callstack in let oldsize = ctx.callsize in let oldenv = ctx.venv in ctx.vthis <- vthis; ctx.callstack <- { cpos = p; cthis = oldthis; cstack = stackpos; cenv = oldenv } :: ctx.callstack; ctx.callsize <- oldsize + 1; if oldsize > 600 then exc (VString "Stack overflow"); let ret = (try (match vfun with | VClosure (vl,f) -> f vl pl | VFunction f -> (match pl, f with | [], Fun0 f -> f() | [a], Fun1 f -> f a | [a;b], Fun2 f -> f a b | [a;b;c], Fun3 f -> f a b c | [a;b;c;d], Fun4 f -> f a b c d | [a;b;c;d;e], Fun5 f -> f a b c d e | _, FunVar f -> f pl | _ -> exc (VString (Printf.sprintf "Invalid call (%d args instead of %d)" (List.length pl) (nargs f)))) | VAbstract (ALazyType (f,get)) -> get() | _ -> exc (VString "Invalid call")) with Return v -> v | Stack_overflow -> exc (VString "Compiler Stack overflow") | Sys_error msg | Failure msg -> exc (VString msg) | Unix.Unix_error (_,cmd,msg) -> exc (VString ("Error " ^ cmd ^ " " ^ msg)) | Invalid_expr -> exc (VString "Invalid input value") | Builtin_error | Invalid_argument _ -> exc (VString "Invalid call")) in ctx.vthis <- oldthis; ctx.venv <- oldenv; ctx.callstack <- oldstack; ctx.callsize <- oldsize; pop ctx (DynArray.length ctx.stack - stackpos); ret let eval_delayed ctx e = eval ctx (Genneko.gen_expr ctx.gen e) (* ---------------------------------------------------------------------- *) (* OTHERS *) let rec to_string ctx n v = if n > 5 then "<...>" else let n = n + 1 in match v with | VNull -> "null" | VBool true -> "true" | VBool false -> "false" | VInt i -> string_of_int i | VInt32 i -> Int32.to_string i | VFloat f -> let s = float_repres f in let len = String.length s in if String.unsafe_get s (len - 1) = '.' then String.sub s 0 (len - 1) else s | VString s -> s | VArray vl -> "[" ^ String.concat "," (Array.to_list (Array.map (to_string ctx n) vl)) ^ "]" | VAbstract a -> (match a with | APos p -> "#pos(" ^ Lexer.get_error_pos (Printf.sprintf "%s:%d:") p ^ ")" | _ -> "#abstract") | VFunction f -> "#function:" ^ string_of_int (nargs f) | VClosure _ -> "#function:-1" | VObject o -> match eval_oop ctx null_pos o h_string [] with | Some (VString s) -> s | _ -> let b = Buffer.create 0 in let first = ref true in Buffer.add_char b '{'; Array.iter (fun (f,v) -> if !first then begin Buffer.add_char b ' '; first := false; end else Buffer.add_string b ", "; Buffer.add_string b (field_name ctx f); Buffer.add_string b " => "; Buffer.add_string b (to_string ctx n v); ) o.ofields; Buffer.add_string b (if !first then "}" else " }"); Buffer.contents b let rec compare ctx a b = let fcmp (a:float) b = if a = b then CEq else if a < b then CInf else if a > b then CSup else CUndef in let scmp (a:string) b = if a = b then CEq else if a < b then CInf else CSup in let icmp (a:int32) b = let l = Int32.compare a b in if l = 0 then CEq else if l < 0 then CInf else CSup in match a, b with | VNull, VNull -> CEq | VInt a, VInt b -> if a = b then CEq else if a < b then CInf else CSup | VInt32 a, VInt32 b -> icmp a b | VInt a, VInt32 b -> icmp (Int32.of_int a) b | VInt32 a, VInt b -> icmp a (Int32.of_int b) | VFloat a, VFloat b -> fcmp a b | VFloat a, VInt b -> fcmp a (float_of_int b) | VFloat a, VInt32 b -> fcmp a (Int32.to_float b) | VInt a, VFloat b -> fcmp (float_of_int a) b | VInt32 a, VFloat b -> fcmp (Int32.to_float a) b | VBool a, VBool b -> if a = b then CEq else if a then CSup else CInf | VString a, VString b -> scmp a b | VInt _ , VString s | VInt32 _, VString s | VFloat _ , VString s | VBool _ , VString s -> scmp (to_string ctx 0 a) s | VString s, VInt _ | VString s, VInt32 _ | VString s, VFloat _ | VString s, VBool _ -> scmp s (to_string ctx 0 b) | VObject oa, VObject ob -> if oa == ob then CEq else (match eval_oop ctx null_pos oa h_compare [b] with | Some (VInt i) -> if i = 0 then CEq else if i < 0 then CInf else CSup | _ -> CUndef) | VAbstract a, VAbstract b -> if a == b then CEq else CUndef | VArray a, VArray b -> if a == b then CEq else CUndef | VFunction a, VFunction b -> if a == b then CEq else CUndef | VClosure (la,fa), VClosure (lb,fb) -> if la == lb && fa == fb then CEq else CUndef | _ -> CUndef let value_match_failure s expected actual = let sl = String.concat ", " in let slv l = sl (List.map s_value_kind l) in Printf.sprintf "%s (expected [%s], got [%s])" s (sl expected) (slv actual) let load_prim ctx f n = match f, n with | VString f, VInt n -> let lib, fname = (try ExtString.String.split f "@" with _ -> "", f) in (try let f = (match lib with | "std" -> Hashtbl.find std_lib fname | "macro" -> Hashtbl.find macro_lib fname | "regexp" -> Hashtbl.find reg_lib fname | "zlib" -> Hashtbl.find z_lib fname | _ -> failwith ("You cannot use the library '" ^ lib ^ "' inside a macro"); ) in if nargs f <> n then raise Not_found; VFunction f with Not_found -> VFunction (FunVar (fun _ -> exc (VString ("Primitive not found " ^ f ^ ":" ^ string_of_int n))))) | _ -> exc (VString (value_match_failure "Invalid call" ["VString";"VInt"] [f;n])) let create com api = let loader = obj hash [ "args",VArray (Array.of_list (List.map (fun s -> VString s) com.sys_args)); "loadprim",VFunction (Fun2 (fun a b -> (get_ctx()).do_loadprim a b)); "loadmodule",VFunction (Fun2 (fun a b -> assert false)); ] in let ctx = { gen = Genneko.new_context com 2 true; types = Hashtbl.create 0; error = false; error_proto = { ofields = [||]; oproto = None }; prototypes = Hashtbl.create 0; enums = [||]; (* eval *) locals_map = PMap.empty; locals_count = 0; locals_barrier = 0; locals_env = DynArray.create(); globals = PMap.empty; (* runtime *) callstack = []; callsize = 0; stack = DynArray.create(); exc = []; vthis = VNull; venv = [||]; fields_cache = Hashtbl.copy constants; (* api *) do_call = Obj.magic(); do_string = Obj.magic(); do_loadprim = Obj.magic(); do_compare = Obj.magic(); (* context *) curapi = api; loader = VObject loader; exports = VObject { ofields = [||]; oproto = None }; } in ctx.do_call <- call ctx; ctx.do_string <- to_string ctx 0; ctx.do_loadprim <- load_prim ctx; ctx.do_compare <- compare ctx; select ctx; List.iter (fun e -> ignore((eval ctx e)())) (Genneko.header()); ctx let do_reuse ctx api = ctx.curapi <- api let can_reuse ctx types = let has_old_version t = let inf = Type.t_infos t in try Hashtbl.find ctx.types inf.mt_path <> inf.mt_module.m_id with Not_found -> false in not (List.exists has_old_version types) let add_types ctx types ready = let types = List.filter (fun t -> match t with | TAbstractDecl a when not (Meta.has Meta.CoreType a.a_meta) -> (* A @:native on an abstract causes the implementation class and the abstract to have the same path. Let's skip all abstracts so this doesn't matter. *) false | _ -> let path = Type.t_path t in if Hashtbl.mem ctx.types path then false else begin Hashtbl.add ctx.types path (Type.t_infos t).mt_module.m_id; true; end ) types in List.iter ready types; let e = (EBlock (Genneko.build ctx.gen types), null_pos) in ignore(catch_errors ctx (fun() -> ignore((eval ctx e)()))) let get_path ctx path p = let rec loop = function | [] -> assert false | [x] -> (EConst (Ident x),p) | x :: l -> (EField (loop l,x),p) in (eval ctx (loop (List.rev path)))() let set_error ctx e = ctx.error <- e let call_path ctx path f vl api = if ctx.error then None else let old = ctx.curapi in ctx.curapi <- api; let p = Genneko.pos ctx.gen api.pos in catch_errors ctx ~final:(fun() -> ctx.curapi <- old) (fun() -> match get_path ctx path p with | VObject o -> let f = get_field o (hash f) in call ctx (VObject o) f vl p | v -> print_endline (value_match_failure ("Unexpected value for " ^ (String.concat "." path)) ["VObject"] [v]); assert false ) let init ctx = let get_enum_proto e = match get_path ctx ["haxe";"macro";enum_name e] null_pos with | VObject e -> (match get_field e h_constructs with | VObject cst -> (match get_field cst h_a with | VArray a -> Array.map (fun s -> match s with | VObject s -> (match get_field s h_s with VString s -> get_field e (hash s),s | _ -> assert false) | _ -> assert false ) a | _ -> assert false) | _ -> assert false) | _ -> failwith ("haxe.macro." ^ enum_name e ^ " does not exists") in ctx.enums <- Array.of_list (List.map get_enum_proto MacroApi.all_enums); ctx.error_proto <- (match get_path ctx ["haxe";"macro";"Error";"prototype"] null_pos with VObject p -> p | _ -> failwith ("haxe.macro.Error does not exists")) (* ---------------------------------------------------------------------- *) (* MACRO API IMPL *) let vnull = VNull let vint i = VInt i let vint32 i = VInt32 i let vfun0 f = VFunction (Fun0 f) let vfun1 f = VFunction (Fun1 f) let vfun2 f = VFunction (Fun2 f) let vfun3 f = VFunction (Fun3 f) let vfun4 f = VFunction (Fun4 f) let vfun5 f = VFunction (Fun5 f) let vbool b = VBool b let vfloat f = VFloat f let encode_unsafe o = VAbstract (AUnsafe o) let value_string v = to_string (get_ctx()) 0 v let field v f = match v with | VObject o -> get_field o (hash f) | _ -> raise Invalid_expr let dec_string v = match field v "__s" with | VString s -> s | _ -> raise Invalid_expr let decode_bytes v = match field v "b" with | VString s -> s | _ -> raise Invalid_expr let dec_array v = match field v "__a", field v "length" with | VArray a, VInt l -> Array.to_list (if Array.length a = l then a else Array.sub a 0 l) | _ -> raise Invalid_expr let decode_lazytype = function | VAbstract (ALazyType (t,_)) -> t | _ -> raise Invalid_expr let encode_lazytype t f = VAbstract (ALazyType (t,f)) let encode_tdecl t = VAbstract (ATDecl t) let decode_tdecl = function | VAbstract (ATDecl t) -> t | _ -> raise Invalid_expr let dec_int = function | VInt i -> i | VInt32 i -> Int32.to_int i | _ -> raise Invalid_expr let dec_i32 = function | VInt i -> Int32.of_int i | VInt32 i -> i | _ -> raise Invalid_expr let dec_bytes = function | VString s -> s | _ -> raise Invalid_expr let encode_pos p = VAbstract (APos p) let enc_inst path fields = let ctx = get_ctx() in let p = (try Hashtbl.find ctx.prototypes path with Not_found -> try (match get_path ctx (path@["prototype"]) Nast.null_pos with | VObject o -> Hashtbl.add ctx.prototypes path o; o | _ -> raise (Runtime VNull)) with Runtime _ -> failwith ("Prototype not found " ^ String.concat "." path) ) in let o = obj hash fields in o.oproto <- Some p; VObject o let enc_array l = let a = Array.of_list l in enc_inst ["Array"] [ "__a", VArray a; "length", VInt (Array.length a); ] let enc_string s = enc_inst ["String"] [ "__s", VString s; "length", VInt (String.length s) ] let encode_bytes s = enc_inst ["haxe";"io";"Bytes"] [ "b", VString s; "length", VInt (String.length s) ] let enc_hash h = enc_inst ["haxe";"ds";"StringMap"] [ "h", VAbstract (AHash h); ] let enc_obj _ l = VObject (obj hash l) let encode_enum (i:enum_type) pos index pl = let eindex : int = Obj.magic i in let edef = (get_ctx()).enums.(eindex) in if pl = [] then fst edef.(index) else enc_inst ["haxe";"macro";enum_name i] ( ("tag", VString (snd edef.(index))) :: ("index", VInt index) :: ("args", VArray (Array.of_list pl)) :: (match pos with None -> [] | Some p -> ["pos", encode_pos p]) ) let encode_ref v convert tostr = enc_obj O__Const [ "get", VFunction (Fun0 (fun() -> convert v)); "__string", VFunction (Fun0 (fun() -> VString (tostr()))); "toString", VFunction (Fun0 (fun() -> enc_string (tostr()))); "$", VAbstract (AUnsafe (Obj.repr v)); ] let decode_ref v : 'a = match field v "$" with | VAbstract (AUnsafe t) -> Obj.obj t | _ -> raise Invalid_expr let encode_string_map convert m = let h = Hashtbl.create 0 in PMap.iter (fun k v -> Hashtbl.add h (VString k) (convert v)) m; enc_hash h let decode_pos = function | VAbstract (APos p) -> p | _ -> raise Invalid_expr let decode_enum v = match field v "index", field v "args" with | VInt i, VNull -> i, [] | VInt i, VArray a -> i, Array.to_list a | _ -> raise Invalid_expr let decode_enum_with_pos v = (match field v "index", field v "args" with | VInt i, VNull -> i, [] | VInt i, VArray a -> i, Array.to_list a | _ -> raise Invalid_expr),(match field v "pos" with | VAbstract(APos p) -> p | _ -> Globals.null_pos) (* Can happen from reification and other sources. *) let dec_bool = function | VBool b -> b | _ -> raise Invalid_expr let decode_unsafe = function | VAbstract (AUnsafe o) -> o | _ -> raise Invalid_expr let compiler_error msg pos = exc (enc_inst ["haxe";"macro";"Error"] [("message",enc_string msg);("pos",encode_pos pos)]) let value_to_expr v p = let h_enum = hash "__enum__" and h_et = hash "__et__" and h_ct = hash "__ct__" in let h_tag = hash "tag" and h_args = hash "args" in let h_length = hash "length" in let ctx = get_ctx() in let error v = failwith ("Unsupported value " ^ ctx.do_string v) in let make_path t = let rec loop = function | [] -> assert false | [name] -> (Ast.EConst (Ast.Ident name),p) | name :: l -> (Ast.EField (loop l,name),p) in let t = t_infos t in loop (List.rev (if t.mt_module.m_path = t.mt_path then fst t.mt_path @ [snd t.mt_path] else fst t.mt_module.m_path @ [snd t.mt_module.m_path;snd t.mt_path])) in let rec loop = function | VNull -> (Ast.EConst (Ast.Ident "null"),p) | VBool b -> (Ast.EConst (Ast.Ident (if b then "true" else "false")),p) | VInt i -> (Ast.EConst (Ast.Int (string_of_int i)),p) | VInt32 i -> (Ast.EConst (Ast.Int (Int32.to_string i)),p) | VFloat f -> haxe_float f p | VAbstract (APos p) -> (Ast.EObjectDecl ( (("fileName",Globals.null_pos) , (Ast.EConst (Ast.String p.Globals.pfile) , p)) :: (("lineNumber",Globals.null_pos) , (Ast.EConst (Ast.Int (string_of_int (Lexer.get_error_line p))),p)) :: (("className",Globals.null_pos) , (Ast.EConst (Ast.String ("")),p)) :: [] ), p) | VString _ | VArray _ | VAbstract _ | VFunction _ | VClosure _ as v -> error v | VObject o as v -> match o.oproto with | None -> (match get_field_opt o h_ct with | Some (VAbstract (ATDecl t)) -> make_path t | _ -> let fields = List.fold_left (fun acc (fid,v) -> ((field_name ctx fid,Globals.null_pos), loop v) :: acc) [] (Array.to_list o.ofields) in (Ast.EObjectDecl fields, p)) | Some proto -> match get_field_opt proto h_enum, get_field_opt o h_a, get_field_opt o h_s, get_field_opt o h_length with | _, Some (VArray a), _, Some (VInt len) -> (Ast.EArrayDecl (List.map loop (Array.to_list (Array.sub a 0 len))),p) | _, _, Some (VString s), _ -> (Ast.EConst (Ast.String s),p) | Some (VObject en), _, _, _ -> (match get_field en h_et, get_field o h_tag with | VAbstract (ATDecl t), VString tag -> let e = (Ast.EField (make_path t,tag),p) in (match get_field_opt o h_args with | Some (VArray args) -> let args = List.map loop (Array.to_list args) in (Ast.ECall (e,args),p) | _ -> e) | _ -> error v) | _ -> error v in loop v let value_signature v = let cache = ref [] in let cache_count = ref 0 in let hfiles = Hashtbl.create 0 in let get_file f = try Hashtbl.find hfiles f with Not_found -> let ff = Path.unique_full_path f in Hashtbl.add hfiles f ff; ff in let do_cache (v:value) (v2:value) = (* tricky : we need to have a quick not-linear cache based on objects address but we can't use address since the GC might be triggered here. Instead let's mutate the object temporary. *) let vt = Obj.repr v in let old = Obj.tag vt in let old_val = Obj.field vt 0 in let abstract_tag = 7 in Obj.set_tag vt abstract_tag; Obj.set_field vt 0 (Obj.repr (ACacheRef v2)); cache := (vt,old,old_val) :: !cache; incr cache_count in let rec loop v = match v with | VNull | VBool _ | VInt _ | VFloat _ | VString _ | VInt32 _ -> v | VObject o -> let o2 = { ofields = [||]; oproto = None } in let v2 = VObject o2 in do_cache v v2; Array.iter (fun (f,v) -> if f <> h_class then set_field o2 f (loop v)) o.ofields; (match o.oproto with | None -> () | Some p -> (match loop (VObject p) with VObject p2 -> o2.oproto <- Some p2 | _ -> assert false)); v2 | VArray a -> let a2 = Array.create (Array.length a) VNull in let v2 = VArray a2 in do_cache v v2; for i = 0 to Array.length a - 1 do a2.(i) <- loop a.(i); done; v2 | VFunction f -> let v2 = VFunction (Obj.magic !cache_count) in do_cache v v2; v2 | VClosure (vl,f) -> let rl = ref [] in let v2 = VClosure (Obj.magic rl, Obj.magic !cache_count) in (* in ocaml 4.0+ it was reported some stack overflow, related to vl being GC'ed or mutated in do_cache. let's make sure to have a real pointer to it first. The fix will trigger an alloc which might have simply moved the problem away *) let vl = VNull :: vl in do_cache v v2; rl := List.map loop vl; v2 | VAbstract (APos p) -> VAbstract (APos { p with Globals.pfile = get_file p.Globals.pfile }) | VAbstract (ACacheRef v) -> v | VAbstract (AHash h) -> let h2 = Hashtbl.create 0 in let v2 = VAbstract (AHash h2) in do_cache v v2; Hashtbl.iter (fun k v -> Hashtbl.add h2 k (loop v)) h2; v2 | VAbstract _ -> let v2 = VAbstract (Obj.magic !cache_count) in do_cache v v2; v2 in let v = loop v in (* restore *) List.iter (fun (vt,tag,field) -> Obj.set_tag vt tag; Obj.set_field vt 0 field; ) !cache; Digest.string (Marshal.to_string v [Marshal.Closures]) let prepare_callback v n = match v with | VFunction _ | VClosure _ -> let ctx = get_ctx() in (fun args -> match catch_errors ctx (fun() -> ctx.do_call VNull v args null_pos) with | None -> VNull | Some v -> v ) | _ -> raise Invalid_expr haxe_3.4.4.orig/src/macro/macroApi.ml0000664000175000017500000016200013166552354017370 0ustar andyandy00000000000000open Ast open Type open Common exception Invalid_expr exception Abort (** Our access to the compiler from the macro api **) type 'value compiler_api = { pos : Globals.pos; get_com : unit -> Common.context; get_type : string -> Type.t option; get_module : string -> Type.t list; after_typing : (module_type list -> unit) -> unit; on_generate : (Type.t list -> unit) -> unit; after_generate : (unit -> unit) -> unit; on_type_not_found : (string -> 'value) -> unit; parse_string : string -> Globals.pos -> bool -> Ast.expr; type_expr : Ast.expr -> Type.texpr; resolve_type : Ast.complex_type -> Globals.pos -> t; type_macro_expr : Ast.expr -> Type.texpr; store_typed_expr : Type.texpr -> Ast.expr; allow_package : string -> unit; type_patch : string -> string -> bool -> string option -> unit; meta_patch : string -> string -> string option -> bool -> unit; set_js_generator : (Genjs.ctx -> unit) -> unit; get_local_type : unit -> t option; get_expected_type : unit -> t option; get_call_arguments : unit -> Ast.expr list option; get_local_method : unit -> string; get_local_imports : unit -> Ast.import list; get_local_using : unit -> tclass list; get_local_vars : unit -> (string, Type.tvar) PMap.t; get_build_fields : unit -> 'value; get_pattern_locals : Ast.expr -> Type.t -> (string,Type.tvar * Globals.pos) PMap.t; define_type : 'value -> unit; define_module : string -> 'value list -> ((string * Globals.pos) list * Ast.import_mode) list -> Ast.type_path list -> unit; module_dependency : string -> string -> bool -> unit; current_module : unit -> module_def; on_reuse : (unit -> bool) -> unit; mutable current_macro_module : unit -> module_def; delayed_macro : int -> (unit -> (unit -> 'value)); use_cache : unit -> bool; format_string : string -> Globals.pos -> Ast.expr; cast_or_unify : Type.t -> texpr -> Globals.pos -> Type.texpr; add_global_metadata : string -> string -> (bool * bool * bool) -> unit; add_module_check_policy : string list -> int list -> bool -> int -> unit; } type enum_type = | IExpr | IBinop | IUnop | IConst | ITParam | ICType | IField | IType | IFieldKind | IMethodKind | IVarAccess | IAccess | IClassKind | ITypedExpr | ITConstant | IModuleType | IFieldAccess | IAnonStatus | IImportMode type obj_type = (* make_const *) | O__Const (* Expr *) | OImportExpr | OImportExpr_path | OTypePath | OMetadataEntry | OField | OTypeParamDecl | OFunction | OFunctionArg | OExprDef_fields | OVar | OCase | OCatch | OExpr (* Type *) | OMetaAccess | OTypeParameter | OClassType | OAbstractType | OAnonType | ODefType | OEnumType | OClassField | OAbstractType_binops | OAbstractType_unops | OAbstractType_from | OAbstractType_to | OEnumField | OClassType_superClass | OClassType_interfaces | OType_args | OTVar | OTVar_extra | OTFunc | OTFunc_args | OFieldAccess_c | OTypedExprDef | OTypedExprDef_fields | OTypedExprDef_cases | OTypedExprDef_catches | OJSGenApi | OContext_getPosInfos | OCompiler_getDisplayPos | ORef (* ---- ^^^^^ please exactly match the name of the typedef or use TypeName_field if it's a anonymous *) (** Our access to the interpreter from the macro api **) module type InterpApi = sig type value val vnull : value val vint : int -> value val vfloat : float -> value val vint32 : int32 -> value val vbool : bool -> value val enc_array : value list -> value val enc_string : string -> value val enc_obj : obj_type -> (string * value) list -> value val vfun0 : (unit -> value) -> value val vfun1 : (value -> value) -> value val vfun2 : (value -> value -> value) -> value val vfun3 : (value -> value -> value -> value) -> value val vfun4 : (value -> value -> value -> value -> value) -> value val vfun5 : (value -> value -> value -> value -> value -> value) -> value val encode_pos : Globals.pos -> value val encode_enum : enum_type -> Globals.pos option -> int -> value list -> value val encode_string_map : ('a -> value) -> (string, 'a) PMap.t -> value val encode_tdecl : Type.module_type -> value val encode_lazytype : (unit -> Type.t) ref -> (unit -> value) -> value val encode_unsafe : Obj.t -> value val field : value -> string -> value val dec_bool : value -> bool val dec_int : value -> int val dec_i32 : value -> int32 val dec_string : value -> string val dec_array : value -> value list val decode_pos : value -> Globals.pos val decode_enum : value -> int * value list val decode_tdecl : value -> Type.module_type val decode_lazytype : value -> (unit -> Type.t) ref val decode_unsafe : value -> Obj.t val decode_enum_with_pos : value -> (int * value list) * Globals.pos val encode_ref : 'a -> ('a -> value) -> (unit -> string) -> value val decode_ref : value -> 'a val compiler_error : string -> Globals.pos -> 'a val value_to_expr : value -> Globals.pos -> Ast.expr val value_signature : value -> string val encode_bytes : string -> value val decode_bytes : value -> string (* haxe.io.Bytes *) val prepare_callback : value -> int -> (value list -> value) val value_string : value -> string end let enum_name = function | IExpr -> "ExprDef" | IBinop -> "Binop" | IUnop -> "Unop" | IConst -> "Constant" | ITParam -> "TypeParam" | ICType -> "ComplexType" | IField -> "FieldType" | IType -> "Type" | IFieldKind -> "FieldKind" | IMethodKind -> "MethodKind" | IVarAccess -> "VarAccess" | IAccess -> "Access" | IClassKind -> "ClassKind" | ITypedExpr -> "TypedExprDef" | ITConstant -> "TConstant" | IModuleType -> "ModuleType" | IFieldAccess -> "FieldAccess" | IAnonStatus -> "AnonStatus" | IImportMode -> "ImportMode" let proto_name = function | O__Const -> assert false | OImportExpr -> "ImportExpr", None | OImportExpr_path -> "ImportExpr", Some "path" | OTypePath -> "TypePath", None | OMetadataEntry -> "MetadataEntry", None | OField -> "Field", None | OTypeParamDecl -> "TypeParamDecl", None | OFunction -> "Function", None | OFunctionArg -> "FunctionArg", None | OExprDef_fields -> "ExprDef", Some "fields" | OVar -> "Var", None | OCase -> "Case", None | OCatch -> "Catch", None | OExpr -> "Expr", None | OMetaAccess -> "MetaAccess", None | OTypeParameter -> "TypeParameter", None | OClassType -> "ClassType", None | OAbstractType -> "AbstracType", None | OAnonType -> "AnonType", None | ODefType -> "DefType", None | OEnumType -> "EnumType", None | OClassField -> "ClassField", None | OAbstractType_binops -> "AbstractType", Some "binops" | OAbstractType_unops -> "AbstractType", Some "unops" | OAbstractType_from -> "AbstractType", Some "from" | OAbstractType_to -> "AbstractType", Some "to" | OEnumField -> "EnumField", None | OClassType_superClass -> "ClassType", Some "superClass" | OClassType_interfaces -> "ClassType", Some "interfaces" | OType_args -> "Type", Some "args" | OTVar -> "TVar", None | OTVar_extra -> "TVar", Some "extra" | OTFunc -> "TFunc", None | OTFunc_args -> "TFunc", Some "args" | OFieldAccess_c -> "FieldAccess", Some "c" | OTypedExprDef -> "TypedExprDef", None | OTypedExprDef_fields -> "TypedExprDef", Some "fields" | OTypedExprDef_cases -> "TypedExprDef", Some "cases" | OTypedExprDef_catches -> "TypedExprDef", Some "catches" | OJSGenApi -> "JSGenApi", None | OContext_getPosInfos -> "Context", Some "getPosInfos" | OCompiler_getDisplayPos -> "Compiler", Some "getDisplayPos" | ORef -> "Ref", None let all_enums = let last = IImportMode in let rec loop i = let e : enum_type = Obj.magic i in if e = last then [e] else e :: loop (i + 1) in loop 0 let s_type_path = Globals.s_type_path (* convert float value to haxe expression, handling inf/-inf/nan *) let haxe_float f p = let std = (Ast.EConst (Ast.Ident "std"), p) in let math = (Ast.EField (std, "Math"), p) in if (f = infinity) then (Ast.EField (math, "POSITIVE_INFINITY"), p) else if (f = neg_infinity) then (Ast.EField (math, "NEGATIVE_INFINITY"), p) else if (f <> f) then (Ast.EField (math, "NaN"), p) else (Ast.EConst (Ast.Float (float_repres f)), p) (* ------------------------------------------------------------------------------------------------------------- *) (* Our macro api functor *) module MacroApiImpl(InterpImpl:InterpApi) = struct open InterpImpl (* The whole encoding/decoding of compiler values from/to interpreter values based on interpreter api *) let null f = function | None -> vnull | Some v -> f v let encode_enum ?(pos=None) k tag vl = encode_enum k pos tag vl let encode_const c = let tag, pl = match c with | Int s -> 0, [enc_string s] | Float s -> 1, [enc_string s] | String s -> 2, [enc_string s] | Ident s -> 3, [enc_string s] | Regexp (s,opt) -> 4, [enc_string s;enc_string opt] in encode_enum IConst tag pl let rec encode_binop op = let tag, pl = match op with | OpAdd -> 0, [] | OpMult -> 1, [] | OpDiv -> 2, [] | OpSub -> 3, [] | OpAssign -> 4, [] | OpEq -> 5, [] | OpNotEq -> 6, [] | OpGt -> 7, [] | OpGte -> 8, [] | OpLt -> 9, [] | OpLte -> 10, [] | OpAnd -> 11, [] | OpOr -> 12, [] | OpXor -> 13, [] | OpBoolAnd -> 14, [] | OpBoolOr -> 15, [] | OpShl -> 16, [] | OpShr -> 17, [] | OpUShr -> 18, [] | OpMod -> 19, [] | OpAssignOp op -> 20, [encode_binop op] | OpInterval -> 21, [] | OpArrow -> 22, [] in encode_enum IBinop tag pl let encode_unop op = let tag = match op with | Increment -> 0 | Decrement -> 1 | Not -> 2 | Neg -> 3 | NegBits -> 4 in encode_enum IUnop tag [] let encode_import (path,mode) = let tag,pl = match mode with | INormal -> 0, [] | IAsName s -> 1, [enc_string s] | IAll -> 2,[] in let mode = encode_enum IImportMode tag pl in enc_obj OImportExpr [ "path", enc_array (List.map (fun (name,p) -> enc_obj OImportExpr_path [ "pos", encode_pos p; "name", enc_string name]) path); "mode", mode ] let encode_placed_name (s,p) = enc_string s let rec encode_path (t,_) = let fields = [ "pack", enc_array (List.map enc_string t.tpackage); "name", enc_string t.tname; "params", enc_array (List.map encode_tparam t.tparams); ] in enc_obj OTypePath (match t.tsub with | None -> fields | Some s -> ("sub", enc_string s) :: fields) and encode_tparam = function | TPType t -> encode_enum ITParam 0 [encode_ctype t] | TPExpr e -> encode_enum ITParam 1 [encode_expr e] and encode_access a = let tag = match a with | APublic -> 0 | APrivate -> 1 | AStatic -> 2 | AOverride -> 3 | ADynamic -> 4 | AInline -> 5 | AMacro -> 6 in encode_enum IAccess tag [] and encode_meta_entry (m,ml,p) = enc_obj OMetadataEntry [ "name", enc_string (Meta.to_string m); "params", enc_array (List.map encode_expr ml); "pos", encode_pos p; ] and encode_meta_content m = enc_array (List.map encode_meta_entry m) and encode_field (f:class_field) = let tag, pl = match f.cff_kind with | FVar (t,e) -> 0, [null encode_ctype t; null encode_expr e] | FFun f -> 1, [encode_fun f] | FProp (get,set, t, e) -> 2, [encode_placed_name get; encode_placed_name set; null encode_ctype t; null encode_expr e] in enc_obj OField [ "name",encode_placed_name f.cff_name; "name_pos", encode_pos (pos f.cff_name); "doc", null enc_string f.cff_doc; "pos", encode_pos f.cff_pos; "kind", encode_enum IField tag pl; "meta", encode_meta_content f.cff_meta; "access", enc_array (List.map encode_access f.cff_access); ] and encode_ctype t = let tag, pl = match fst t with | CTPath p -> 0, [encode_path (p,Globals.null_pos)] | CTFunction (pl,r) -> 1, [enc_array (List.map encode_ctype pl);encode_ctype r] | CTAnonymous fl -> 2, [enc_array (List.map encode_field fl)] | CTParent t -> 3, [encode_ctype t] | CTExtend (tl,fields) -> 4, [enc_array (List.map encode_path tl); enc_array (List.map encode_field fields)] | CTOptional t -> 5, [encode_ctype t] in encode_enum ~pos:(Some (pos t)) ICType tag pl and encode_tparam_decl tp = enc_obj OTypeParamDecl [ "name", encode_placed_name tp.tp_name; "name_pos", encode_pos (pos tp.tp_name); "params", enc_array (List.map encode_tparam_decl tp.tp_params); "constraints", enc_array (List.map encode_ctype tp.tp_constraints); "meta", encode_meta_content tp.tp_meta; ] and encode_fun f = enc_obj OFunction [ "params", enc_array (List.map encode_tparam_decl f.f_params); "args", enc_array (List.map (fun (n,opt,m,t,e) -> enc_obj OFunctionArg [ "name", encode_placed_name n; "name_pos", encode_pos (pos n); "opt", vbool opt; "meta", encode_meta_content m; "type", null encode_ctype t; "value", null encode_expr e; ] ) f.f_args); "ret", null encode_ctype f.f_type; "expr", null encode_expr f.f_expr ] and encode_expr e = let rec loop (e,p) = let tag, pl = match e with | EConst c -> 0, [encode_const c] | EArray (e1,e2) -> 1, [loop e1;loop e2] | EBinop (op,e1,e2) -> 2, [encode_binop op;loop e1;loop e2] | EField (e,f) -> 3, [loop e;enc_string f] | EParenthesis e -> 4, [loop e] | EObjectDecl fl -> 5, [enc_array (List.map (fun ((f,p),e) -> enc_obj OExprDef_fields [ "field",enc_string f; "name_pos",encode_pos p; "expr",loop e; ]) fl)] | EArrayDecl el -> 6, [enc_array (List.map loop el)] | ECall (e,el) -> 7, [loop e;enc_array (List.map loop el)] | ENew (p,el) -> 8, [encode_path p; enc_array (List.map loop el)] | EUnop (op,flag,e) -> 9, [encode_unop op; vbool (match flag with Prefix -> false | Postfix -> true); loop e] | EVars vl -> 10, [enc_array (List.map (fun (v,t,eo) -> enc_obj OVar [ "name",encode_placed_name v; "name_pos",encode_pos (pos v); "type",null encode_ctype t; "expr",null loop eo; ] ) vl)] | EFunction (name,f) -> 11, [null enc_string name; encode_fun f] | EBlock el -> 12, [enc_array (List.map loop el)] | EFor (e,eloop) -> 13, [loop e;loop eloop] | EIn (e1,e2) -> 14, [loop e1;loop e2] | EIf (econd,e,eelse) -> 15, [loop econd;loop e;null loop eelse] | EWhile (econd,e,flag) -> 16, [loop econd;loop e;vbool (match flag with NormalWhile -> true | DoWhile -> false)] | ESwitch (e,cases,eopt) -> 17, [loop e;enc_array (List.map (fun (ecl,eg,e,p) -> enc_obj OCase [ "values",enc_array (List.map loop ecl); "guard",null loop eg; "expr",null loop e; "pos",encode_pos p; ] ) cases);null (fun (e,_) -> encode_null_expr e) eopt] | ETry (e,catches) -> 18, [loop e;enc_array (List.map (fun (v,t,e,p) -> enc_obj OCatch [ "name",encode_placed_name v; "name_pos",encode_pos (pos v); "type",encode_ctype t; "expr",loop e; "pos",encode_pos p ] ) catches)] | EReturn eo -> 19, [null loop eo] | EBreak -> 20, [] | EContinue -> 21, [] | EUntyped e -> 22, [loop e] | EThrow e -> 23, [loop e] | ECast (e,t) -> 24, [loop e; null encode_ctype t] | EDisplay (e,flag) -> 25, [loop e; vbool flag] | EDisplayNew t -> 26, [encode_path t] | ETernary (econd,e1,e2) -> 27, [loop econd;loop e1;loop e2] | ECheckType (e,t) -> 28, [loop e; encode_ctype t] | EMeta (m,e) -> 29, [encode_meta_entry m;loop e] in enc_obj OExpr [ "pos", encode_pos p; "expr", encode_enum IExpr tag pl; ] in loop e and encode_null_expr e = match e with | None -> enc_obj OExpr ["pos", vnull;"expr",vnull] | Some e -> encode_expr e (* ---------------------------------------------------------------------- *) (* EXPR DECODING *) let opt f v = if v = vnull then None else Some (f v) let opt_list f v = if v = vnull then [] else f v let dec_opt_bool v = if v = vnull then false else dec_bool v let decode_const c = match decode_enum c with | 0, [s] -> Int (dec_string s) | 1, [s] -> Float (dec_string s) | 2, [s] -> String (dec_string s) | 3, [s] -> Ident (dec_string s) | 4, [s;opt] -> Regexp (dec_string s, dec_string opt) | 5, [s] -> Ident (dec_string s) (** deprecated CType, keep until 3.0 release **) | _ -> raise Invalid_expr let rec decode_op op = match decode_enum op with | 0, [] -> OpAdd | 1, [] -> OpMult | 2, [] -> OpDiv | 3, [] -> OpSub | 4, [] -> OpAssign | 5, [] -> OpEq | 6, [] -> OpNotEq | 7, [] -> OpGt | 8, [] -> OpGte | 9, [] -> OpLt | 10, [] -> OpLte | 11, [] -> OpAnd | 12, [] -> OpOr | 13, [] -> OpXor | 14, [] -> OpBoolAnd | 15, [] -> OpBoolOr | 16, [] -> OpShl | 17, [] -> OpShr | 18, [] -> OpUShr | 19, [] -> OpMod | 20, [op] -> OpAssignOp (decode_op op) | 21, [] -> OpInterval | 22,[] -> OpArrow | _ -> raise Invalid_expr let decode_unop op = match decode_enum op with | 0, [] -> Increment | 1, [] -> Decrement | 2, [] -> Not | 3, [] -> Neg | 4, [] -> NegBits | _ -> raise Invalid_expr let decode_import_mode t = match decode_enum t with | 0, [] -> INormal | 1, [alias] -> IAsName (dec_string alias) | 2, [] -> IAll | _ -> raise Invalid_expr let decode_import t = (List.map (fun o -> ((dec_string (field o "name")), (decode_pos (field o "pos")))) (dec_array (field t "path")), decode_import_mode (field t "mode")) let maybe_decode_pos p = try decode_pos p with Invalid_expr -> Globals.null_pos let decode_placed_name vp v = dec_string v,maybe_decode_pos vp let dec_opt_array f v = if v = vnull then [] else List.map f (dec_array v) let rec decode_path t = { tpackage = List.map dec_string (dec_array (field t "pack")); tname = dec_string (field t "name"); tparams = dec_opt_array decode_tparam (field t "params"); tsub = opt dec_string (field t "sub"); },Globals.null_pos and decode_tparam v = match decode_enum v with | 0,[t] -> TPType (decode_ctype t) | 1,[e] -> TPExpr (decode_expr e) | _ -> raise Invalid_expr and decode_tparams v = dec_opt_array decode_tparam_decl v and decode_tparam_decl v = { tp_name = decode_placed_name (field v "name_pos") (field v "name"); tp_constraints = dec_opt_array decode_ctype (field v "constraints"); tp_params = decode_tparams (field v "params"); tp_meta = decode_meta_content (field v "meta"); } and decode_fun v = { f_params = decode_tparams (field v "params"); f_args = List.map (fun o -> decode_placed_name (field o "name_pos") (field o "name"), dec_opt_bool (field o "opt"), decode_meta_content (field o "meta"), opt decode_ctype (field o "type"), opt decode_expr (field o "value") ) (dec_array (field v "args")); f_type = opt decode_ctype (field v "ret"); f_expr = opt decode_expr (field v "expr"); } and decode_access v = match decode_enum v with | 0, [] -> APublic | 1, [] -> APrivate | 2, [] -> AStatic | 3, [] -> AOverride | 4, [] -> ADynamic | 5, [] -> AInline | 6, [] -> AMacro | _ -> raise Invalid_expr and decode_meta_entry v = Meta.from_string (dec_string (field v "name")), dec_opt_array decode_expr (field v "params"), decode_pos (field v "pos") and decode_meta_content m = dec_opt_array decode_meta_entry m and decode_field v = let fkind = match decode_enum (field v "kind") with | 0, [t;e] -> FVar (opt decode_ctype t, opt decode_expr e) | 1, [f] -> FFun (decode_fun f) | 2, [get;set; t; e] -> FProp (decode_placed_name vnull get, decode_placed_name vnull set, opt decode_ctype t, opt decode_expr e) | _ -> raise Invalid_expr in { cff_name = decode_placed_name (field v "name_pos") (field v "name"); cff_doc = opt dec_string (field v "doc"); cff_pos = decode_pos (field v "pos"); cff_kind = fkind; cff_access = List.map decode_access (opt_list dec_array (field v "access")); cff_meta = opt_list decode_meta_content (field v "meta"); } and decode_ctype t = let (i,args),p = decode_enum_with_pos t in (match i,args with | 0, [p] -> CTPath (fst (decode_path p)) | 1, [a;r] -> CTFunction (List.map decode_ctype (dec_array a), decode_ctype r) | 2, [fl] -> CTAnonymous (List.map decode_field (dec_array fl)) | 3, [t] -> CTParent (decode_ctype t) | 4, [tl;fl] -> CTExtend (List.map decode_path (dec_array tl), List.map decode_field (dec_array fl)) | 5, [t] -> CTOptional (decode_ctype t) | _ -> raise Invalid_expr),p and decode_expr v = let rec loop v = let p = decode_pos (field v "pos") in (decode (field v "expr") p, p) and decode e p = match decode_enum e with | 0, [c] -> EConst (decode_const c) | 1, [e1;e2] -> EArray (loop e1, loop e2) | 2, [op;e1;e2] -> EBinop (decode_op op, loop e1, loop e2) | 3, [e;f] -> EField (loop e, dec_string f) | 4, [e] -> EParenthesis (loop e) | 5, [a] -> EObjectDecl (List.map (fun o -> (decode_placed_name (field o "name_pos") (field o "field")),loop (field o "expr") ) (dec_array a)) | 6, [a] -> EArrayDecl (List.map loop (dec_array a)) | 7, [e;el] -> ECall (loop e,List.map loop (dec_array el)) | 8, [t;el] -> ENew (decode_path t,List.map loop (dec_array el)) | 9, [op;f;e] -> EUnop (decode_unop op,(if dec_bool f then Postfix else Prefix),loop e) | 10, [vl] -> EVars (List.map (fun v -> ((decode_placed_name (field v "name_pos") (field v "name")),opt decode_ctype (field v "type"),opt loop (field v "expr")) ) (dec_array vl)) | 11, [fname;f] -> EFunction (opt dec_string fname,decode_fun f) | 12, [el] -> EBlock (List.map loop (dec_array el)) | 13, [e1;e2] -> EFor (loop e1, loop e2) | 14, [e1;e2] -> EIn (loop e1, loop e2) | 15, [e1;e2;e3] -> EIf (loop e1, loop e2, opt loop e3) | 16, [e1;e2;flag] -> EWhile (loop e1,loop e2,if dec_bool flag then NormalWhile else DoWhile) | 17, [e;cases;eo] -> let cases = List.map (fun c -> (List.map loop (dec_array (field c "values")),opt loop (field c "guard"),opt loop (field c "expr"),maybe_decode_pos (field c "pos")) ) (dec_array cases) in ESwitch (loop e,cases,opt (fun v -> (if field v "expr" = vnull then None else Some (decode_expr v)),Globals.null_pos) eo) | 18, [e;catches] -> let catches = List.map (fun c -> ((decode_placed_name (field c "name_pos") (field c "name")),(decode_ctype (field c "type")),loop (field c "expr"),maybe_decode_pos (field c "pos")) ) (dec_array catches) in ETry (loop e, catches) | 19, [e] -> EReturn (opt loop e) | 20, [] -> EBreak | 21, [] -> EContinue | 22, [e] -> EUntyped (loop e) | 23, [e] -> EThrow (loop e) | 24, [e;t] -> ECast (loop e,opt decode_ctype t) | 25, [e;f] -> EDisplay (loop e,dec_bool f) | 26, [t] -> EDisplayNew (decode_path t) | 27, [e1;e2;e3] -> ETernary (loop e1,loop e2,loop e3) | 28, [e;t] -> ECheckType (loop e, (decode_ctype t)) | 29, [m;e] -> EMeta (decode_meta_entry m,loop e) | 30, [e;f] -> EField (loop e, dec_string f) (*** deprecated EType, keep until haxe 3 **) | _ -> raise Invalid_expr in try loop v with Stack_overflow -> raise Invalid_expr (* ---------------------------------------------------------------------- *) (* TYPE ENCODING *) let encode_pmap_array convert m = let l = ref [] in PMap.iter (fun _ v -> l := !l @ [(convert v)]) m; enc_array !l let encode_array convert l = enc_array (List.map convert l) let vopt f v = match v with | None -> vnull | Some v -> f v let encode_meta m set = let meta = ref m in enc_obj OMetaAccess [ "get", vfun0 (fun() -> encode_meta_content (!meta) ); "add", vfun3 (fun k vl p -> (try let el = List.map decode_expr (dec_array vl) in meta := (Meta.from_string (dec_string k), el, decode_pos p) :: !meta; set (!meta) with Invalid_expr -> failwith "Invalid expression"); vnull ); "extract", vfun1 (fun k -> let k = Meta.from_string (dec_string k) in encode_array encode_meta_entry (List.filter (fun (m,_,_) -> m = k) (!meta)) ); "remove", vfun1 (fun k -> let k = Meta.from_string (dec_string k) in meta := List.filter (fun (m,_,_) -> m <> k) (!meta); set (!meta); vnull ); "has", vfun1 (fun k -> let k = Meta.from_string (dec_string k) in vbool (List.exists (fun (m,_,_) -> m = k) (!meta)); ); ] let rec encode_mtype ot t fields = let i = t_infos t in enc_obj ot ([ "__t", encode_tdecl t; "pack", enc_array (List.map enc_string (fst i.mt_path)); "name", enc_string (snd i.mt_path); "pos", encode_pos i.mt_pos; "module", enc_string (s_type_path i.mt_module.m_path); "isPrivate", vbool i.mt_private; "meta", encode_meta i.mt_meta (fun m -> i.mt_meta <- m); "doc", null enc_string i.mt_doc; "params", encode_type_params i.mt_params; ] @ fields) and encode_type_params tl = enc_array (List.map (fun (n,t) -> enc_obj OTypeParameter ["name",enc_string n;"t",encode_type t]) tl) and encode_tenum e = encode_mtype OEnumType (TEnumDecl e) [ "isExtern", vbool e.e_extern; "exclude", vfun0 (fun() -> e.e_extern <- true; vnull); "constructs", encode_string_map encode_efield e.e_constrs; "names", enc_array (List.map enc_string e.e_names); ] and encode_tabstract a = encode_mtype OAbstractType (TAbstractDecl a) [ "type", encode_type a.a_this; "impl", (match a.a_impl with None -> vnull | Some c -> encode_clref c); "binops", enc_array (List.map (fun (op,cf) -> enc_obj OAbstractType_binops [ "op",encode_binop op; "field",encode_cfield cf]) a.a_ops); "unops", enc_array (List.map (fun (op,postfix,cf) -> enc_obj OAbstractType_unops [ "op",encode_unop op; "isPostfix",vbool (match postfix with Postfix -> true | Prefix -> false); "field",encode_cfield cf]) a.a_unops); "from", enc_array ((List.map (fun t -> enc_obj OAbstractType_from [ "t",encode_type t; "field",vnull]) a.a_from) @ (List.map (fun (t,cf) -> enc_obj OAbstractType_from [ "t",encode_type t; "field",encode_cfield cf]) a.a_from_field)); "to", enc_array ((List.map (fun t -> enc_obj OAbstractType_to [ "t",encode_type t; "field",vnull]) a.a_to) @ (List.map (fun (t,cf) -> enc_obj OAbstractType_to [ "t",encode_type t; "field",encode_cfield cf]) a.a_to_field)); "array", enc_array (List.map encode_cfield a.a_array); "resolve", (match a.a_resolve with None -> vnull | Some cf -> encode_cfref cf) ] and encode_efield f = enc_obj OEnumField [ "name", enc_string f.ef_name; "type", encode_type f.ef_type; "pos", encode_pos f.ef_pos; "namePos", encode_pos f.ef_name_pos; "index", vint f.ef_index; "meta", encode_meta f.ef_meta (fun m -> f.ef_meta <- m); "doc", null enc_string f.ef_doc; "params", encode_type_params f.ef_params; ] and encode_cfield f = enc_obj OClassField [ "name", enc_string f.cf_name; "type", (match f.cf_kind with Method _ -> encode_lazy_type f.cf_type | _ -> encode_type f.cf_type); "isPublic", vbool f.cf_public; "params", encode_type_params f.cf_params; "meta", encode_meta f.cf_meta (fun m -> f.cf_meta <- m); "expr", vfun0 (fun() -> ignore(follow f.cf_type); (match f.cf_expr with None -> vnull | Some e -> encode_texpr e)); "kind", encode_field_kind f.cf_kind; "pos", encode_pos f.cf_pos; "namePos",encode_pos f.cf_name_pos; "doc", null enc_string f.cf_doc; "overloads", encode_ref f.cf_overloads (encode_array encode_cfield) (fun() -> "overloads"); ] and encode_field_kind k = let tag, pl = (match k with | Type.Var v -> 0, [encode_var_access v.v_read; encode_var_access v.v_write] | Method m -> 1, [encode_method_kind m] ) in encode_enum IFieldKind tag pl and encode_var_access a = let tag, pl = (match a with | AccNormal -> 0, [] | AccNo -> 1, [] | AccNever -> 2, [] | AccResolve -> 3, [] | AccCall -> 4, [] | AccInline -> 5, [] | AccRequire (s,msg) -> 6, [enc_string s; null enc_string msg] ) in encode_enum IVarAccess tag pl and encode_method_kind m = let tag, pl = (match m with | MethNormal -> 0, [] | MethInline -> 1, [] | MethDynamic -> 2, [] | MethMacro -> 3, [] ) in encode_enum IMethodKind tag pl and encode_class_kind k = let tag, pl = (match k with | KNormal -> 0, [] | KTypeParameter pl -> 1, [encode_tparams pl] (* KExtension was here *) | KExpr e -> 3, [encode_expr e] | KGeneric -> 4, [] | KGenericInstance (cl, params) -> 5, [encode_clref cl; encode_tparams params] | KMacroType -> 6, [] | KAbstractImpl a -> 7, [encode_abref a] | KGenericBuild cfl -> 8, [] ) in encode_enum IClassKind tag pl and encode_tclass c = ignore(c.cl_build()); encode_mtype OClassType (TClassDecl c) [ "kind", encode_class_kind c.cl_kind; "isExtern", vbool c.cl_extern; "exclude", vfun0 (fun() -> c.cl_extern <- true; c.cl_init <- None; vnull); "isInterface", vbool c.cl_interface; "superClass", (match c.cl_super with | None -> vnull | Some (c,pl) -> enc_obj OClassType_superClass ["t",encode_clref c;"params",encode_tparams pl] ); "interfaces", enc_array (List.map (fun (c,pl) -> enc_obj OClassType_interfaces ["t",encode_clref c;"params",encode_tparams pl]) c.cl_implements); "fields", encode_ref c.cl_ordered_fields (encode_array encode_cfield) (fun() -> "class fields"); "statics", encode_ref c.cl_ordered_statics (encode_array encode_cfield) (fun() -> "class fields"); "constructor", (match c.cl_constructor with None -> vnull | Some cf -> encode_cfref cf); "init", (match c.cl_init with None -> vnull | Some e -> encode_texpr e); "overrides", (enc_array (List.map encode_cfref c.cl_overrides)) ] and encode_ttype t = encode_mtype ODefType (TTypeDecl t) [ "isExtern", vbool false; "exclude", vfun0 (fun() -> vnull); "type", encode_type t.t_type; ] and encode_tanon a = enc_obj OAnonType [ "fields", encode_pmap_array encode_cfield a.a_fields; "status", encode_anon_status !(a.a_status); ] and encode_anon_status s = let tag, pl = (match s with | Closed -> 0, [] | Opened -> 1, [] | Type.Const -> 2, [] | Extend tl -> 3, [encode_ref tl (fun tl -> enc_array (List.map encode_type tl)) (fun() -> "")] | Statics cl -> 4, [encode_clref cl] | EnumStatics en -> 5, [encode_enref en] | AbstractStatics ab -> 6, [encode_abref ab] ) in encode_enum IAnonStatus tag pl and encode_tparams pl = enc_array (List.map encode_type pl) and encode_clref c = encode_ref c encode_tclass (fun() -> s_type_path c.cl_path) and encode_enref en = encode_ref en encode_tenum (fun() -> s_type_path en.e_path) and encode_cfref cf = encode_ref cf encode_cfield (fun() -> cf.cf_name) and encode_abref ab = encode_ref ab encode_tabstract (fun() -> s_type_path ab.a_path) and encode_type t = let rec loop = function | TMono r -> (match !r with | None -> 0, [encode_ref r (fun r -> match !r with None -> vnull | Some t -> encode_type t) (fun() -> "")] | Some t -> loop t) | TEnum (e, pl) -> 1 , [encode_ref e encode_tenum (fun() -> s_type_path e.e_path); encode_tparams pl] | TInst (c, pl) -> 2 , [encode_clref c; encode_tparams pl] | TType (t,pl) -> 3 , [encode_ref t encode_ttype (fun() -> s_type_path t.t_path); encode_tparams pl] | TFun (pl,ret) -> let pl = List.map (fun (n,o,t) -> enc_obj OType_args [ "name",enc_string n; "opt",vbool o; "t",encode_type t ] ) pl in 4 , [enc_array pl; encode_type ret] | TAnon a -> 5, [encode_ref a encode_tanon (fun() -> "")] | TDynamic tsub as t -> if t == t_dynamic then 6, [vnull] else 6, [encode_type tsub] | TLazy f -> loop (!f()) | TAbstract (a, pl) -> 8, [encode_abref a; encode_tparams pl] in let tag, pl = loop t in encode_enum IType tag pl and encode_lazy_type t = let rec loop = function | TMono r -> (match !r with | Some t -> loop t | _ -> encode_type t) | TLazy f -> encode_enum IType 7 [encode_lazytype f (fun() -> encode_type (!f()))] | _ -> encode_type t in loop t and decode_type t = match decode_enum t with | 0, [r] -> TMono (decode_ref r) | 1, [e; pl] -> TEnum (decode_ref e, List.map decode_type (dec_array pl)) | 2, [c; pl] -> TInst (decode_ref c, List.map decode_type (dec_array pl)) | 3, [t; pl] -> TType (decode_ref t, List.map decode_type (dec_array pl)) | 4, [pl; r] -> TFun (List.map (fun p -> dec_string (field p "name"), dec_bool (field p "opt"), decode_type (field p "t")) (dec_array pl), decode_type r) | 5, [a] -> TAnon (decode_ref a) | 6, [t] -> if t = vnull then t_dynamic else TDynamic (decode_type t) | 7, [f] -> TLazy (decode_lazytype f) | 8, [a; pl] -> TAbstract (decode_ref a, List.map decode_type (dec_array pl)) | _ -> raise Invalid_expr and decode_type_decl t = decode_tdecl (field t "__t") (* ---------------------------------------------------------------------- *) (* TEXPR Encoding *) and encode_tconst c = let tag, pl = match c with | TInt i -> 0,[vint32 i] | TFloat f -> 1,[enc_string f] | TString s -> 2,[enc_string s] | TBool b -> 3,[vbool b] | TNull -> 4,[] | TThis -> 5,[] | TSuper -> 6,[] in encode_enum ITConstant tag pl and encode_tvar v = let f_extra (pl,e) = enc_obj OTVar_extra [ "params",encode_type_params pl; "expr",vopt encode_texpr e ] in enc_obj OTVar [ "id", vint v.v_id; "name", enc_string v.v_name; "t", encode_type v.v_type; "capture", vbool v.v_capture; "extra", vopt f_extra v.v_extra; "meta", encode_meta v.v_meta (fun m -> v.v_meta <- m); "$", encode_unsafe (Obj.repr v); ] and encode_module_type mt = let tag,pl = match mt with | TClassDecl c -> 0,[encode_clref c] | TEnumDecl e -> 1,[encode_enref e] | TTypeDecl t -> 2,[encode_ref t encode_ttype (fun () -> s_type_path t.t_path)] | TAbstractDecl a -> 3,[encode_abref a] in encode_enum IModuleType tag pl and encode_tfunc func = enc_obj OTFunc [ "args",enc_array (List.map (fun (v,c) -> enc_obj OTFunc_args [ "v",encode_tvar v; "value",match c with None -> vnull | Some c -> encode_tconst c ] ) func.tf_args); "t",encode_type func.tf_type; "expr",encode_texpr func.tf_expr ] and encode_field_access fa = let encode_instance c tl = enc_obj OFieldAccess_c [ "c",encode_clref c; "params",encode_tparams tl ] in let tag,pl = match fa with | FInstance(c,tl,cf) -> 0,[encode_clref c;encode_tparams tl;encode_cfref cf] | FStatic(c,cf) -> 1,[encode_clref c;encode_cfref cf] | FAnon(cf) -> 2,[encode_cfref cf] | FDynamic(s) -> 3,[enc_string s] | FClosure(co,cf) -> 4,[(match co with Some (c,tl) -> encode_instance c tl | None -> vnull);encode_cfref cf] | FEnum(en,ef) -> 5,[encode_enref en;encode_efield ef] in encode_enum IFieldAccess tag pl and encode_texpr e = let rec loop e = let tag, pl = match e.eexpr with | TConst c -> 0,[encode_tconst c] | TLocal v -> 1,[encode_tvar v] | TArray(e1,e2) -> 2,[loop e1; loop e2] | TBinop(op,e1,e2) -> 3,[encode_binop op;loop e1;loop e2] | TField(e1,fa) -> 4,[loop e1;encode_field_access fa] | TTypeExpr mt -> 5,[encode_module_type mt] | TParenthesis e1 -> 6,[loop e1] | TObjectDecl fl -> 7, [enc_array (List.map (fun (f,e) -> enc_obj OTypedExprDef_fields [ "name",enc_string f; "expr",loop e; ]) fl)] | TArrayDecl el -> 8,[encode_texpr_list el] | TCall(e1,el) -> 9,[loop e1;encode_texpr_list el] | TNew(c,pl,el) -> 10,[encode_clref c;encode_tparams pl;encode_texpr_list el] | TUnop(op,flag,e1) -> 11,[encode_unop op;vbool (flag = Postfix);loop e1] | TFunction func -> 12,[encode_tfunc func] | TVar (v,eo) -> 13,[encode_tvar v;vopt encode_texpr eo] | TBlock el -> 14,[encode_texpr_list el] | TFor(v,e1,e2) -> 15,[encode_tvar v;loop e1;loop e2] | TIf(eif,ethen,eelse) -> 16,[loop eif;loop ethen;vopt encode_texpr eelse] | TWhile(econd,e1,flag) -> 17,[loop econd;loop e1;vbool (flag = NormalWhile)] | TSwitch(e1,cases,edef) -> 18,[ loop e1; enc_array (List.map (fun (el,e) -> enc_obj OTypedExprDef_cases ["values",encode_texpr_list el;"expr",loop e]) cases); vopt encode_texpr edef ] | TTry(e1,catches) -> 19,[ loop e1; enc_array (List.map (fun (v,e) -> enc_obj OTypedExprDef_catches [ "v",encode_tvar v; "expr",loop e ]) catches )] | TReturn e1 -> 20,[vopt encode_texpr e1] | TBreak -> 21,[] | TContinue -> 22,[] | TThrow e1 -> 23,[loop e1] | TCast(e1,mt) -> 24,[loop e1;match mt with None -> vnull | Some mt -> encode_module_type mt] | TMeta(m,e1) -> 25,[encode_meta_entry m;loop e1] | TEnumParameter(e1,ef,i) -> 26,[loop e1;encode_efield ef;vint i] in enc_obj OTypedExprDef [ "pos", encode_pos e.epos; "expr", encode_enum ITypedExpr tag pl; "t", encode_type e.etype ] in loop e and encode_texpr_list el = enc_array (List.map encode_texpr el) (* ---------------------------------------------------------------------- *) (* TEXPR Decoding *) let decode_tconst c = match decode_enum c with | 0, [s] -> TInt (dec_i32 s) | 1, [s] -> TFloat (dec_string s) | 2, [s] -> TString (dec_string s) | 3, [s] -> TBool (dec_bool s) | 4, [] -> TNull | 5, [] -> TThis | 6, [] -> TSuper | _ -> raise Invalid_expr let decode_type_params v = List.map (fun v -> dec_string (field v "name"),decode_type (field v "t")) (dec_array v) let decode_tvar v = (Obj.obj (decode_unsafe (field v "$")) : tvar) let decode_var_access v = match decode_enum v with | 0, [] -> AccNormal | 1, [] -> AccNo | 2, [] -> AccNever | 3, [] -> AccResolve | 4, [] -> AccCall | 5, [] -> AccInline | 6, [s1;s2] -> AccRequire(dec_string s1, opt dec_string s2) | _ -> raise Invalid_expr let decode_method_kind v = match decode_enum v with | 0, [] -> MethNormal | 1, [] -> MethInline | 2, [] -> MethDynamic | 3, [] -> MethMacro | _ -> raise Invalid_expr let decode_field_kind v = match decode_enum v with | 0, [vr;vw] -> Type.Var({v_read = decode_var_access vr; v_write = decode_var_access vw}) | 1, [m] -> Method (decode_method_kind m) | _ -> raise Invalid_expr let decode_cfield v = { cf_name = dec_string (field v "name"); cf_type = decode_type (field v "type"); cf_public = dec_bool (field v "isPublic"); cf_pos = decode_pos (field v "pos"); cf_name_pos = decode_pos (field v "namePos"); cf_doc = opt dec_string (field v "doc"); cf_meta = []; (* TODO *) cf_kind = decode_field_kind (field v "kind"); cf_params = decode_type_params (field v "params"); cf_expr = None; cf_expr_unoptimized = None; cf_overloads = decode_ref (field v "overloads"); } let decode_efield v = { ef_name = dec_string (field v "name"); ef_type = decode_type (field v "type"); ef_pos = decode_pos (field v "pos"); ef_name_pos = decode_pos (field v "namePos"); ef_index = dec_int (field v "index"); ef_meta = []; (* TODO *) ef_doc = opt dec_string (field v "doc"); ef_params = decode_type_params (field v "params") } let decode_field_access v = match decode_enum v with | 0, [c;tl;cf] -> let c = decode_ref c in FInstance(c,List.map decode_type (dec_array tl),decode_ref cf) | 1, [c;cf] -> FStatic(decode_ref c,decode_ref cf) | 2, [cf] -> FAnon(decode_ref cf) | 3, [s] -> FDynamic(dec_string s) | 4, [co;cf] -> let co = if co = vnull then None else Some (decode_ref (field co "c"),List.map decode_type (dec_array (field co "params"))) in FClosure(co,decode_ref cf) | 5, [e;ef] -> FEnum(decode_ref e,decode_efield ef) | _ -> raise Invalid_expr let decode_module_type v = match decode_enum v with | 0, [c] -> TClassDecl (decode_ref c) | 1, [en] -> TEnumDecl (decode_ref en) | 2, [t] -> TTypeDecl (decode_ref t) | 3, [a] -> TAbstractDecl (decode_ref a) | _ -> raise Invalid_expr let rec decode_tfunc v = { tf_args = List.map (fun v -> decode_tvar (field v "v"),opt decode_tconst (field v "value")) (dec_array (field v "args")); tf_type = decode_type (field v "t"); tf_expr = decode_texpr (field v "expr") } and decode_texpr v = let rec loop v = mk (decode (field v "expr")) (decode_type (field v "t")) (decode_pos (field v "pos")) and decode e = match decode_enum e with | 0, [c] -> TConst(decode_tconst c) | 1, [v] -> TLocal(decode_tvar v) | 2, [v1;v2] -> TArray(loop v1,loop v2) | 3, [op;v1;v2] -> TBinop(decode_op op,loop v1,loop v2) | 4, [v1;fa] -> TField(loop v1,decode_field_access fa) | 5, [mt] -> TTypeExpr(decode_module_type mt) | 6, [v1] -> TParenthesis(loop v1) | 7, [v] -> TObjectDecl(List.map (fun v -> dec_string (field v "name"),loop (field v "expr")) (dec_array v)) | 8, [vl] -> TArrayDecl(List.map loop (dec_array vl)) | 9, [v1;vl] -> TCall(loop v1,List.map loop (dec_array vl)) | 10, [c;tl;vl] -> TNew(decode_ref c,List.map decode_type (dec_array tl),List.map loop (dec_array vl)) | 11, [op;pf;v1] -> TUnop(decode_unop op,(if dec_bool pf then Postfix else Prefix),loop v1) | 12, [f] -> TFunction(decode_tfunc f) | 13, [v;eo] -> TVar(decode_tvar v,opt loop eo) | 14, [vl] -> TBlock(List.map loop (dec_array vl)) | 15, [v;v1;v2] -> TFor(decode_tvar v,loop v1,loop v2) | 16, [vif;vthen;velse] -> TIf(loop vif,loop vthen,opt loop velse) | 17, [vcond;v1;b] -> TWhile(loop vcond,loop v1,if dec_bool b then NormalWhile else DoWhile) | 18, [v1;cl;vdef] -> TSwitch(loop v1,List.map (fun v -> List.map loop (dec_array (field v "values")),loop (field v "expr")) (dec_array cl),opt loop vdef) | 19, [v1;cl] -> TTry(loop v1,List.map (fun v -> decode_tvar (field v "v"),loop (field v "expr")) (dec_array cl)) | 20, [vo] -> TReturn(opt loop vo) | 21, [] -> TBreak | 22, [] -> TContinue | 23, [v1] -> TThrow(loop v1) | 24, [v1;mto] -> TCast(loop v1,opt decode_module_type mto) | 25, [m;v1] -> TMeta(decode_meta_entry m,loop v1) | 26, [v1;ef;i] -> TEnumParameter(loop v1,decode_efield ef,dec_int i) | i,el -> Printf.printf "%i %i\n" i (List.length el); raise Invalid_expr in try loop v with Stack_overflow -> raise Invalid_expr (* ---------------------------------------------------------------------- *) (* TYPE DEFINITION *) let decode_type_def v = let pack = List.map dec_string (dec_array (field v "pack")) in let name = decode_placed_name (field v "name_pos") (field v "name") in let meta = decode_meta_content (field v "meta") in let pos = decode_pos (field v "pos") in let isExtern = dec_opt_bool (field v "isExtern") in let fields = List.map decode_field (dec_array (field v "fields")) in let mk fl dl = { d_name = name; d_doc = None; d_params = decode_tparams (field v "params"); d_meta = meta; d_flags = fl; d_data = dl; } in let tdef = (match decode_enum (field v "kind") with | 0, [] -> let conv f = let loop ((n,_),opt,_,t,_) = match t with | None -> raise Invalid_expr | Some t -> n, opt, t in let args, params, t = (match f.cff_kind with | FVar (t,None) -> [], [], t | FFun f -> List.map loop f.f_args, f.f_params, f.f_type | _ -> raise Invalid_expr ) in { ec_name = f.cff_name; ec_doc = f.cff_doc; ec_meta = f.cff_meta; ec_pos = f.cff_pos; ec_args = args; ec_params = params; ec_type = t; } in EEnum (mk (if isExtern then [EExtern] else []) (List.map conv fields)) | 1, [] -> ETypedef (mk (if isExtern then [EExtern] else []) (CTAnonymous fields,Globals.null_pos)) | 2, [ext;impl;interf] -> let flags = if isExtern then [HExtern] else [] in let is_interface = dec_opt_bool interf in let interfaces = (match opt (fun v -> List.map decode_path (dec_array v)) impl with Some l -> l | _ -> [] ) in let flags = (match opt decode_path ext with None -> flags | Some t -> HExtends t :: flags) in let flags = if is_interface then begin let flags = HInterface :: flags in List.map (fun t -> HExtends t) interfaces @ flags end else begin List.map (fun t -> HImplements t) interfaces @ flags end in EClass (mk flags fields) | 3, [t] -> ETypedef (mk (if isExtern then [EExtern] else []) (decode_ctype t)) | 4, [tthis;tfrom;tto] -> let flags = match opt dec_array tfrom with None -> [] | Some ta -> List.map (fun t -> AFromType (decode_ctype t)) ta in let flags = match opt dec_array tto with None -> flags | Some ta -> (List.map (fun t -> AToType (decode_ctype t)) ta) @ flags in let flags = match opt decode_ctype tthis with None -> flags | Some t -> (AIsType t) :: flags in EAbstract(mk flags fields) | _ -> raise Invalid_expr ) in (* if our package ends with an uppercase letter, then it's the module name *) let pack,name = (match List.rev pack with | last :: l when not (is_lower_ident last) -> List.rev l, last | _ -> pack, fst name ) in (pack, name), tdef, pos (* ---------------------------------------------------------------------- *) (* VALUE-TO-CONSTANT *) let rec make_const e = match e.eexpr with | TConst c -> (match c with | TInt i -> vint32 i | TFloat s -> vfloat (float_of_string s) | TString s -> enc_string s | TBool b -> vbool b | TNull -> vnull | TThis | TSuper -> raise Exit) | TParenthesis e | TMeta(_,e) | TCast(e,None) -> make_const e | TObjectDecl el -> enc_obj O__Const (List.map (fun (f,e) -> f, make_const e) el) | TArrayDecl al -> enc_array (List.map make_const al) | _ -> raise Exit (* ------------------------------------------------------------------------- *) (* MACRO API *) (** Our macro API implementation. It gets called by the interpreter and accesses the compiler with the compiler_api **) let macro_api ccom get_api = [ "current_pos", vfun0 (fun() -> encode_pos (get_api()).pos ); "error", vfun2 (fun msg p -> let msg = dec_string msg in let p = decode_pos p in (ccom()).error msg p; raise Abort ); "fatal_error", vfun2 (fun msg p -> let msg = dec_string msg in let p = decode_pos p in raise (Error.Fatal_error (msg,p)) ); "warning", vfun2 (fun msg p -> let msg = dec_string msg in let p = decode_pos p in (ccom()).warning msg p; vnull ); "class_path", vfun0 (fun() -> enc_array (List.map enc_string (ccom()).class_path); ); "resolve_path", vfun1 (fun file -> let file = dec_string file in enc_string (try Common.find_file (ccom()) file with Not_found -> failwith ("File not found '" ^ file ^ "'")) ); "define", vfun2 (fun s v -> let v = if v = vnull then "" else "=" ^ (dec_string v) in Common.raw_define (ccom()) ((dec_string s) ^ v); vnull ); "defined", vfun1 (fun s -> vbool (Common.raw_defined (ccom()) (dec_string s)) ); "defined_value", vfun1 (fun s -> try enc_string (Common.raw_defined_value (ccom()) (dec_string s)) with Not_found -> vnull ); "get_defines", vfun0 (fun() -> encode_string_map enc_string (ccom()).defines ); "get_type", vfun1 (fun s -> let tname = dec_string s in match (get_api()).get_type tname with | None -> failwith ("Type not found '" ^ tname ^ "'") | Some t -> encode_type t ); "get_module", vfun1 (fun s -> enc_array (List.map encode_type ((get_api()).get_module (dec_string s))) ); "on_after_typing", vfun1 (fun f -> let f = prepare_callback f 1 in (get_api()).after_typing (fun tl -> ignore(f [enc_array (List.map encode_module_type tl)])); vnull ); "on_generate", vfun1 (fun f -> let f = prepare_callback f 1 in (get_api()).on_generate (fun tl -> ignore(f [enc_array (List.map encode_type tl)])); vnull ); "on_after_generate", vfun1 (fun f -> let f = prepare_callback f 0 in (get_api()).after_generate (fun () -> ignore(f [])); vnull ); "on_type_not_found", vfun1 (fun f -> let f = prepare_callback f 1 in (get_api()).on_type_not_found (fun path -> f [enc_string path]); vnull ); "do_parse", vfun3 (fun s p b -> let s = dec_string s in if s = "" then raise Invalid_expr; encode_expr ((get_api()).parse_string s (decode_pos p) (dec_bool b)) ); "make_expr", vfun2 (fun v p -> encode_expr (value_to_expr v (decode_pos p)) ); "signature", vfun1 (fun v -> enc_string (Digest.to_hex (value_signature v)) ); "to_complex_type", vfun1 (fun v -> try encode_ctype (TExprToExpr.convert_type' (decode_type v)) with Exit -> vnull ); "unify", vfun2 (fun t1 t2 -> let e1 = mk (TObjectDecl []) (decode_type t1) Globals.null_pos in try ignore(((get_api()).cast_or_unify) (decode_type t2) e1 Globals.null_pos); vbool true with Error.Error (Error.Unify _,_) -> vbool false ); "typeof", vfun1 (fun v -> encode_type ((get_api()).type_expr (decode_expr v)).etype ); "type_expr", vfun1 (fun v -> encode_texpr ((get_api()).type_expr (decode_expr v)) ); "resolve_type", vfun2 (fun t p -> encode_type ((get_api()).resolve_type (fst (decode_ctype t)) (decode_pos p)); ); "s_type", vfun1 (fun v -> enc_string (Type.s_type (print_context()) (decode_type v)) ); "s_expr", vfun2 (fun v b -> let f = if dec_opt_bool b then Type.s_expr_pretty false "" false else Type.s_expr_ast true "" in enc_string (f (Type.s_type (print_context())) (decode_texpr v)) ); "is_fmt_string", vfun1 (fun p -> vbool (Lexer.is_fmt_string (decode_pos p)) ); "format_string", vfun2 (fun s p -> encode_expr ((get_api()).format_string (dec_string s) (decode_pos p)) ); "allow_package", vfun1 (fun s -> (get_api()).allow_package (dec_string s); vnull ); "type_patch", vfun4 (fun t f s v -> (get_api()).type_patch (dec_string t) (dec_string f) (dec_bool s) (opt dec_string v); vnull ); "meta_patch", vfun4 (fun m t f s -> (get_api()).meta_patch (dec_string m) (dec_string t) (opt dec_string f) (dec_bool s); vnull ); "add_global_metadata_impl", vfun5 (fun s1 s2 b1 b2 b3 -> (get_api()).add_global_metadata (dec_string s1) (dec_string s2) (dec_bool b1,dec_bool b2,dec_bool b3); vnull ); "set_custom_js_generator", vfun1 (fun f -> let f = prepare_callback f 1 in (get_api()).set_js_generator (fun js_ctx -> let com = ccom() in let api = enc_obj OJSGenApi [ "outputFile", enc_string com.file; "types", enc_array (List.map (fun t -> encode_type (type_of_module_type t)) com.types); "main", (match com.main with None -> vnull | Some e -> encode_texpr e); "generateValue", vfun1 (fun v -> let e = decode_texpr v in let str = Genjs.gen_single_expr js_ctx e false in enc_string str ); "isKeyword", vfun1 (fun v -> vbool (Hashtbl.mem Genjs.kwds (dec_string v)) ); "hasFeature", vfun1 (fun v -> vbool (Common.has_feature com (dec_string v)) ); "addFeature", vfun1 (fun v -> Common.add_feature com (dec_string v); vnull ); "quoteString", vfun1 (fun v -> enc_string ("\"" ^ Ast.s_escape (dec_string v) ^ "\"") ); "buildMetaData", vfun1 (fun t -> match Codegen.build_metadata com (decode_type_decl t) with | None -> vnull | Some e -> encode_texpr e ); "generateStatement", vfun1 (fun v -> let e = decode_texpr v in let str = Genjs.gen_single_expr js_ctx e true in enc_string str ); "setTypeAccessor", vfun1 (fun callb -> let callb = prepare_callback callb 1 in js_ctx.Genjs.type_accessor <- (fun t -> dec_string (callb [encode_type (type_of_module_type t)]) ); vnull ); "setCurrentClass", vfun1 (fun c -> Genjs.set_current_class js_ctx (match decode_type_decl c with TClassDecl c -> c | _ -> assert false); vnull ); ] in ignore(f [api]); ); vnull ); "get_pos_infos", vfun1 (fun p -> let p = decode_pos p in enc_obj OContext_getPosInfos ["min",vint p.Globals.pmin;"max",vint p.Globals.pmax;"file",enc_string p.Globals.pfile] ); "make_position", vfun3 (fun min max file -> encode_pos { Globals.pmin = dec_int min; Globals.pmax = dec_int max; Globals.pfile = dec_string file } ); "add_resource", vfun2 (fun name data -> let name = dec_string name in let data = decode_bytes data in if name = "" then failwith "Empty resource name"; Hashtbl.replace (ccom()).resources name data; let m = if name.[0] = '$' then (get_api()).current_macro_module() else (get_api()).current_module() in m.m_extra.m_binded_res <- PMap.add name data m.m_extra.m_binded_res; vnull ); "get_resources", vfun0 (fun() -> encode_string_map encode_bytes (Hashtbl.fold (fun k v acc -> PMap.add k v acc) (ccom()).resources PMap.empty) ); "get_local_module", vfun0 (fun() -> let m = (get_api()).current_module() in enc_string (s_type_path m.m_path); ); "get_local_type", vfun0 (fun() -> match (get_api()).get_local_type() with | None -> vnull | Some t -> encode_type t ); "get_expected_type", vfun0 (fun() -> match (get_api()).get_expected_type() with | None -> vnull | Some t -> encode_type t ); "get_call_arguments", vfun0 (fun() -> match (get_api()).get_call_arguments() with | None -> vnull | Some el -> enc_array (List.map encode_expr el) ); "get_local_method", vfun0 (fun() -> enc_string ((get_api()).get_local_method()) ); "get_local_using", vfun0 (fun() -> enc_array (List.map encode_clref ((get_api()).get_local_using())) ); "get_local_imports", vfun0 (fun() -> enc_array (List.map encode_import ((get_api()).get_local_imports())) ); "local_vars", vfun1 (fun as_var -> let as_var = dec_opt_bool as_var in let vars = (get_api()).get_local_vars() in encode_string_map (if as_var then encode_tvar else (fun v -> encode_type v.v_type)) vars ); "follow_with_abstracts", vfun2 (fun v once -> let t = decode_type v in let follow_once t = match t with | TMono r -> (match !r with | None -> t | Some t -> t) | TAbstract (a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> Abstract.get_underlying_type a tl | TAbstract _ | TEnum _ | TInst _ | TFun _ | TAnon _ | TDynamic _ -> t | TType (t,tl) -> apply_params t.t_params tl t.t_type | TLazy f -> (!f)() in encode_type (if dec_opt_bool once then follow_once t else Abstract.follow_with_abstracts t) ); "follow", vfun2 (fun v once -> let t = decode_type v in let follow_once t = match t with | TMono r -> (match !r with | None -> t | Some t -> t) | TAbstract _ | TEnum _ | TInst _ | TFun _ | TAnon _ | TDynamic _ -> t | TType (t,tl) -> apply_params t.t_params tl t.t_type | TLazy f -> (!f)() in encode_type (if dec_opt_bool once then follow_once t else follow t) ); "get_build_fields", vfun0 (fun() -> (get_api()).get_build_fields() ); "define_type", vfun1 (fun v -> (get_api()).define_type v; vnull ); "define_module", vfun4 (fun path vl ui ul -> (get_api()).define_module (dec_string path) (dec_array vl) (List.map decode_import (dec_array ui)) (List.map fst (List.map decode_path (dec_array ul))); vnull ); "add_class_path", vfun1 (fun cp -> let com = ccom() in let cp = dec_string cp in let cp = Path.add_trailing_slash cp in com.class_path <- cp :: com.class_path; (match com.get_macros() with | Some(mcom) -> mcom.class_path <- cp :: mcom.class_path; | None -> ()); Hashtbl.clear com.file_lookup_cache; vnull ); "add_native_lib", vfun1 (fun file -> let file = dec_string file in let com = ccom() in (match com.platform with | Globals.Flash -> Genswf.add_swf_lib com file false | Globals.Java -> Genjava.add_java_lib com file false | Globals.Cs -> let file, is_std = match ExtString.String.nsplit file "@" with | [file] -> file,false | [file;"std"] -> file,true | _ -> failwith ("unsupported file@`std` format: " ^ file) in Gencs.add_net_lib com file is_std | _ -> failwith "Unsupported platform"); vnull ); "add_native_arg", vfun1 (fun arg -> let arg = dec_string arg in let com = ccom() in (match com.platform with | Globals.Java | Globals.Cs | Globals.Cpp -> com.c_args <- arg :: com.c_args | _ -> failwith "Unsupported platform"); vnull ); "register_module_dependency", vfun2 (fun m file -> (get_api()).module_dependency (dec_string m) (dec_string file) false; vnull ); "register_module_reuse_call", vfun2 (fun m mcall -> (get_api()).module_dependency (dec_string m) (dec_string mcall) true; vnull ); "get_typed_expr", vfun1 (fun e -> let e = decode_texpr e in encode_expr (TExprToExpr.convert_expr e) ); "store_typed_expr", vfun1 (fun e -> let e = decode_texpr e in encode_expr ((get_api()).store_typed_expr e) ); "get_output", vfun0 (fun() -> enc_string (ccom()).file ); "set_output", vfun1 (fun s -> (ccom()).file <- dec_string s; vnull ); "get_display_pos", vfun0 (fun() -> let p = !Parser.resume_display in if p = Globals.null_pos then vnull else enc_obj OCompiler_getDisplayPos ["file",enc_string p.Globals.pfile;"pos",vint p.Globals.pmin] ); "pattern_locals", vfun2 (fun e t -> let loc = (get_api()).get_pattern_locals (decode_expr e) (decode_type t) in encode_string_map (fun (v,_) -> encode_type v.v_type) loc ); "on_macro_context_reused", vfun1 (fun c -> let c = prepare_callback c 0 in (get_api()).on_reuse (fun() -> dec_bool (c [])); vnull ); "apply_params", vfun3 (fun tpl tl t -> let tl = List.map decode_type (dec_array tl) in let tpl = List.map (fun v -> dec_string (field v "name"), decode_type (field v "t")) (dec_array tpl) in let rec map t = match t with | TInst({cl_kind = KTypeParameter _},_) -> begin try (* use non-physical equality check here to make apply_params work *) snd (List.find (fun (_,t2) -> type_iseq t t2) tpl) with Not_found -> Type.map map t end | _ -> Type.map map t in encode_type (apply_params tpl tl (map (decode_type t))) ); "include_file", vfun2 (fun file position -> let file = dec_string file in let position = dec_string position in let file = if Sys.file_exists file then file else try Common.find_file (ccom()) file with | Not_found -> failwith ("unable to find file for inclusion: " ^ file) in (ccom()).include_files <- (file, position) :: (ccom()).include_files; vnull ); (* Compilation server *) "server_add_module_check_policy", vfun4 (fun filter policy recursive context_options -> let filter = List.map dec_string (dec_array filter) in let policy = List.map dec_int (dec_array policy) in (get_api()).add_module_check_policy filter policy (dec_bool recursive) (dec_int context_options); vnull ); "server_invalidate_files", vfun1 (fun a -> let cs = match CompilationServer.get() with Some cs -> cs | None -> failwith "compilation server not running" in List.iter (fun v -> let s = dec_string v in let s = Path.unique_full_path s in CompilationServer.taint_modules cs s; CompilationServer.remove_files cs s; ) (dec_array a); vnull ); ] end haxe_3.4.4.orig/src/macro/macroContext.ml0000664000175000017500000006434313166552354020316 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Common.DisplayMode open Common open Type open Typecore open Error open Globals module InterpImpl = Interp (* Hlmacro *) module Interp = struct module BuiltApi = MacroApi.MacroApiImpl(InterpImpl) include InterpImpl include BuiltApi end let macro_enable_cache = ref false let macro_interp_cache = ref None let macro_interp_on_reuse = ref [] let macro_interp_reused = ref false let delayed_macro_result = ref ((fun() -> assert false) : unit -> unit -> Interp.value) let unify_call_args_ref = ref (fun _ _ _ _ _ _ _-> assert false) let unify_call_args a b c d e f g : (texpr list * t) = !unify_call_args_ref a b c d e f g let get_next_stored_typed_expr_id = let uid = ref 0 in (fun() -> incr uid; !uid) let get_stored_typed_expr com id = let e = PMap.find id com.stored_typed_exprs in Texpr.duplicate_tvars e let get_type_patch ctx t sub = let new_patch() = { tp_type = None; tp_remove = false; tp_meta = [] } in let path = Ast.parse_path t in let h, tp = (try Hashtbl.find ctx.g.type_patches path with Not_found -> let h = Hashtbl.create 0 in let tp = new_patch() in Hashtbl.add ctx.g.type_patches path (h,tp); h, tp ) in match sub with | None -> tp | Some k -> try Hashtbl.find h k with Not_found -> let tp = new_patch() in Hashtbl.add h k tp; tp let macro_timer ctx l = Common.timer (if Common.defined ctx.com Define.MacroTimes then ("macro" :: l) else ["macro"]) let typing_timer ctx need_type f = let t = Common.timer ["typing"] in let old = ctx.com.error and oldp = ctx.pass in (* disable resumable errors... unless we are in display mode (we want to reach point of completion) *) (*if ctx.com.display = DMNone then ctx.com.error <- (fun e p -> raise (Error(Custom e,p)));*) (* TODO: review this... *) ctx.com.error <- (fun e p -> raise (Error(Custom e,p))); if need_type && ctx.pass < PTypeField then ctx.pass <- PTypeField; let exit() = t(); ctx.com.error <- old; ctx.pass <- oldp; in try let r = f() in exit(); r with Error (ekind,p) -> exit(); Interp.compiler_error (error_msg ekind) p | WithTypeError (l,p) -> exit(); Interp.compiler_error (error_msg l) p | e -> exit(); raise e let load_macro_ref : (typer -> bool -> path -> string -> pos -> (typer * ((string * bool * t) list * t * tclass * Type.tclass_field) * (Interp.value list -> Interp.value option))) ref = ref (fun _ _ _ _ -> assert false) let make_macro_api ctx p = let parse_expr_string s p inl = typing_timer ctx false (fun() -> try Parser.parse_expr_string ctx.com s p error inl with Exit -> raise MacroApi.Invalid_expr) in { MacroApi.pos = p; MacroApi.get_com = (fun() -> ctx.com); MacroApi.get_type = (fun s -> typing_timer ctx true (fun() -> let path = parse_path s in let tp = match List.rev (fst path) with | s :: sl when String.length s > 0 && (match s.[0] with 'A'..'Z' -> true | _ -> false) -> { tpackage = List.rev sl; tname = s; tparams = []; tsub = Some (snd path) } | _ -> { tpackage = fst path; tname = snd path; tparams = []; tsub = None } in try let m = Some (Typeload.load_instance ctx (tp,null_pos) true p) in m with Error (Module_not_found _,p2) when p == p2 -> None ) ); MacroApi.resolve_type = (fun t p -> typing_timer ctx true (fun() -> Typeload.load_complex_type ctx false p (t,null_pos)) ); MacroApi.get_module = (fun s -> typing_timer ctx true (fun() -> let path = parse_path s in let m = List.map type_of_module_type (Typeload.load_module ctx path p).m_types in m ) ); MacroApi.after_typing = (fun f -> Common.add_typing_filter ctx.com (fun tl -> let t = macro_timer ctx ["afterTyping"] in f tl; t() ) ); MacroApi.on_generate = (fun f -> Common.add_filter ctx.com (fun() -> let t = macro_timer ctx ["onGenerate"] in f (List.map type_of_module_type ctx.com.types); t() ) ); MacroApi.after_generate = (fun f -> Common.add_final_filter ctx.com (fun() -> let t = macro_timer ctx ["afterGenerate"] in f(); t() ) ); MacroApi.on_type_not_found = (fun f -> ctx.com.load_extern_type <- ctx.com.load_extern_type @ [fun path p -> let td = f (s_type_path path) in if td = Interp.vnull then None else let (pack,name),tdef,p = Interp.decode_type_def td in Some (name,(pack,[tdef,p])) ]; ); MacroApi.parse_string = parse_expr_string; MacroApi.type_expr = (fun e -> typing_timer ctx true (fun() -> type_expr ctx e Value) ); MacroApi.type_macro_expr = (fun e -> let e = typing_timer ctx true (fun() -> type_expr ctx e Value) in let rec loop e = match e.eexpr with | TField(_,FStatic(c,({cf_kind = Method _} as cf))) -> ignore(!load_macro_ref ctx false c.cl_path cf.cf_name e.epos) | _ -> Type.iter loop e in loop e; e ); MacroApi.store_typed_expr = (fun te -> let p = te.epos in let id = get_next_stored_typed_expr_id() in ctx.com.stored_typed_exprs <- PMap.add id te ctx.com.stored_typed_exprs; let eid = (EConst (Int (string_of_int id))), p in (EMeta ((Meta.StoredTypedExpr,[],p), eid)), p ); MacroApi.allow_package = (fun v -> Common.allow_package ctx.com v); MacroApi.type_patch = (fun t f s v -> typing_timer ctx false (fun() -> let v = (match v with None -> None | Some s -> match Parser.parse_string ctx.com ("typedef T = " ^ s) null_pos error false with | _,[ETypedef { d_data = ct },_] -> Some ct | _ -> assert false ) in let tp = get_type_patch ctx t (Some (f,s)) in match v with | None -> tp.tp_remove <- true | Some _ -> tp.tp_type <- Option.map fst v ); ); MacroApi.meta_patch = (fun m t f s -> let m = (match Parser.parse_string ctx.com (m ^ " typedef T = T") null_pos error false with | _,[ETypedef t,_] -> t.d_meta | _ -> assert false ) in let tp = get_type_patch ctx t (match f with None -> None | Some f -> Some (f,s)) in tp.tp_meta <- tp.tp_meta @ m; ); MacroApi.set_js_generator = (fun gen -> let js_ctx = Genjs.alloc_ctx ctx.com in ctx.com.js_gen <- Some (fun() -> let t = macro_timer ctx ["jsGenerator"] in gen js_ctx; t() ); ); MacroApi.get_local_type = (fun() -> match ctx.g.get_build_infos() with | Some (mt,tl,_) -> Some (match mt with | TClassDecl c -> TInst (c,tl) | TEnumDecl e -> TEnum (e,tl) | TTypeDecl t -> TType (t,tl) | TAbstractDecl a -> TAbstract(a,tl)) | None -> if ctx.curclass == null_class then None else Some (TInst (ctx.curclass,[])) ); MacroApi.get_expected_type = (fun() -> match ctx.with_type_stack with | (WithType t) :: _ -> Some t | _ -> None ); MacroApi.get_call_arguments = (fun() -> match ctx.call_argument_stack with | [] -> None | el :: _ -> Some el ); MacroApi.get_local_method = (fun() -> ctx.curfield.cf_name; ); MacroApi.get_local_using = (fun() -> List.map fst ctx.m.module_using; ); MacroApi.get_local_imports = (fun() -> ctx.m.module_imports; ); MacroApi.get_local_vars = (fun () -> ctx.locals; ); MacroApi.get_build_fields = (fun() -> match ctx.g.get_build_infos() with | None -> Interp.vnull | Some (_,_,fields) -> Interp.enc_array (List.map Interp.encode_field fields) ); MacroApi.get_pattern_locals = (fun e t -> !get_pattern_locals_ref ctx e t ); MacroApi.define_type = (fun v -> let m, tdef, pos = (try Interp.decode_type_def v with MacroApi.Invalid_expr -> Interp.exc_string "Invalid type definition") in let add is_macro ctx = let mnew = Typeload.type_module ctx m ctx.m.curmod.m_extra.m_file [tdef,pos] pos in mnew.m_extra.m_kind <- if is_macro then MMacro else MFake; add_dependency mnew ctx.m.curmod; in add false ctx; (* if we are adding a class which has a macro field, we also have to add it to the macro context (issue #1497) *) if not ctx.in_macro then match tdef,ctx.g.macros with | EClass c,Some (_,mctx) when List.exists (fun cff -> (Meta.has Meta.Macro cff.cff_meta || List.mem AMacro cff.cff_access)) c.d_data -> add true mctx | _ -> () ); MacroApi.define_module = (fun m types imports usings -> let types = List.map (fun v -> let _, tdef, pos = (try Interp.decode_type_def v with MacroApi.Invalid_expr -> Interp.exc_string "Invalid type definition") in tdef, pos ) types in let pos = (match types with [] -> null_pos | (_,p) :: _ -> p) in let imports = List.map (fun (il,ik) -> EImport(il,ik),pos) imports in let usings = List.map (fun tp -> let sl = tp.tpackage @ [tp.tname] @ (match tp.tsub with None -> [] | Some s -> [s]) in EUsing (List.map (fun s -> s,null_pos) sl),pos ) usings in let types = imports @ usings @ types in let mpath = Ast.parse_path m in begin try let m = Hashtbl.find ctx.g.modules mpath in ignore(Typeload.type_types_into_module ctx m types pos) with Not_found -> let mnew = Typeload.type_module ctx mpath ctx.m.curmod.m_extra.m_file types pos in mnew.m_extra.m_kind <- MFake; add_dependency mnew ctx.m.curmod; end ); MacroApi.module_dependency = (fun mpath file ismacro -> let m = typing_timer ctx false (fun() -> Typeload.load_module ctx (parse_path mpath) p) in if ismacro then m.m_extra.m_macro_calls <- file :: List.filter ((<>) file) m.m_extra.m_macro_calls else add_dependency m (create_fake_module ctx file); ); MacroApi.current_module = (fun() -> ctx.m.curmod ); MacroApi.current_macro_module = (fun () -> assert false); MacroApi.delayed_macro = (fun i -> let mctx = (match ctx.g.macros with None -> assert false | Some (_,mctx) -> mctx) in let f = (try DynArray.get mctx.g.delayed_macros i with _ -> failwith "Delayed macro retrieve failure") in f(); let ret = !delayed_macro_result in delayed_macro_result := (fun() -> assert false); ret ); MacroApi.use_cache = (fun() -> !macro_enable_cache ); MacroApi.format_string = (fun s p -> ctx.g.do_format_string ctx s p ); MacroApi.cast_or_unify = (fun t e p -> AbstractCast.cast_or_unify_raise ctx t e p ); MacroApi.add_global_metadata = (fun s1 s2 config -> let meta = (match Parser.parse_string ctx.com (s2 ^ " typedef T = T") null_pos error false with | _,[ETypedef t,_] -> t.d_meta | _ -> assert false ) in List.iter (fun m -> ctx.g.global_metadata <- (ExtString.String.nsplit s1 ".",m,config) :: ctx.g.global_metadata; ) meta; ); MacroApi.add_module_check_policy = (fun sl il b i -> let add ctx = ctx.g.module_check_policies <- (List.fold_left (fun acc s -> (ExtString.String.nsplit s ".",List.map Obj.magic il,b) :: acc) ctx.g.module_check_policies sl); Hashtbl.iter (fun _ m -> m.m_extra.m_check_policy <- Typeload.get_policy ctx m.m_path) ctx.g.modules; in let add_macro ctx = match ctx.g.macros with | None -> () | Some(_,mctx) -> add mctx; in match Obj.magic i with | CompilationServer.NormalContext -> add ctx | CompilationServer.MacroContext -> add_macro ctx | CompilationServer.NormalAndMacroContext -> add ctx; add_macro ctx; ); MacroApi.on_reuse = (fun f -> macro_interp_on_reuse := f :: !macro_interp_on_reuse ); } let rec init_macro_interp ctx mctx mint = let p = null_pos in ignore(Typeload.load_module mctx (["haxe";"macro"],"Expr") p); ignore(Typeload.load_module mctx (["haxe";"macro"],"Type") p); flush_macro_context mint ctx; Interp.init mint; if !macro_enable_cache && not (Common.defined mctx.com Define.NoMacroCache) then begin macro_interp_cache := Some mint; macro_interp_on_reuse := []; macro_interp_reused := true; end and flush_macro_context mint ctx = let t = macro_timer ctx ["flush"] in let mctx = (match ctx.g.macros with None -> assert false | Some (_,mctx) -> mctx) in ctx.g.do_finalize mctx; let _, types, modules = ctx.g.do_generate mctx in mctx.com.types <- types; mctx.com.Common.modules <- modules; let check_reuse() = if !macro_interp_reused then true else if not (List.for_all (fun f -> f()) !macro_interp_on_reuse) then false else begin macro_interp_reused := true; true; end in (* if one of the type we are using has been modified, we need to create a new macro context from scratch *) let mint = if not (Interp.can_reuse mint types && check_reuse()) then begin let com2 = mctx.com in let mint = Interp.create com2 (make_macro_api ctx Globals.null_pos) in let macro = ((fun() -> Interp.select mint), mctx) in ctx.g.macros <- Some macro; mctx.g.macros <- Some macro; init_macro_interp ctx mctx mint; mint end else mint in (* we should maybe ensure that all filters in Main are applied. Not urgent atm *) let expr_filters = [AbstractCast.handle_abstract_casts mctx; Filters.captured_vars mctx.com; Filters.rename_local_vars mctx] in (* some filters here might cause side effects that would break compilation server. let's save the minimal amount of information we need *) let minimal_restore t = match t with | TClassDecl c -> let meta = c.cl_meta in let path = c.cl_path in c.cl_restore <- (fun() -> c.cl_meta <- meta; c.cl_path <- path); | _ -> () in let type_filters = [ Filters.add_field_inits mctx; minimal_restore; Filters.apply_native_paths mctx ] in let ready = fun t -> Filters.apply_filters_once mctx expr_filters t; List.iter (fun f -> f t) type_filters in (try Interp.add_types mint types ready with Error (e,p) -> t(); raise (Fatal_error(error_msg e,p))); t(); Filters.next_compilation() let create_macro_interp ctx mctx = let com2 = mctx.com in let mint, init = (match !macro_interp_cache with | None -> let mint = Interp.create com2 (make_macro_api ctx null_pos) in mint, (fun() -> init_macro_interp ctx mctx mint) | Some mint -> macro_interp_reused := false; Interp.do_reuse mint (make_macro_api ctx null_pos); mint, (fun() -> ()) ) in let on_error = com2.error in com2.error <- (fun e p -> Interp.set_error (Interp.get_ctx()) true; macro_interp_cache := None; on_error e p ); let macro = ((fun() -> Interp.select mint), mctx) in ctx.g.macros <- Some macro; mctx.g.macros <- Some macro; (* mctx.g.core_api <- ctx.g.core_api; // causes some issues because of optional args and Null type in Flash9 *) init() let get_macro_context ctx p = let api = make_macro_api ctx p in match ctx.g.macros with | Some (select,ctx) -> select(); api, ctx | None -> let com2 = Common.clone ctx.com in ctx.com.get_macros <- (fun() -> Some com2); com2.package_rules <- PMap.empty; com2.main_class <- None; com2.display <- DisplayMode.create DMNone; List.iter (fun p -> com2.defines <- PMap.remove (Globals.platform_name p) com2.defines) Globals.platforms; com2.defines_signature <- None; com2.class_path <- List.filter (fun s -> not (ExtString.String.exists s "/_std/")) com2.class_path; let name = platform_name !Globals.macro_platform in com2.class_path <- List.map (fun p -> p ^ name ^ "/_std/") com2.std_path @ com2.class_path; let to_remove = List.map (fun d -> fst (Define.infos d)) [Define.NoTraces] in let to_remove = to_remove @ List.map (fun (_,d) -> "flash" ^ d) Common.flash_versions in com2.defines <- PMap.foldi (fun k v acc -> if List.mem k to_remove then acc else PMap.add k v acc) com2.defines PMap.empty; Common.define com2 Define.Macro; Common.init_platform com2 !Globals.macro_platform; let mctx = ctx.g.do_create com2 in mctx.is_display_file <- ctx.is_display_file; create_macro_interp ctx mctx; api, mctx let load_macro ctx display cpath f p = let api, mctx = get_macro_context ctx p in let mint = Interp.get_ctx() in let cpath, sub = (match List.rev (fst cpath) with | name :: pack when name.[0] >= 'A' && name.[0] <= 'Z' -> (List.rev pack,name), Some (snd cpath) | _ -> cpath, None ) in let meth = try Hashtbl.find mctx.com.cached_macros (cpath,f) with Not_found -> let t = macro_timer ctx ["typing";s_type_path cpath ^ "." ^ f] in (* Temporarily enter display mode while typing the macro. *) if display then mctx.com.display <- ctx.com.display; let m = (try Hashtbl.find ctx.g.types_module cpath with Not_found -> cpath) in let mloaded = Typeload.load_module mctx m p in api.MacroApi.current_macro_module <- (fun() -> mloaded); mctx.m <- { curmod = mloaded; module_types = []; module_using = []; module_globals = PMap.empty; wildcard_packages = []; module_imports = []; }; add_dependency ctx.m.curmod mloaded; let mt = Typeload.load_type_def mctx p { tpackage = fst cpath; tname = snd cpath; tparams = []; tsub = sub } in let cl, meth = (match mt with | TClassDecl c -> let t = macro_timer ctx ["finalize"] in mctx.g.do_finalize mctx; t(); c, (try PMap.find f c.cl_statics with Not_found -> error ("Method " ^ f ^ " not found on class " ^ s_type_path cpath) p) | _ -> error "Macro should be called on a class" p ) in if not (Common.defined ctx.com Define.NoDeprecationWarnings) then Display.DeprecationCheck.check_cf mctx.com meth p; let meth = (match follow meth.cf_type with TFun (args,ret) -> args,ret,cl,meth | _ -> error "Macro call should be a method" p) in mctx.com.display <- DisplayMode.create DMNone; if not ctx.in_macro then flush_macro_context mint ctx; Hashtbl.add mctx.com.cached_macros (cpath,f) meth; mctx.m <- { curmod = null_module; module_types = []; module_using = []; module_globals = PMap.empty; wildcard_packages = []; module_imports = []; }; t(); meth in let call args = let t = macro_timer ctx ["execution";s_type_path cpath ^ "." ^ f] in incr stats.s_macros_called; let r = Interp.call_path (Interp.get_ctx()) ((fst cpath) @ [(match sub with None -> snd cpath | Some s -> s)]) f args api in t(); r in mctx, meth, call type macro_arg_type = | MAExpr | MAFunction | MAOther let type_macro ctx mode cpath f (el:Ast.expr list) p = let mctx, (margs,mret,mclass,mfield), call_macro = load_macro ctx (mode = MDisplay) cpath f p in let mpos = mfield.cf_pos in let ctexpr = { tpackage = ["haxe";"macro"]; tname = "Expr"; tparams = []; tsub = None } in let expr = Typeload.load_instance mctx (ctexpr,null_pos) false p in (match mode with | MDisplay -> raise Exit (* We don't have to actually call the macro. *) | MExpr -> unify mctx mret expr mpos; | MBuild -> let ctfields = { tpackage = []; tname = "Array"; tparams = [TPType (CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tparams = []; tsub = Some "Field" },null_pos)]; tsub = None } in let tfields = Typeload.load_instance mctx (ctfields,null_pos) false p in unify mctx mret tfields mpos | MMacroType -> let cttype = { tpackage = ["haxe";"macro"]; tname = "Type"; tparams = []; tsub = None } in let ttype = Typeload.load_instance mctx (cttype,null_pos) false p in try unify_raise mctx mret ttype mpos; (* TODO: enable this again in the future *) (* ctx.com.warning "Returning Type from @:genericBuild macros is deprecated, consider returning ComplexType instead" p; *) with Error (Unify _,_) -> let cttype = { tpackage = ["haxe";"macro"]; tname = "Expr"; tparams = []; tsub = Some ("ComplexType") } in let ttype = Typeload.load_instance mctx (cttype,null_pos) false p in unify_raise mctx mret ttype mpos; ); (* if the function's last argument is of Array, split the argument list and use [] for unify_call_args *) let el,el2 = match List.rev margs with | (_,_,TInst({cl_path=([], "Array")},[e])) :: rest when (try Type.type_eq EqStrict e expr; true with Unify_error _ -> false) -> let rec loop (acc1,acc2) el1 el2 = match el1,el2 with | [],[] -> List.rev acc1, List.rev acc2 | [], e2 :: [] -> (List.rev ((EArrayDecl [],p) :: acc1), []) | [], _ -> (* not enough arguments, will be handled by unify_call_args *) List.rev acc1, List.rev acc2 | e1 :: l1, e2 :: [] -> loop (((EArrayDecl [],p) :: acc1), [e1]) l1 [] | e1 :: l1, [] -> loop (acc1, e1 :: acc2) l1 [] | e1 :: l1, e2 :: l2 -> loop (e1 :: acc1, acc2) l1 l2 in loop ([],[]) el margs | _ -> el,[] in let todo = ref [] in let args = (* force default parameter types to haxe.macro.Expr, and if success allow to pass any value type since it will be encoded *) let eargs = List.map (fun (n,o,t) -> try unify_raise mctx t expr p; (n, o, t_dynamic), MAExpr with Error (Unify _,_) -> match follow t with | TFun _ -> (n,o,t_dynamic), MAFunction | _ -> (n,o,t), MAOther ) margs in (* this is quite tricky here : we want to use unify_call_args which will type our AST expr but we want to be able to get it back after it's been padded with nulls *) let index = ref (-1) in let constants = List.map (fun e -> let p = snd e in let e = (try (match Codegen.type_constant_value ctx.com e with | { eexpr = TConst (TString _); epos = p } when Lexer.is_fmt_string p -> Lexer.remove_fmt_string p; todo := (fun() -> Lexer.add_fmt_string p) :: !todo; | _ -> ()); e with Error (Custom _,_) -> (* if it's not a constant, let's make something that is typed as haxe.macro.Expr - for nice error reporting *) (EBlock [ (EVars [("__tmp",null_pos),Some (CTPath ctexpr,p),Some (EConst (Ident "null"),p)],p); (EConst (Ident "__tmp"),p); ],p) ) in (* let's track the index by doing [e][index] (we will keep the expression type this way) *) incr index; (EArray ((EArrayDecl [e],p),(EConst (Int (string_of_int (!index))),p)),p) ) el in let elt, _ = unify_call_args mctx constants (List.map fst eargs) t_dynamic p false false in List.iter (fun f -> f()) (!todo); List.map2 (fun (_,mct) e -> let e, et = (match e.eexpr with (* get back our index and real expression *) | TArray ({ eexpr = TArrayDecl [e] }, { eexpr = TConst (TInt index) }) -> List.nth el (Int32.to_int index), e (* added by unify_call_args *) | TConst TNull -> (EConst (Ident "null"),e.epos), e | _ -> assert false ) in let ictx = Interp.get_ctx() in match mct with | MAExpr -> Interp.encode_expr e | MAFunction -> let e = ictx.Interp.curapi.MacroApi.type_macro_expr e in begin match Interp.eval_expr ictx e with | Some v -> v | None -> Interp.vnull end | MAOther -> match Interp.eval_expr ictx et with | None -> assert false | Some v -> v ) eargs elt in let args = match el2 with | [] -> args | _ -> (match List.rev args with _::args -> List.rev args | [] -> []) @ [Interp.enc_array (List.map Interp.encode_expr el2)] in let call() = match call_macro args with | None -> None | Some v -> try Some (match mode with | MExpr | MDisplay -> Interp.decode_expr v | MBuild -> let fields = if v = Interp.vnull then (match ctx.g.get_build_infos() with | None -> assert false | Some (_,_,fields) -> fields) else List.map Interp.decode_field (Interp.dec_array v) in (EVars [("fields",null_pos),Some (CTAnonymous fields,p),None],p) | MMacroType -> let t = if v = Interp.vnull then mk_mono() else try let ct = Interp.decode_ctype v in Typeload.load_complex_type ctx false p ct; with MacroApi.Invalid_expr -> Interp.decode_type v in ctx.ret <- t; (EBlock [],p) ) with MacroApi.Invalid_expr -> if v = Interp.vnull then error "Unexpected null value returned from macro" p else error "The macro didn't return a valid result" p in let e = (if ctx.in_macro then begin (* this is super-tricky : we can't evaluate a macro inside a macro because we might trigger some cycles. So instead, we generate a haxe.macro.Context.delayedCalled(i) expression that will only evaluate the macro if/when it is called. The tricky part is that the whole delayed-evaluation process has to use the same contextual informations as if it was evaluated now. *) let ctx = { ctx with locals = ctx.locals; } in let pos = DynArray.length mctx.g.delayed_macros in DynArray.add mctx.g.delayed_macros (fun() -> delayed_macro_result := (fun() -> let mint = Interp.get_ctx() in match call() with | None -> (fun() -> raise MacroApi.Abort) | Some e -> Interp.eval_delayed mint (type_expr ctx e Value) ); ); ctx.m.curmod.m_extra.m_time <- -1.; (* disable caching for modules having macro-in-macro *) if Common.defined ctx.com Define.MacroDebug then ctx.com.warning "Macro-in-macro call detected" p; let e = (EConst (Ident "$__delayed_call__"),p) in Some (EUntyped (ECall (e,[EConst (Int (string_of_int pos)),p]),p),p) end else call() ) in e let call_macro ctx path meth args p = let mctx, (margs,_,mclass,mfield), call = load_macro ctx false path meth p in let el, _ = unify_call_args mctx args margs t_dynamic p false false in call (List.map (fun e -> try Interp.make_const e with Exit -> error "Parameter should be a constant" e.epos) el) let call_init_macro ctx e = let p = { pfile = "--macro"; pmin = 0; pmax = 0 } in let e = try Parser.parse_expr_string ctx.com e p error false with err -> display_error ctx ("Could not parse `" ^ e ^ "`") p; raise err in match fst e with | ECall (e,args) -> 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, meth = (match loop e with | [meth] -> (["haxe";"macro"],"Compiler"), meth | [meth;"server"] -> (["haxe";"macro"],"CompilationServer"), meth | meth :: cl :: path -> (List.rev path,cl), meth | _ -> error "Invalid macro call" p) in ignore(call_macro ctx path meth args p); | _ -> error "Invalid macro call" p let interpret ctx = let mctx = Interp.create ctx.com (make_macro_api ctx null_pos) in Interp.add_types mctx ctx.com.types (fun t -> ()); match ctx.com.main with | None -> () | Some e -> ignore(Interp.eval_expr mctx e) let setup() = Interp.setup Interp.macro_api ;; load_macro_ref := load_macro; haxe_3.4.4.orig/src/main.ml0000664000175000017500000010577413166552354015477 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) (* Conventions: - e: expression (typed or untyped) - c: class - en: enum - td: typedef (tdef) - a: abstract - an: anon - tf: tfunc - cf: class_field - ef: enum_field - t: type (t) - ct: complex_type - v: local variable (tvar) - m: module (module_def) - mt: module_type - p: pos "param" refers to type parameters "arg" refers to function arguments leading s_ means function returns string trailing l means list (but we also use natural plurals such as "metas") semantic suffixes may be used freely (e.g. e1, e_if, e') *) open Printf open Genswf open Common open Common.DisplayMode open Type open Server open Globals exception Abort let executable_path() = Extc.executable_path() let format msg p = if p = null_pos then msg else begin let error_printer file line = sprintf "%s:%d:" file line in let epos = Lexer.get_error_pos error_printer p in let msg = String.concat ("\n" ^ epos ^ " : ") (ExtString.String.nsplit msg "\n") in sprintf "%s : %s" epos msg end let message ctx msg p = ctx.messages <- format msg p :: ctx.messages let deprecated = [] let limit_string s offset = let rest = 80 - offset in let words = ExtString.String.nsplit s " " in let rec loop i words = match words with | word :: words -> if String.length word + i + 1 > rest then (Printf.sprintf "\n%*s" offset "") :: word :: loop (String.length word) words else (if i = 0 then "" else " ") :: word :: loop (i + 1 + String.length word) words | [] -> [] in String.concat "" (loop 0 words) let error ctx msg p = let msg = try List.assoc msg deprecated with Not_found -> msg in message ctx msg p; ctx.has_error <- true let reserved_flags = [ "cross";"js";"lua";"neko";"flash";"php";"cpp";"cs";"java";"python"; "as3";"swc";"macro";"sys" ] let delete_file f = try Sys.remove f with _ -> () let expand_env ?(h=None) path = let r = Str.regexp "%\\([A-Za-z0-9_]+\\)%" in Str.global_substitute r (fun s -> let key = Str.matched_group 1 s in try Sys.getenv key with Not_found -> try match h with | None -> raise Not_found | Some h -> Hashtbl.find h key with Not_found -> "%" ^ key ^ "%" ) path let add_libs com libs = let call_haxelib() = let t = Common.timer ["haxelib"] in let cmd = "haxelib path " ^ String.concat " " libs in let pin, pout, perr = Unix.open_process_full cmd (Unix.environment()) in let lines = Std.input_list pin in let err = Std.input_list perr in let ret = Unix.close_process_full (pin,pout,perr) in if ret <> Unix.WEXITED 0 then failwith (match lines, err with | [], [] -> "Failed to call haxelib (command not found ?)" | [], [s] when ExtString.String.ends_with (ExtString.String.strip s) "Module not found : path" -> "The haxelib command has been strip'ed, please install it again" | _ -> String.concat "\n" (lines@err)); t(); lines in match libs with | [] -> [] | _ -> let lines = match CompilationServer.get() with | Some cs -> (try (* if we are compiling, really call haxelib since library path might have changed *) if not com.display.dms_display then raise Not_found; CompilationServer.find_haxelib cs libs with Not_found -> let lines = call_haxelib() in CompilationServer.cache_haxelib cs libs lines; lines) | _ -> call_haxelib() in let extra_args = ref [] in let lines = List.fold_left (fun acc l -> let l = ExtString.String.strip l in if l = "" then acc else if l.[0] <> '-' then l :: acc else match (try ExtString.String.split l " " with _ -> l, "") with | ("-L",dir) -> com.neko_libs <- String.sub l 3 (String.length l - 3) :: com.neko_libs; acc | param, value -> extra_args := param :: !extra_args; if value <> "" then extra_args := value :: !extra_args; acc ) [] lines in com.class_path <- lines @ com.class_path; List.rev !extra_args let run_command ctx cmd = let h = Hashtbl.create 0 in Hashtbl.add h "__file__" ctx.com.file; Hashtbl.add h "__platform__" (platform_name ctx.com.platform); let t = Common.timer ["command"] in let cmd = expand_env ~h:(Some h) cmd in let len = String.length cmd in if len > 3 && String.sub cmd 0 3 = "cd " then begin Sys.chdir (String.sub cmd 3 (len - 3)); 0 end else let binary_string s = if not Globals.is_windows then s else String.concat "\n" (Str.split (Str.regexp "\r\n") s) in let pout, pin, perr = Unix.open_process_full cmd (Unix.environment()) in let iout = Unix.descr_of_in_channel pout in let ierr = Unix.descr_of_in_channel perr in let berr = Buffer.create 0 in let bout = Buffer.create 0 in let tmp = String.create 1024 in let result = ref None in (* we need to read available content on process out/err if we want to prevent the process from blocking when the pipe is full *) let is_process_running() = let pid, r = Unix.waitpid [Unix.WNOHANG] (-1) in if pid = 0 then true else begin result := Some r; false; end in let rec loop ins = let (ch,_,_), timeout = (try Unix.select ins [] [] 0.02, true with _ -> ([],[],[]),false) in match ch with | [] -> (* make sure we read all *) if timeout && is_process_running() then loop ins else begin Buffer.add_string berr (IO.read_all (IO.input_channel perr)); Buffer.add_string bout (IO.read_all (IO.input_channel pout)); end | s :: _ -> let n = Unix.read s tmp 0 (String.length tmp) in if s == iout && n > 0 then ctx.com.print (String.sub tmp 0 n) else Buffer.add_substring (if s == iout then bout else berr) tmp 0 n; loop (if n = 0 then List.filter ((!=) s) ins else ins) in (try loop [iout;ierr] with Unix.Unix_error _ -> ()); let serr = binary_string (Buffer.contents berr) in let sout = binary_string (Buffer.contents bout) in if serr <> "" then ctx.messages <- (if serr.[String.length serr - 1] = '\n' then String.sub serr 0 (String.length serr - 1) else serr) :: ctx.messages; if sout <> "" then ctx.com.print sout; let r = (match (try Unix.close_process_full (pout,pin,perr) with Unix.Unix_error (Unix.ECHILD,_,_) -> (match !result with None -> assert false | Some r -> r)) with | Unix.WEXITED e -> e | Unix.WSIGNALED s | Unix.WSTOPPED s -> if s = 0 then -1 else s ) in t(); r module Initialize = struct let set_platform com pf file = if com.platform <> Cross then failwith "Multiple targets"; Common.init_platform com pf; com.file <- file; if (pf = Flash) && file_extension file = "swc" then Common.define com Define.Swc let initialize_target ctx com classes = let add_std dir = com.class_path <- List.filter (fun s -> not (List.mem s com.std_path)) com.class_path @ List.map (fun p -> p ^ dir ^ "/_std/") com.std_path @ com.std_path in match com.platform with | Cross -> (* no platform selected *) set_platform com Cross ""; "?" | Flash -> let rec loop = function | [] -> () | (v,_) :: _ when v > com.flash_version -> () | (v,def) :: l -> Common.raw_define com ("flash" ^ def); loop l in loop Common.flash_versions; Common.raw_define com "flash"; com.package_rules <- PMap.remove "flash" com.package_rules; add_std "flash"; "swf" | Neko -> add_std "neko"; "n" | Js -> if not (PMap.exists (fst (Define.infos Define.JqueryVer)) com.defines) then Common.define_value com Define.JqueryVer "11204"; let es_version = try int_of_string (Common.defined_value com Define.JsEs) with | Not_found -> (Common.define_value com Define.JsEs "5"; 5) | _ -> 0 in if es_version < 3 || es_version = 4 then (* we don't support ancient and there's no 4th *) failwith "Invalid -D js-es value"; if es_version >= 5 then Common.raw_define com "js-es5"; (* backward-compatibility *) add_std "js"; "js" | Lua -> add_std "lua"; "lua" | Php -> if Common.is_php7 com then begin com.package_rules <- PMap.add "php" (Directory "php7") com.package_rules; com.package_rules <- PMap.add "php7" Forbidden com.package_rules; add_std "php7" end else add_std "php"; "php" | Cpp -> Common.define_value com Define.HxcppApiLevel "331"; add_std "cpp"; if Common.defined com Define.Cppia then classes := (Path.parse_path "cpp.cppia.HostClasses" ) :: !classes; "cpp" | Cs -> let old_flush = ctx.flush in ctx.flush <- (fun () -> com.net_libs <- []; old_flush() ); Gencs.before_generate com; add_std "cs"; "cs" | Java -> let old_flush = ctx.flush in ctx.flush <- (fun () -> List.iter (fun (_,_,close,_,_) -> close()) com.java_libs; com.java_libs <- []; old_flush() ); Genjava.before_generate com; add_std "java"; "java" | Python -> add_std "python"; "python" | Hl -> add_std "hl"; "hl" end let generate tctx ext xml_out interp swf_header = let com = tctx.Typecore.com in (* check file extension. In case of wrong commandline, we don't want to accidentaly delete a source file. *) if file_extension com.file = ext then delete_file com.file; if com.platform = Flash || com.platform = Cpp || com.platform = Hl then List.iter (Codegen.fix_overrides com) com.types; if Common.defined com Define.Dump then Codegen.Dump.dump_types com; if Common.defined com Define.DumpDependencies then begin Codegen.Dump.dump_dependencies com; if not tctx.Typecore.in_macro then match tctx.Typecore.g.Typecore.macros with | None -> () | Some(_,ctx) -> print_endline "generate"; Codegen.Dump.dump_dependencies ~target_override:(Some "macro") ctx.Typecore.com end; begin match com.platform with | Neko | Hl when interp -> () | Cpp when Common.defined com Define.Cppia -> () | Cpp | Cs | Java | Php -> Common.mkdir_from_path (com.file ^ "/.") | _ -> Common.mkdir_from_path com.file end; if interp then MacroContext.interpret tctx else if com.platform = Cross then () else begin let generate,name = match com.platform with | Flash when Common.defined com Define.As3 -> Genas3.generate,"AS3" | Flash -> Genswf.generate swf_header,"swf" | Neko -> Genneko.generate,"neko" | Js -> Genjs.generate,"js" | Lua -> Genlua.generate,"lua" | Php -> if Common.is_php7 com then Genphp7.generate,"php" else Genphp.generate,"php" | Cpp -> Gencpp.generate,"cpp" | Cs -> Gencs.generate,"cs" | Java -> Genjava.generate,"java" | Python -> Genpy.generate,"python" | Hl -> Genhl.generate,"hl" | Cross -> assert false in Common.log com ("Generating " ^ name ^ ": " ^ com.file); let t = Common.timer ["generate";name] in generate com; t() end let get_std_class_paths () = try let p = Sys.getenv "HAXE_STD_PATH" in let rec loop = function | drive :: path :: l -> if String.length drive = 1 && ((drive.[0] >= 'a' && drive.[0] <= 'z') || (drive.[0] >= 'A' && drive.[0] <= 'Z')) then (drive ^ ":" ^ path) :: loop l else drive :: loop (path :: l) | l -> l in let parts = Str.split_delim (Str.regexp "[;:]") p in "" :: List.map Path.add_trailing_slash (loop parts) with Not_found -> if Sys.os_type = "Unix" then [ "/usr/lib/haxe/std/"; "/usr/share/haxe/std/"; "/usr/local/lib/haxe/std/"; "/usr/lib/haxe/extraLibs/"; "/usr/local/lib/haxe/extraLibs/"; "" ] else let base_path = Path.add_trailing_slash (Path.get_real_path (try executable_path() with _ -> "./")) in [ base_path ^ "std/"; base_path ^ "extraLibs/"; "" ] let rec process_params create pl = let each_params = ref [] in let rec loop acc = function | [] -> let ctx = create (!each_params @ (List.rev acc)) in init ctx; ctx.flush() | "--next" :: l when acc = [] -> (* skip empty --next *) loop [] l | "--next" :: l -> let ctx = create (!each_params @ (List.rev acc)) in ctx.has_next <- true; init ctx; ctx.flush(); loop [] l | "--each" :: l -> each_params := List.rev acc; loop [] l | "--cwd" :: dir :: l -> (* we need to change it immediately since it will affect hxml loading *) (try Unix.chdir dir with _ -> raise (Arg.Bad ("Invalid directory: " ^ dir))); loop acc l | "--connect" :: hp :: l -> (match CompilationServer.get() with | None -> let host, port = (try ExtString.String.split hp ":" with _ -> "127.0.0.1", hp) in do_connect host (try int_of_string port with _ -> raise (Arg.Bad "Invalid port")) ((List.rev acc) @ l) | Some _ -> (* already connected : skip *) loop acc l) | "--run" :: cl :: args -> let acc = cl :: "-main" :: "--interp" :: acc in let ctx = create (!each_params @ (List.rev acc)) in ctx.com.sys_args <- args; init ctx; ctx.flush() | arg :: l -> match List.rev (ExtString.String.nsplit arg ".") with | "hxml" :: _ when (match acc with "-cmd" :: _ -> false | _ -> true) -> let acc, l = (try acc, parse_hxml arg @ l with Not_found -> (arg ^ " (file not found)") :: acc, l) in loop acc l | _ -> loop (arg :: acc) l in (* put --display in front if it was last parameter *) let pl = (match List.rev pl with | file :: "--display" :: pl when file <> "memory" -> "--display" :: file :: List.rev pl | "use_rtti_doc" :: "-D" :: file :: "--display" :: pl -> "--display" :: file :: List.rev pl | _ -> pl ) in loop [] pl and init ctx = let usage = Printf.sprintf "Haxe Compiler %s - (C)2005-2017 Haxe Foundation\n Usage : haxe%s -main [-swf|-js|-neko|-php|-cpp|-cppia|-as3|-cs|-java|-python|-hl|-lua] [options]\n Options :" Globals.s_version (if Sys.os_type = "Win32" then ".exe" else "") in let com = ctx.com in let classes = ref [([],"Std")] in try let xml_out = ref None in let swf_header = ref None in let cmds = ref [] in let config_macros = ref [] in let cp_libs = ref [] in let added_libs = Hashtbl.create 0 in let no_output = ref false in let did_something = ref false in let force_typing = ref false in let pre_compilation = ref [] in let interp = ref false in let swf_version = ref false in let evals = ref [] in Common.define_value com Define.HaxeVer (float_repres (float_of_int Globals.version /. 1000.)); Common.raw_define com "haxe3"; Common.define_value com Define.Dce "std"; com.warning <- (fun msg p -> message ctx ("Warning : " ^ msg) p); com.error <- error ctx; if CompilationServer.runs() then com.run_command <- run_command ctx; Parser.display_error := (fun e p -> com.error (Parser.error_msg e) p); Parser.use_doc := !Common.display_default <> DMNone || (CompilationServer.runs()); com.class_path <- get_std_class_paths (); com.std_path <- List.filter (fun p -> ExtString.String.ends_with p "std/" || ExtString.String.ends_with p "std\\") com.class_path; let define f = Arg.Unit (fun () -> Common.define com f) in let process_ref = ref (fun args -> ()) in let process_libs() = let libs = List.filter (fun l -> not (Hashtbl.mem added_libs l)) (List.rev !cp_libs) in cp_libs := []; List.iter (fun l -> Hashtbl.add added_libs l ()) libs; (* immediately process the arguments to insert them at the place -lib was defined *) match add_libs com libs with | [] -> () | args -> (!process_ref) args in let arg_delays = ref [] in let basic_args_spec = [ ("-cp",Arg.String (fun path -> process_libs(); com.class_path <- Path.add_trailing_slash path :: com.class_path )," : add a directory to find source files"); ("-js",Arg.String (Initialize.set_platform com Js)," : compile code to JavaScript file"); ("-lua",Arg.String (Initialize.set_platform com Lua)," : compile code to Lua file"); ("-swf",Arg.String (Initialize.set_platform com Flash)," : compile code to Flash SWF file"); ("-as3",Arg.String (fun dir -> Initialize.set_platform com Flash dir; Common.define com Define.As3; Common.define com Define.NoInline; )," : generate AS3 code into target directory"); ("-neko",Arg.String (Initialize.set_platform com Neko)," : compile code to Neko Binary"); ("-php",Arg.String (fun dir -> classes := (["php"],"Boot") :: !classes; Initialize.set_platform com Php dir; )," : generate PHP code into target directory"); ("-cpp",Arg.String (fun dir -> Initialize.set_platform com Cpp dir; )," : generate C++ code into target directory"); ("-cppia",Arg.String (fun file -> Initialize.set_platform com Cpp file; Common.define com Define.Cppia; )," : generate Cppia code into target file"); ("-cs",Arg.String (fun dir -> cp_libs := "hxcs" :: !cp_libs; Initialize.set_platform com Cs dir; )," : generate C# code into target directory"); ("-java",Arg.String (fun dir -> cp_libs := "hxjava" :: !cp_libs; Initialize.set_platform com Java dir; )," : generate Java code into target directory"); ("-python",Arg.String (fun dir -> Initialize.set_platform com Python dir; )," : generate Python code as target file"); ("-hl",Arg.String (fun file -> Initialize.set_platform com Hl file; )," : compile HL code as target file"); ("-xml",Arg.String (fun file -> Parser.use_doc := true; xml_out := Some file )," : generate XML types description"); ("-main",Arg.String (fun cl -> if com.main_class <> None then raise (Arg.Bad "Multiple -main"); let cpath = Path.parse_type_path cl in com.main_class <- Some cpath; classes := cpath :: !classes )," : select startup class"); ("-lib",Arg.String (fun l -> cp_libs := l :: !cp_libs; Common.raw_define com l; )," : use a haxelib library"); ("-D",Arg.String (fun var -> begin match var with | "no_copt" | "no-copt" -> com.foptimize <- false; | "use_rtti_doc" | "use-rtti-doc" -> Parser.use_doc := true; | _ -> if List.mem var reserved_flags then raise (Arg.Bad (var ^ " is a reserved compiler flag and cannot be defined from command line")); end; Common.raw_define com var; )," : define a conditional compilation flag"); ("-v",Arg.Unit (fun () -> com.verbose <- true ),": turn on verbose mode"); ("-debug", Arg.Unit (fun() -> Common.define com Define.Debug; com.debug <- true; ), ": add debug information to the compiled code"); ] in let adv_args_spec = [ ("-dce", Arg.String (fun mode -> (match mode with | "std" | "full" | "no" -> () | _ -> raise (Arg.Bad "Invalid DCE mode, expected std | full | no")); Common.define_value com Define.Dce mode ),"[std|full|no] : set the dead code elimination mode (default std)"); ("-swf-version",Arg.Float (fun v -> if not !swf_version || com.flash_version < v then com.flash_version <- v; swf_version := true; )," : change the SWF version"); ("-swf-header",Arg.String (fun h -> try swf_header := Some (match ExtString.String.nsplit h ":" with | [width; height; fps] -> (int_of_string width,int_of_string height,float_of_string fps,0xFFFFFF) | [width; height; fps; color] -> let color = if ExtString.String.starts_with color "0x" then color else "0x" ^ color in (int_of_string width, int_of_string height, float_of_string fps, int_of_string color) | _ -> raise Exit) with _ -> raise (Arg.Bad "Invalid SWF header format, expected width:height:fps[:color]") ),"
: define SWF header (width:height:fps:color)"); ("-swf-lib",Arg.String (fun file -> process_libs(); (* linked swf order matters, and lib might reference swf as well *) Genswf.add_swf_lib com file false )," : add the SWF library to the compiled SWF"); ("-swf-lib-extern",Arg.String (fun file -> Genswf.add_swf_lib com file true )," : use the SWF library for type checking"); ("-java-lib",Arg.String (fun file -> let std = file = "lib/hxjava-std.jar" in arg_delays := (fun () -> Genjava.add_java_lib com file std) :: !arg_delays; )," : add an external JAR or class directory library"); ("-net-lib",Arg.String (fun file -> let file, is_std = match ExtString.String.nsplit file "@" with | [file] -> file,false | [file;"std"] -> file,true | _ -> raise Exit in arg_delays := (fun () -> Gencs.add_net_lib com file is_std) :: !arg_delays; ),"[@std] : add an external .NET DLL file"); ("-net-std",Arg.String (fun file -> Gencs.add_net_std com file )," : add a root std .NET DLL search path"); ("-c-arg",Arg.String (fun arg -> com.c_args <- arg :: com.c_args )," : pass option to the native Java/C# compiler"); ("-x", Arg.String (fun file -> let neko_file = file ^ ".n" in Initialize.set_platform com Neko neko_file; if com.main_class = None then begin let cpath = Path.parse_type_path file in com.main_class <- Some cpath; classes := cpath :: !classes end; cmds := ("neko " ^ neko_file) :: !cmds; )," : shortcut for compiling and executing a neko file"); ("-resource",Arg.String (fun res -> let file, name = (match ExtString.String.nsplit res "@" with | [file; name] -> file, name | [file] -> file, file | _ -> raise (Arg.Bad "Invalid Resource format, expected file@name") ) in let file = (try Common.find_file com file with Not_found -> file) in let data = (try let s = Std.input_file ~bin:true file in if String.length s > 12000000 then raise Exit; s; with | Sys_error _ -> failwith ("Resource file not found : " ^ file) | _ -> failwith ("Resource '" ^ file ^ "' excess the maximum size of 12MB") ) in if Hashtbl.mem com.resources name then failwith ("Duplicate resource name " ^ name); Hashtbl.add com.resources name data ),"[@name] : add a named resource file"); ("-prompt", Arg.Unit (fun() -> prompt := true),": prompt on error"); ("-cmd", Arg.String (fun cmd -> cmds := DisplayOutput.unquote cmd :: !cmds ),": run the specified command after successful compilation"); ("--flash-strict", define Define.FlashStrict, ": more type strict flash API"); ("--no-traces", define Define.NoTraces, ": don't compile trace calls in the program"); ("--gen-hx-classes", Arg.Unit (fun() -> force_typing := true; pre_compilation := (fun() -> List.iter (fun (_,_,extract) -> Hashtbl.iter (fun n _ -> classes := n :: !classes) (extract()) ) com.swf_libs; List.iter (fun (_,std,_,all_files,_) -> if not std then List.iter (fun path -> if path <> (["java";"lang"],"String") then classes := path :: !classes) (all_files()) ) com.java_libs; List.iter (fun (_,std,all_files,_) -> if not std then List.iter (fun path -> classes := path :: !classes) (all_files()) ) com.net_libs; ) :: !pre_compilation; xml_out := Some "hx" ),": generate hx headers for all input classes"); ("--next", Arg.Unit (fun() -> assert false), ": separate several haxe compilations"); ("--each", Arg.Unit (fun() -> assert false), ": append preceding parameters to all haxe compilations separated by --next"); ("--display", Arg.String (fun file_pos -> DisplayOutput.handle_display_argument com file_pos pre_compilation did_something; ),": display code tips"); ("--no-output", Arg.Unit (fun() -> no_output := true),": compiles but does not generate any file"); ("--times", Arg.Unit (fun() -> measure_times := true),": measure compilation times"); ("--no-inline", define Define.NoInline, ": disable inlining"); ("--no-opt", Arg.Unit (fun() -> com.foptimize <- false; Common.define com Define.NoOpt; ), ": disable code optimizations"); ("--php-front",Arg.String (fun f -> if com.php_front <> None then raise (Arg.Bad "Multiple --php-front"); com.php_front <- Some f; )," : select the name for the php front file"); ("--php-lib",Arg.String (fun f -> if com.php_lib <> None then raise (Arg.Bad "Multiple --php-lib"); com.php_lib <- Some f; )," : select the name for the php lib folder"); ("--php-prefix", Arg.String (fun f -> if com.php_prefix <> None then raise (Arg.Bad "Multiple --php-prefix"); com.php_prefix <- Some f; Common.define com Define.PhpPrefix; )," : prefix all classes with given name"); ("--remap", Arg.String (fun s -> let pack, target = (try ExtString.String.split s ":" with _ -> raise (Arg.Bad "Invalid remap format, expected source:target")) in com.package_rules <- PMap.add pack (Remap target) com.package_rules; )," : remap a package to another one"); ("--interp", Arg.Unit (fun() -> Common.define com Define.Interp; Initialize.set_platform com (!Globals.macro_platform) ""; interp := true; ),": interpret the program using internal macro system"); ("--macro", Arg.String (fun e -> force_typing := true; config_macros := e :: !config_macros )," : call the given macro before typing anything else"); ("--eval", Arg.String (fun s -> force_typing := true; evals := s :: !evals; ), " : evaluates argument as Haxe module code"); ("--wait", Arg.String (fun hp -> let accept = match hp with | "stdio" -> Server.init_wait_stdio() | _ -> let host, port = (try ExtString.String.split hp ":" with _ -> "127.0.0.1", hp) in let port = try int_of_string port with _ -> raise (Arg.Bad "Invalid port") in init_wait_socket com.verbose host port in wait_loop process_params com.verbose accept ),"<[host:]port> : wait on the given port for commands to run)"); ("--connect",Arg.String (fun _ -> assert false ),"<[host:]port> : connect on the given port and run commands there)"); ("--cwd", Arg.String (fun dir -> assert false )," : set current working directory"); ("-version",Arg.Unit (fun() -> message ctx Globals.s_version null_pos; did_something := true; ),": print version and exit"); ("--help-defines", Arg.Unit (fun() -> let m = ref 0 in let rec loop i = let d = Obj.magic i in if d <> Define.Last then begin let t, doc = Define.infos d in if String.length t > !m then m := String.length t; ((String.concat "-" (ExtString.String.nsplit t "_")),doc) :: (loop (i + 1)) end else [] in let all = List.sort (fun (s1,_) (s2,_) -> String.compare s1 s2) (loop 0) in let all = List.map (fun (n,doc) -> Printf.sprintf " %-*s: %s" !m n (limit_string doc (!m + 3))) all in List.iter (fun msg -> ctx.com.print (msg ^ "\n")) all; did_something := true ),": print help for all compiler specific defines"); ("--help-metas", Arg.Unit (fun() -> let all,max_length = Meta.get_documentation_list() in let all = List.map (fun (n,doc) -> Printf.sprintf " %-*s: %s" max_length n (limit_string doc (max_length + 3))) all in List.iter (fun msg -> ctx.com.print (msg ^ "\n")) all; did_something := true ),": print help for all compiler metadatas"); ] in let args_callback cl = let path,name = Path.parse_path cl in if Path.starts_uppercase name then classes := (path,name) :: !classes else begin force_typing := true; config_macros := (Printf.sprintf "include('%s', true, null, null, true)" cl) :: !config_macros; end in let all_args_spec = basic_args_spec @ adv_args_spec in let process args = let current = ref 0 in (try Arg.parse_argv ~current (Array.of_list ("" :: List.map expand_env args)) all_args_spec args_callback usage; List.iter (fun fn -> fn()) !arg_delays with (Arg.Bad msg) as exc -> let r = Str.regexp "unknown option `\\([-A-Za-z]+\\)'" in try ignore(Str.search_forward r msg 0); let s = Str.matched_group 1 msg in let sl = List.map (fun (s,_,_) -> s) all_args_spec in let msg = StringError.string_error_raise s sl (Printf.sprintf "Invalid command: %s" s) in raise (Arg.Bad msg) with Not_found -> raise exc); arg_delays := [] in process_ref := process; process ctx.com.args; process_libs(); if com.display.dms_display then begin com.warning <- if com.display.dms_error_policy = EPCollect then (fun s p -> add_diagnostics_message com s p DisplayTypes.DiagnosticsSeverity.Warning) else message ctx; com.error <- error ctx; end; DisplayOutput.process_display_file com classes; let ext = Initialize.initialize_target ctx com classes in (* if we are at the last compilation step, allow all packages accesses - in case of macros or opening another project file *) if com.display.dms_display then begin if not ctx.has_next then com.package_rules <- PMap.foldi (fun p r acc -> match r with Forbidden -> acc | _ -> PMap.add p r acc) com.package_rules PMap.empty; end; com.config <- get_config com; (* make sure to adapt all flags changes defined after platform *) List.iter (fun f -> f()) (List.rev (!pre_compilation)); if !classes = [([],"Std")] && not !force_typing then begin let help_spec = basic_args_spec @ [ ("-help", Arg.Unit (fun () -> ()),": show extended help information"); ("--help", Arg.Unit (fun () -> ()),": show extended help information"); ("--help-defines", Arg.Unit (fun () -> ()),": print help for all compiler specific defines"); ("--help-metas", Arg.Unit (fun () -> ()),": print help for all compiler metadatas"); ("", Arg.Unit (fun () -> ()),": compile the module specified by dot-path"); ] in if !cmds = [] && not !did_something then Arg.usage help_spec usage; end else begin ctx.setup(); Common.log com ("Classpath : " ^ (String.concat ";" com.class_path)); Common.log com ("Defines : " ^ (String.concat ";" (PMap.foldi (fun k v acc -> (match v with "1" -> k | _ -> k ^ "=" ^ v) :: acc) com.defines []))); let t = Common.timer ["typing"] in Typecore.type_expr_ref := (fun ctx e with_type -> Typer.type_expr ctx e with_type); let tctx = Typer.create com in List.iter (MacroContext.call_init_macro tctx) (List.rev !config_macros); List.iter (Typer.eval tctx) !evals; List.iter (fun cpath -> ignore(tctx.Typecore.g.Typecore.do_load_module tctx cpath null_pos)) (List.rev !classes); Typer.finalize tctx; t(); if not ctx.com.display.dms_display && ctx.has_error then raise Abort; if ctx.com.display.dms_exit_during_typing then begin if ctx.has_next || ctx.has_error then raise Abort; failwith "No completion point was found"; end; let t = Common.timer ["filters"] in let main, types, modules = Typer.generate tctx in com.main <- main; com.types <- types; com.modules <- modules; DisplayOutput.process_global_display_mode com tctx; if not (Common.defined com Define.NoDeprecationWarnings) then Display.DeprecationCheck.run com; Filters.run com tctx main; t(); if ctx.has_error then raise Abort; (match !xml_out with | None -> () | Some "hx" -> Genxml.generate_hx com | Some file -> Common.log com ("Generating xml : " ^ file); Common.mkdir_from_path file; Genxml.generate com file); if not !no_output then generate tctx ext !xml_out !interp !swf_header; end; Sys.catch_break false; List.iter (fun f -> f()) (List.rev com.callbacks.after_generation); if not !no_output then begin List.iter (fun c -> let r = run_command ctx c in if r <> 0 then failwith ("Command failed with error " ^ string_of_int r) ) (List.rev !cmds) end with | Abort -> () | Error.Fatal_error (m,p) -> error ctx m p | Common.Abort (m,p) -> error ctx m p | Lexer.Error (m,p) -> error ctx (Lexer.error_msg m) p | Parser.Error (m,p) -> error ctx (Parser.error_msg m) p | Typecore.Forbid_package ((pack,m,p),pl,pf) -> if !Common.display_default <> DMNone && ctx.has_next then begin ctx.has_error <- false; ctx.messages <- []; end else begin error ctx (Printf.sprintf "You cannot access the %s package while %s (for %s)" pack (if pf = "macro" then "in a macro" else "targeting " ^ pf) (s_type_path m) ) p; List.iter (error ctx " referenced here") (List.rev pl); end | Error.Error (m,p) -> error ctx (Error.error_msg m) p | Interp.Error (msg,p :: l) | Hlmacro.Error (msg,p :: l) -> message ctx msg p; List.iter (message ctx "Called from") l; error ctx "Aborted" null_pos; | Typeload.Generic_Exception(m,p) -> error ctx m p | Arg.Bad msg -> error ctx ("Error: " ^ msg) null_pos | Failure msg when not (is_debug_run()) -> error ctx ("Error: " ^ msg) null_pos | Arg.Help msg -> message ctx msg null_pos | Display.DisplayPackage pack -> raise (DisplayOutput.Completion (String.concat "." pack)) | Display.DisplayFields fields -> let fields = List.map ( fun (name,kind,doc) -> name, kind, (Option.default "" doc) ) fields in let fields = if !measure_times then begin close_times(); (List.map (fun (name,value) -> ("@TIME " ^ name, Display.FKTimer value, "")) (DisplayOutput.get_timer_fields !start_time)) @ fields end else fields in raise (DisplayOutput.Completion (DisplayOutput.print_fields fields)) | Display.DisplayType (t,p,doc) -> let doc = match doc with Some _ -> doc | None -> DisplayOutput.find_doc t in raise (DisplayOutput.Completion (DisplayOutput.print_type t p doc)) | Display.DisplaySignatures(signatures,display_arg) -> if ctx.com.display.dms_kind = DMSignature then raise (DisplayOutput.Completion (DisplayOutput.print_signature signatures display_arg)) else raise (DisplayOutput.Completion (DisplayOutput.print_signatures signatures)) | Display.DisplayPosition pl -> raise (DisplayOutput.Completion (DisplayOutput.print_positions pl)) | Display.DisplayToplevel il -> let il = if !measure_times then begin close_times(); (List.map (fun (name,value) -> IdentifierType.ITTimer ("@TIME " ^ name ^ ": " ^ value)) (DisplayOutput.get_timer_fields !start_time)) @ il end else il in raise (DisplayOutput.Completion (DisplayOutput.print_toplevel il)) | Parser.TypePath (p,c,is_import) -> let fields = try begin match c with | None -> DisplayOutput.TypePathHandler.complete_type_path com p | Some (c,cur_package) -> DisplayOutput.TypePathHandler.complete_type_path_inner com p c cur_package is_import end with Common.Abort(msg,p) -> error ctx msg p; None in Option.may (fun fields -> raise (DisplayOutput.Completion (DisplayOutput.print_fields fields))) fields | Display.ModuleSymbols s | Display.Diagnostics s | Display.Statistics s | Display.Metadata s -> raise (DisplayOutput.Completion s) | Interp.Sys_exit i | Hlinterp.Sys_exit i -> ctx.flush(); exit i | e when (try Sys.getenv "OCAMLRUNPARAM" <> "b" || CompilationServer.runs() with _ -> true) && not (is_debug_run()) -> error ctx (Printexc.to_string e) null_pos ;; let other = Common.timer ["other"] in Sys.catch_break true; MacroContext.setup(); let args = List.tl (Array.to_list Sys.argv) in (try let server = Sys.getenv "HAXE_COMPILATION_SERVER" in let host, port = (try ExtString.String.split server ":" with _ -> "127.0.0.1", server) in do_connect host (try int_of_string port with _ -> failwith "Invalid HAXE_COMPILATION_SERVER port") args with Not_found -> try process_params create_context args with DisplayOutput.Completion c -> prerr_endline c; exit 0 | Arg.Bad msg -> prerr_endline ("Error: " ^ msg); exit 1 ); other(); if !measure_times then report_times prerr_endline haxe_3.4.4.orig/src/optimization/analyzer.ml0000664000175000017500000010664113166552354021120 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Type open Common open AnalyzerTexpr open AnalyzerTypes open OptimizerTexpr open Globals (* File organization: * analyzer.ml: The controlling file with all graph-based optimizations * analyzerConfig.ml: The general configuration which is used in multiple modules * analyzerTexpr.ml: Transformations and query functions on texpr, independent of graph/blocks * analyzerTexprTransformer.ml: Translation of texpr to graph/blocks * analyzerTypes.ml: Definition of graph, block and the analyzer context *) (* Ssa changes the expressions of a graph to conform to SSA rules. All variables are assigned to only once and SSA-phi expressions are created where necessary. The first pass inserts SSA-phi expressions for each variable in the dominance frontier of all its defining blocks. The second pass then creates and renames variables to ensure SSA property. *) module Ssa = struct open BasicBlock open Graph let add_phi g bb v = let p = bb.bb_pos in let ev = mk (TLocal v) v.v_type p in let el = List.map (fun _ -> ev) bb.bb_incoming in let e_phi = mk (TConst (TString "phi")) t_dynamic p in let ec = mk (TCall(e_phi,el)) t_dynamic p in let e = mk (TBinop(OpAssign,ev,ec)) t_dynamic p in DynArray.add bb.bb_phi e let insert_phi ctx = DynArray.iter (fun vi -> let v = vi.vi_var in if vi.vi_bb_declare == ctx.graph.g_unreachable then () else begin let done_list = Hashtbl.create 0 in let w = ref vi.vi_writes in while !w <> [] do let x = List.hd !w in w := List.tl !w; List.iter (fun y -> if not (Hashtbl.mem done_list y.bb_id) then begin Hashtbl.add done_list y.bb_id true; if in_scope y vi.vi_bb_declare then begin add_phi ctx.graph y v; if not (List.memq y vi.vi_writes) then w := y :: !w end end ) x.bb_df; done end ) ctx.graph.g_var_infos let set_reaching_def g v vo = let vi = get_var_info g v in vi.vi_reaching_def <- vo let get_reaching_def g v = (get_var_info g v).vi_reaching_def let rec dominates bb_dom bb = bb_dom == bb || bb.bb_dominator == bb_dom || (bb.bb_dominator != bb && dominates bb_dom bb.bb_dominator) let dominates ctx r bb = let l = (get_var_info ctx.graph r).vi_writes in List.exists (fun bb' -> dominates bb' bb) l let update_reaching_def ctx v bb = let rec loop r = match r with | Some r -> if dominates ctx r bb then Some r else loop (get_reaching_def ctx.graph r) | None -> None in let v' = (loop (get_reaching_def ctx.graph v)) in set_reaching_def ctx.graph v v' let local ctx e v bb = update_reaching_def ctx v bb; match get_reaching_def ctx.graph v with | Some v' -> v' | None -> v let update_phi ctx edge = let bb = edge.cfg_to in let rec loop i e = match e.eexpr with | TBinop(OpAssign,({eexpr = TLocal v0} as e1), ({eexpr = TCall({eexpr = TConst (TString "phi")} as ephi,el)} as ecall)) -> let el = List.map2 (fun e inc -> let bb_pred = inc.cfg_from in if bb_pred != edge.cfg_from then e else match e.eexpr with | TLocal v -> let v' = local ctx e v edge.cfg_from in add_ssa_edge ctx.graph v' bb true i; {e with eexpr = TLocal v'} | _ -> assert false ) el edge.cfg_to.bb_incoming in let ephi = {ecall with eexpr = TCall(ephi,el)} in set_var_value ctx.graph v0 bb true i; {e with eexpr = TBinop(OpAssign,e1,ephi)} | _ -> Type.map_expr (loop i) e in dynarray_mapi loop bb.bb_phi let rec rename_in_block ctx bb = let write_var v is_phi i = update_reaching_def ctx v bb; let v' = alloc_var (v.v_name) v.v_type v.v_pos in declare_var ctx.graph v' bb; v'.v_meta <- v.v_meta; v'.v_capture <- v.v_capture; add_var_def ctx.graph bb v'; set_reaching_def ctx.graph v' (get_reaching_def ctx.graph v); set_reaching_def ctx.graph v (Some v'); set_var_value ctx.graph v' bb is_phi i; add_var_origin ctx.graph v' v; v' in let rec loop is_phi i e = match e.eexpr with | TLocal v when not (is_unbound v) -> let v' = local ctx e v bb in add_ssa_edge ctx.graph v' bb is_phi i; {e with eexpr = TLocal v'} | TVar(v,Some e1) when not (is_unbound v) -> let e1 = (loop is_phi i) e1 in let v' = write_var v is_phi i in {e with eexpr = TVar(v',Some e1)} | TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) when not (is_unbound v) -> let e2 = (loop is_phi i) e2 in let v' = write_var v is_phi i in {e with eexpr = TBinop(OpAssign,{e1 with eexpr = TLocal v'},e2)}; | TCall({eexpr = TConst (TString "phi")},_) -> e | _ -> Type.map_expr (loop is_phi i) e in dynarray_mapi (loop true) bb.bb_phi; dynarray_mapi (loop false) bb.bb_el; List.iter (update_phi ctx) bb.bb_outgoing; List.iter (rename_in_block ctx) bb.bb_dominated let apply ctx = Graph.infer_dominance_frontier ctx.graph; insert_phi ctx; rename_in_block ctx ctx.graph.g_root end module type DataFlowApi = sig type t val flag : BasicBlock.cfg_edge_Flag val transfer : analyzer_context -> BasicBlock.t -> texpr -> t (* The transfer function *) val equals : t -> t -> bool (* The equality function *) val bottom : t (* The bottom element of the lattice *) val top : t (* The top element of the lattice *) val get_cell : int -> t (* Lattice cell getter *) val set_cell : int -> t -> unit (* Lattice cell setter *) val init : analyzer_context -> unit (* The initialization function which is called at the start *) val commit : analyzer_context -> unit (* The commit function which is called at the end *) val conditional : bool (* Whether or not conditional branches are checked *) end (* DataFlow provides a framework for data flow analysis. It follows CFG edges from the root of the graph and visits the expressions and SSA-phi expressions of blocks on its way. If such an expression assigns to a variable (TVar or TBinop(OpAsssign)), all uses of that variable are checked by following the variable's SSA edges. A conditional branch edge (CFGCondBranch and CFGCondElse) is only followed if the available information suggests that it might be executable. This causes information from dead branches to not be taken into account. For SSA-phi nodes, only those incoming edges which are considered to be executable are processed. The algorithm continues until no further changes occur. *) module DataFlow (M : DataFlowApi) = struct open Graph open BasicBlock let get_ssa_edges_from g v = (get_var_info g v).vi_ssa_edges let run ctx = let g = ctx.graph in let ssa_work_list = ref [] in let cfg_work_list = ref g.g_root.bb_outgoing in let add_ssa_edge edge = ssa_work_list := edge :: !ssa_work_list in let add_cfg_edge edge = cfg_work_list := edge :: !cfg_work_list in let visit_phi bb v el = let el = List.fold_left2 (fun acc e edge -> if has_flag edge M.flag then e :: acc else acc ) [] el bb.bb_incoming in let el = List.map (fun e -> M.transfer ctx bb e) el in match el with | e1 :: el when List.for_all (M.equals e1) el -> e1; | _ -> M.bottom; in let set_lattice_cell v e = let e' = M.get_cell v.v_id in M.set_cell v.v_id e; if not (M.equals e e') then List.iter (fun edge -> add_ssa_edge edge) (get_ssa_edges_from g v); in let visit_assignment bb v e = match e.eexpr with | TCall({eexpr = TConst (TString "phi")},el) -> set_lattice_cell v (visit_phi bb v el) | _ -> if List.exists (fun edge -> has_flag edge M.flag) bb.bb_incoming then set_lattice_cell v (M.transfer ctx bb e) in let visit_expression bb e = match e.eexpr with | TBinop(OpAssign,{eexpr = TLocal v},e2) | TVar(v,Some e2) -> visit_assignment bb v e2; false | TMeta((Meta.Custom ":cond-branch",_,_),e1) when M.conditional -> let e1 = M.transfer ctx bb e1 in let edges = if e1 == M.bottom || e1 == M.top then bb.bb_outgoing else begin let rec loop yes maybe also edges = match edges with | edge :: edges -> begin match edge.cfg_kind with | CFGCondBranch e -> let e = M.transfer ctx bb e in if M.equals e e1 then loop (edge :: yes) maybe also edges else loop yes maybe also edges | CFGCondElse -> loop yes (edge :: maybe) also edges | CFGGoto | CFGFunction | CFGMaybeThrow -> loop yes maybe (edge :: also) edges end | [] -> yes,maybe,also in let yes,maybe,also = loop [] [] [] bb.bb_outgoing in match yes,maybe with | [],[] -> bb.bb_outgoing | [],maybe -> maybe @ also | yes,_ -> yes @ also end in List.iter add_cfg_edge edges; true | _ -> false in let visit_expressions bb = let b = DynArray.fold_left (fun b e -> visit_expression bb e || b ) false bb.bb_el in if not b then List.iter add_cfg_edge bb.bb_outgoing in let visit_phis bb = DynArray.iter (fun e -> match e.eexpr with | TBinop(OpAssign,{eexpr = TLocal v},{eexpr = TCall({eexpr = TConst (TString "phi")},el)}) -> set_lattice_cell v (visit_phi bb v el) | _ -> assert false ) bb.bb_phi in let rec loop () = match !cfg_work_list,!ssa_work_list with | edge :: edges,_ -> cfg_work_list := edges; if not (has_flag edge M.flag) then begin edge.cfg_flags <- M.flag :: edge.cfg_flags; visit_phis edge.cfg_to; let i = List.fold_left (fun i edge -> i + if has_flag edge M.flag then 1 else 0) 0 edge.cfg_to.bb_incoming in if i = 1 || edge.cfg_to == g.g_root then visit_expressions edge.cfg_to; begin match edge.cfg_to.bb_outgoing with | [edge] -> add_cfg_edge edge | _ -> () end end; loop(); | [],((bb,is_phi,i) :: edges) -> ssa_work_list := edges; let e = get_texpr bb is_phi i in ignore(visit_expression bb e); loop() | [],[] -> () in loop () let apply ctx = M.init ctx; run ctx; M.commit ctx end (* ConstPropagation implements sparse conditional constant propagation using the DataFlow algorithm. Its lattice consists of constants and enum values, but only the former are propagated. Enum values are treated as immutable data tuples and allow extracting constants, their index or other enum values. This module also deals with binop/unop optimization and standard API inlining. *) module ConstPropagation = DataFlow(struct open BasicBlock type t = | Top | Bottom | Const of tconstant | EnumValue of int * t list let conditional = true let flag = FlagExecutable let lattice = Hashtbl.create 0 let get_cell i = try Hashtbl.find lattice i with Not_found -> Top let set_cell i ct = Hashtbl.replace lattice i ct let top = Top let bottom = Bottom let equals lat1 lat2 = match lat1,lat2 with | Top,Top | Bottom,Bottom -> true | Const ct1,Const ct2 -> ct1 = ct2 | EnumValue(i1,_),EnumValue(i2,_) -> i1 = i2 | _ -> false let transfer ctx bb e = let rec eval bb e = let wrap = function | Const ct -> mk (TConst ct) t_dynamic null_pos | _ -> raise Exit in let unwrap e = match e.eexpr with | TConst ct -> Const ct | _ -> raise Exit in match e.eexpr with | TConst (TSuper | TThis | TNull) -> Bottom | TConst ct -> Const ct | TLocal v -> if is_unbound v || (follow v.v_type) == t_dynamic || v.v_capture then Bottom else get_cell v.v_id | TBinop(OpAssign,_,e2) -> eval bb e2 | TBinop(op,e1,e2) -> let cl1 = eval bb e1 in let cl2 = eval bb e2 in let e1 = wrap cl1 in let e2 = wrap cl2 in let e = {e with eexpr = TBinop(op,e1,e2)} in let e' = optimize_binop e op e1 e2 in if e != e' then eval bb e' else unwrap e' | TUnop(op,flag,e1) -> let cl1 = eval bb e1 in let e1 = wrap cl1 in let e = {e with eexpr = TUnop(op,flag,e1)} in let e' = optimize_unop e op flag e1 in if e != e' then eval bb e' else unwrap e' | TField(_,FEnum(_,ef)) -> EnumValue(ef.ef_index,[]) | TCall({eexpr = TField(_,FEnum(_,ef))},el) -> let cll = List.map (fun e -> try eval bb e with Exit -> Bottom) el in EnumValue(ef.ef_index,cll) | TEnumParameter(e1,_,i) -> begin match eval bb e1 with | EnumValue(_,el) -> (try List.nth el i with Failure _ -> raise Exit) | _ -> raise Exit end; | TCall ({ eexpr = TField (_,FStatic(c,cf))},el) -> let el = List.map (eval bb) el in let el = List.map wrap el in begin match Optimizer.api_inline2 ctx.com c cf.cf_name el e.epos with | None -> raise Exit | Some e -> eval bb e end | TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) -> eval bb e1 | _ -> let e1 = match ctx.com.platform,e.eexpr with | Js,TArray(e1,{eexpr = TConst(TInt i)}) when Int32.to_int i = 1 -> e1 | Cpp,TCall({eexpr = TField(e1,FDynamic "__Index")},[]) -> e1 | Neko,TField(e1,FDynamic "index") -> e1 | _ -> raise Exit in begin match follow e1.etype,eval bb e1 with | TEnum _,EnumValue(i,_) -> Const (TInt (Int32.of_int i)) | _ -> raise Exit end in try eval bb e with Exit -> Bottom let init ctx = Hashtbl.clear lattice let commit ctx = let inline e i = match get_cell i with | Top | Bottom | EnumValue _ -> raise Not_found | Const ct -> let e' = Codegen.type_constant ctx.com (tconst_to_const ct) e.epos in if not (type_change_ok ctx.com e'.etype e.etype) then raise Not_found; e' in let is_special_var v = v.v_capture || is_asvar_type v.v_type in let rec commit e = match e.eexpr with | TLocal v when not (is_special_var v) -> begin try inline e v.v_id with Not_found -> e end | TBinop((OpAssign | OpAssignOp _ as op),({eexpr = TLocal v} as e1),e2) -> let e2 = try if (has_side_effect e2) then raise Not_found; inline e2 v.v_id with Not_found -> commit e2 in {e with eexpr = TBinop(op,e1,e2)} | TVar(v,Some e1) when not (has_side_effect e1) -> let e1 = try inline e1 v.v_id with Not_found -> commit e1 in {e with eexpr = TVar(v,Some e1)} | _ -> Type.map_expr commit e in Graph.iter_dom_tree ctx.graph (fun bb -> if not (List.exists (fun edge -> has_flag edge FlagExecutable) bb.bb_incoming) then bb.bb_dominator <- ctx.graph.Graph.g_unreachable; dynarray_map commit bb.bb_el ); end) (* Propagates local variables to other local variables. Respects scopes on targets where it matters (all except JS and As3). *) module CopyPropagation = DataFlow(struct open BasicBlock open Graph type t = | Top | Bottom | Local of tvar let to_string = function | Top -> "Top" | Bottom -> "Bottom" | Local v -> Printf.sprintf "%s<%i>" v.v_name v.v_id let conditional = false let flag = FlagCopyPropagation let lattice = Hashtbl.create 0 let get_cell i = try Hashtbl.find lattice i with Not_found -> Top let set_cell i ct = Hashtbl.replace lattice i ct let top = Top let bottom = Bottom let equals t1 t2 = match t1,t2 with | Top,Top -> true | Bottom,Bottom -> true | Local v1,Local v2 -> v1.v_id = v2.v_id | _ -> false let transfer ctx bb e = let rec loop e = match e.eexpr with | TLocal v when not v.v_capture -> Local v | TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) -> loop e1 | _ -> Bottom in loop e let init ctx = Hashtbl.clear lattice let commit ctx = let rec commit bb e = match e.eexpr with | TLocal v when not v.v_capture -> begin try let lat = get_cell v.v_id in let leave () = Hashtbl.remove lattice v.v_id; raise Not_found in let v' = match lat with Local v -> v | _ -> leave() in if not (type_change_ok ctx.com v'.v_type v.v_type) then leave(); let v'' = get_var_origin ctx.graph v' in (* This restriction is in place due to how we currently reconstruct the AST. Multiple SSA-vars may be turned back to the same origin var, which creates interference that is not tracked in the analysis. We address this by only considering variables whose origin-variables are assigned to at most once. *) let writes = (get_var_info ctx.graph v'').vi_writes in begin match writes with | [bb'] when in_scope bb bb' -> () | _ -> leave() end; commit bb {e with eexpr = TLocal v'} with Not_found -> e end | TBinop((OpAssign | OpAssignOp _ as op),({eexpr = TLocal _} as e1),e2) -> let e2 = commit bb e2 in {e with eexpr = TBinop(op,e1,e2)} | _ -> Type.map_expr (commit bb) e in Graph.iter_dom_tree ctx.graph (fun bb -> dynarray_map (commit bb) bb.bb_el ); end) (* LocalDce implements a mark & sweep dead code elimination. The mark phase follows the CFG edges of the graphs to find variable usages and marks variables accordingly. If ConstPropagation was run before, only CFG edges which are considered executable are processed. If a variable is marked as used, its reaching definition is recursively marked as used too. Furthermore its value is processed as an expression. The sweep phase removes all variable declarations and assignments of unused variables, keeping only the assigned expression in case of side-effects. *) module LocalDce = struct open BasicBlock open Graph open AnalyzerConfig let rec has_side_effect e = let rec loop e = match e.eexpr with | TConst _ | TLocal _ | TTypeExpr _ | TFunction _ -> () | TCall ({ eexpr = TField(_,FStatic({ cl_path = ([],"Std") },{ cf_name = "string" })) },args) -> Type.iter loop e | TCall ({eexpr = TField(_,FEnum _)},_) -> Type.iter loop e | TCall ({eexpr = TConst (TString ("phi" | "fun"))},_) -> () | TCall({eexpr = TField(e1,fa)},el) when PurityState.is_pure_field_access fa -> loop e1; List.iter loop el | 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 let rec apply ctx = let is_used v = Meta.has Meta.Used v.v_meta in let keep v = is_used v || (not (Meta.has Meta.CompilerGenerated v.v_meta) && not ctx.config.local_dce) || is_ref_type v.v_type || v.v_capture || Meta.has Meta.This v.v_meta in let rec use v = if not (is_used v) then begin v.v_meta <- (Meta.Used,[],null_pos) :: v.v_meta; (try expr (get_var_value ctx.graph v) with Not_found -> ()); begin match Ssa.get_reaching_def ctx.graph v with | None -> use (get_var_origin ctx.graph v) | Some v -> use v; end end and expr e = match e.eexpr with | TLocal v when not (is_unbound v) -> use v; | TBinop(OpAssign,{eexpr = TLocal v},e1) | TVar(v,Some e1) when not (is_unbound v) -> if has_side_effect e1 || keep v then expr e1 else () | _ -> Type.iter expr e in let bb_marked = ref [] in let rec mark bb = bb_marked := bb :: !bb_marked; DynArray.iter expr bb.bb_el; DynArray.iter expr bb.bb_phi; List.iter (fun edge -> if not (has_flag edge FlagDce) then begin edge.cfg_flags <- FlagDce :: edge.cfg_flags; if not ctx.config.const_propagation || has_flag edge FlagExecutable then mark edge.cfg_from; end ) bb.bb_incoming in mark ctx.graph.g_exit; let rec sweep e = match e.eexpr with | TBinop(OpAssign,{eexpr = TLocal v},e2) | TVar(v,Some e2) when not (keep v) -> if has_side_effect e2 then e2 else mk (TConst TNull) e.etype e.epos | TVar(v,None) when not (keep v) -> mk (TConst TNull) e.etype e.epos | _ -> Type.map_expr sweep e in List.iter (fun bb -> dynarray_map sweep bb.bb_el ) !bb_marked; end module Debug = struct open BasicBlock open Graph type node_info = | NIExpr | NIVars | NIPhi | NILoopGroups | NIScopes let s_var v = Printf.sprintf "%s<%i>" v.v_name v.v_id let dot_debug_node g ch nil bb = let s = Printf.sprintf "(%i)" bb.bb_id in let s = List.fold_left (fun s ni -> s ^ match ni with | NIExpr -> if DynArray.length bb.bb_el = 0 then "" else "\n" ^ String.concat "\n" (DynArray.to_list (DynArray.map s_expr_pretty bb.bb_el)) | NIPhi -> if DynArray.length bb.bb_phi = 0 then "" else "\n" ^ String.concat "\n" (DynArray.to_list (DynArray.map (fun e -> s_expr_pretty e) bb.bb_phi)) | NIVars -> if bb.bb_var_writes = [] then "" else "\n" ^ String.concat ", " (List.map (fun v -> s_var v) bb.bb_var_writes) | NILoopGroups -> if bb.bb_loop_groups = [] then "" else "\nLoops: " ^ (String.concat ", " (List.map string_of_int bb.bb_loop_groups)) | NIScopes -> if bb.bb_scopes = [] then "" else "\nScopes: " ^ (String.concat ", " (List.map string_of_int bb.bb_scopes)) ) s nil in let s_kind = match bb.bb_kind with | BKRoot -> "\n" | BKFunctionBegin _ -> "\n" | BKFunctionEnd -> "\n" | BKLoopHead -> "\n" | _ -> "" in Printf.fprintf ch "n%i [shape=box,label=\"%s%s\"];\n" bb.bb_id s_kind (s_escape s) let dot_debug_cfg_edge ch edge = let label = match edge.cfg_kind with | CFGGoto -> "goto" | CFGFunction -> "function" | CFGMaybeThrow -> "throw?" | CFGCondBranch _ -> "branch" | CFGCondElse -> "else" in let s_edge_flag = function | FlagExecutable -> "exe" | FlagDce -> "dce" | FlagCopyPropagation -> "copy" in let label = label ^ match edge.cfg_flags with | [] -> "" | _ -> Printf.sprintf " [%s]" (String.concat ", " (List.map s_edge_flag edge.cfg_flags)) in Printf.fprintf ch "n%i -> n%i[label=\"%s\"];\n" edge.cfg_from.bb_id edge.cfg_to.bb_id (s_escape label) let dot_debug_syntax_edge ch bb se = let edge bb' label = Printf.fprintf ch "n%i -> n%i[style=\"dashed\",color=\"gray\",label=\"%s\"];\n" bb.bb_id bb'.bb_id label; in match se with | SESubBlock(bb_sub,bb_next) -> edge bb_sub "sub"; edge bb_next "next"; | SEIfThen(bb_then,bb_next,_) -> edge bb_then "then"; edge bb_next "next" | SEIfThenElse(bb_then,bb_else,bb_next,_,_) -> edge bb_then "then"; edge bb_else "else"; edge bb_next "next"; | SEWhile(bb_head,bb_body,bb_next) -> edge bb_head "loop-head"; edge bb_body "loop-body"; edge bb_next "next"; | SEMerge bb_next -> edge bb_next "merge" | SESwitch(bbl,bo,bb_next,_) -> List.iter (fun (el,bb) -> edge bb ("case " ^ (String.concat " | " (List.map s_expr_pretty el)))) bbl; (match bo with None -> () | Some bb -> edge bb "default"); edge bb_next "next"; | SETry(bb_try,_,bbl,bb_next,_) -> edge bb_try "try"; List.iter (fun (_,bb_catch) -> edge bb_catch "catch") bbl; edge bb_next "next"; | SEEnd -> () | SENone -> () let htmlescape s = let s = String.concat "&" (ExtString.String.nsplit s "&") in let s = String.concat "<" (ExtString.String.nsplit s "<") in let s = String.concat ">" (ExtString.String.nsplit s ">") in s let generate_cfg_ssa ch g = Printf.fprintf ch "\tnode [shape=plaintext];\n"; let expr_name b i = Printf.sprintf "e%s%i" (if b then "p" else "") i in List.iter (fun bb -> Printf.fprintf ch "n%i[label=<\n\t\n" bb.bb_id bb.bb_id (BasicBlock.s_block_kind bb.bb_kind); let s_expr b i e = Printf.fprintf ch "\t\n" (expr_name b i) (s_escape (htmlescape (s_expr_pretty e))) in DynArray.iteri (s_expr true) bb.bb_phi; DynArray.iteri (s_expr false) bb.bb_el; Printf.fprintf ch "\t\n
(%i) %s
%s
>];\n"; ) g.g_nodes; Graph.iter_edges g (fun edge -> Printf.fprintf ch "n%i:out -> n%i:in[label=\"%s\"];\n" edge.cfg_from.bb_id edge.cfg_to.bb_id (BasicBlock.s_cfg_edge_kind edge.cfg_kind) ); DynArray.iter (fun vi -> begin try let (bb,is_phi,i) = match vi.vi_value with None -> raise Not_found | Some i -> i in let n1 = Printf.sprintf "n%i:%s" bb.bb_id (expr_name is_phi i) in List.iter (fun (bb',is_phi',i') -> if bb != bb' then begin (* intra-node edges look stupid in dot *) let n2 = Printf.sprintf "n%i:%s" bb'.bb_id (expr_name is_phi' i') in Printf.fprintf ch "%s -> %s[color=lightblue,constraint=false];\n" n1 n2; end ) vi.vi_ssa_edges; with Not_found -> () end ) g.g_var_infos let get_dump_path ctx c cf = "dump" :: [platform_name ctx.com.platform] @ (fst c.cl_path) @ [Printf.sprintf "%s.%s" (snd c.cl_path) cf.cf_name] let dot_debug ctx c cf = let g = ctx.graph in let start_graph ?(graph_config=[]) suffix = let ch = Codegen.Dump.create_file suffix [] (get_dump_path ctx c cf) in Printf.fprintf ch "digraph graphname {\n"; List.iter (fun s -> Printf.fprintf ch "%s;\n" s) graph_config; ch,(fun () -> Printf.fprintf ch "}\n"; close_out ch ) in let ch,f = start_graph "-cfg.dot" in List.iter (fun bb -> dot_debug_node g ch [NILoopGroups;NIScopes;NIPhi;NIExpr] bb) g.g_nodes; Graph.iter_edges g (dot_debug_cfg_edge ch); f(); let ch,f = start_graph "-cfg-ssa.dot" in generate_cfg_ssa ch g; f(); let ch,f = start_graph "-dj.dot" in List.iter (fun bb -> dot_debug_node g ch [] bb; List.iter (fun einc -> let bb' = einc.cfg_from in let style = if bb' == bb.bb_dominator then "solid" else "dashed" in Printf.fprintf ch "n%i -> n%i[style=\"%s\"];\n" bb'.bb_id bb.bb_id style; ) bb.bb_incoming; ) g.g_nodes; f(); let ch,f = start_graph "-df.dot" in List.iter (fun bb -> dot_debug_node g ch [NIVars] bb; List.iter (fun bb' -> Printf.fprintf ch "n%i -> n%i;\n" bb.bb_id bb'.bb_id) bb.bb_df; ) g.g_nodes; f(); let ch,f = start_graph "-dom.dot" in List.iter (fun bb -> dot_debug_node g ch [NIVars] bb; List.iter (fun bb' -> Printf.fprintf ch "n%i -> n%i;\n" bb.bb_id bb'.bb_id) bb.bb_dominated; ) g.g_nodes; f(); let ch,f = start_graph "-syntax.dot" in List.iter (fun bb -> dot_debug_node g ch [NIExpr] bb; dot_debug_syntax_edge ch bb bb.bb_syntax_edge ) g.g_nodes; f(); let ch,f = start_graph "-ssa-edges.dot" in let nodes = ref PMap.empty in let node_name bb is_phi i = Printf.sprintf "e%i_%b_%i" bb.bb_id is_phi i in let node_name2 bb is_phi i = let n = node_name bb is_phi i in nodes := PMap.add n true !nodes; n in DynArray.iter (fun vi -> begin try let (bb,is_phi,i) = match vi.vi_value with None -> raise Not_found | Some i -> i in let n1 = node_name2 bb is_phi i in List.iter (fun (bb',is_phi',i') -> let n2 = node_name2 bb' is_phi' i' in Printf.fprintf ch "%s -> %s;\n" n1 n2 ) vi.vi_ssa_edges with Not_found -> () end ) g.g_var_infos; List.iter (fun bb -> let f is_phi acc i e = let n = node_name bb is_phi i in (i + 1),if PMap.mem n !nodes then (n,s_expr_pretty e) :: acc else acc in let _,active_nodes = DynArray.fold_left (fun (i,acc) -> f true acc i) (0,[]) bb.bb_phi in let _,active_nodes = DynArray.fold_left (fun (i,acc) -> f false acc i) (0,active_nodes) bb.bb_el in if active_nodes <> [] then begin Printf.fprintf ch "subgraph cluster_%i {\n" bb.bb_id; Printf.fprintf ch "label=%i;\n" bb.bb_id; Printf.fprintf ch "style=filled;\n"; Printf.fprintf ch "color=lightblue;\n"; List.iter (fun (n,s) -> Printf.fprintf ch "%s[shape=box,label=\"%s\"];\n" n (s_escape s) ) active_nodes; Printf.fprintf ch "}\n"; end; ) g.g_nodes; f() end module Run = struct open AnalyzerConfig open Graph let with_timer detailed s f = let timer = timer (if detailed then "analyzer" :: s else ["analyzer"]) in let r = f() in timer(); r let create_analyzer_context com config e = let g = Graph.create e.etype e.epos in let ctx = { com = com; config = config; graph = g; (* For CPP we want to use variable names which are "probably" not used by users in order to avoid problems with the debugger, see https://github.com/HaxeFoundation/hxcpp/issues/365 *) temp_var_name = (match com.platform with Cpp -> "_hx_tmp" | _ -> "tmp"); entry = g.g_unreachable; has_unbound = false; loop_counter = 0; loop_stack = []; debug_exprs = []; name_stack = []; } in ctx let add_debug_expr ctx s e = ctx.debug_exprs <- (s,e) :: ctx.debug_exprs let there actx e = if actx.com.debug then add_debug_expr actx "initial" e; let e = with_timer actx.config.detail_times ["->";"var-lazifier"] (fun () -> VarLazifier.apply actx.com e) in if actx.com.debug then add_debug_expr actx "after var-lazifier" e; let e = with_timer actx.config.detail_times ["->";"filter-apply"] (fun () -> TexprFilter.apply actx.com e) in if actx.com.debug then add_debug_expr actx "after filter-apply" e; let tf,t,is_real_function = match e.eexpr with | TFunction tf -> tf,e.etype,true | _ -> (* Wrap expression in a function so we don't have to treat it as a special case throughout. *) let e = mk (TReturn (Some e)) t_dynamic e.epos in let tf = { tf_args = []; tf_type = e.etype; tf_expr = e; } in tf,tfun [] e.etype,false in with_timer actx.config.detail_times ["->";"from-texpr"] (fun () -> AnalyzerTexprTransformer.from_tfunction actx tf t e.epos); is_real_function let back_again actx is_real_function = let e = with_timer actx.config.detail_times ["<-";"to-texpr"] (fun () -> AnalyzerTexprTransformer.to_texpr actx) in if actx.com.debug then add_debug_expr actx "after to-texpr" e; DynArray.iter (fun vi -> vi.vi_var.v_extra <- vi.vi_extra; ) actx.graph.g_var_infos; let e = if actx.config.fusion then with_timer actx.config.detail_times ["<-";"fusion"] (fun () -> Fusion.apply actx.com actx.config e) else e in if actx.com.debug then add_debug_expr actx "after fusion" e; let e = with_timer actx.config.detail_times ["<-";"cleanup"] (fun () -> Cleanup.apply actx.com e) in if actx.com.debug then add_debug_expr actx "after cleanup" e; let e = if is_real_function then e else begin (* Get rid of the wrapping function and its return expressions. *) let rec loop first e = match e.eexpr with | TReturn (Some e) -> e | TFunction tf when first -> begin match loop false tf.tf_expr with | {eexpr = TBlock _ | TIf _ | TSwitch _ | TTry _} when actx.com.platform = Cpp || actx.com.platform = Hl -> mk (TCall(e,[])) tf.tf_type e.epos | e -> e end | TBlock [e] -> loop first e | TFunction _ -> e | _ -> Type.map_expr (loop first) e in loop true e end in e let run_on_expr actx e = let is_real_function = there actx e in with_timer actx.config.detail_times ["->";"idom"] (fun () -> Graph.infer_immediate_dominators actx.graph); with_timer actx.config.detail_times ["->";"infer_scopes"] (fun () -> Graph.infer_scopes actx.graph); with_timer actx.config.detail_times ["->";"var writes"] (fun () -> Graph.infer_var_writes actx.graph); if actx.com.debug then Graph.check_integrity actx.graph; if actx.config.optimize && not actx.has_unbound then begin with_timer actx.config.detail_times ["optimize";"ssa-apply"] (fun () -> Ssa.apply actx); if actx.config.const_propagation then with_timer actx.config.detail_times ["optimize";"const-propagation"] (fun () -> ConstPropagation.apply actx); if actx.config.copy_propagation then with_timer actx.config.detail_times ["optimize";"copy-propagation"] (fun () -> CopyPropagation.apply actx); with_timer actx.config.detail_times ["optimize";"local-dce"] (fun () -> LocalDce.apply actx); end; back_again actx is_real_function let rec reduce_control_flow ctx e = let e = Type.map_expr (reduce_control_flow ctx) e in Optimizer.reduce_control_flow ctx e let run_on_field ctx config c cf = match cf.cf_expr with | Some e when not (is_ignored cf.cf_meta) && not (Typecore.is_removable_field ctx cf) -> let config = update_config_from_meta ctx.Typecore.com config cf.cf_meta in (match e.eexpr with TFunction tf -> cf.cf_expr_unoptimized <- Some tf | _ -> ()); let actx = create_analyzer_context ctx.Typecore.com config e in let debug() = print_endline (Printf.sprintf "While analyzing %s.%s" (s_type_path c.cl_path) cf.cf_name); List.iter (fun (s,e) -> print_endline (Printf.sprintf "<%s>" s); print_endline (Type.s_expr_pretty true "" false (s_type (print_context())) e); print_endline (Printf.sprintf "" s); ) (List.rev actx.debug_exprs); Debug.dot_debug actx c cf; print_endline (Printf.sprintf "dot graph written to %s" (String.concat "/" (Debug.get_dump_path actx c cf))); in let e = try run_on_expr actx e with | Error.Error _ | Abort _ as exc -> raise exc | exc -> debug(); raise exc in let e = reduce_control_flow ctx e in begin match config.debug_kind with | DebugNone -> () | DebugDot -> Debug.dot_debug actx c cf; | DebugFull -> debug() end; cf.cf_expr <- Some e; | _ -> () let run_on_class ctx config c = let config = update_config_from_meta ctx.Typecore.com config c.cl_meta in let process_field stat cf = match cf.cf_kind with | Var _ when not stat -> () | _ -> run_on_field ctx config c cf in List.iter (process_field false) c.cl_ordered_fields; List.iter (process_field true) c.cl_ordered_statics; begin match c.cl_constructor with | None -> () | Some f -> process_field false f; end; begin match c.cl_init with | None -> () | Some e -> let tf = { tf_args = []; tf_type = e.etype; tf_expr = e; } in let e = mk (TFunction tf) (tfun [] e.etype) e.epos in let actx = create_analyzer_context ctx.Typecore.com {config with optimize = false} e in let e = run_on_expr actx e in let e = match e.eexpr with | TFunction tf -> tf.tf_expr | _ -> assert false in c.cl_init <- Some e end 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.Typecore.com in let config = get_base_config com in with_timer config.detail_times ["other"] (fun () -> let cfl = if config.optimize && config.purity_inference then with_timer config.detail_times ["optimize";"purity-inference"] (fun () -> Purity.infer com) else [] in List.iter (run_on_type ctx config) types; List.iter (fun cf -> cf.cf_meta <- List.filter (fun (m,_,_) -> m <> Meta.Pure) cf.cf_meta) cfl ) end ;; Typecore.analyzer_run_on_expr_ref := (fun com e -> let config = AnalyzerConfig.get_base_config com in (* We always want to optimize because const propagation might be required to obtain a constant expression for inline field initializations (see issue #4977). *) let config = {config with AnalyzerConfig.optimize = true} in let actx = Run.create_analyzer_context com config e in Run.run_on_expr actx e )haxe_3.4.4.orig/src/optimization/analyzerConfig.ml0000664000175000017500000001123013166552354022233 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Type open Common open Globals type debug_kind = | DebugNone | DebugDot | DebugFull type t = { optimize : bool; const_propagation : bool; copy_propagation : bool; local_dce : bool; fusion : bool; purity_inference : bool; debug_kind : debug_kind; detail_times : bool; user_var_fusion : bool; fusion_debug : bool; } let flag_optimize = "optimize" let flag_const_propagation = "const_propagation" let flag_copy_propagation = "copy_propagation" let flag_local_dce = "local_dce" let flag_fusion = "fusion" let flag_ignore = "ignore" let flag_dot_debug = "dot_debug" let flag_full_debug = "full_debug" let flag_user_var_fusion = "user_var_fusion" let flag_fusion_debug = "fusion_debug" let all_flags = List.fold_left (fun acc flag -> flag :: ("no_" ^ flag) :: acc ) [] [flag_optimize;flag_const_propagation;flag_copy_propagation;flag_local_dce;flag_fusion;flag_ignore;flag_dot_debug;flag_user_var_fusion] 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 = has_analyzer_option meta flag_ignore let get_base_config com = { optimize = Common.raw_defined com "analyzer-optimize"; const_propagation = not (Common.raw_defined com "analyzer-no-const-propagation"); copy_propagation = not (Common.raw_defined com "analyzer-no-copy-propagation"); local_dce = not (Common.raw_defined com "analyzer-no-local-dce"); fusion = not (Common.raw_defined com "analyzer-no-fusion"); purity_inference = not (Common.raw_defined com "analyzer-no-purity-inference"); debug_kind = DebugNone; detail_times = Common.raw_defined com "analyzer-times"; user_var_fusion = (match com.platform with Flash | Java -> false | _ -> true) && (Common.raw_defined com "analyzer-user-var-fusion" || (not com.debug && not (Common.raw_defined com "analyzer-no-user-var-fusion"))); fusion_debug = false; } let update_config_from_meta com 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) -> begin match s with | "optimize" -> { config with optimize = true } | "no_optimize" -> { config with optimize = false } | "const_propagation" -> { config with const_propagation = true } | "no_const_propagation" -> { config with const_propagation = false } | "copy_propagation" -> { config with copy_propagation = true } | "no_copy_propagation" -> { config with copy_propagation = false } | "local_dce" -> { config with local_dce = true } | "no_local_dce" -> { config with local_dce = false } | "fusion" -> { config with fusion = true } | "no_fusion" -> { config with fusion = false } | "user_var_fusion" -> { config with user_var_fusion = true } | "no_user_var_fusion" -> { config with user_var_fusion = false } | "dot_debug" -> { config with debug_kind = DebugDot } | "full_debug" -> { config with debug_kind = DebugFull } | "fusion_debug" -> { config with fusion_debug = true } | "as_var" -> config | _ -> com.warning (StringError.string_error s all_flags ("Unrecognized analyzer option: " ^ s)) (pos e); config end | _ -> let s = Ast.s_expr e in com.warning (StringError.string_error s all_flags ("Unrecognized analyzer option: " ^ s)) (pos e); config ) config el | (Meta.HasUntyped,_,_) -> {config with optimize = false} | _ -> config ) config meta let get_class_config com c = let config = get_base_config com in update_config_from_meta com config c.cl_meta let get_field_config com c cf = let config = get_class_config com c in update_config_from_meta com config cf.cf_metahaxe_3.4.4.orig/src/optimization/analyzerTexpr.ml0000664000175000017500000011634013166552354022140 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Type open Common open OptimizerTexpr open Globals let s_expr_pretty e = s_expr_pretty false "" false (s_type (print_context())) e let rec is_true_expr e1 = match e1.eexpr with | TConst(TBool true) -> true | TParenthesis e1 -> is_true_expr e1 | _ -> false let is_stack_allocated c = Meta.has Meta.StructAccess c.cl_meta let map_values ?(allow_control_flow=true) f e = let branching = ref false in let efinal = ref None in let f e = if !branching then f e else begin efinal := Some e; mk (TConst TNull) e.etype e.epos end in let rec loop complex e = match e.eexpr with | TIf(e1,e2,Some e3) -> branching := true; let e2 = loop true e2 in let e3 = loop true e3 in {e with eexpr = TIf(e1,e2,Some e3)} | TSwitch(e1,cases,edef) -> branching := true; let cases = List.map (fun (el,e) -> el,loop true e) cases in let edef = Option.map (loop true) edef in {e with eexpr = TSwitch(e1,cases,edef)} | TBlock [e1] -> loop complex e1 | TBlock el -> begin match List.rev el with | e1 :: el -> let e1 = loop true e1 in let e = {e with eexpr = TBlock (List.rev (e1 :: el))} in {e with eexpr = TMeta((Meta.MergeBlock,[],e.epos),e)} | [] -> f e end | TTry(e1,catches) -> branching := true; let e1 = loop true e1 in let catches = List.map (fun (v,e) -> v,loop true e) catches in {e with eexpr = TTry(e1,catches)} | TMeta(m,e1) -> {e with eexpr = TMeta(m,loop complex e1)} | TParenthesis e1 -> {e with eexpr = TParenthesis (loop complex e1)} | TBreak | TContinue | TThrow _ | TReturn _ -> if not allow_control_flow then raise Exit; e | _ -> if not complex then raise Exit; f e in let e = loop false e in e,!efinal let can_throw e = let rec loop e = match e.eexpr with | TConst _ | TLocal _ | TTypeExpr _ | TFunction _ | TBlock _ -> () | TCall _ | TNew _ | TThrow _ | TCast(_,Some _) -> raise Exit | TField _ | TArray _ -> raise Exit (* sigh *) | _ -> Type.iter loop e in try loop e; false with Exit -> true let rec can_be_inlined e = match e.eexpr with | TConst _ -> true | TParenthesis e1 | TMeta(_,e1) -> can_be_inlined e1 | _ -> false let target_handles_unops com = match com.platform with | Lua | Python -> false | _ -> true let target_handles_assign_ops com = match com.platform with (* Technically PHP can handle assign ops, but unfortunately x += y is not always equivalent to x = x + y in case y has side-effects. *) | Lua | Php -> false | Cpp when not (Common.defined com Define.Cppia) -> false | _ -> true let target_handles_side_effect_order com = match com.platform with | Cpp -> Common.defined com Define.Cppia | Php -> false | _ -> true let rec can_be_used_as_value com e = let rec loop e = match e.eexpr with | TBlock [e] -> loop e | TBlock _ | TSwitch _ | TTry _ -> raise Exit | TCall({eexpr = TConst (TString "phi")},_) -> raise Exit (* | TCall _ | TNew _ when (match com.platform with Cpp | Php -> true | _ -> false) -> raise Exit *) | TReturn _ | TThrow _ | TBreak | TContinue -> raise Exit | TUnop((Increment | Decrement),_,_) when not (target_handles_unops com) -> raise Exit | TNew _ when com.platform = Php && not (Common.is_php7 com) -> raise Exit | TFunction _ -> () | _ -> Type.iter loop e in try begin match com.platform,e.eexpr with | (Cs | Cpp | Java | Flash | Lua),TConst TNull -> raise Exit | _ -> () end; loop e; true with Exit -> false let wrap_meta s e = mk (TMeta((Meta.Custom s,[],e.epos),e)) e.etype e.epos let is_really_unbound v = match v.v_name with | "`trace" | "__int__" -> false | _ -> is_unbound v let r = Str.regexp "^\\([A-Za-z0-9_]\\)+$" let is_unbound_call_that_might_have_side_effects v el = match v.v_name,el with | "__js__",[{eexpr = TConst (TString s)}] when Str.string_match r s 0 -> false | _ -> true let is_ref_type = function | TType({t_path = ["cs"],("Ref" | "Out")},_) -> true | TType({t_path = path},_) when path = Genphp7.ref_type_path -> true | TType({t_path = ["cpp"],("Reference")},_) -> true | TAbstract({a_path=["hl";"types"],"Ref"},_) -> true | _ -> false let rec is_asvar_type t = let check meta = AnalyzerConfig.has_analyzer_option meta "as_var" in match t with | TInst(c,_) -> check c.cl_meta | TEnum(en,_) -> check en.e_meta | TType(t,tl) -> check t.t_meta || (is_asvar_type (apply_params t.t_params tl t.t_type)) | TAbstract(a,_) -> check a.a_meta | TLazy f -> is_asvar_type (!f()) | TMono r -> (match !r with | Some t -> is_asvar_type t | _ -> false) | _ -> false let type_change_ok com t1 t2 = if t1 == t2 then true else begin let rec map t = match t with | TMono r -> (match !r with None -> t_dynamic | Some t -> map t) | _ -> Type.map map t in let t1 = map t1 in let t2 = map t2 in let rec is_nullable_or_whatever = function | TMono r -> (match !r with None -> false | Some t -> is_nullable_or_whatever t) | TType ({ t_path = ([],"Null") },[_]) -> true | TLazy f -> is_nullable_or_whatever (!f()) | TType (t,tl) -> is_nullable_or_whatever (apply_params t.t_params tl t.t_type) | TFun _ -> false | TInst ({ cl_kind = KTypeParameter _ },_) -> false | TAbstract (a,_) when Meta.has Meta.CoreType a.a_meta -> not (Meta.has Meta.NotNull a.a_meta) | TAbstract (a,tl) -> not (Meta.has Meta.NotNull a.a_meta) && is_nullable_or_whatever (apply_params a.a_params tl a.a_this) | _ -> true in (* Check equality again to cover cases where TMono became t_dynamic *) t1 == t2 || match follow t1,follow t2 with | TDynamic _,_ | _,TDynamic _ -> false | _ -> if com.config.pf_static && is_nullable_or_whatever t1 <> is_nullable_or_whatever t2 then false else type_iseq t1 t2 end let dynarray_map f d = DynArray.iteri (fun i e -> DynArray.unsafe_set d i (f e)) d let dynarray_mapi f d = DynArray.iteri (fun i e -> DynArray.unsafe_set d i (f i e)) d (* This module rewrites some expressions to reduce the amount of special cases for subsequent analysis. After analysis it restores some of these expressions back to their original form. The following expressions are removed from the AST after `apply` has run: - OpBoolAnd and OpBoolOr binary operations are rewritten to TIf - OpAssignOp on a variable is rewritten to OpAssign - Prefix increment/decrement operations are rewritten to OpAssign - Postfix increment/decrement operations are rewritten to a TBlock with OpAssign and OpAdd/OpSub - `do {} while(true)` is rewritten to `while(true) {}` - TWhile expressions are rewritten to `while (true)` with appropriate conditional TBreak - TFor is rewritten to TWhile *) module TexprFilter = struct let apply com e = let rec loop e = match e.eexpr with | TBinop(OpBoolAnd | OpBoolOr as op,e1,e2) -> let e_then = e2 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)) e.etype e.epos) | TBinop(OpAssignOp op,({eexpr = TLocal _} as e1),e2) -> let e = {e with eexpr = TBinop(op,e1,e2)} in loop {e with eexpr = TBinop(OpAssign,e1,e)} | TUnop((Increment | Decrement as op),flag,({eexpr = TLocal _} as e1)) -> let e_one = mk (TConst (TInt (Int32.of_int 1))) com.basic.tint e1.epos in let e = {e with eexpr = TBinop(OpAssignOp (if op = Increment then OpAdd else OpSub),e1,e_one)} in let e = if flag = Prefix then e else mk (TBlock [ {e with eexpr = TBinop(OpAssignOp (if op = Increment then OpAdd else OpSub),e1,e_one)}; {e with eexpr = TBinop((if op = Increment then OpSub else OpAdd),e1,e_one)}; ]) e.etype e.epos in loop e | TWhile(e1,e2,DoWhile) when is_true_expr e1 -> loop {e with eexpr = TWhile(e1,e2,NormalWhile)} | TWhile(e1,e2,flag) when not (is_true_expr e1) -> 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 -> Texpr.duplicate_tvars (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_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 e = Codegen.for_remap com v e1 e2 e.epos in loop e | _ -> Type.map_expr loop e in loop e end module VarLazifier = struct let apply com e = let rec loop var_inits e = match e.eexpr with | TVar(v,Some e1) when (Meta.has (Meta.Custom ":extractorVariable") v.v_meta) -> let var_inits,e1 = loop var_inits e1 in let var_inits = PMap.add v.v_id e1 var_inits in var_inits,{e with eexpr = TVar(v,None)} | TLocal v -> begin try let e_init = PMap.find v.v_id var_inits in let e = {e with eexpr = TBinop(OpAssign,e,e_init)} in let e = {e with eexpr = TParenthesis e} in let var_inits = PMap.remove v.v_id var_inits in var_inits,e with Not_found -> var_inits,e end | TIf(e1,e2,eo) -> let var_inits,e1 = loop var_inits e1 in let _,e2 = loop var_inits e2 in let eo = match eo with None -> None | Some e -> Some (snd (loop var_inits e)) in var_inits,{e with eexpr = TIf(e1,e2,eo)} | TSwitch(e1,cases,edef) -> let var_inits,e1 = loop var_inits e1 in let cases = List.map (fun (el,e) -> let _,e = loop var_inits e in el,e ) cases in let edef = match edef with None -> None | Some e -> Some (snd (loop var_inits e)) in var_inits,{e with eexpr = TSwitch(e1,cases,edef)} | _ -> Texpr.foldmap loop var_inits e in snd (loop PMap.empty e) end (* An InterferenceReport represents in which way a given code may be influenced and how it might influence other code itself. It keeps track of read and write operations for both variable and fields, as well as a generic state read and write. *) module InterferenceReport = struct type interference_report = { ir_var_reads : (int,bool) Hashtbl.t; ir_var_writes : (int,bool) Hashtbl.t; ir_field_reads : (string,bool) Hashtbl.t; ir_field_writes : (string,bool) Hashtbl.t; mutable ir_state_read : bool; mutable ir_state_write : bool; } let create () = { ir_var_reads = Hashtbl.create 0; ir_var_writes = Hashtbl.create 0; ir_field_reads = Hashtbl.create 0; ir_field_writes = Hashtbl.create 0; ir_state_read = false; ir_state_write = false; } let set_var_read ir v = Hashtbl.replace ir.ir_var_reads v.v_id true let set_var_write ir v = Hashtbl.replace ir.ir_var_writes v.v_id true let set_field_read ir s = Hashtbl.replace ir.ir_field_reads s true let set_field_write ir s = Hashtbl.replace ir.ir_field_writes s true let set_state_read ir = ir.ir_state_read <- true let set_state_write ir = ir.ir_state_write <- true let has_var_read ir v = Hashtbl.mem ir.ir_var_reads v.v_id let has_var_write ir v = Hashtbl.mem ir.ir_var_writes v.v_id let has_field_read ir s = Hashtbl.mem ir.ir_field_reads s let has_field_write ir s = Hashtbl.mem ir.ir_field_writes s let has_state_read ir = ir.ir_state_read let has_state_write ir = ir.ir_state_write let has_any_field_read ir = Hashtbl.length ir.ir_field_reads > 0 let has_any_field_write ir = Hashtbl.length ir.ir_field_writes > 0 let has_any_var_read ir = Hashtbl.length ir.ir_var_reads > 0 let has_any_var_write ir = Hashtbl.length ir.ir_var_writes > 0 let from_texpr e = let ir = create () in let rec loop e = match e.eexpr with (* vars *) | TLocal v -> set_var_read ir v; if v.v_capture then set_state_read ir; | TBinop(OpAssign,{eexpr = TLocal v},e2) -> set_var_write ir v; if v.v_capture then set_state_write ir; loop e2 | TBinop(OpAssignOp _,{eexpr = TLocal v},e2) -> set_var_read ir v; set_var_write ir v; if v.v_capture then begin set_state_read ir; set_state_write ir; end; loop e2 | TUnop((Increment | Decrement),_,{eexpr = TLocal v}) -> set_var_read ir v; set_var_write ir v; (* fields *) | TField(e1,fa) -> loop e1; if not (is_read_only_field_access e1 fa) then set_field_read ir (field_name fa); | TBinop(OpAssign,{eexpr = TField(e1,fa)},e2) -> set_field_write ir (field_name fa); loop e1; loop e2; | TBinop(OpAssignOp _,{eexpr = TField(e1,fa)},e2) -> let name = field_name fa in set_field_read ir name; set_field_write ir name; loop e1; loop e2; | TUnop((Increment | Decrement),_,{eexpr = TField(e1,fa)}) -> let name = field_name fa in set_field_read ir name; set_field_write ir name; loop e1 (* array *) | TArray(e1,e2) -> set_state_read ir; loop e1; loop e2; | TBinop(OpAssign,{eexpr = TArray(e1,e2)},e3) -> set_state_write ir; loop e1; loop e2; loop e3; | TBinop(OpAssignOp _,{eexpr = TArray(e1,e2)},e3) -> set_state_read ir; set_state_write ir; loop e1; loop e2; loop e3; | TUnop((Increment | Decrement),_,{eexpr = TArray(e1,e2)}) -> set_state_read ir; set_state_write ir; loop e1; loop e2; (* state *) | TCall({eexpr = TLocal v},el) when not (is_unbound_call_that_might_have_side_effects v el) -> List.iter loop el | TNew(c,_,el) when (match c.cl_constructor with Some cf when PurityState.is_pure c cf -> true | _ -> false) -> set_state_read ir; List.iter loop el; | TCall({eexpr = TField(e1,FEnum _)},el) -> loop e1; List.iter loop el; | TCall({eexpr = TField(e1,fa)},el) when PurityState.is_pure_field_access fa -> set_state_read ir; loop e1; List.iter loop el | TCall(e1,el) -> set_state_read ir; set_state_write ir; loop e1; List.iter loop el | TNew(_,_,el) -> set_state_read ir; set_state_write ir; List.iter loop el | TBinop(OpAssign,e1,e2) -> set_state_write ir; loop e1; loop e2; | TBinop(OpAssignOp _,e1,e2) -> set_state_read ir; set_state_write ir; loop e1; loop e2; | TUnop((Increment | Decrement),_,e1) -> set_state_read ir; set_state_write ir; loop e1 | _ -> Type.iter loop e in loop e; ir let to_string ir = let s_hashtbl f h = String.concat ", " (Hashtbl.fold (fun k _ acc -> (f k) :: acc) h []) in Type.Printer.s_record_fields "\t" [ "ir_var_reads",s_hashtbl string_of_int ir.ir_var_reads; "ir_var_writes",s_hashtbl string_of_int ir.ir_var_writes; "ir_field_reads",s_hashtbl (fun x -> x) ir.ir_field_reads; "ir_field_writes",s_hashtbl (fun x -> x) ir.ir_field_writes; "ir_state_read",string_of_bool ir.ir_state_read; "ir_state_write",string_of_bool ir.ir_state_write; ] end class fusion_state = object(self) val mutable _changed = false val var_reads = Hashtbl.create 0 val var_writes = Hashtbl.create 0 method private change map v delta = Hashtbl.replace map v.v_id ((try Hashtbl.find map v.v_id with Not_found -> 0) + delta); method inc_reads (v : tvar) : unit = self#change var_reads v 1 method dec_reads (v : tvar) : unit = self#change var_reads v (-1) method inc_writes (v : tvar) : unit = self#change var_writes v 1 method dec_writes (v : tvar) : unit = self#change var_writes v (-1) method get_reads (v : tvar) = try Hashtbl.find var_reads v.v_id with Not_found -> 0 method get_writes (v : tvar) = try Hashtbl.find var_writes v.v_id with Not_found -> 0 method change_writes (v : tvar) delta = self#change var_writes v delta method changed = _changed <- true method reset = _changed <- false method did_change = _changed method infer_from_texpr (e : texpr) = let rec loop e = match e.eexpr with | TLocal v -> self#inc_reads v; | TBinop(OpAssign,{eexpr = TLocal v},e2) -> self#inc_writes v; loop e2 | _ -> Type.iter loop e in loop e end (* Fusion tries to join expressions together in order to make the output "look nicer". To that end, several transformations occur: - `var x; x = e;` is transformed to `var x = e;` - `var x; if(e1) x = e2 else x = e3` is transformed to `var x = e1 ? e2 : e3` on targets that deal well with that. - `var x = e;` is transformed to `e` if `x` is unused. - Some block-level increment/decrement unary operators are put back into value places and the transformation of their postfix variant is reversed. - `x = x op y` is transformed (back) to `x op= y` on targets that deal well with that. Most importantly, any `var v = e;` might be fused into expressions that follow it in the same block if there is no interference. *) module Fusion = struct open AnalyzerConfig open InterferenceReport let is_assign_op = function | OpAdd | OpMult | OpDiv | OpSub | OpAnd | OpOr | OpXor | OpShl | OpShr | OpUShr | OpMod -> true | OpAssign | OpEq | OpNotEq | OpGt | OpGte | OpLt | OpLte | OpBoolAnd | OpBoolOr | OpAssignOp _ | OpInterval | OpArrow -> false let use_assign_op com op e1 e2 = is_assign_op op && target_handles_assign_ops com && Texpr.equal e1 e2 && not (has_side_effect e1) && match com.platform with | Cs when is_null e1.etype || is_null e2.etype -> false (* C# hates OpAssignOp on Null *) | _ -> true let apply com config e = let state = new fusion_state in state#infer_from_texpr e; (* Handles block-level expressions, e.g. by removing side-effect-free ones and recursing into compound constructs like array or object declarations. The resulting element list is reversed. *) let rec block_element acc el = match el with | {eexpr = TBinop((OpAssign | OpAssignOp _),_,_) | TUnop((Increment | Decrement),_,_)} as e1 :: el -> block_element (e1 :: acc) el | {eexpr = TLocal _} as e1 :: el when not config.local_dce -> block_element (e1 :: acc) el | {eexpr = TLocal v} :: el -> state#dec_reads v; block_element acc el (* no-side-effect *) | {eexpr = TEnumParameter _ | TFunction _ | TConst _ | TTypeExpr _} :: el -> block_element acc el | {eexpr = TMeta((Meta.Pure,_,_),_)} :: el -> block_element acc el | {eexpr = TCall({eexpr = TField(e1,fa)},el1)} :: el2 when PurityState.is_pure_field_access fa && config.local_dce -> block_element acc (e1 :: el1 @ el2) | {eexpr = TNew(c,tl,el1)} :: el2 when (match c.cl_constructor with Some cf when PurityState.is_pure c cf -> true | _ -> false) && config.local_dce -> block_element acc (el1 @ el2) (* no-side-effect composites *) | {eexpr = TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) | TField(e1,_) | TUnop(_,_,e1)} :: el -> block_element acc (e1 :: el) | {eexpr = TArray(e1,e2) | TBinop(_,e1,e2)} :: el -> block_element acc (e1 :: e2 :: el) | {eexpr = TArrayDecl el1 | TCall({eexpr = TField(_,FEnum _)},el1)} :: el2 -> (* TODO: check e1 of FEnum *) block_element acc (el1 @ el2) | {eexpr = TObjectDecl fl} :: el -> block_element acc ((List.map snd fl) @ el) | {eexpr = TIf(e1,{eexpr = TBlock []},(Some {eexpr = TBlock []} | None))} :: el -> block_element acc (e1 :: el) | {eexpr = TBlock [e1]} :: el -> block_element acc (e1 :: el) | {eexpr = TBlock []} :: el -> block_element acc el | e1 :: el -> block_element (e1 :: acc) el | [] -> acc in let can_be_fused v e = let num_uses = state#get_reads v in let num_writes = state#get_writes v in let can_be_used_as_value = can_be_used_as_value com e in let is_compiler_generated = Meta.has Meta.CompilerGenerated v.v_meta in let has_type_params = match v.v_extra with Some (tl,_) when tl <> [] -> true | _ -> false in let b = num_uses <= 1 && num_writes = 0 && can_be_used_as_value && not (is_asvar_type v.v_type) && (is_compiler_generated || config.optimize && config.fusion && config.user_var_fusion && not has_type_params) in if config.fusion_debug then begin print_endline (Printf.sprintf "FUSION\n\tvar %s<%i> = %s" v.v_name v.v_id (s_expr_pretty e)); print_endline (Printf.sprintf "\tcan_be_fused:%b: num_uses:%i <= 1 && num_writes:%i = 0 && can_be_used_as_value:%b && (is_compiler_generated:%b || config.optimize:%b && config.fusion:%b && config.user_var_fusion:%b)" b num_uses num_writes can_be_used_as_value is_compiler_generated config.optimize config.fusion config.user_var_fusion) end; b in let rec fuse acc el = match el with | ({eexpr = TVar(v1,None)} as e1) :: {eexpr = TBinop(OpAssign,{eexpr = TLocal v2},e2)} :: el when v1 == v2 -> state#changed; let e1 = {e1 with eexpr = TVar(v1,Some e2)} in state#dec_writes v1; fuse (e1 :: acc) el | ({eexpr = TVar(v1,None)} as e1) :: ({eexpr = TIf(eif,_,Some _)} as e2) :: el when can_be_used_as_value com e2 && not (ExtType.is_void e2.etype) && (match com.platform with | Php when not (Common.is_php7 com) -> false | Cpp when not (Common.defined com Define.Cppia) -> false | _ -> true) -> begin try let i = ref 0 in let check_assign e = match e.eexpr with | TBinop(OpAssign,{eexpr = TLocal v2},e2) when v1 == v2 -> incr i; e2 | _ -> raise Exit in let e,_ = map_values ~allow_control_flow:false check_assign e2 in let e1 = {e1 with eexpr = TVar(v1,Some e)} in state#changed; state#change_writes v1 (- !i); fuse (e1 :: acc) el with Exit -> fuse (e1 :: acc) (e2 :: el) end | {eexpr = TVar(v1,Some e1)} :: el when config.optimize && config.local_dce && state#get_reads v1 = 0 && state#get_writes v1 = 0 -> fuse acc (e1 :: el) | ({eexpr = TVar(v1,Some e1)} as ev) :: el when can_be_fused v1 e1 -> let found = ref false in let blocked = ref false in let ir = InterferenceReport.from_texpr e1 in if config.fusion_debug then print_endline (Printf.sprintf "\tInterferenceReport: %s\n\t%s" (InterferenceReport.to_string ir) (Type.s_expr_pretty true "\t" false (s_type (print_context())) (mk (TBlock el) t_dynamic null_pos))); (* This function walks the AST in order of evaluation and tries to find an occurrence of v1. If successful, that occurrence is replaced with e1. If there's an interference "on the way" the replacement is canceled. *) let rec replace e = let explore e = let old = !blocked in blocked := true; let e = replace e in blocked := old; e in let handle_el el = (* This mess deals with the fact that the order of evaluation is undefined for call arguments on these targets. Even if we find a replacement, we pretend that we didn't in order to find possible interferences in later call arguments. *) let temp_found = false in let really_found = ref !found in let el = List.map (fun e -> found := temp_found; let e = replace e in if !found then really_found := true; e ) el in found := !really_found; el in let handle_el = if not (target_handles_side_effect_order com) then handle_el else List.map replace in let handle_call e2 el = match com.platform with | Neko -> (* Neko has this reversed at the moment (issue #4787) *) let el = List.map replace el in let e2 = replace e2 in e2,el | Php | Cpp when not (Common.defined com Define.Cppia) && not (Common.is_php7 com) -> let is_php_safe e1 = let rec loop e = match e.eexpr with | TCall _ -> raise Exit | TCast(e1,_) | TParenthesis e1 | TMeta(_,e1) -> loop e1 | _ -> () in try loop e1; true with Exit -> false in (* PHP5 doesn't like call()() expressions. *) let e2 = if com.platform = Php && not (is_php_safe e1) then explore e2 else replace e2 in let el = handle_el el in e2,el | _ -> let e2 = replace e2 in let el = List.map replace el in e2,el in if !found then e else match e.eexpr with | TWhile _ | TTry _ -> raise Exit | TFunction _ -> e | TIf(e1,e2,eo) -> let e1 = replace e1 in if not !found && (has_state_write ir || has_any_field_write ir || has_any_var_write ir) then raise Exit; let e2 = replace e2 in let eo = Option.map replace eo in {e with eexpr = TIf(e1,e2,eo)} | TSwitch(e1,cases,edef) -> let e1 = match com.platform with | Lua | Python -> explore e1 | _ -> replace e1 in if not !found then raise Exit; {e with eexpr = TSwitch(e1,cases,edef)} (* locals *) | TLocal v2 when v1 == v2 && not !blocked -> found := true; if type_change_ok com v1.v_type e1.etype then e1 else mk (TCast(e1,None)) v1.v_type e.epos | TLocal v -> if has_var_write ir v || ((v.v_capture || is_ref_type v.v_type) && (has_state_write ir)) then raise Exit; e | TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) -> let e2 = replace e2 in if not !found && has_var_read ir v then raise Exit; {e with eexpr = TBinop(OpAssign,e1,e2)} | TBinop(OpAssignOp _ as op,({eexpr = TLocal v} as e1),e2) -> let e2 = replace e2 in if not !found && (has_var_read ir v || has_var_write ir v) then raise Exit; {e with eexpr = TBinop(op,e1,e2)} | TUnop((Increment | Decrement),_,{eexpr = TLocal v}) when has_var_read ir v || has_var_write ir v -> raise Exit (* fields *) | TField(e1,fa) -> let e1 = replace e1 in if not !found && not (is_read_only_field_access e1 fa) && (has_field_write ir (field_name fa) || has_state_write ir) then raise Exit; {e with eexpr = TField(e1,fa)} | TBinop(OpAssign,({eexpr = TField(e1,fa)} as ef),e2) -> let e1 = replace e1 in let e2 = replace e2 in if not !found && (has_field_read ir (field_name fa) || has_state_read ir) then raise Exit; {e with eexpr = TBinop(OpAssign,{ef with eexpr = TField(e1,fa)},e2)} | TBinop(OpAssignOp _ as op,({eexpr = TField(e1,fa)} as ef),e2) -> let e1 = replace e1 in let s = field_name fa in if not !found && (has_field_write ir s || has_state_write ir) then raise Exit; let e2 = replace e2 in if not !found && (has_field_read ir s || has_state_read ir) then raise Exit; {e with eexpr = TBinop(op,{ef with eexpr = TField(e1,fa)},e2)} | TUnop((Increment | Decrement),_,{eexpr = TField(e1,fa)}) when has_field_read ir (field_name fa) || has_state_read ir || has_field_write ir (field_name fa) || has_state_write ir -> raise Exit (* state *) | TCall({eexpr = TLocal v},el) when not (is_unbound_call_that_might_have_side_effects v el) -> e | TNew(c,tl,el) when (match c.cl_constructor with Some cf when PurityState.is_pure c cf -> true | _ -> false) -> let el = handle_el el in if not !found && (has_state_write ir || has_any_field_write ir) then raise Exit; {e with eexpr = TNew(c,tl,el)} | TNew(c,tl,el) -> let el = handle_el el in if not !found && (has_state_write ir || has_state_read ir || has_any_field_read ir || has_any_field_write ir) then raise Exit; {e with eexpr = TNew(c,tl,el)} | TCall({eexpr = TField(_,FEnum _)} as ef,el) -> let el = handle_el el in {e with eexpr = TCall(ef,el)} | TCall({eexpr = TField(_,fa)} as ef,el) when PurityState.is_pure_field_access fa -> let ef,el = handle_call ef el in if not !found && (has_state_write ir || has_any_field_write ir) then raise Exit; {e with eexpr = TCall(ef,el)} | TCall(e1,el) -> let e1,el = match e1.eexpr with | TLocal v when is_really_unbound v -> e1,el | _ -> handle_call e1 el in if not !found && (((has_state_read ir || has_any_field_read ir)) || has_state_write ir || has_any_field_write ir) then raise Exit; {e with eexpr = TCall(e1,el)} | TObjectDecl fl -> let el = handle_el (List.map snd fl) in if not !found && (has_state_write ir || has_any_field_write ir) then raise Exit; {e with eexpr = TObjectDecl (List.map2 (fun (s,_) e -> s,e) fl el)} | TArrayDecl el -> let el = handle_el el in (*if not !found && (has_state_write ir || has_any_field_write ir) then raise Exit;*) {e with eexpr = TArrayDecl el} | TBinop(OpAssign,({eexpr = TArray(e1,e2)} as ea),e3) -> let e1 = replace e1 in let e2 = replace e2 in let e3 = replace e3 in if not !found && has_state_read ir then raise Exit; {e with eexpr = TBinop(OpAssign,{ea with eexpr = TArray(e1,e2)},e3)} | TBinop(op,e1,e2) when (match com.platform with Cpp | Php when not (Common.is_php7 com) -> true | _ -> false) -> let e1 = replace e1 in let temp_found = !found in found := false; let e2 = replace e2 in found := !found || temp_found; {e with eexpr = TBinop(op,e1,e2)} | TArray(e1,e2) -> let e1 = replace e1 in let e2 = replace e2 in if not !found && has_state_write ir then raise Exit; {e with eexpr = TArray(e1,e2)} | _ -> Type.map_expr replace e in begin try let rec loop acc el = match el with | e :: el -> let e = replace e in if !found then (List.rev (e :: acc)) @ el else loop (e :: acc) el | [] -> List.rev acc in let el = loop [] el in if not !found then raise Exit; state#changed; state#dec_reads v1; if config.fusion_debug then print_endline (Printf.sprintf "YES: %s" (s_expr_pretty (mk (TBlock el) t_dynamic null_pos))); fuse acc el with Exit -> if config.fusion_debug then print_endline (Printf.sprintf "NO: %s" (Printexc.get_backtrace())); fuse (ev :: acc) el end | {eexpr = TUnop((Increment | Decrement as op,Prefix,({eexpr = TLocal v} as ev)))} as e1 :: e2 :: el -> begin try let e2,f = match e2.eexpr with | TReturn (Some e2) -> e2,(fun e -> {e2 with eexpr = TReturn (Some e)}) | TBinop(OpAssign,e21,e22) -> e22,(fun e -> {e2 with eexpr = TBinop(OpAssign,e21,e)}) | TVar(v,Some e2) -> e2,(fun e -> {e2 with eexpr = TVar(v,Some e)}) | _ -> raise Exit in let ops_match op1 op2 = match op1,op2 with | Increment,OpSub | Decrement,OpAdd -> true | _ -> false in begin match e2.eexpr with | TBinop(op2,{eexpr = TLocal v2},{eexpr = TConst (TInt i32)}) when v == v2 && Int32.to_int i32 = 1 && ops_match op op2 -> state#changed; state#dec_reads v2; let e = (f {e1 with eexpr = TUnop(op,Postfix,ev)}) in fuse (e :: acc) el | TLocal v2 when v == v2 -> state#changed; state#dec_reads v2; let e = (f {e1 with eexpr = TUnop(op,Prefix,ev)}) in fuse (e :: acc) el | _ -> raise Exit end with Exit -> fuse (e1 :: acc) (e2 :: el) end | {eexpr = TBinop(OpAssign,e1,{eexpr = TBinop(op,e2,e3)})} as e :: el when use_assign_op com op e1 e2 -> let rec loop e = match e.eexpr with | TLocal v -> state#dec_reads v; | _ -> Type.iter loop e in loop e1; state#changed; fuse acc ({e with eexpr = TBinop(OpAssignOp op,e1,e3)} :: el) | {eexpr = TBinop(OpAssignOp _,e1,_)} as eop :: ({eexpr = TVar(v,Some e2)} as evar) :: el when Texpr.equal e1 e2 -> state#changed; fuse ({evar with eexpr = TVar(v,Some eop)} :: acc) el | e1 :: el -> fuse (e1 :: acc) el | [] -> acc in let rec loop e = match e.eexpr with | TBlock el -> let el = List.rev_map loop el in let el = block_element [] el in (* fuse flips element order, but block_element doesn't care and flips it back *) let el = fuse [] el in let el = block_element [] el in let rec fuse_loop el = state#reset; let el = fuse [] el in let el = block_element [] el in if state#did_change then fuse_loop el else el in let el = fuse_loop el in {e with eexpr = TBlock el} | TCall({eexpr = TLocal v},_) when is_really_unbound v -> e | _ -> Type.map_expr loop e in loop e end module Cleanup = struct let apply com e = let if_or_op e e1 e2 e3 = match (Texpr.skip e1).eexpr,(Texpr.skip e3).eexpr with | TUnop(Not,Prefix,e1),TConst (TBool true) -> optimize_binop {e with eexpr = TBinop(OpBoolOr,e1,e2)} OpBoolOr e1 e2 | _,TConst (TBool false) -> optimize_binop {e with eexpr = TBinop(OpBoolAnd,e1,e2)} OpBoolAnd e1 e2 | _,TBlock [] -> {e with eexpr = TIf(e1,e2,None)} | _ -> match (Texpr.skip e2).eexpr with | TBlock [] when com.platform <> Cs -> let e1' = mk (TUnop(Not,Prefix,e1)) e1.etype e1.epos in let e1' = optimize_unop e1' Not Prefix e1 in {e with eexpr = TIf(e1',e3,None)} | _ -> {e with eexpr = TIf(e1,e2,Some e3)} in let rec loop e = match e.eexpr with | 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; | TUnop((Increment | Decrement),_,e1) when (match (Texpr.skip e1).eexpr with TConst _ -> true | _ -> false) -> loop e1 | TCall({eexpr = TLocal v},_) when is_really_unbound v -> e | TBlock el -> let el = List.map (fun e -> let e = loop e in match e.eexpr with | TIf _ -> {e with etype = com.basic.tvoid} | _ -> e ) el in {e with eexpr = TBlock el} | TWhile(e1,e2,NormalWhile) -> let e1 = loop e1 in let e2 = loop e2 in begin match e2.eexpr with | TBlock ({eexpr = TIf(e1,({eexpr = TBlock[{eexpr = TBreak}]} as eb),None)} :: el2) -> let e1 = Texpr.skip e1 in let e1 = match e1.eexpr with TUnop(_,_,e1) -> e1 | _ -> {e1 with eexpr = TUnop(Not,Prefix,e1)} in {e with eexpr = TWhile(e1,{eb with eexpr = TBlock el2},NormalWhile)} | TBlock el -> let rec loop2 el = match el with | {eexpr = TBreak | TContinue | TReturn _ | TThrow _} as e :: el -> [e] | e :: el -> e :: (loop2 el) | [] -> [] in let el = loop2 el in {e with eexpr = TWhile(e1,{e2 with eexpr = TBlock el},NormalWhile)} | _ -> {e with eexpr = TWhile(e1,e2,NormalWhile)} end | TField(e1,(FAnon {cf_name = s} | FDynamic s)) -> let e1 = loop e1 in let fa = quick_field_dynamic e1.etype s in {e with eexpr = TField(e1,fa)} | TField({eexpr = TTypeExpr _},_) -> e | TTypeExpr (TClassDecl c) -> List.iter (fun cf -> if not (Meta.has Meta.MaybeUsed cf.cf_meta) then cf.cf_meta <- (Meta.MaybeUsed,[],cf.cf_pos) :: cf.cf_meta;) c.cl_ordered_statics; e | _ -> Type.map_expr loop e in loop e end module Purity = struct open PurityState type purity_node = { pn_class : tclass; pn_field : tclass_field; mutable pn_purity : PurityState.t; mutable pn_dependents : purity_node list; } exception Purity_conflict of purity_node * pos let node_lut = Hashtbl.create 0 let get_field_id c cf = Printf.sprintf "%s.%s" (s_type_path c.cl_path) cf.cf_name let get_node c cf = try Hashtbl.find node_lut (get_field_id c cf) with Not_found -> let node = { pn_class = c; pn_field = cf; pn_purity = PurityState.get_purity c cf; pn_dependents = [] } in Hashtbl.replace node_lut (get_field_id c cf) node; node let rec taint node = match node.pn_purity with | Impure -> () | ExpectPure p -> raise (Purity_conflict(node,p)); | MaybePure | Pure -> node.pn_purity <- Impure; List.iter taint node.pn_dependents; let rec loop c = match c.cl_super with | None -> () | Some(c,_) -> begin try let cf = PMap.find node.pn_field.cf_name c.cl_fields in taint (get_node c cf); with Not_found -> () end; loop c in loop node.pn_class let taint_raise node = taint node; raise Exit let apply_to_field com is_ctor c cf = let node = get_node c cf in let check_field c cf = let node' = get_node c cf in match node'.pn_purity with | Pure | ExpectPure _ -> () | Impure -> taint_raise node; | MaybePure -> node'.pn_dependents <- node :: node'.pn_dependents in let rec check_write e1 = begin match e1.eexpr with | TLocal v -> if is_ref_type v.v_type then taint_raise node; (* Writing to a ref type means impurity. *) () (* Writing to locals does not violate purity. *) | TField({eexpr = TConst TThis},_) when is_ctor -> () (* A constructor can write to its own fields without violating purity. *) | _ -> taint_raise node end and loop e = match e.eexpr with | TMeta((Meta.Pure,_,_),_) -> () | TThrow _ -> taint_raise node; | TBinop((OpAssign | OpAssignOp _),e1,e2) -> check_write e1; loop e2; | TUnop((Increment | Decrement),_,e1) -> check_write e1; | TCall({eexpr = TField(_,FStatic(c,cf))},el) -> List.iter loop el; check_field c cf; | TNew(c,_,el) -> List.iter loop el; begin match c.cl_constructor with | Some cf -> check_field c cf | None -> taint_raise node end | TCall({eexpr = TConst TSuper},el) -> begin match c.cl_super with | Some({cl_constructor = Some cf} as c,_) -> check_field c cf; List.iter loop el | _ -> taint_raise node (* Can that even happen? *) end | TCall({eexpr = TLocal v},el) when not (is_unbound_call_that_might_have_side_effects v el) -> List.iter loop el; | TCall _ -> taint_raise node | _ -> Type.iter loop e in match cf.cf_kind with | Method MethDynamic | Var _ -> taint node; | _ -> match cf.cf_expr with | None -> if not (is_pure c cf) then taint node (* TODO: The function code check shouldn't be here I guess. *) | Some _ when (Meta.has Meta.Extern cf.cf_meta || Meta.has Meta.FunctionCode cf.cf_meta || Meta.has (Meta.Custom ":hlNative") cf.cf_meta || Meta.has (Meta.Custom ":hlNative") c.cl_meta) -> if not (is_pure c cf) then taint node | Some e -> try begin match node.pn_purity with | Impure -> taint_raise node | Pure -> raise Exit | _ -> loop e end with Exit -> () let apply_to_class com c = List.iter (apply_to_field com false c) c.cl_ordered_fields; List.iter (apply_to_field com false c) c.cl_ordered_statics; (match c.cl_constructor with Some cf -> apply_to_field com true c cf | None -> ()) let infer com = Hashtbl.clear node_lut; List.iter (fun mt -> match mt with | TClassDecl c -> begin try apply_to_class com c with Purity_conflict(impure,p) -> com.error "Impure field overrides/implements field which was explicitly marked as @:pure" impure.pn_field.cf_pos; Error.error "Pure field is here" p; end | _ -> () ) com.types; Hashtbl.fold (fun _ node acc -> match node.pn_purity with | Pure | MaybePure -> node.pn_field.cf_meta <- (Meta.Pure,[EConst(Ident "true"),node.pn_field.cf_pos],node.pn_field.cf_pos) :: node.pn_field.cf_meta; node.pn_field :: acc | _ -> acc ) node_lut []; end haxe_3.4.4.orig/src/optimization/analyzerTexprTransformer.ml0000664000175000017500000006262713166552354024373 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open Ast open Type open Common open AnalyzerConfig open AnalyzerTypes open AnalyzerTypes.BasicBlock open AnalyzerTypes.Graph open AnalyzerTexpr open OptimizerTexpr (* Transforms an expression to a graph, and a graph back to an expression. This module relies on TexprFilter being run first. The created graph is intact and can immediately be transformed back to an expression, or used for analysis first. *) let rec func ctx bb tf t p = let g = ctx.graph in let create_node kind t p = let bb = Graph.create_node g kind t p in bb.bb_loop_groups <- ctx.loop_stack; bb in let bb_root = create_node (BKFunctionBegin tf) tf.tf_expr.etype tf.tf_expr.epos in let bb_exit = create_node BKFunctionEnd tf.tf_expr.etype tf.tf_expr.epos in add_function g tf t p bb_root; add_cfg_edge bb bb_root CFGFunction; let make_block_meta b = let e = mk (TConst (TInt (Int32.of_int b.bb_id))) ctx.com.basic.tint b.bb_pos in wrap_meta ":block" e in let bb_breaks = ref [] in let bb_continue = ref None in let b_try_stack = ref [] in let begin_loop bb_loop_pre bb_continue' = let old = !bb_breaks,!bb_continue in bb_breaks := []; bb_continue := Some bb_continue'; let id = ctx.loop_counter in g.g_loops <- IntMap.add id bb_loop_pre g.g_loops; ctx.loop_stack <- id :: ctx.loop_stack; bb_continue'.bb_loop_groups <- id :: bb_continue'.bb_loop_groups; ctx.loop_counter <- id + 1; (fun () -> let breaks = !bb_breaks in bb_breaks := fst old; bb_continue := snd old; ctx.loop_stack <- List.tl ctx.loop_stack; breaks; ) in let begin_try b = b_try_stack := b :: !b_try_stack; (fun () -> b_try_stack := List.tl !b_try_stack ) in let add_terminator bb e = add_texpr bb e; close_node g bb; g.g_unreachable in let check_unbound_call v el = if v.v_name = "$ref" then begin match el with | [{eexpr = TLocal v}] -> v.v_capture <- true | _ -> () end; if is_unbound_call_that_might_have_side_effects v el then ctx.has_unbound <- true; in let no_void t p = if ExtType.is_void (follow t) then Error.error "Cannot use Void as value" p in let push_name s = ctx.name_stack <- s :: ctx.name_stack; (fun () -> ctx.name_stack <- List.tl ctx.name_stack) in let rec value' bb e = match e.eexpr with | TLocal v -> bb,e | TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) -> block_element bb e,e1 | TBlock [e1] -> value bb e1 | TBlock _ | TIf _ | TSwitch _ | TTry _ -> bind_to_temp bb false e | TCall({eexpr = TLocal v},el) when is_really_unbound v -> check_unbound_call v el; bb,e | TCall(e1,el) -> call bb e e1 el | TBinop(OpAssignOp op,({eexpr = TArray(e1,e2)} as ea),e3) -> array_assign_op bb op e ea e1 e2 e3 | TBinop(OpAssignOp op,({eexpr = TField(e1,fa)} as ef),e2) -> field_assign_op bb op e ef e1 fa e2 | TBinop((OpAssign | OpAssignOp _) as op,e1,e2) -> let bb,e1 = value bb e1 in let bb,e2 = value bb e2 in bb,{e with eexpr = TBinop(op,e1,e2)} | TBinop(op,e1,e2) -> let bb,e1,e2 = match ordered_value_list bb [e1;e2] with | bb,[e1;e2] -> bb,e1,e2 | _ -> assert false in bb,{e with eexpr = TBinop(op,e1,e2)} | TUnop(op,flag,e1) -> let bb,e1 = value bb e1 in bb,{e with eexpr = TUnop(op,flag,e1)} | TArrayDecl el -> let bb,el = ordered_value_list bb el in bb,{e with eexpr = TArrayDecl el} | TObjectDecl fl -> let el = List.map snd fl in let bb,el = ordered_value_list bb el in bb,{e with eexpr = TObjectDecl (List.map2 (fun (s,_) e -> s,e) fl el)} | TField({eexpr = TTypeExpr _},fa) -> bb,e | TField(e1,fa) -> let bb,e1 = value bb e1 in bb,{e with eexpr = TField(e1,fa)} | TArray(e1,e2) -> let bb,e1,e2 = match ordered_value_list bb [e1;e2] with | bb,[e1;e2] -> bb,e1,e2 | _ -> assert false in bb,{e with eexpr = TArray(e1,e2)} | TMeta(m,e1) -> let bb,e1 = value bb e1 in bb,{e with eexpr = TMeta(m,e1)} | TParenthesis e1 -> let bb,e1 = value bb e1 in bb,{e with eexpr = TParenthesis e1} | TCast(e1,mto) -> let bb,e1 = value bb e1 in bb,{e with eexpr = TCast(e1,mto)} | TNew(c,tl,el) -> let bb,el = ordered_value_list bb el in bb,{e with eexpr = TNew(c,tl,el)} | TEnumParameter(e1,ef,ei) -> let bb,e1 = value bb e1 in bb,{e with eexpr = TEnumParameter(e1,ef,ei)} | TFunction tf -> let bb_func,bb_func_end = func ctx bb tf e.etype e.epos in let e_fun = mk (TConst (TString "fun")) t_dynamic p in let econst = mk (TConst (TInt (Int32.of_int bb_func.bb_id))) ctx.com.basic.tint e.epos in let ec = mk (TCall(e_fun,[econst])) t_dynamic p in let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in add_cfg_edge bb bb_next CFGGoto; set_syntax_edge bb (SEMerge bb_next); close_node g bb; add_cfg_edge bb_func_end bb_next CFGGoto; bb_next,ec (*| TTypeExpr(TClassDecl {cl_kind = KAbstractImpl a}) when not (Meta.has Meta.RuntimeValue a.a_meta) -> error "Cannot use abstract as value" e.epos*) | TConst _ | TTypeExpr _ -> bb,e | TThrow _ | TReturn _ | TBreak | TContinue -> let bb = block_element bb e in bb,mk (TConst TNull) t_dynamic e.epos | TVar _ | TFor _ | TWhile _ -> Error.error "Cannot use this expression as value" e.epos and value bb e = let bb,e = value' bb e in no_void e.etype e.epos; bb,e and ordered_value_list bb el = let might_be_affected,collect_modified_locals = create_affection_checker() in let rec can_be_optimized e = match e.eexpr with | TBinop _ | TArray _ | TCall _ -> true | TParenthesis e1 -> can_be_optimized e1 | _ -> false in let _,el = List.fold_left (fun (had_side_effect,acc) e -> if had_side_effect then (true,(might_be_affected e || has_side_effect e,can_be_optimized e,e) :: acc) else begin let had_side_effect = has_side_effect e in if had_side_effect then collect_modified_locals e; let opt = can_be_optimized e in (had_side_effect || opt,(false,opt,e) :: acc) end ) (false,[]) (List.rev el) in let bb,values = List.fold_left (fun (bb,acc) (aff,opt,e) -> let bb,value = if aff || opt then bind_to_temp bb aff e else value bb e in bb,(value :: acc) ) (bb,[]) el in bb,List.rev values and bind_to_temp ?(v=None) bb sequential e = let is_probably_not_affected e e1 fa = match fa with | FAnon cf | FInstance (_,_,cf) | FStatic (_,cf) | FClosure (_,cf) when cf.cf_kind = Method MethNormal -> true | FStatic(_,{cf_kind = Method MethDynamic}) -> false | FEnum _ -> true | FDynamic ("cca" | "__Index" | "__s") -> true (* This is quite retarded, but we have to deal with this somehow... *) | _ -> match follow e.etype,follow e1.etype with | TFun _,TInst _ -> false | TFun _,_ -> true (* We don't know what's going on here, don't create a temp var (see #5082). *) | _ -> false in let rec loop fl e = match e.eexpr with | TField(e1,fa) when is_probably_not_affected e e1 fa -> loop ((fun e' -> {e with eexpr = TField(e',fa)}) :: fl) e1 | TField(e1,fa) -> let fa = match fa with | FInstance(c,tl,({cf_kind = Method _ } as cf)) -> FClosure(Some(c,tl),cf) | _ -> fa in fl,{e with eexpr = TField(e1,fa)} | _ -> fl,e in let fl,e = loop [] e in let rec loop e = match e.eexpr with | TLocal v -> v.v_name | TArray(e1,_) | TField(e1,_) | TParenthesis e1 | TCast(e1,None) | TMeta(_,e1) -> loop e1 | _ -> match ctx.name_stack with | s :: _ -> s | [] -> ctx.temp_var_name in let v = match v with Some v -> v | None -> alloc_var (loop e) e.etype e.epos in begin match ctx.com.platform with | Globals.Cpp when sequential && not (Common.defined ctx.com Define.Cppia) -> () | _ -> v.v_meta <- [Meta.CompilerGenerated,[],e.epos]; end; let bb = declare_var_and_assign bb v e e.epos in let e = {e with eexpr = TLocal v} in let e = List.fold_left (fun e f -> f e) e fl in bb,e and declare_var_and_assign bb v e p = (* TODO: this section shouldn't be here because it can be handled as part of the normal value processing *) let rec loop bb e = match e.eexpr with | TParenthesis e1 -> loop bb e1 | TBlock el -> let rec loop2 bb el = match el with | [e] -> bb,e | e1 :: el -> let bb = block_element bb e1 in if bb == g.g_unreachable then raise Exit; loop2 bb el | [] -> assert false in let bb,e = loop2 bb el in loop bb e | _ -> bb,e in let generate bb e = no_void v.v_type p; let ev = mk (TLocal v) v.v_type p in let was_assigned = ref false in let assign e = if not !was_assigned then begin was_assigned := true; add_texpr bb (mk (TVar(v,None)) ctx.com.basic.tvoid ev.epos); end; mk (TBinop(OpAssign,ev,e)) ev.etype ev.epos in let close = push_name v.v_name in let bb = try block_element_plus bb (map_values assign e) (fun e -> mk (TVar(v,Some e)) ctx.com.basic.tvoid ev.epos) with Exit -> let bb,e = value bb e in add_texpr bb (mk (TVar(v,Some e)) ctx.com.basic.tvoid ev.epos); bb in close(); bb in try let bb,e = loop bb e in generate bb e with Exit -> g.g_unreachable and block_element_plus bb (e,efinal) f = let bb = block_element bb e in let bb = match efinal with | None -> bb | Some e -> block_element bb (f e) in bb and block_element_value bb e f = let e,efinal = map_values f e in block_element_plus bb (e,efinal) f and call bb e e1 el = let bb = ref bb in let check e t = match e.eexpr with | TLocal v when is_ref_type t -> v.v_capture <- true; e | _ -> if is_asvar_type t then begin let v = alloc_var "tmp" t e.epos in let bb',e = bind_to_temp ~v:(Some v) !bb false e in bb := bb'; e end else e in let el = Codegen.UnificationCallback.check_call check el e1.etype in let bb,el = ordered_value_list !bb (e1 :: el) in match el with | e1 :: el -> bb,{e with eexpr = TCall(e1,el)} | _ -> assert false and array_assign_op bb op e ea e1 e2 e3 = let bb,e1 = bind_to_temp bb false e1 in let bb,e2 = bind_to_temp bb false e2 in let ea = {ea with eexpr = TArray(e1,e2)} in let bb,e4 = bind_to_temp bb false ea in let bb,e3 = bind_to_temp bb false e3 in let eop = {e with eexpr = TBinop(op,e4,e3)} in add_texpr bb {e with eexpr = TBinop(OpAssign,ea,eop)}; bb,ea and field_assign_op bb op e ef e1 fa e2 = let bb,e1 = match fa with | FInstance(c,_,_) | FClosure(Some(c,_),_) when is_stack_allocated c -> bb,e1 | _ -> bind_to_temp bb false e1 in let ef = {ef with eexpr = TField(e1,fa)} in let bb,e3 = bind_to_temp bb false ef in let bb,e2 = bind_to_temp bb false e2 in let eop = {e with eexpr = TBinop(op,e3,e2)} in add_texpr bb {e with eexpr = TBinop(OpAssign,ef,eop)}; bb,ef and block_element bb e = match e.eexpr with (* variables *) | TVar(v,None) -> add_texpr bb e; bb | TVar(v,Some e1) -> declare_var_and_assign bb v e1 e.epos | TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) -> let assign e = mk (TBinop(OpAssign,e1,e)) e.etype e.epos in let close = push_name v.v_name in let bb = try block_element_value bb e2 assign with Exit -> let bb,e2 = value bb e2 in add_texpr bb {e with eexpr = TBinop(OpAssign,e1,e2)}; bb in close(); bb (* branching *) | TMeta((Meta.MergeBlock,_,_),{eexpr = TBlock el}) -> block_el bb el | TBlock el -> let bb_sub = create_node BKSub e.etype e.epos in add_cfg_edge bb bb_sub CFGGoto; close_node g bb; let bb_sub_next = block_el bb_sub el in if bb_sub_next != g.g_unreachable then begin let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in set_syntax_edge bb (SESubBlock(bb_sub,bb_next)); add_cfg_edge bb_sub_next bb_next CFGGoto; close_node g bb_sub_next; bb_next; end else begin set_syntax_edge bb (SEMerge bb_sub); close_node g bb_sub_next; bb_sub_next end | TIf(e1,e2,None) -> let bb,e1 = bind_to_temp bb false e1 in let bb_then = create_node BKConditional e2.etype e2.epos in add_texpr bb (wrap_meta ":cond-branch" e1); add_cfg_edge bb bb_then (CFGCondBranch (mk (TConst (TBool true)) ctx.com.basic.tbool e2.epos)); let bb_then_next = block bb_then e2 in let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in set_syntax_edge bb (SEIfThen(bb_then,bb_next,e.epos)); add_cfg_edge bb bb_next CFGCondElse; close_node g bb; add_cfg_edge bb_then_next bb_next CFGGoto; close_node g bb_then_next; bb_next | TIf(e1,e2,Some e3) -> let bb,e1 = bind_to_temp bb false e1 in let bb_then = create_node BKConditional e2.etype e2.epos in let bb_else = create_node BKConditional e3.etype e3.epos in add_texpr bb (wrap_meta ":cond-branch" e1); add_cfg_edge bb bb_then (CFGCondBranch (mk (TConst (TBool true)) ctx.com.basic.tbool e2.epos)); add_cfg_edge bb bb_else CFGCondElse; close_node g bb; let bb_then_next = block bb_then e2 in let bb_else_next = block bb_else e3 in if bb_then_next == g.g_unreachable && bb_else_next == g.g_unreachable then begin set_syntax_edge bb (SEIfThenElse(bb_then,bb_else,g.g_unreachable,e.etype,e.epos)); g.g_unreachable end else begin let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in set_syntax_edge bb (SEIfThenElse(bb_then,bb_else,bb_next,e.etype,e.epos)); add_cfg_edge bb_then_next bb_next CFGGoto; add_cfg_edge bb_else_next bb_next CFGGoto; close_node g bb_then_next; close_node g bb_else_next; bb_next end | TSwitch(e1,cases,edef) -> let is_exhaustive = edef <> None || is_exhaustive e1 in let bb,e1 = bind_to_temp bb false e1 in add_texpr bb (wrap_meta ":cond-branch" e1); let reachable = ref [] in let make_case e = let bb_case = create_node BKConditional e.etype e.epos in let bb_case_next = block bb_case e in if bb_case_next != g.g_unreachable then reachable := bb_case_next :: !reachable; close_node g bb_case_next; bb_case in let cases = List.map (fun (el,e) -> let bb_case = make_case e in List.iter (fun e -> add_cfg_edge bb bb_case (CFGCondBranch e)) el; el,bb_case ) cases in let def = match edef with | None -> None | Some e -> let bb_case = make_case e in add_cfg_edge bb bb_case (CFGCondElse); Some (bb_case) in if is_exhaustive && !reachable = [] then begin set_syntax_edge bb (SESwitch(cases,def,g.g_unreachable,e.epos)); close_node g bb; g.g_unreachable; end else begin let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in if not is_exhaustive then add_cfg_edge bb bb_next CFGGoto; List.iter (fun bb -> add_cfg_edge bb bb_next CFGGoto) !reachable; set_syntax_edge bb (SESwitch(cases,def,bb_next,e.epos)); close_node g bb; bb_next end | TWhile(e1,e2,NormalWhile) -> let bb_loop_pre = create_node BKNormal e1.etype e1.epos in add_cfg_edge bb bb_loop_pre CFGGoto; set_syntax_edge bb (SEMerge bb_loop_pre); close_node g bb; let bb_loop_head = create_node BKLoopHead e1.etype e1.epos in add_cfg_edge bb_loop_pre bb_loop_head CFGGoto; let close = begin_loop bb bb_loop_head in let bb_loop_body = create_node BKNormal e2.etype e2.epos in let bb_loop_body_next = block bb_loop_body e2 in let bb_breaks = close() in let bb_next = if bb_breaks = [] then begin (* The loop appears to be infinite, let's assume that something within it throws. Otherwise DCE's mark-pass won't see its body and removes everything. *) add_cfg_edge bb_loop_body_next bb_exit CFGMaybeThrow; g.g_unreachable end else create_node BKNormal bb.bb_type bb.bb_pos in List.iter (fun bb -> add_cfg_edge bb bb_next CFGGoto) bb_breaks; set_syntax_edge bb_loop_pre (SEWhile(bb_loop_head,bb_loop_body,bb_next)); close_node g bb_loop_pre; add_texpr bb_loop_pre {e with eexpr = TWhile(e1,make_block_meta bb_loop_body,NormalWhile)}; add_cfg_edge bb_loop_body_next bb_loop_head CFGGoto; add_cfg_edge bb_loop_head bb_loop_body CFGGoto; close_node g bb_loop_body_next; close_node g bb_loop_head; bb_next; | TTry(e1,catches) -> let bb_try = create_node BKNormal e1.etype e1.epos in let bb_exc = create_node BKException t_dynamic e.epos in add_cfg_edge bb bb_try CFGGoto; let close = begin_try bb_exc in let bb_try_next = block bb_try e1 in close(); (* We always want to keep catch-blocks, so let's add a pseudo CFG edge if it's unreachable. *) if bb_exc.bb_incoming = [] then add_cfg_edge (if bb_try_next == g.g_unreachable then bb_try else bb_try_next) bb_exc CFGMaybeThrow; let is_reachable = ref (not (bb_try_next == g.g_unreachable)) in let catches = List.map (fun (v,e) -> let bb_catch = create_node (BKCatch v) e.etype e.epos in add_cfg_edge bb_exc bb_catch CFGGoto; let bb_catch_next = block bb_catch e in is_reachable := !is_reachable || (not (bb_catch_next == g.g_unreachable)); v,bb_catch,bb_catch_next ) catches in let bb_next = if !is_reachable then create_node BKNormal bb.bb_type bb.bb_pos else g.g_unreachable in let catches = List.map (fun (v,bb_catch,bb_catch_next) -> if bb_catch_next != g.g_unreachable then add_cfg_edge bb_catch_next bb_next CFGGoto; close_node g bb_catch_next; v,bb_catch ) catches in set_syntax_edge bb (SETry(bb_try,bb_exc,catches,bb_next,e.epos)); if bb_try_next != g.g_unreachable then add_cfg_edge bb_try_next bb_next CFGGoto; close_node g bb_try_next; close_node g bb_exc; close_node g bb; bb_next (* control flow *) | TReturn None -> add_cfg_edge bb bb_exit CFGGoto; add_terminator bb e | TReturn (Some e1) when ExtType.is_void (follow e1.etype) -> let bb = block_element bb e1 in block_element bb (mk (TReturn None) t_dynamic e.epos) | TReturn (Some e1) -> begin try let mk_return e1 = mk (TReturn (Some e1)) t_dynamic e1.epos in block_element_value bb e1 mk_return with Exit -> let bb,e1 = value bb e1 in add_cfg_edge bb bb_exit CFGGoto; add_terminator bb {e with eexpr = TReturn(Some e1)}; end | TBreak -> bb_breaks := bb :: !bb_breaks; add_terminator bb e | TContinue -> begin match !bb_continue with | Some bb_continue -> add_cfg_edge bb bb_continue CFGGoto | _ -> assert false end; add_terminator bb e | TThrow e1 -> begin try let mk_throw e1 = mk (TThrow e1) t_dynamic e.epos in block_element_value bb e1 mk_throw with Exit -> let bb,e1 = value bb e1 in begin match !b_try_stack with | [] -> add_cfg_edge bb bb_exit CFGGoto | _ -> List.iter (fun bb_exc -> add_cfg_edge bb bb_exc CFGGoto) !b_try_stack; end; add_terminator bb {e with eexpr = TThrow e1}; end (* side_effects *) | TCall({eexpr = TLocal v},el) when is_really_unbound v -> check_unbound_call v el; add_texpr bb e; bb | TCall(e1,el) -> let bb,e = call bb e e1 el in add_texpr bb e; bb | TNew(c,tl,el) -> let bb,el = ordered_value_list bb el in add_texpr bb {e with eexpr = TNew(c,tl,el)}; bb | TCast(e1,Some mt) -> let b,e1 = value bb e1 in add_texpr bb {e with eexpr = TCast(e1,Some mt)}; bb | TBinop(OpAssignOp op,({eexpr = TArray(e1,e2)} as ea),e3) -> let bb,_ = array_assign_op bb op e ea e1 e2 e3 in bb | TBinop(OpAssignOp op,({eexpr = TField(e1,fa)} as ef),e2) -> let bb,_ = field_assign_op bb op e ef e1 fa e2 in bb | TBinop(OpAssign,({eexpr = TArray(e1,e2)} as ea),e3) -> let bb,e1,e2,e3 = match ordered_value_list bb [e1;e2;e3] with | bb,[e1;e2;e3] -> bb,e1,e2,e3 | _ -> assert false in add_texpr bb {e with eexpr = TBinop(OpAssign,{ea with eexpr = TArray(e1,e2)},e3)}; bb | TBinop((OpAssign | OpAssignOp _ as op),e1,e2) -> let bb,e1 = value bb e1 in let bb,e2 = value bb e2 in add_texpr bb {e with eexpr = TBinop(op,e1,e2)}; bb | TUnop((Increment | Decrement as op),flag,e1) -> let bb,e1 = value bb e1 in add_texpr bb {e with eexpr = TUnop(op,flag,e1)}; bb | TLocal _ when not ctx.config.AnalyzerConfig.local_dce -> add_texpr bb e; bb (* no-side-effect *) | TEnumParameter _ | TFunction _ | TConst _ | TTypeExpr _ | TLocal _ -> bb (* no-side-effect composites *) | TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) | TField(e1,_) | TUnop(_,_,e1) -> block_element bb e1 | TArray(e1,e2) | TBinop(_,e1,e2) -> let bb = block_element bb e1 in block_element bb e2 | TArrayDecl el -> block_el bb el | TObjectDecl fl -> block_el bb (List.map snd fl) | TFor _ | TWhile(_,_,DoWhile) -> assert false and block_el bb el = match !b_try_stack with | [] -> let rec loop bb el = match el with | [] -> bb | e :: el -> let bb = block_element bb e in if bb == g.g_unreachable then bb else loop bb el in loop bb el | bbl -> let rec loop bb el = match el with | [] -> bb | e :: el -> let bb = if not (can_throw e) then block_element bb e else begin let bb' = create_node BKNormal e.etype e.epos in add_cfg_edge bb bb' CFGGoto; List.iter (fun bb_exc -> add_cfg_edge bb bb_exc CFGMaybeThrow) bbl; set_syntax_edge bb (SEMerge bb'); close_node g bb; block_element bb' e end in if bb == g.g_unreachable then bb else loop bb el in loop bb el and block bb e = let el = match e.eexpr with | TBlock el -> el | _ -> [e] in block_el bb el in let bb_last = block bb_root tf.tf_expr in close_node g bb_last; add_cfg_edge bb_last bb_exit CFGGoto; (* implied return *) close_node g bb_exit; bb_root,bb_exit let from_tfunction ctx tf t p = let g = ctx.graph in let bb_func,bb_exit = func ctx g.g_root tf t p in ctx.entry <- bb_func; close_node g g.g_root; g.g_exit <- bb_exit; set_syntax_edge bb_exit SEEnd let rec block_to_texpr_el ctx bb = if bb.bb_dominator == ctx.graph.g_unreachable then [] else begin let block bb = block_to_texpr ctx bb in let rec loop bb se = let el = List.rev (DynArray.to_list bb.bb_el) in match el,se with | el,SESubBlock(bb_sub,bb_next) -> Some bb_next,(block bb_sub) :: el | el,SEMerge bb_next -> Some bb_next,el | el,(SEEnd | SENone) -> None,el | {eexpr = TWhile(e1,_,flag)} as e :: el,(SEWhile(_,bb_body,bb_next)) -> let e2 = block bb_body in Some bb_next,{e with eexpr = TWhile(e1,e2,flag)} :: el | el,SETry(bb_try,_,bbl,bb_next,p) -> Some bb_next,(mk (TTry(block bb_try,List.map (fun (v,bb) -> v,block bb) bbl)) ctx.com.basic.tvoid p) :: el | e1 :: el,se -> let e1 = Texpr.skip e1 in let bb_next,e1_def,t,p = match se with | SEIfThen(bb_then,bb_next,p) -> Some bb_next,TIf(e1,block bb_then,None),ctx.com.basic.tvoid,p | SEIfThenElse(bb_then,bb_else,bb_next,t,p) -> Some bb_next,TIf(e1,block bb_then,Some (block bb_else)),t,p | SESwitch(bbl,bo,bb_next,p) -> Some bb_next,TSwitch(e1,List.map (fun (el,bb) -> el,block bb) bbl,Option.map block bo),ctx.com.basic.tvoid,p | _ -> abort (Printf.sprintf "Invalid node exit: %s" (s_expr_pretty e1)) bb.bb_pos in bb_next,(mk e1_def t p) :: el | [],_ -> None,[] in let bb_next,el = loop bb bb.bb_syntax_edge in let el = match bb_next with | None -> el | Some bb -> (block_to_texpr_el ctx bb) @ el in el end and block_to_texpr ctx bb = assert(bb.bb_closed); let el = block_to_texpr_el ctx bb in let e = mk (TBlock (List.rev el)) bb.bb_type bb.bb_pos in e and func ctx i = let bb,t,p,tf = Hashtbl.find ctx.graph.g_functions i in let e = block_to_texpr ctx bb in let rec loop e = match e.eexpr with | TLocal v when not (is_unbound v) -> {e with eexpr = TLocal (get_var_origin ctx.graph v)} | TVar(v,eo) when not (is_unbound v) -> let eo = Option.map loop eo in let v' = get_var_origin ctx.graph v in {e with eexpr = TVar(v',eo)} | TBinop(OpAssign,e1,({eexpr = TBinop(op,e2,e3)} as e4)) when target_handles_assign_ops ctx.com -> let e1 = loop e1 in let e2 = loop e2 in let e3 = loop e3 in let is_valid_assign_op = function | OpAdd | OpMult | OpDiv | OpSub | OpAnd | OpOr | OpXor | OpShl | OpShr | OpUShr | OpMod -> true | OpAssignOp _ | OpInterval | OpArrow | OpAssign | OpEq | OpNotEq | OpGt | OpGte | OpLt | OpLte | OpBoolAnd | OpBoolOr -> false in begin match e1.eexpr,e2.eexpr with | TLocal v1,TLocal v2 when v1 == v2 && not v1.v_capture && is_valid_assign_op op -> begin match op,e3.eexpr with | OpAdd,TConst (TInt i32) when Int32.to_int i32 = 1 && target_handles_assign_ops ctx.com -> {e with eexpr = TUnop(Increment,Prefix,e1)} | OpSub,TConst (TInt i32) when Int32.to_int i32 = 1 && target_handles_assign_ops ctx.com -> {e with eexpr = TUnop(Decrement,Prefix,e1)} | _ -> {e with eexpr = TBinop(OpAssignOp op,e1,e3)} end | _ -> {e with eexpr = TBinop(OpAssign,e1,{e4 with eexpr = TBinop(op,e2,e3)})} end | TCall({eexpr = TConst (TString "fun")},[{eexpr = TConst (TInt i32)}]) -> func ctx (Int32.to_int i32) | TCall({eexpr = TLocal v},_) when is_really_unbound v -> e | _ -> Type.map_expr loop e in let e = loop e in mk (TFunction {tf with tf_expr = e}) t p let to_texpr ctx = func ctx ctx.entry.bb_idhaxe_3.4.4.orig/src/optimization/analyzerTypes.ml0000664000175000017500000004214413166552354022142 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open Ast open Type open Common (* A BasicBlock represents a node in the control flow. It has expression elements similar to TBlock in the AST, but also holds additional information related to control flow and variables. Basic blocks are created whenever it is relevant for control flow. They differ from TBlock in that only their final element can be a control flow expression (the terminator). As a consequence, a given TBlock is split up into several basic blocks when control flow expressions are encountered. *) module BasicBlock = struct type block_kind = | BKRoot (* The unique root block of the graph *) | BKNormal (* A normal block *) | BKFunctionBegin of tfunc (* Entry block of a function *) | BKFunctionEnd (* Exit block of a function *) | BKSub (* A sub block *) | BKConditional (* A "then", "else" or "case" block *) | BKLoopHead (* Header block of a loop *) | BKException (* Relay block for exceptions *) | BKUnreachable (* The unique unreachable block *) | BKCatch of tvar (* A catch block *) type cfg_edge_Flag = | FlagExecutable (* Used by constant propagation to handle live edges *) | FlagDce (* Used by DCE to keep track of handled edges *) | FlagCopyPropagation (* Used by copy propagation to track handled eges *) type cfg_edge_kind = | CFGGoto (* An unconditional branch *) | CFGFunction (* Link to a function *) | CFGMaybeThrow (* The block may or may not throw an exception *) | CFGCondBranch of texpr (* A conditional branch *) | CFGCondElse (* A conditional alternative (else,default) *) and cfg_edge = { cfg_from : t; (* The source block *) cfg_to : t; (* The target block *) cfg_kind : cfg_edge_kind; (* The edge kind *) mutable cfg_flags : cfg_edge_Flag list; (* Edge flags *) } and syntax_edge = | SEIfThen of t * t * pos (* `if` with "then" and "next" *) | SEIfThenElse of t * t * t * Type.t * pos (* `if` with "then", "else" and "next" *) | SESwitch of (texpr list * t) list * t option * t * pos (* `switch` with cases, "default" and "next" *) | SETry of t * t * (tvar * t) list * t * pos (* `try` with "exc", catches and "next" *) | SEWhile of t * t * t (* `while` with "head", "body" and "next" *) | SESubBlock of t * t (* "sub" with "next" *) | SEMerge of t (* Merge to same block *) | SEEnd (* End of syntax *) | SENone (* No syntax exit *) and t = { bb_id : int; (* The unique ID of the block *) bb_type : Type.t; (* The block type *) bb_pos : pos; (* The block position *) bb_kind : block_kind; (* The block kind *) mutable bb_closed : bool; (* Whether or not the block has been closed *) (* elements *) bb_el : texpr DynArray.t; (* The block expressions *) bb_phi : texpr DynArray.t; (* SSA-phi expressions *) (* relations *) mutable bb_outgoing : cfg_edge list; (* Outgoing edges *) mutable bb_incoming : cfg_edge list; (* Incoming edges *) mutable bb_dominator : t; (* The block's dominator *) mutable bb_dominated : t list; (* The dominated blocks *) mutable bb_df : t list; (* The dominance frontier *) mutable bb_syntax_edge : syntax_edge; (* The syntactic edge *) mutable bb_loop_groups : int list; (* The loop groups this block belongs to *) mutable bb_scopes : int list; (* The scopes this block belongs to *) (* variables *) mutable bb_var_writes : tvar list; (* List of assigned variables *) } let s_block_kind = function | BKRoot -> "BKRoot" | BKNormal -> "BKNormal" | BKFunctionBegin _ -> "BKFunctionBegin" | BKFunctionEnd -> "BKFunctionEnd" | BKSub -> "BKSub" | BKConditional -> "BKConditional" | BKLoopHead -> "BKLoopHead" | BKException -> "BKException" | BKUnreachable -> "BKUnreachable" | BKCatch _ -> "BKCatch" let s_cfg_edge_kind = function | CFGGoto -> "CFGGoto" | CFGFunction -> "CFGFunction" | CFGMaybeThrow -> "CFGMaybeThrow" | CFGCondBranch e -> "CFGCondBranch " ^ (s_expr_pretty false "" false (s_type (print_context())) e) | CFGCondElse -> "CFGCondElse" let has_flag edge flag = List.mem flag edge.cfg_flags (* expressions *) let add_texpr bb e = DynArray.add bb.bb_el e let get_texpr bb is_phi i = DynArray.get (if is_phi then bb.bb_phi else bb.bb_el) i (* edges *) let set_syntax_edge bb se = bb.bb_syntax_edge <- se let add_cfg_edge bb_from bb_to kind = if bb_from.bb_kind <> BKUnreachable then begin let edge = { cfg_from = bb_from; cfg_to = bb_to; cfg_kind = kind; cfg_flags = [] } in bb_from.bb_outgoing <- edge :: bb_from.bb_outgoing; bb_to.bb_incoming <- edge :: bb_to.bb_incoming; end let _create id kind t p = let rec bb = { bb_kind = kind; bb_id = id; bb_type = t; bb_pos = p; bb_closed = false; bb_el = DynArray.create(); bb_phi = DynArray.create(); bb_outgoing = []; bb_incoming = []; bb_dominator = bb; bb_dominated = []; bb_df = []; bb_syntax_edge = SENone; bb_loop_groups = []; bb_var_writes = []; bb_scopes = []; } in bb let in_scope bb bb' = match bb'.bb_scopes with | [] -> abort (Printf.sprintf "Scope-less block (kind: %s)" (s_block_kind bb'.bb_kind)) bb'.bb_pos | scope :: _ -> List.mem scope bb.bb_scopes end (* A Graph contains all relevant information for a given method. It is built from the field expression and then refined in subsequent modules such as Ssa. *) module Graph = struct open BasicBlock type texpr_lookup = BasicBlock.t * bool * int type tfunc_info = BasicBlock.t * Type.t * pos * tfunc type var_write = BasicBlock.t list type 'a itbl = (int,'a) Hashtbl.t type var_info = { vi_var : tvar; (* The variable itself *) vi_extra : tvar_extra; (* The original v_extra *) vi_bb_declare : BasicBlock.t; (* The block where this variable was declared *) mutable vi_origin : tvar; (* The origin variable of this variable *) mutable vi_writes : var_write; (* A list of blocks that assign to this variable *) mutable vi_value : texpr_lookup option; (* The value of this variable, if known *) mutable vi_ssa_edges : texpr_lookup list; (* The expressions this variable influences *) mutable vi_reaching_def : tvar option; (* The current reaching definition variable of this variable *) } type t = { mutable g_root : BasicBlock.t; (* The unique root block *) mutable g_exit : BasicBlock.t; (* The unique exit block *) mutable g_unreachable : BasicBlock.t; (* The unique unreachable block *) mutable g_functions : tfunc_info itbl; (* A map of functions, indexed by their block IDs *) mutable g_nodes : BasicBlock.t list; (* A list of all blocks *) g_var_infos : var_info DynArray.t; (* A map of variable information *) mutable g_loops : BasicBlock.t IntMap.t; (* A map containing loop information *) } (* variables *) let create_var_info g bb v = let vi = { vi_var = v; vi_extra = v.v_extra; vi_bb_declare = bb; vi_origin = v; vi_writes = []; vi_value = None; vi_ssa_edges = []; vi_reaching_def = None; } in DynArray.add g.g_var_infos vi; let i = DynArray.length g.g_var_infos - 1 in v.v_extra <- Some([],Some (mk (TConst (TInt (Int32.of_int i))) t_dynamic null_pos)); vi let get_var_info g v = match v.v_extra with | Some(_,Some {eexpr = TConst (TInt i32)}) -> DynArray.get g.g_var_infos (Int32.to_int i32) | _ -> print_endline "Unbound variable, please report this"; print_endline (Printer.s_tvar v); create_var_info g g.g_unreachable v let declare_var g v bb = ignore(create_var_info g bb v) let add_var_def g bb v = if bb.bb_id > 0 then begin bb.bb_var_writes <- v :: bb.bb_var_writes; let vi = get_var_info g v in vi.vi_writes <- bb :: vi.vi_writes; end let set_var_value g v bb is_phi i = (get_var_info g v).vi_value <- Some (bb,is_phi,i) let get_var_value g v = let value = (get_var_info g v).vi_value in let bb,is_phi,i = match value with | None -> raise Not_found | Some l -> l in match (get_texpr bb is_phi i).eexpr with | TVar(_,Some e) | TBinop(OpAssign,_,e) -> e | _ -> assert false let add_var_origin g v v_origin = (get_var_info g v).vi_origin <- v_origin let get_var_origin g v = (get_var_info g v).vi_origin let add_ssa_edge g v bb is_phi i = let vi = get_var_info g v in vi.vi_ssa_edges <- (bb,is_phi,i) :: vi.vi_ssa_edges (* nodes *) let add_function g tf t p bb = Hashtbl.add g.g_functions bb.bb_id (bb,t,p,tf) let alloc_id = let r = ref 1 in (fun () -> incr r; !r ) let create_node g kind t p = let bb = BasicBlock._create (alloc_id()) kind t p in g.g_nodes <- bb :: g.g_nodes; bb let close_node g bb = if bb.bb_id > 0 then begin assert(not bb.bb_closed); bb.bb_closed <- true end let iter_dom_tree_from g bb f = let rec loop bb = f bb; List.iter loop bb.bb_dominated in loop bb let iter_dom_tree g f = iter_dom_tree_from g g.g_root f let iter_edges_from g bb f = iter_dom_tree_from g bb (fun bb -> List.iter f bb.bb_outgoing) let iter_edges g f = iter_dom_tree g (fun bb -> List.iter f bb.bb_outgoing) (* graph *) let create t p = let bb_root = BasicBlock._create 1 BKRoot t p; in let bb_unreachable = BasicBlock._create 0 BKUnreachable t_dynamic null_pos in { g_root = bb_root; g_exit = bb_unreachable; g_unreachable = bb_unreachable; g_functions = Hashtbl.create 0; g_nodes = [bb_root]; g_var_infos = DynArray.create(); g_loops = IntMap.empty; } let check_integrity g = List.iter (fun bb -> List.iter (fun edge -> if edge.cfg_to = g.g_unreachable then print_endline (Printf.sprintf "Outgoing edge from %i to the unreachable block" bb.bb_id) else if not (List.memq edge edge.cfg_to.bb_incoming) then print_endline (Printf.sprintf "Outgoing edge %i -> %i has no matching incoming edge" edge.cfg_from.bb_id edge.cfg_to.bb_id) ) bb.bb_outgoing; List.iter (fun edge -> if edge.cfg_from == g.g_unreachable then print_endline (Printf.sprintf "Incoming edge to %i from the unreachable block" bb.bb_id) else if not (List.memq edge edge.cfg_from.bb_outgoing) then print_endline (Printf.sprintf "Incoming edge %i <- %i has no matching outgoing edge" edge.cfg_to.bb_id edge.cfg_from.bb_id) ) bb.bb_incoming ) g.g_nodes (* inference *) type dom_bb_info = { bb : BasicBlock.t; parent : dom_bb_info; mutable idom : dom_bb_info; mutable semi : int; mutable label : dom_bb_info; mutable ancestor : dom_bb_info; mutable bucket : dom_bb_info list; } (* Infers the immediate dominators for all reachable blocks. This function can be run multiple times in case an update is necessary. *) let infer_immediate_dominators g = let info = Hashtbl.create 0 in let nodes = DynArray.create () in let get_info i = Hashtbl.find info i in let add_info bb bb_parent = let rec bbi = { bb = bb; parent = bbi; idom = bbi; semi = DynArray.length nodes; label = bbi; ancestor = bbi; bucket = []; } in let bbi = if bb == bb_parent then bbi else {bbi with parent = get_info bb_parent.bb_id} in Hashtbl.add info bb.bb_id bbi; DynArray.add nodes bbi; in let rec loop bb_parent bb = bb.bb_dominated <- []; add_info bb bb_parent; List.iter (fun edge -> let bb_to = edge.cfg_to in if not (Hashtbl.mem info bb_to.bb_id) then loop bb bb_to ) bb.bb_outgoing in loop g.g_root g.g_root; let compress bbi = let rec loop l bbi = if bbi.ancestor == bbi then l else loop (bbi :: l) bbi.ancestor in let worklist = loop [bbi] bbi.ancestor in match worklist with | a :: worklist -> ignore(List.fold_left (fun (a,min_semi) bbi_desc -> let bbi = bbi_desc.label in if bbi.semi > min_semi then begin bbi_desc.label <- a.label; (bbi_desc,min_semi) end else (bbi_desc,bbi.semi) ) (a,a.label.semi) worklist) | [] -> assert false in let eval v = let bbi = get_info v in if bbi.ancestor != bbi then begin compress bbi; bbi.label end else bbi in let rec loop nodes' = match nodes' with | [_] -> () | [] -> assert false | w :: nodes' -> let semi = List.fold_left (fun acc v -> min acc (eval v.cfg_from.bb_id).semi) w.semi w.bb.bb_incoming in w.semi <- semi; let bbi = DynArray.get nodes semi in bbi.bucket <- w :: bbi.bucket; let bbi_p = w.parent in w.ancestor <- bbi_p; List.iter (fun v -> let u = eval v.bb.bb_id in if u.semi < v.semi then v.idom <- u else v.idom <- bbi_p ) bbi_p.bucket; bbi_p.bucket <- []; loop nodes' in let l = DynArray.to_list nodes in loop (List.rev l); List.iter (fun w -> if w.idom != (DynArray.get nodes w.semi) then w.idom <- w.idom.idom ) (List.tl l); DynArray.iter (fun bbi -> if bbi.idom != bbi then begin let bb = bbi.bb in let bb' = bbi.idom.bb in if bb != bb' then begin bb.bb_dominator <- bb'; bb'.bb_dominated <- bb :: bb'.bb_dominated end end ) nodes (* Infers the dominance frontier for all reachable blocks. This function should only be run once. *) let infer_dominance_frontier g = iter_edges g (fun edge -> let rec loop bb = if bb != g.g_unreachable && bb != edge.cfg_to && bb != edge.cfg_to.bb_dominator then begin if edge.cfg_to != g.g_exit then bb.bb_df <- edge.cfg_to :: bb.bb_df; if bb.bb_dominator != bb then loop bb.bb_dominator end in loop edge.cfg_from ) (* Infers variable declarations and definitions. This function should only be run once. *) let infer_var_writes g = iter_dom_tree g (fun bb -> begin match bb.bb_kind with | BKCatch v -> declare_var g v bb; add_var_def g bb v | BKFunctionBegin tf -> List.iter (fun (v,_) -> declare_var g v bb; add_var_def g bb v ) tf.tf_args; | _ -> () end; DynArray.iter (fun e -> match e.eexpr with | TVar(v,eo) when not (is_unbound v) -> declare_var g v bb; if eo <> None then add_var_def g bb v; | TBinop(OpAssign,{eexpr = TLocal v},_) when not (is_unbound v) -> add_var_def g bb v | _ -> () ) bb.bb_el ) (* Infers the scopes of all reachable blocks. This function can be run multiple times in case an update is necessary *) let infer_scopes g = let next_scope_id = ref 0 in let next_scope scopes = incr next_scope_id; !next_scope_id :: scopes in let rec loop scopes bb = bb.bb_scopes <- scopes; begin match bb.bb_syntax_edge with | SEIfThen(bb_then,bb_next,_) -> loop (next_scope scopes) bb_then; loop scopes bb_next | SEIfThenElse(bb_then,bb_else,bb_next,_,_) -> loop (next_scope scopes) bb_then; loop (next_scope scopes) bb_else; loop scopes bb_next | SESwitch(cases,bbo,bb_next,_) -> List.iter (fun (_,bb_case) -> loop (next_scope scopes) bb_case) cases; (match bbo with None -> () | Some bb -> loop (next_scope scopes) bb); loop scopes bb_next; | SETry(bb_try,bb_exc,catches,bb_next,_) -> let scopes' = next_scope scopes in loop scopes' bb_try; loop scopes' bb_exc; List.iter (fun (_,bb_catch) -> loop (next_scope scopes) bb_catch) catches; loop scopes bb_next | SEWhile(bb_head,bb_body,bb_next) -> let scopes' = next_scope scopes in loop scopes' bb_head; loop scopes' bb_body; loop scopes bb_next; | SESubBlock(bb_sub,bb_next) -> loop (next_scope scopes) bb_sub; loop scopes bb_next | SEMerge bb -> loop scopes bb | SEEnd | SENone -> () end in Hashtbl.iter (fun _ (bb,_,_,_) -> loop [0] bb) g.g_functions end type analyzer_context = { com : Common.context; config : AnalyzerConfig.t; graph : Graph.t; temp_var_name : string; mutable entry : BasicBlock.t; mutable has_unbound : bool; mutable loop_counter : int; mutable loop_stack : int list; mutable debug_exprs : (string * texpr) list; mutable name_stack : string list; }haxe_3.4.4.orig/src/optimization/dce.ml0000664000175000017500000006674113166552354020034 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Common open Type open Globals type dce = { com : context; full : bool; std_dirs : string list; debug : bool; follow_expr : dce -> texpr -> unit; dependent_types : (string list * string,module_type list) Hashtbl.t; 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_path = ([],("Math"|"Array"|"String"))} when dce.com.platform = Lua -> 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; Hashtbl.replace dce.curclass.cl_module.m_extra.m_features s true (* 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 = begin match c.cl_constructor with | Some cf -> add cf | None -> () end; match c.cl_super with | Some(csup,_) -> loop csup | None -> () in loop c end else begin 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 end 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; (* do not generate has_enum feature for @:fakeEnum enums since they are not really enums *) if not (Meta.has Meta.FakeEnum e.e_meta) then 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 (Typecore.AbstractCast.find_multitype_specialization dce.com a pl p)) with Error.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 = let dependent = try Hashtbl.find dce.dependent_types csup.cl_path with Not_found -> let cl = List.filter (fun mt -> match mt with TClassDecl c -> is_parent csup c | _ -> false) dce.com.types in Hashtbl.add dce.dependent_types csup.cl_path cl; cl in 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 | _ -> () ) dependent (* 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 mark_directly_used_t com p t = match follow t with | TInst({cl_kind = KNormal} as c,pl) -> mark_directly_used_class c; List.iter (mark_directly_used_t com p) pl | TEnum(e,pl) -> mark_directly_used_enum e; List.iter (mark_directly_used_t com p) pl | TAbstract(a,pl) when Meta.has Meta.MultiType a.a_meta -> begin try (* this is copy-pasted from mark_t *) mark_directly_used_t com p (snd (Typecore.AbstractCast.find_multitype_specialization com a pl p)) with Error.Error _ -> () end | TAbstract(a,pl) -> List.iter (mark_directly_used_t com p) pl; if not (Meta.has Meta.CoreType a.a_meta) then mark_directly_used_t com p (Abstract.get_underlying_type a pl) | _ -> () 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_field dce e fa is_call_expr = let do_default = fun () -> 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 in let mark_instance_field_access c cf = if (not is_call_expr && dce.com.platform = Python) then begin if c.cl_path = ([], "Array") then begin check_and_add_feature dce "closure_Array"; check_and_add_feature dce ("python.internal.ArrayImpl." ^ cf.cf_name); check_and_add_feature dce ("python.internal.ArrayImpl") end else if c.cl_path = ([], "String") then begin check_and_add_feature dce "closure_String"; check_and_add_feature dce ("python.internal.StringImpl." ^ cf.cf_name); check_and_add_feature dce ("python.internal.StringImpl") end end; in begin match fa with | FStatic(c,cf) -> mark_class dce c; mark_field dce c cf true; | FInstance(c,_,cf) -> (*mark_instance_field_access c cf;*) mark_class dce c; mark_field dce c cf false | FClosure (Some(c, _), cf) -> mark_instance_field_access c cf; do_default() | FClosure _ -> do_default() | _ -> do_default() end; expr dce e; 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 begin check_feature dce "typed_catch"; mark_directly_used_t dce.com v.v_pos v.v_type; end; 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; | TUnop((Increment | Decrement),_,({eexpr = TArray _} as e1)) -> check_and_add_feature dce "array_write"; check_and_add_feature dce "array_read"; expr dce e1; | 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)) as op,e1,e2) when ((is_string e1.etype || is_string e2.etype) && not ( is_const_string e1 && is_const_string e2)) -> (* add array_write if we're doing += to an array element, since this pattern comes before the array_write one *) (match op, e1 with (OpAssignOp _, {eexpr = TArray({etype = t},_)}) when is_array t -> check_and_add_feature dce "array_write" | _ -> ()); 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 | OpAssignOp OpUShr),e1,e2) -> check_and_add_feature dce "binop_>>>"; expr dce e1; expr dce e2; | TCall(({ eexpr = TField(ef, fa) } as e2), el ) -> mark_t dce e2.epos e2.etype; expr_field dce ef fa true; List.iter (expr dce) el; | TField(e,fa) -> expr_field dce e fa false; | TThrow e -> check_and_add_feature dce "has_throw"; expr dce e; (* TODO: Simon, save me! \o This is a hack needed to keep toString field of the actual exception objects that are thrown, but are wrapped into HaxeError before DCE comes into play. *) let e = (match e.eexpr with | TNew({cl_path=(["js";"_Boot"],"HaxeError")}, _, [eoriginal]) -> eoriginal | _ -> e ) in to_string dce e.etype | _ -> Type.iter (expr dce) e let fix_accessors com = List.iter (fun mt -> match mt with (* filter empty abstract implementation classes (issue #1885). *) | TClassDecl({cl_kind = KAbstractImpl _} as c) when c.cl_ordered_statics = [] && c.cl_ordered_fields = [] && not (Meta.has Meta.Used c.cl_meta) -> c.cl_extern <- true | TClassDecl({cl_kind = KAbstractImpl a} as c) when Meta.has Meta.Enum a.a_meta -> let is_runtime_field cf = not (Meta.has Meta.Enum cf.cf_meta) in (* also filter abstract implementation classes that have only @:enum fields (issue #2858) *) if not (List.exists is_runtime_field c.cl_ordered_statics) then c.cl_extern <- true | (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; dependent_types = Hashtbl.create 0; std_dirs = if full then [] else List.map Path.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)))},_)} | Some {eexpr = TBlock ({ 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 null_pos 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.4.4.orig/src/optimization/filters.ml0000664000175000017500000010522113166552354020734 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Common open Type open Typecore open Error open Globals (* PASS 1 begin *) (* Adds final returns to functions as required by some platforms *) let rec add_final_return e = let rec loop e t = let def_return p = let c = (match follow t with | TAbstract ({ a_path = [],"Int" },_) -> TInt 0l | TAbstract ({ a_path = [],"Float" },_) -> TFloat "0." | TAbstract ({ a_path = [],"Bool" },_) -> TBool false | _ -> TNull ) in { eexpr = TReturn (Some { eexpr = TConst c; epos = p; etype = t }); etype = t_dynamic; epos = p } in match e.eexpr with | TBlock el -> (match List.rev el with | [] -> e | elast :: el -> match loop elast t with | { eexpr = TBlock el2 } -> { e with eexpr = TBlock ((List.rev el) @ el2) } | elast -> { e with eexpr = TBlock (List.rev (elast :: el)) }) | TReturn _ -> e | _ -> { e with eexpr = TBlock [e;def_return e.epos] } in let e = Type.map_expr add_final_return e in match e.eexpr with | TFunction f -> let f = (match follow f.tf_type with | TAbstract ({ a_path = [],"Void" },[]) -> f | _ -> { f with tf_expr = loop f.tf_expr f.tf_type } ) in { e with eexpr = TFunction f } | _ -> e let rec wrap_js_exceptions com e = let rec is_error t = match follow t with | TInst ({cl_path = (["js"],"Error")},_) -> true | TInst ({cl_super = Some (csup,tl)}, _) -> is_error (TInst (csup,tl)) | _ -> false in let rec loop e = match e.eexpr with | TThrow eerr when not (is_error eerr.etype) -> let terr = List.find (fun mt -> match mt with TClassDecl {cl_path = ["js";"_Boot"],"HaxeError"} -> true | _ -> false) com.types in let cerr = match terr with TClassDecl c -> c | _ -> assert false in (match eerr.etype with | TDynamic _ -> let eterr = Codegen.ExprBuilder.make_static_this cerr e.epos in let ewrap = Codegen.fcall eterr "wrap" [eerr] t_dynamic e.epos in { e with eexpr = TThrow ewrap } | _ -> let ewrap = { eerr with eexpr = TNew (cerr,[],[eerr]); etype = TInst (cerr,[]) } in { e with eexpr = TThrow ewrap } ) | _ -> Type.map_expr loop e in loop e (* -------------------------------------------------------------------------- *) (* CHECK LOCAL VARS INIT *) let check_local_vars_init e = let intersect vl1 vl2 = PMap.mapi (fun v t -> t && PMap.find v vl2) vl1 in let join vars cvars = List.iter (fun v -> vars := intersect !vars v) cvars in let restore vars old_vars declared = (* restore variables declared in this block to their previous state *) vars := List.fold_left (fun acc v -> try PMap.add v (PMap.find v old_vars) acc with Not_found -> PMap.remove v acc ) !vars declared; in let declared = ref [] in let outside_vars = ref IntMap.empty in let rec loop vars e = match e.eexpr with | TLocal v -> let init = (try PMap.find v.v_id !vars with Not_found -> true) in if not init && not (IntMap.mem v.v_id !outside_vars) then begin if v.v_name = "this" then error "Missing this = value" e.epos else error ("Local variable " ^ v.v_name ^ " used without being initialized") e.epos end | TVar (v,eo) -> begin match eo with | None when Meta.has Meta.InlineConstructorVariable v.v_meta -> () | None -> declared := v.v_id :: !declared; vars := PMap.add v.v_id false !vars | Some e -> loop vars e end | TBlock el -> let old = !declared in let old_vars = !vars in declared := []; List.iter (loop vars) el; restore vars old_vars (List.rev !declared); declared := old; | TBinop (OpAssign,{ eexpr = TLocal v },e) when PMap.mem v.v_id !vars -> loop vars e; vars := PMap.add v.v_id true !vars | TIf (e1,e2,eo) -> loop vars e1; let vbase = !vars in loop vars e2; (match eo with | None -> vars := vbase (* ignore else false cases (they are added by the side-effect handler) *) | Some {eexpr = TConst (TBool(false))} -> () | Some e -> let v1 = !vars in vars := vbase; loop vars e; vars := intersect !vars v1) | TWhile (cond,e,flag) -> (match flag with | NormalWhile when (match cond.eexpr with TParenthesis {eexpr = TConst (TBool true)} -> false | _ -> true) -> loop vars cond; let old = !vars in loop vars e; vars := old; | _ -> loop vars e; loop vars cond) | TTry (e,catches) -> let cvars = List.map (fun (v,e) -> let old = !vars in loop vars e; let v = !vars in vars := old; v ) catches in loop vars e; join vars cvars; | TSwitch (e,cases,def) -> loop vars e; let cvars = List.map (fun (ec,e) -> let old = !vars in List.iter (loop vars) ec; vars := old; loop vars e; let v = !vars in vars := old; v ) cases in (match def with | None when (match e.eexpr with TMeta((Meta.Exhaustive,_,_),_) | TParenthesis({eexpr = TMeta((Meta.Exhaustive,_,_),_)}) -> true | _ -> false) -> (match cvars with | cv :: cvars -> PMap.iter (fun i b -> if b then vars := PMap.add i b !vars) cv; join vars cvars | [] -> ()) | None -> () | Some e -> loop vars e; join vars cvars) (* mark all reachable vars as initialized, since we don't exit the block *) | TBreak | TContinue | TReturn None -> vars := PMap.map (fun _ -> true) !vars | TThrow e | TReturn (Some e) -> loop vars e; vars := PMap.map (fun _ -> true) !vars | TFunction tf -> let old = !outside_vars in (* Mark all known variables as "outside" so we can ignore their initialization state within the function. We cannot use `vars` directly because we still care about initializations the function might make. *) PMap.iter (fun i _ -> outside_vars := IntMap.add i true !outside_vars) !vars; loop vars tf.tf_expr; outside_vars := old; | _ -> Type.iter (loop vars) e in loop (ref PMap.empty) e; e (* -------------------------------------------------------------------------- *) (* BLOCK VARIABLES CAPTURE *) (* For some platforms, it will simply mark the variables which are used in closures using the v_capture flag so it can be processed in a more optimized For Flash/JS platforms, it will ensure that variables used in loop sub-functions have an unique scope. It transforms the following expression : for( x in array ) funs.push(function() return x++); Into the following : for( _x in array ) { var x = [_x]; funs.push(function(x) { function() return x[0]++; }(x)); } *) type usage = | Block of ((usage -> unit) -> unit) | Loop of ((usage -> unit) -> unit) | Function of ((usage -> unit) -> unit) | Declare of tvar | Use of tvar | Assign of tvar let rec local_usage f e = match e.eexpr with | TBinop ((OpAssign | OpAssignOp _), { eexpr = TLocal v }, e2) -> local_usage f e2; f (Assign v) | TUnop ((Increment | Decrement), _, { eexpr = TLocal v }) -> f (Assign v) | TLocal v -> f (Use v) | TVar (v,eo) -> (match eo with None -> () | Some e -> local_usage f e); f (Declare v); | TFunction tf -> let cc f = List.iter (fun (v,_) -> f (Declare v)) tf.tf_args; local_usage f tf.tf_expr; in f (Function cc) | TBlock l -> f (Block (fun f -> List.iter (local_usage f) l)) | TFor (v,it,e) -> local_usage f it; f (Loop (fun f -> f (Declare v); local_usage f e; )) | TWhile _ -> f (Loop (fun f -> iter (local_usage f) e )) | TTry (e,catchs) -> local_usage f e; List.iter (fun (v,e) -> f (Block (fun f -> f (Declare v); local_usage f e; )) ) catchs; | _ -> iter (local_usage f) e let captured_vars com e = let t = com.basic in let impl = match com.platform with (* optimized version for C#/Java - use native arrays *) | Cs | Java -> let cnativearray = match (List.find (fun md -> match md with | TClassDecl ({ cl_path = ["cs"|"java"],"NativeArray" }) -> true | _ -> false ) com.types) with TClassDecl cl -> cl | _ -> assert false in object method captured_type t = TInst (cnativearray,[t]) method mk_ref v ve p = match ve with | None -> let eone = mk (TConst (TInt (Int32.of_int 1))) t.tint p in let t = match v.v_type with TInst (_, [t]) -> t | _ -> assert false in mk (TNew (cnativearray,[t],[eone])) v.v_type p | Some e -> { (Optimizer.mk_untyped_call "__array__" p [e]) with etype = v.v_type } method mk_ref_access e v = mk (TArray ({ e with etype = v.v_type }, mk (TConst (TInt 0l)) t.tint e.epos)) e.etype e.epos method mk_init av v pos = let elocal = mk (TLocal v) v.v_type pos in let earray = { (Optimizer.mk_untyped_call "__array__" pos [elocal]) with etype = av.v_type } in mk (TVar (av,Some earray)) t.tvoid pos end (* default implementation - use haxe array *) | _ -> object method captured_type = t.tarray method mk_ref v ve p = mk (TArrayDecl (match ve with None -> [] | Some e -> [e])) v.v_type p method mk_ref_access e v = mk (TArray ({ e with etype = v.v_type }, mk (TConst (TInt 0l)) t.tint e.epos)) e.etype e.epos method mk_init av v pos = mk (TVar (av,Some (mk (TArrayDecl [mk (TLocal v) v.v_type pos]) av.v_type pos))) t.tvoid pos end in let mk_var v used = let v2 = alloc_var v.v_name (PMap.find v.v_id used) v.v_pos in v2.v_meta <- v.v_meta; v2 in let rec wrap used e = match e.eexpr with | TVar (v,ve) -> let v,ve = if PMap.mem v.v_id used then v, Some (impl#mk_ref v (Option.map (wrap used) ve) e.epos) else v, (match ve with None -> None | Some e -> Some (wrap used e)) in { e with eexpr = TVar (v,ve) } | TLocal v when PMap.mem v.v_id used -> impl#mk_ref_access e v | TFor (v,it,expr) when PMap.mem v.v_id used -> let vtmp = mk_var v used in let it = wrap used it in let expr = wrap used expr in mk (TFor (vtmp,it,Type.concat (impl#mk_init v vtmp e.epos) expr)) e.etype e.epos | TTry (expr,catchs) -> let catchs = List.map (fun (v,e) -> let e = wrap used e in try let vtmp = mk_var v used in vtmp, Type.concat (impl#mk_init v vtmp e.epos) e with Not_found -> v, e ) catchs in mk (TTry (wrap used expr,catchs)) e.etype e.epos | TFunction f -> (* list variables that are marked as used, but also used in that function and which are not declared inside it ! *) let fused = ref PMap.empty in let tmp_used = ref used in let rec browse = function | Block f | Loop f | Function f -> f browse | Use v | Assign v -> if PMap.mem v.v_id !tmp_used then fused := PMap.add v.v_id v !fused; | Declare v -> tmp_used := PMap.remove v.v_id !tmp_used in local_usage browse e; let vars = PMap.fold (fun v acc -> v :: acc) !fused [] in (* in case the variable has been marked as used in a parallel scope... *) let fexpr = ref (wrap used f.tf_expr) in let fargs = List.map (fun (v,o) -> if PMap.mem v.v_id used then let vtmp = mk_var v used in fexpr := Type.concat (impl#mk_init v vtmp e.epos) !fexpr; vtmp, o else v, o ) f.tf_args in let e = { e with eexpr = TFunction { f with tf_args = fargs; tf_expr = !fexpr } } in (* Create a new function scope to make sure that the captured loop variable will not be overwritten in next loop iteration *) if com.config.pf_capture_policy = CPLoopVars then (* We don't want to duplicate any variable declarations, so let's make copies (issue #3902). *) let new_vars = List.map (fun v -> v.v_id,alloc_var v.v_name v.v_type v.v_pos) vars in let rec loop e = match e.eexpr with | TLocal v -> begin try let v' = List.assoc v.v_id new_vars in v'.v_capture <- true; {e with eexpr = TLocal v'} with Not_found -> e end | _ -> Type.map_expr loop e in let e = loop e in mk (TCall ( Codegen.mk_parent (mk (TFunction { tf_args = List.map (fun (_,v) -> v, None) new_vars; tf_type = e.etype; tf_expr = mk_block (mk (TReturn (Some e)) e.etype e.epos); }) (TFun (List.map (fun (_,v) -> v.v_name,false,v.v_type) new_vars,e.etype)) e.epos), List.map (fun v -> mk (TLocal v) v.v_type e.epos) vars) ) e.etype e.epos else e | _ -> map_expr (wrap used) e and do_wrap used e = if PMap.is_empty used then e else let used = PMap.map (fun v -> let vt = v.v_type in v.v_type <- impl#captured_type vt; v.v_capture <- true; vt ) used in wrap used e and out_loop e = match e.eexpr with | TFor _ | TWhile _ -> (* collect variables that are declared in loop but used in subfunctions *) let vars = ref PMap.empty in let used = ref PMap.empty in let depth = ref 0 in let rec collect_vars in_loop = function | Block f -> let old = !vars in f (collect_vars in_loop); vars := old; | Loop f -> let old = !vars in f (collect_vars true); vars := old; | Function f -> incr depth; f (collect_vars false); decr depth; | Declare v -> if in_loop then vars := PMap.add v.v_id !depth !vars; | Use v | Assign v -> try let d = PMap.find v.v_id !vars in if d <> !depth then used := PMap.add v.v_id v !used; with Not_found -> () in local_usage (collect_vars false) e; do_wrap !used e | _ -> map_expr out_loop e and all_vars e = let vars = ref PMap.empty in let used = ref PMap.empty in let assigned = ref PMap.empty in let depth = ref 0 in let rec collect_vars = function | Block f -> let old = !vars in f collect_vars; vars := old; | Loop f -> let old = !vars in f collect_vars; vars := old; | Function f -> incr depth; f collect_vars; decr depth; | Declare v -> vars := PMap.add v.v_id !depth !vars; | Use v -> (try let d = PMap.find v.v_id !vars in if d <> !depth then used := PMap.add v.v_id v !used; with Not_found -> ()) | Assign v -> (try let d = PMap.find v.v_id !vars in (* different depth - needs wrap *) if d <> !depth then begin used := PMap.add v.v_id v !used; assigned := PMap.add v.v_id v !assigned; end (* same depth but assigned after being used on a different depth - needs wrap *) else if PMap.mem v.v_id !used then assigned := PMap.add v.v_id v !assigned; with Not_found -> ()) in local_usage collect_vars e; (* mark all capture variables - also used in rename_local_vars at later stage *) PMap.iter (fun _ v -> v.v_capture <- true) !used; !assigned in let captured = all_vars e in match com.config.pf_capture_policy with | CPNone -> e | CPWrapRef -> do_wrap captured e | CPLoopVars -> out_loop e (* -------------------------------------------------------------------------- *) (* RENAME LOCAL VARS *) let rename_local_vars ctx e = let vars = ref [] in let declare v = vars := v :: !vars in let reserved = ref StringMap.empty in let reserve name = reserved := StringMap.add name true !reserved in let check t = match (t_infos t).mt_path with | [], name | name :: _, _ -> reserve name in let check_type t = match follow t with | TInst (c,_) -> check (TClassDecl c) | TEnum (e,_) -> check (TEnumDecl e) | TType (t,_) -> check (TTypeDecl t) | TAbstract (a,_) -> check (TAbstractDecl a) | TMono _ | TLazy _ | TAnon _ | TDynamic _ | TFun _ -> () in let rec collect e = match e.eexpr with | TVar(v,eo) -> declare v; (match eo with None -> () | Some e -> collect e) | TFor(v,e1,e2) -> declare v; collect e1; collect e2; | TTry(e1,catches) -> collect e1; List.iter (fun (v,e) -> declare v; check_type v.v_type; collect e ) catches | TFunction tf -> List.iter (fun (v,_) -> declare v) tf.tf_args; collect tf.tf_expr | TTypeExpr t -> check t | TNew (c,_,_) -> Type.iter collect e; check (TClassDecl c); | TCast (e,Some t) -> collect e; check t; | TConst TSuper -> check_type e.etype | _ -> Type.iter collect e in (* Pass 1: Collect used identifiers and variables. *) reserve "this"; if ctx.com.platform = Java then reserve "_"; begin match ctx.curclass.cl_path with | s :: _,_ | [],s -> reserve s end; collect e; (* Pass 2: Check and rename variables. *) let count_table = Hashtbl.create 0 in let maybe_rename v = (* chop escape char for all local variables generated *) if is_gen_local v then v.v_name <- "_g" ^ String.sub v.v_name 1 (String.length v.v_name - 1); let name = ref v.v_name in let count = ref (try Hashtbl.find count_table v.v_name with Not_found -> 0) in while StringMap.mem !name !reserved do incr count; name := v.v_name ^ (string_of_int !count); done; reserve !name; Hashtbl.replace count_table v.v_name !count; if not (Meta.has Meta.RealPath v.v_meta) then v.v_meta <- (Meta.RealPath,[EConst (String v.v_name),e.epos],e.epos) :: v.v_meta; v.v_name <- !name; in List.iter maybe_rename (List.rev !vars); e let check_unification ctx e t = begin match e.eexpr,t with | TLocal v,TType({t_path = ["cs"],("Ref" | "Out")},_) -> (* TODO: this smells of hack, but we have to deal with it somehow *) v.v_capture <- true | _ -> () end; e (* PASS 1 end *) (* Saves a class state so it can be restored later, e.g. after DCE or native path rewrite *) let save_class_state ctx t = match t with | TClassDecl c -> let mk_field_restore f = let rec mk_overload_restore f = f.cf_name,f.cf_kind,f.cf_expr,f.cf_type,f.cf_meta,f.cf_params in ( f,mk_overload_restore f, List.map (fun f -> f,mk_overload_restore f) f.cf_overloads ) in let restore_field (f,res,overloads) = let restore_field (f,(name,kind,expr,t,meta,params)) = f.cf_name <- name; f.cf_kind <- kind; f.cf_expr <- expr; f.cf_type <- t; f.cf_meta <- meta; f.cf_params <- params; f in let f = restore_field (f,res) in f.cf_overloads <- List.map restore_field overloads; f in let mk_pmap lst = List.fold_left (fun pmap f -> PMap.add f.cf_name f pmap) PMap.empty lst in let meta = c.cl_meta and path = c.cl_path and ext = c.cl_extern and over = c.cl_overrides in let sup = c.cl_super and impl = c.cl_implements in let csr = Option.map (mk_field_restore) c.cl_constructor in let ofr = List.map (mk_field_restore) c.cl_ordered_fields in let osr = List.map (mk_field_restore) c.cl_ordered_statics in let init = c.cl_init in c.cl_restore <- (fun() -> c.cl_super <- sup; c.cl_implements <- impl; c.cl_meta <- meta; c.cl_extern <- ext; c.cl_path <- path; c.cl_init <- init; c.cl_ordered_fields <- List.map restore_field ofr; c.cl_ordered_statics <- List.map restore_field osr; c.cl_fields <- mk_pmap c.cl_ordered_fields; c.cl_statics <- mk_pmap c.cl_ordered_statics; c.cl_constructor <- Option.map restore_field csr; c.cl_overrides <- over; ) | _ -> () (* PASS 2 begin *) let rec is_removable_class c = match c.cl_kind with | KGeneric -> (Meta.has Meta.Remove c.cl_meta || (match c.cl_super with | Some (c,_) -> is_removable_class c | _ -> false) || List.exists (fun (_,t) -> match follow t with | TInst(c,_) -> has_ctor_constraint c || Meta.has Meta.Const c.cl_meta | _ -> false ) c.cl_params) | KTypeParameter _ -> (* this shouldn't happen, have to investigate (see #4092) *) true | _ -> false let remove_generic_base ctx t = match t with | TClassDecl c when is_removable_class c -> c.cl_extern <- true | _ -> () (* Removes extern and macro fields, also checks for Void fields *) let remove_extern_fields ctx t = match t with | TClassDecl c -> if not (Common.defined ctx.com Define.DocGen) then begin c.cl_ordered_fields <- List.filter (fun f -> let b = is_removable_field ctx f in if b then c.cl_fields <- PMap.remove f.cf_name c.cl_fields; not b ) c.cl_ordered_fields; c.cl_ordered_statics <- List.filter (fun f -> let b = is_removable_field ctx f in if b then c.cl_statics <- PMap.remove f.cf_name c.cl_statics; not b ) c.cl_ordered_statics; end | _ -> () (* PASS 2 end *) (* PASS 3 begin *) (* Checks if a private class' path clashes with another path *) let check_private_path ctx t = match t with | TClassDecl c when c.cl_private -> let rpath = (fst c.cl_module.m_path,"_" ^ snd c.cl_module.m_path) in if Hashtbl.mem ctx.g.types_module rpath then error ("This private class name will clash with " ^ s_type_path rpath) c.cl_pos; | _ -> () (* Rewrites class or enum paths if @:native metadata is set *) let apply_native_paths ctx t = let get_native_name meta = let rec get_native meta = match meta with | [] -> raise Not_found | (Meta.Native,[v],p as meta) :: _ -> meta | _ :: meta -> get_native meta in let (_,e,mp) = get_native meta in match e with | [Ast.EConst (Ast.String name),p] -> name,p | [] -> raise Not_found | _ -> error "String expected" mp in let get_real_name meta name = let name',p = get_native_name meta in (Meta.RealPath,[Ast.EConst (Ast.String (name)), p], p), name' in let get_real_path meta path = let name,p = get_native_name meta in (Meta.RealPath,[Ast.EConst (Ast.String (s_type_path path)), p], p), parse_path name in try (match t with | TClassDecl c -> let did_change = ref false in let field cf = try let meta,name = get_real_name cf.cf_meta cf.cf_name in cf.cf_name <- name; cf.cf_meta <- meta :: cf.cf_meta; List.iter (fun cf -> cf.cf_name <- name) cf.cf_overloads; did_change := true with Not_found -> () in let fields cfs old_map = did_change := false; List.iter field cfs; if !did_change then List.fold_left (fun map f -> PMap.add f.cf_name f map) PMap.empty cfs else old_map in c.cl_fields <- fields c.cl_ordered_fields c.cl_fields; c.cl_statics <- fields c.cl_ordered_statics c.cl_statics; let meta,path = get_real_path c.cl_meta c.cl_path in c.cl_meta <- meta :: c.cl_meta; c.cl_path <- path; | TEnumDecl e -> let meta,path = get_real_path e.e_meta e.e_path in e.e_meta <- meta :: e.e_meta; e.e_path <- path; | _ -> ()) with Not_found -> () (* Adds the __rtti field if required *) let add_rtti ctx t = let rec has_rtti c = Meta.has Meta.Rtti c.cl_meta || match c.cl_super with None -> false | Some (csup,_) -> has_rtti csup in match t with | TClassDecl c when has_rtti c && not (PMap.mem "__rtti" c.cl_statics) -> let f = mk_field "__rtti" ctx.t.tstring c.cl_pos null_pos in let str = Genxml.gen_type_string ctx.com t in f.cf_expr <- Some (mk (TConst (TString str)) f.cf_type c.cl_pos); c.cl_ordered_statics <- f :: c.cl_ordered_statics; c.cl_statics <- PMap.add f.cf_name f c.cl_statics; | _ -> () (* Adds member field initializations as assignments to the constructor *) let add_field_inits ctx t = let is_as3 = Common.defined ctx.com Define.As3 && not ctx.in_macro in let apply c = let ethis = mk (TConst TThis) (TInst (c,List.map snd c.cl_params)) c.cl_pos in (* TODO: we have to find a variable name which is not used in any of the functions *) let v = alloc_var "_g" ethis.etype ethis.epos in let need_this = ref false in let inits,fields = List.fold_left (fun (inits,fields) cf -> match cf.cf_kind,cf.cf_expr with | Var _, Some _ -> if is_as3 then (inits, cf :: fields) else (cf :: inits, cf :: fields) | Method MethDynamic, Some e when is_as3 -> (* TODO : this would have a better place in genSWF9 I think - NC *) (* we move the initialization of dynamic functions to the constructor and also solve the 'this' problem along the way *) let rec use_this v e = match e.eexpr with | TConst TThis -> need_this := true; mk (TLocal v) v.v_type e.epos | _ -> Type.map_expr (use_this v) e in let e = Type.map_expr (use_this v) e in let cf2 = {cf with cf_expr = Some e} in (* if the method is an override, we have to remove the class field to not get invalid overrides *) let fields = if List.memq cf c.cl_overrides then begin c.cl_fields <- PMap.remove cf.cf_name c.cl_fields; fields end else cf2 :: fields in (cf2 :: inits, fields) | _ -> (inits, cf :: fields) ) ([],[]) c.cl_ordered_fields in c.cl_ordered_fields <- (List.rev fields); match inits with | [] -> () | _ -> let el = List.map (fun cf -> match cf.cf_expr with | None -> assert false | Some e -> let lhs = mk (TField(ethis,FInstance (c,List.map snd c.cl_params,cf))) cf.cf_type e.epos in cf.cf_expr <- None; let eassign = mk (TBinop(OpAssign,lhs,e)) e.etype e.epos in if is_as3 then begin let echeck = mk (TBinop(OpEq,lhs,(mk (TConst TNull) lhs.etype e.epos))) ctx.com.basic.tbool e.epos in mk (TIf(echeck,eassign,None)) eassign.etype e.epos end else eassign; ) inits in let el = if !need_this then (mk (TVar((v, Some ethis))) ethis.etype ethis.epos) :: el else el in let cf = match c.cl_constructor with | None -> let ct = TFun([],ctx.com.basic.tvoid) in let ce = mk (TFunction { tf_args = []; tf_type = ctx.com.basic.tvoid; tf_expr = mk (TBlock el) ctx.com.basic.tvoid c.cl_pos; }) ct c.cl_pos in let ctor = mk_field "new" ct c.cl_pos null_pos in ctor.cf_kind <- Method MethNormal; { ctor with cf_expr = Some ce } | Some cf -> match cf.cf_expr with | Some { eexpr = TFunction f } -> let bl = match f.tf_expr with {eexpr = TBlock b } -> b | x -> [x] in let ce = mk (TFunction {f with tf_expr = mk (TBlock (el @ bl)) ctx.com.basic.tvoid c.cl_pos }) cf.cf_type cf.cf_pos in {cf with cf_expr = Some ce }; | _ -> assert false in let config = AnalyzerConfig.get_field_config ctx.com c cf in Analyzer.Run.run_on_field ctx config c cf; (match cf.cf_expr with | Some e -> (* This seems a bit expensive, but hopefully constructor expressions aren't that massive. *) let e = rename_local_vars ctx e in let e = Optimizer.sanitize ctx.com e in cf.cf_expr <- Some e | _ -> ()); c.cl_constructor <- Some cf in match t with | TClassDecl c -> apply c | _ -> () (* Adds the __meta__ field if required *) let add_meta_field ctx t = match t with | TClassDecl c -> (match Codegen.build_metadata ctx.com t with | None -> () | Some e -> add_feature ctx.com "has_metadata"; let f = mk_field "__meta__" t_dynamic c.cl_pos null_pos in f.cf_expr <- Some e; let can_deal_with_interface_metadata () = match ctx.com.platform with | Flash when Common.defined ctx.com Define.As3 -> false | Php when not (Common.is_php7 ctx.com) -> false | _ -> true in if c.cl_interface && not (can_deal_with_interface_metadata()) then begin (* borrowed from gencommon, but I did wash my hands afterwards *) let path = fst c.cl_path,snd c.cl_path ^ "_HxMeta" in let ncls = mk_class c.cl_module path c.cl_pos null_pos in let cf = mk_field "__meta__" e.etype e.epos null_pos in cf.cf_expr <- Some e; ncls.cl_statics <- PMap.add "__meta__" cf ncls.cl_statics; ncls.cl_ordered_statics <- cf :: ncls.cl_ordered_statics; ctx.com.types <- (TClassDecl ncls) :: ctx.com.types; c.cl_meta <- (Meta.Custom ":hasMetadata",[],e.epos) :: c.cl_meta end else begin c.cl_ordered_statics <- f :: c.cl_ordered_statics; c.cl_statics <- PMap.add f.cf_name f c.cl_statics end) | _ -> () (* C# events have special semantics: if we have an @:event var field, there should also be add_ and remove_ methods, this filter checks for their existence and also adds some metadata for analyzer and C# generator *) let check_cs_events com t = match t with | TClassDecl cl when not cl.cl_extern -> let check fields f = match f.cf_kind with | Var { v_read = AccNormal; v_write = AccNormal } when Meta.has Meta.Event f.cf_meta -> if f.cf_public then error "@:event fields must be private" f.cf_pos; (* prevent generating reflect helpers for the event in gencommon *) f.cf_meta <- (Meta.SkipReflection, [], f.cf_pos) :: f.cf_meta; (* type for both add and remove methods *) let tmeth = (tfun [f.cf_type] com.basic.tvoid) in let process_event_method name = let m = try PMap.find name fields with Not_found -> error ("Missing event method: " ^ name) f.cf_pos in (* check method signature *) begin try type_eq EqStrict m.cf_type tmeth with Unify_error el -> List.iter (fun e -> com.error (unify_error_msg (print_context()) e) m.cf_pos) el end; (* add @:pure(false) to prevent purity inference, because empty add/remove methods have special meaning here and they are always impure *) m.cf_meta <- (Meta.Pure,[EConst(Ident "false"),f.cf_pos],f.cf_pos) :: (Meta.Custom ":cs_event_impl",[],f.cf_pos) :: m.cf_meta; (* add @:keep to event methods if the event is kept *) if Meta.has Meta.Keep f.cf_meta && not (Meta.has Meta.Keep m.cf_meta) then m.cf_meta <- (Meta.Keep,[],f.cf_pos) :: m.cf_meta; in process_event_method ("add_" ^ f.cf_name); process_event_method ("remove_" ^ f.cf_name) | _ -> () in List.iter (check cl.cl_fields) cl.cl_ordered_fields; List.iter (check cl.cl_statics) cl.cl_ordered_statics | _ -> () (* Removes interfaces tagged with @:remove metadata *) let check_remove_metadata ctx t = match t with | TClassDecl c -> c.cl_implements <- List.filter (fun (c,_) -> not (Meta.has Meta.Remove c.cl_meta)) c.cl_implements; | _ -> () (* Checks for Void class fields *) let check_void_field ctx t = match t with | TClassDecl c -> let check f = match follow f.cf_type with TAbstract({a_path=[],"Void"},_) -> error "Fields of type Void are not allowed" f.cf_pos | _ -> (); in List.iter check c.cl_ordered_fields; List.iter check c.cl_ordered_statics; | _ -> () (* Interfaces have no 'super', but can extend many other interfaces. This makes the first extended (implemented) interface the super for efficiency reasons (you can get one for 'free') and leaves the remaining ones as 'implemented' *) let promote_first_interface_to_super ctx t = match t with | TClassDecl c when c.cl_interface -> begin match c.cl_implements with | ({ cl_path = ["cpp";"rtti"],_ },_ ) :: _ -> () | first_interface :: remaining -> c.cl_super <- Some first_interface; c.cl_implements <- remaining | _ -> () end | _ -> () let commit_features ctx t = let m = (t_infos t).mt_module in Hashtbl.iter (fun k v -> Common.add_feature ctx.com k; ) m.m_extra.m_features let check_reserved_type_paths ctx t = let check path pos = if List.mem path ctx.com.config.pf_reserved_type_paths then ctx.com.warning ("Type path " ^ (s_type_path path) ^ " is reserved on this target") pos in match t with | TClassDecl c when not c.cl_extern -> check c.cl_path c.cl_pos | TEnumDecl e when not e.e_extern -> check e.e_path e.e_pos | _ -> () (* PASS 3 end *) let run_expression_filters ctx filters t = let run e = List.fold_left (fun e f -> f e) e filters in match t with | TClassDecl c when is_removable_class c -> () | TClassDecl c -> ctx.curclass <- c; let rec process_field f = (match f.cf_expr with | Some e when not (is_removable_field ctx f) -> AbstractCast.cast_stack := f :: !AbstractCast.cast_stack; f.cf_expr <- Some (run e); AbstractCast.cast_stack := List.tl !AbstractCast.cast_stack; | _ -> ()); List.iter process_field f.cf_overloads 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 -> c.cl_init <- Some (run e)); | TEnumDecl _ -> () | TTypeDecl _ -> () | TAbstractDecl _ -> () let pp_counter = ref 1 let is_cached t = let m = (t_infos t).mt_module.m_extra in if m.m_processed = 0 then m.m_processed <- !pp_counter; m.m_processed <> !pp_counter let apply_filters_once ctx filters t = if not (is_cached t) then run_expression_filters ctx filters t let next_compilation() = incr pp_counter let iter_expressions fl mt = match mt with | TClassDecl c -> let field cf = match cf.cf_expr with | None -> () | Some e -> List.iter (fun f -> f e) fl in List.iter field c.cl_ordered_statics; List.iter field c.cl_ordered_fields; (match c.cl_constructor with None -> () | Some cf -> field cf) | _ -> () let run com tctx main = let new_types = List.filter (fun t -> not (is_cached t)) com.types in (* PASS 1: general expression filters *) let filters = [ AbstractCast.handle_abstract_casts tctx; Optimizer.inline_constructors tctx; check_local_vars_init; Optimizer.reduce_expression tctx; captured_vars com; ] in List.iter (run_expression_filters tctx filters) new_types; (* PASS 1.5: pre-analyzer type filters *) List.iter (fun t -> if com.platform = Cs then check_cs_events tctx.com t; ) new_types; if com.platform <> Cross then Analyzer.Run.run_on_types tctx new_types; let filters = [ Optimizer.sanitize com; if com.config.pf_add_final_return then add_final_return else (fun e -> e); if com.platform = Js then wrap_js_exceptions com else (fun e -> e); rename_local_vars tctx; ] in List.iter (run_expression_filters tctx filters) new_types; next_compilation(); List.iter (fun f -> f()) (List.rev com.callbacks.before_dce); (* macros onGenerate etc. *) List.iter (save_class_state tctx) new_types; (* PASS 2: type filters pre-DCE *) List.iter (fun t -> remove_generic_base tctx t; remove_extern_fields tctx t; Codegen.update_cache_dependencies t; (* check @:remove metadata before DCE so it is ignored there (issue #2923) *) check_remove_metadata tctx t; ) com.types; (* DCE *) let dce_mode = if Common.defined com Define.As3 then "no" else (try Common.defined_value com Define.Dce with _ -> "no") in begin match dce_mode with | "full" -> Dce.run com main (not (Common.defined com Define.Interp)) | "std" -> Dce.run com main false | "no" -> Dce.fix_accessors com | _ -> failwith ("Unknown DCE mode " ^ dce_mode) end; (* PASS 3: type filters post-DCE *) let type_filters = [ check_private_path; apply_native_paths; add_rtti; (match com.platform with | Java | Cs -> (fun _ _ -> ()) | _ -> add_field_inits); (match com.platform with Hl -> (fun _ _ -> ()) | _ -> add_meta_field); check_void_field; (match com.platform with | Cpp -> promote_first_interface_to_super | _ -> (fun _ _ -> ()) ); commit_features; (if com.config.pf_reserved_type_paths <> [] then check_reserved_type_paths else (fun _ _ -> ())); ] in List.iter (fun t -> List.iter (fun f -> f tctx t) type_filters) com.types haxe_3.4.4.orig/src/optimization/optimizer.ml0000664000175000017500000015735513166552354021325 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Type open Common open Typecore open OptimizerTexpr open Error open Globals (* ---------------------------------------------------------------------- *) (* API OPTIMIZATIONS *) let mk_untyped_call name p params = { eexpr = TCall({ eexpr = TLocal(alloc_unbound_var name t_dynamic p); etype = t_dynamic; epos = p }, params); etype = t_dynamic; epos = p; } let api_inline2 com c field params p = match c.cl_path, field, params with | ([],"Type"),"enumIndex",[{ eexpr = TField (_,FEnum (en,f)) }] -> (match com.platform with | Cs when en.e_extern && not (Meta.has Meta.HxGen en.e_meta) -> (* We don't want to optimize enums from external sources; as they might change unexpectedly *) (* and since native C# enums don't have the concept of index - they have rather a value, *) (* which can't be mapped to a native API - this kind of substitution is dangerous *) None | _ -> Some (mk (TConst (TInt (Int32.of_int f.ef_index))) com.basic.tint p)) | ([],"Type"),"enumIndex",[{ eexpr = TCall({ eexpr = TField (_,FEnum (en,f)) },pl) }] when List.for_all (fun e -> not (has_side_effect e)) pl -> (match com.platform with | Cs when en.e_extern && not (Meta.has Meta.HxGen en.e_meta) -> (* see comment above *) None | _ -> Some (mk (TConst (TInt (Int32.of_int f.ef_index))) com.basic.tint p)) | ([],"Std"),"int",[{ eexpr = TConst (TInt _) } as e] -> Some { e with epos = p } | ([],"String"),"fromCharCode",[{ eexpr = TConst (TInt i) }] when i > 0l && i < 128l -> Some (mk (TConst (TString (String.make 1 (char_of_int (Int32.to_int i))))) com.basic.tstring p) | ([],"Std"),"string",[{ eexpr = TCast ({ eexpr = TConst c } as e, None)}] | ([],"Std"),"string",[{ eexpr = TConst c } as e] -> (match c with | TString s -> Some { e with epos = p } | TInt i -> Some { eexpr = TConst (TString (Int32.to_string i)); epos = p; etype = com.basic.tstring } | TBool b -> Some { eexpr = TConst (TString (if b then "true" else "false")); epos = p; etype = com.basic.tstring } | _ -> None) | ([],"Std"),"string",[{ eexpr = TIf (_,{ eexpr = TConst (TString _)},Some { eexpr = TConst (TString _) }) } as e] -> Some e | ([],"Std"),"string",[{ eexpr = TLocal v | TField({ eexpr = TLocal v },_) } as ev] when (com.platform = Js || com.platform = Flash) && not (Meta.has Meta.CompilerGenerated v.v_meta) -> let pos = ev.epos in let stringv() = let to_str = mk (TBinop (Ast.OpAdd, mk (TConst (TString "")) com.basic.tstring pos, ev)) com.basic.tstring pos in if com.platform = Js || is_nullable ev.etype then let chk_null = mk (TBinop (Ast.OpEq, ev, mk (TConst TNull) t_dynamic pos)) com.basic.tbool pos in mk (TIf (chk_null, mk (TConst (TString "null")) com.basic.tstring pos, Some to_str)) com.basic.tstring pos else to_str in (match follow ev.etype with | TInst ({ cl_path = [],"String" }, []) -> Some (stringv()) | TAbstract ({ a_path = [],"Float" }, []) -> Some (stringv()) | TAbstract ({ a_path = [],"Int" }, []) -> Some (stringv()) | TAbstract ({ a_path = [],"UInt" }, []) -> Some (stringv()) | TAbstract ({ a_path = [],"Bool" }, []) -> Some (stringv()) | _ -> None) | ([],"Std"),"int",[{ eexpr = TConst (TFloat f) }] -> let f = float_of_string f in (match classify_float f with | FP_infinite | FP_nan -> None | _ when f <= Int32.to_float Int32.min_int -. 1. || f >= Int32.to_float Int32.max_int +. 1. -> None (* out range, keep platform-specific behavior *) | _ -> Some { eexpr = TConst (TInt (Int32.of_float f)); etype = com.basic.tint; epos = p }) | ([],"Math"),"ceil",[{ eexpr = TConst (TFloat f) }] -> let f = float_of_string f in (match classify_float f with | FP_infinite | FP_nan -> None | _ when f <= Int32.to_float Int32.min_int -. 1. || f >= Int32.to_float Int32.max_int -> None (* out range, keep platform-specific behavior *) | _ -> Some { eexpr = TConst (TInt (Int32.of_float (ceil f))); etype = com.basic.tint; epos = p }) | ([],"Math"),"floor",[{ eexpr = TConst (TFloat f) }] -> let f = float_of_string f in (match classify_float f with | FP_infinite | FP_nan -> None | _ when f <= Int32.to_float Int32.min_int || f >= Int32.to_float Int32.max_int +. 1. -> None (* out range, keep platform-specific behavior *) | _ -> Some { eexpr = TConst (TInt (Int32.of_float (floor f))); etype = com.basic.tint; epos = p }) | (["cs"],"Lib"),("fixed" | "checked" | "unsafe"),[e] -> Some (mk_untyped_call ("__" ^ field ^ "__") p [e]) | (["cs"],"Lib"),("lock"),[obj;block] -> Some (mk_untyped_call ("__lock__") p [obj;mk_block block]) | (["java"],"Lib"),("lock"),[obj;block] -> Some (mk_untyped_call ("__lock__") p [obj;mk_block block]) | _ -> None let api_inline ctx c field params p = match c.cl_path, field, params with | ([],"Std"),"is",[o;t] | (["js"],"Boot"),"__instanceof",[o;t] when ctx.com.platform = Js -> let mk_local ctx n t pos = mk (TLocal (try PMap.find n ctx.locals with _ -> let v = add_local ctx n t p in v.v_meta <- [Meta.Unbound,[],p]; v )) t pos in let tstring = ctx.com.basic.tstring in let tbool = ctx.com.basic.tbool in let tint = ctx.com.basic.tint in let is_trivial e = match e.eexpr with | TConst _ | TLocal _ -> true | _ -> false in let typeof t = let tof = mk_local ctx "__typeof__" (tfun [o.etype] tstring) p in let tof = mk (TCall (tof, [o])) tstring p in mk (TBinop (Ast.OpEq, tof, (mk (TConst (TString t)) tstring p))) tbool p in (match t.eexpr with (* generate simple typeof checks for basic types *) | TTypeExpr (TClassDecl ({ cl_path = [],"String" })) -> Some (typeof "string") | TTypeExpr (TAbstractDecl ({ a_path = [],"Bool" })) -> Some (typeof "boolean") | TTypeExpr (TAbstractDecl ({ a_path = [],"Float" })) -> Some (typeof "number") | TTypeExpr (TAbstractDecl ({ a_path = [],"Int" })) when is_trivial o -> (* generate typeof(o) == "number" && (o|0) === o check *) let teq = mk_local ctx "__strict_eq__" (tfun [tint; tint] tbool) p in let lhs = mk (TBinop (Ast.OpOr, o, mk (TConst (TInt Int32.zero)) tint p)) tint p in let jscheck = mk (TCall (teq, [lhs; o])) tbool p in Some(mk (TBinop (Ast.OpBoolAnd, typeof "number", jscheck)) tbool p) | TTypeExpr (TClassDecl ({ cl_path = [],"Array" })) -> (* generate (o instanceof Array) && o.__enum__ == null check *) let iof = mk_local ctx "__instanceof__" (tfun [o.etype;t.etype] tbool) p in let iof = mk (TCall (iof, [o; t])) tbool p in let enum = mk (TField (o, FDynamic "__enum__")) (mk_mono()) p in let null = mk (TConst TNull) (mk_mono()) p in let not_enum = mk (TBinop (Ast.OpEq, enum, null)) tbool p in Some (mk (TBinop (Ast.OpBoolAnd, iof, not_enum)) tbool p) | _ -> None) | (["cs" | "java"],"Lib"),("nativeArray"),[{ eexpr = TArrayDecl args } as edecl; _] | (["haxe";"ds";"_Vector"],"Vector_Impl_"),("fromArrayCopy"),[{ eexpr = TArrayDecl args } as edecl] -> (try let platf = match ctx.com.platform with | Cs -> "cs" | Java -> "java" | _ -> raise Exit in let mpath = if field = "fromArrayCopy" then (["haxe";"ds"],"Vector") else ([platf],"NativeArray") in let m = ctx.g.do_load_module ctx mpath null_pos in let main = List.find (function | TClassDecl _ | TAbstractDecl _ -> true | _ -> false) m.m_types in let t = match follow edecl.etype, main with | TInst({ cl_path = [],"Array" }, [t]), TClassDecl(cl) -> TInst(cl,[t]) | TInst({ cl_path = [],"Array" }, [t]), TAbstractDecl(a) -> TAbstract(a,[t]) | _ -> assert false in Some ({ (mk_untyped_call "__array__" p args) with etype = t }) with | Exit -> None) | _ -> api_inline2 ctx.com c field params p (* ---------------------------------------------------------------------- *) (* INLINING *) type in_local = { i_var : tvar; i_subst : tvar; i_outside : bool; i_abstract_this : bool; mutable i_captured : bool; mutable i_write : bool; mutable i_read : int; mutable i_force_temp : bool; } let inline_default_config cf t = (* type substitution on both class and function type parameters *) let rec get_params c pl = match c.cl_super with | None -> c.cl_params, pl | Some (csup,spl) -> let spl = (match apply_params c.cl_params pl (TInst (csup,spl)) with | TInst (_,pl) -> pl | _ -> assert false ) in let ct, cpl = get_params csup spl in c.cl_params @ ct, pl @ cpl in let tparams = (match follow t with | TInst (c,pl) -> get_params c pl | _ -> ([],[])) in let pmonos = List.map (fun _ -> mk_mono()) cf.cf_params in let tmonos = snd tparams @ pmonos in let tparams = fst tparams @ cf.cf_params in tparams <> [], apply_params tparams tmonos let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=false) force = (* perform some specific optimization before we inline the call since it's not possible to detect at final optimization time *) try let cl = (match follow ethis.etype with | TInst (c,_) -> c | TAnon a -> (match !(a.a_status) with Statics c -> c | _ -> raise Exit) | _ -> raise Exit ) in (match api_inline ctx cl cf.cf_name params p with | None -> raise Exit | Some e -> Some e) with Exit -> let has_params,map_type = match config with Some config -> config | None -> inline_default_config cf ethis.etype in (* locals substitution *) let locals = Hashtbl.create 0 in let local v = try Hashtbl.find locals v.v_id with Not_found -> let v' = alloc_var v.v_name v.v_type v.v_pos in if Meta.has Meta.Unbound v.v_meta then v'.v_meta <- [Meta.Unbound,[],p]; let i = { i_var = v; i_subst = v'; i_outside = false; i_abstract_this = Meta.has Meta.This v.v_meta; i_captured = false; i_write = false; i_force_temp = false; i_read = 0; } in i.i_subst.v_meta <- List.filter (fun (m,_,_) -> m <> Meta.This) v.v_meta; Hashtbl.add locals v.v_id i; Hashtbl.add locals i.i_subst.v_id i; i in let in_local_fun = ref false in let read_local v = let l = try Hashtbl.find locals v.v_id with Not_found -> (* make sure to duplicate unbound inline variable to prevent dependency leak when unifying monomorph *) if has_meta Meta.Unbound v.v_meta then local v else { i_var = v; i_subst = v; i_outside = true; i_abstract_this = Meta.has Meta.This v.v_meta; i_captured = false; i_write = false; i_force_temp = false; i_read = 0; } in if !in_local_fun then l.i_captured <- true; l in (* use default values for null/unset arguments *) let rec loop pl al first = match pl, al with | _, [] -> [] | e :: pl, (v, opt) :: al -> (* if we pass a Null var to an inlined method that needs a T. we need to force a local var to be created on some platforms. *) if ctx.com.config.pf_static && not (is_nullable v.v_type) && is_null e.etype then (local v).i_force_temp <- true; (* if we cast from Dynamic, create a local var as well to do the cast once and allow DCE to perform properly. *) let e = if follow v.v_type != t_dynamic && follow e.etype == t_dynamic then mk (TCast(e,None)) v.v_type e.epos else e in (match e.eexpr, opt with | TConst TNull , Some c -> mk (TConst c) v.v_type e.epos (* This is really weird and should be reviewed again. The problem is that we cannot insert a TCast here because the abstract `this` value could be written to, which is not possible if it is wrapped in a cast. The original problem here is that we do not generate a temporary variable and thus mute the type of the `this` variable, which leads to unification errors down the line. See issues #2236 and #3713. *) (* | _ when first && (Meta.has Meta.Impl cf.cf_meta) -> {e with etype = v.v_type} *) | _ -> e) :: loop pl al false | [], (v,opt) :: al -> (mk (TConst (match opt with None -> TNull | Some c -> c)) v.v_type p) :: loop [] al false in (* Build the expr/var subst list *) let ethis = (match ethis.eexpr with TConst TSuper -> { ethis with eexpr = TConst TThis } | _ -> ethis) in let vthis = alloc_var "_this" ethis.etype ethis.epos in let might_be_affected,collect_modified_locals = create_affection_checker() in let had_side_effect = ref false in let inlined_vars = List.map2 (fun e (v,_) -> let l = local v in if has_side_effect e then begin collect_modified_locals e; had_side_effect := true; l.i_force_temp <- true; end; if l.i_abstract_this then l.i_subst.v_extra <- Some ([],Some e); l, e ) (ethis :: loop params f.tf_args true) ((vthis,None) :: f.tf_args) in List.iter (fun (l,e) -> if might_be_affected e then l.i_force_temp <- true; ) inlined_vars; let inlined_vars = List.rev inlined_vars in (* here, we try to eliminate final returns from the expression tree. However, this is not entirely correct since we don't yet correctly propagate the type of returned expressions upwards ("return" expr itself being Dynamic). We also substitute variables with fresh ones that might be renamed at later stage. *) let opt f = function | None -> None | Some e -> Some (f e) in let has_vars = ref false in let in_loop = ref false in let cancel_inlining = ref false in let has_return_value = ref false in let ret_val = (match follow f.tf_type with TAbstract ({ a_path = ([],"Void") },[]) -> false | _ -> true) in let map_pos = if self_calling_closure then (fun e -> e) else (fun e -> { e with epos = p }) in let rec map term e = let po = e.epos in let e = map_pos e in match e.eexpr with | TLocal v -> let l = read_local v in l.i_read <- l.i_read + (if !in_loop then 2 else 1); (* never inline a function which contain a delayed macro because its bound to its variables and not the calling method *) if v.v_name = "$__delayed_call__" then cancel_inlining := true; let e = { e with eexpr = TLocal l.i_subst } in if l.i_abstract_this then mk (TCast(e,None)) v.v_type e.epos else e | TConst TThis -> let l = read_local vthis in l.i_read <- l.i_read + (if !in_loop then 2 else 1); { e with eexpr = TLocal l.i_subst } | TVar (v,eo) -> has_vars := true; { e with eexpr = TVar ((local v).i_subst,opt (map false) eo)} | TReturn eo when not !in_local_fun -> if not term then error "Cannot inline a not final return" po; (match eo with | None -> mk (TConst TNull) f.tf_type p | Some e -> has_return_value := true; map term e) | TFor (v,e1,e2) -> let i = local v in let e1 = map false e1 in let old = !in_loop in in_loop := true; let e2 = map false e2 in in_loop := old; { e with eexpr = TFor (i.i_subst,e1,e2) } | TWhile (cond,eloop,flag) -> let cond = map false cond in let old = !in_loop in in_loop := true; let eloop = map false eloop in in_loop := old; { e with eexpr = TWhile (cond,eloop,flag) } | TSwitch (e1,cases,def) when term -> let term = term && (def <> None || is_exhaustive e1) in let cases = List.map (fun (el,e) -> let el = List.map (map false) el in el, map term e ) cases in let def = opt (map term) def in { e with eexpr = TSwitch (map false e1,cases,def); etype = if ret_val then unify_min ctx ((List.map snd cases) @ (match def with None -> [] | Some e -> [e])) else e.etype } | TTry (e1,catches) -> { e with eexpr = TTry (map term e1,List.map (fun (v,e) -> let lv = (local v).i_subst in let e = map term e in lv,e ) catches); etype = if term && ret_val then unify_min ctx (e1::List.map snd catches) else e.etype } | TBlock l -> let old = save_locals ctx in let t = ref e.etype in let rec has_term_return e = let rec loop e = let r = match e.eexpr with | TReturn _ -> true | TFunction _ -> false | TIf (_,_,None) | TSwitch (_,_,None) | TFor _ | TWhile (_,_,NormalWhile) -> false (* we might not enter this code at all *) | TTry (a, catches) -> List.for_all has_term_return (a :: List.map snd catches) | TIf (cond,a,Some b) -> has_term_return cond || (has_term_return a && has_term_return b) | TSwitch (cond,cases,Some def) -> has_term_return cond || List.for_all has_term_return (def :: List.map snd cases) | TBinop (OpBoolAnd,a,b) -> has_term_return a && has_term_return b | _ -> Type.iter loop e; false in if r then raise Exit in try loop e; false with Exit -> true in let rec loop = function | [] when term -> t := mk_mono(); [mk (TConst TNull) (!t) p] | [] -> [] | [e] -> let e = map term e in if term then t := e.etype; [e] | ({ eexpr = TIf (cond,e1,None) } as e) :: l when term && has_term_return e1 -> loop [{ e with eexpr = TIf (cond,e1,Some (mk (TBlock l) e.etype e.epos)); epos = punion e.epos (match List.rev l with e :: _ -> e.epos | [] -> assert false) }] | e :: l -> let e = map false e in e :: loop l in let l = loop l in old(); { e with eexpr = TBlock l; etype = !t } | TIf (econd,eif,Some eelse) when term -> let econd = map false econd in let eif = map term eif in let eelse = map term eelse in { e with eexpr = TIf(econd,eif,Some eelse); etype = if ret_val then unify_min ctx [eif;eelse] else e.etype } | TParenthesis e1 -> let e1 = map term e1 in mk (TParenthesis e1) e1.etype e.epos | TUnop ((Increment|Decrement) as op,flag,({ eexpr = TLocal v } as e1)) -> let l = read_local v in l.i_write <- true; {e with eexpr = TUnop(op,flag,{e1 with eexpr = TLocal l.i_subst})} | TBinop ((OpAssign | OpAssignOp _) as op,({ eexpr = TLocal v } as e1),e2) -> let l = read_local v in l.i_write <- true; let e2 = map false e2 in {e with eexpr = TBinop(op,{e1 with eexpr = TLocal l.i_subst},e2)} | TObjectDecl fl -> let fl = List.map (fun (s,e) -> s,map false e) fl in begin match follow e.etype with | TAnon an when (match !(an.a_status) with Const -> true | _ -> false) -> {e with eexpr = TObjectDecl fl; etype = TAnon { an with a_status = ref Closed}} | _ -> {e with eexpr = TObjectDecl fl} end | TFunction f -> (match f.tf_args with [] -> () | _ -> has_vars := true); let old = save_locals ctx and old_fun = !in_local_fun in let args = List.map (function(v,c) -> (local v).i_subst, c) f.tf_args in in_local_fun := true; let expr = map false f.tf_expr in in_local_fun := old_fun; old(); { e with eexpr = TFunction { tf_args = args; tf_expr = expr; tf_type = f.tf_type } } | TCall({eexpr = TConst TSuper; etype = t},el) -> begin match follow t with | TInst({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction tf})} as cf)} as c,_) -> begin match type_inline_ctor ctx c cf tf ethis el po with | Some e -> map term e | None -> error "Could not inline super constructor call" po end | _ -> error "Cannot inline function containing super" po end | TConst TSuper -> error "Cannot inline function containing super" po | TMeta(m,e1) -> let e1 = map term e1 in {e with eexpr = TMeta(m,e1)} | _ -> Type.map_expr (map false) e in let e = map true f.tf_expr in (* if variables are not written and used with a const value, let's substitute with the actual value, either create a temp var *) let subst = ref PMap.empty in let is_constant e = let rec loop e = match e.eexpr with | TLocal _ | TConst TThis (* not really, but should not be move inside a function body *) -> raise Exit | TField (_,FEnum _) | TTypeExpr _ | TConst _ -> () | _ -> Type.iter loop e in try loop e; true with Exit -> false in let is_writable e = match e.eexpr with | TField _ | TEnumParameter _ | TLocal _ | TArray _ -> true | _ -> false in let force = ref force in let vars = List.fold_left (fun acc (i,e) -> let flag = not i.i_force_temp && (match e.eexpr with | TLocal _ when i.i_abstract_this -> true | TLocal _ | TConst _ -> not i.i_write | TFunction _ -> if i.i_write then error "Cannot modify a closure parameter inside inline method" p; true | _ -> not i.i_write && i.i_read <= 1 ) in let flag = flag && (not i.i_captured || is_constant e) in (* force inlining if we modify 'this' *) if i.i_write && i.i_abstract_this then force := true; (* force inlining of 'this' variable if it is written *) let flag = if not flag && i.i_abstract_this && i.i_write then begin if not (is_writable e) then error "Cannot modify the abstract value, store it into a local first" p; true end else flag in if flag then begin subst := PMap.add i.i_subst.v_id e !subst; acc end else begin (* mark the replacement local for the analyzer *) if i.i_read <= 1 && not i.i_write then i.i_subst.v_meta <- (Meta.CompilerGenerated,[],p) :: i.i_subst.v_meta; (i.i_subst,Some e) :: acc end ) [] inlined_vars in let subst = !subst in let rec inline_params e = match e.eexpr with | TLocal v -> (try PMap.find v.v_id subst with Not_found -> e) | _ -> Type.map_expr inline_params e in let e = (if PMap.is_empty subst then e else inline_params e) in let init = match vars with [] -> None | l -> Some l in (* If we have local variables and returning a value, then this will result in unoptimized JS code, so let's instead skip inlining. This could be fixed with better post process code cleanup (planed) *) if !cancel_inlining then None else let wrap e = (* we can't mute the type of the expression because it is not correct to do so *) let etype = if has_params then map_type e.etype else e.etype in (* if the expression is "untyped" and we don't want to unify it accidentally ! *) try (match follow e.etype with | TMono _ | TInst ({cl_kind = KTypeParameter _ },_) -> (match follow tret with | TAbstract ({ a_path = [],"Void" },_) -> e | _ -> raise (Unify_error [])) | _ -> type_eq (if ctx.com.config.pf_static then EqDoNotFollowNull else EqStrict) etype tret; e) with Unify_error _ -> mk (TCast (e,None)) tret e.epos in let e = (match e.eexpr, init with | _, None when not !has_return_value -> begin match e.eexpr with | TBlock _ -> {e with etype = tret} | _ -> mk (TBlock [e]) tret e.epos end | TBlock [e] , None -> wrap e | _ , None -> wrap e | TBlock l, Some vl -> let el_v = List.map (fun (v,eo) -> mk (TVar (v,eo)) ctx.t.tvoid e.epos) vl in mk (TBlock (el_v @ l)) tret e.epos | _, Some vl -> let el_v = List.map (fun (v,eo) -> mk (TVar (v,eo)) ctx.t.tvoid e.epos) vl in mk (TBlock (el_v @ [e])) tret e.epos ) in let inline_meta e meta = match meta with | (Meta.Deprecated | Meta.Pure),_,_ -> mk (TMeta(meta,e)) e.etype e.epos | _ -> e in let e = List.fold_left inline_meta e cf.cf_meta in let e = Display.Diagnostics.secure_generated_code ctx e in if Meta.has (Meta.Custom ":inlineDebug") ctx.meta then begin let se t = s_expr_pretty true t true (s_type (print_context())) in print_endline (Printf.sprintf "Inline %s:\n\tArgs: %s\n\tExpr: %s\n\tResult: %s" cf.cf_name (String.concat "" (List.map (fun (i,e) -> Printf.sprintf "\n\t\t%s<%i> = %s" (i.i_subst.v_name) (i.i_subst.v_id) (se "\t\t" e)) inlined_vars)) (se "\t" f.tf_expr) (se "\t" e) ); end; (* we need to replace type-parameters that were used in the expression *) if not has_params then Some e else let mt = map_type cf.cf_type in let unify_func () = unify_raise ctx mt (TFun (List.map (fun e -> "",false,e.etype) params,tret)) p in (match follow ethis.etype with | TAnon a -> (match !(a.a_status) with | Statics {cl_kind = KAbstractImpl a } when Meta.has Meta.Impl cf.cf_meta -> if cf.cf_name <> "_new" then begin (* the first argument must unify with a_this for abstract implementation functions *) let tb = (TFun(("",false,map_type a.a_this) :: List.map (fun e -> "",false,e.etype) (List.tl params),tret)) in unify_raise ctx mt tb p end | _ -> unify_func()) | _ -> unify_func()); (* this is very expensive since we are building the substitution list for every expression, but hopefully in such cases the expression size is small *) let vars = Hashtbl.create 0 in let map_var v = if not (Hashtbl.mem vars v.v_id) then begin Hashtbl.add vars v.v_id (); if not (read_local v).i_outside then v.v_type <- map_type v.v_type; end; v in let rec map_expr_type e = Type.map_expr_type map_expr_type map_type map_var e in Some (map_expr_type e) (* Same as type_inline, but modifies the function body to add field inits *) and type_inline_ctor ctx c cf tf ethis el po = let field_inits = let cparams = List.map snd c.cl_params in let ethis = mk (TConst TThis) (TInst (c,cparams)) c.cl_pos in let el = List.fold_left (fun acc cf -> match cf.cf_kind,cf.cf_expr with | Var _,Some e -> let lhs = mk (TField(ethis,FInstance (c,cparams,cf))) cf.cf_type e.epos in let eassign = mk (TBinop(OpAssign,lhs,e)) cf.cf_type e.epos in eassign :: acc | _ -> acc ) [] c.cl_ordered_fields in List.rev el in let tf = if field_inits = [] then tf else let bl = match tf.tf_expr with {eexpr = TBlock b } -> b | x -> [x] in {tf with tf_expr = mk (TBlock (field_inits @ bl)) ctx.t.tvoid c.cl_pos} in type_inline ctx cf tf ethis el ctx.t.tvoid None po true (* ---------------------------------------------------------------------- *) (* LOOPS *) let rec optimize_for_loop ctx (i,pi) e1 e2 p = let t_void = ctx.t.tvoid in let t_int = ctx.t.tint in let lblock el = Some (mk (TBlock el) t_void p) in let mk_field e n = TField (e,try quick_field e.etype n with Not_found -> assert false) in let gen_int_iter pt f_get f_length = let i = add_local ctx i pt pi in let index = gen_local ctx t_int pi in let arr, avars = (match e1.eexpr with | TLocal _ -> e1, None | _ -> let atmp = gen_local ctx e1.etype e1.epos in mk (TLocal atmp) e1.etype e1.epos, (Some (atmp,Some e1)) ) in let iexpr = mk (TLocal index) t_int p in let e2 = type_expr ctx e2 NoValue in let aget = mk (TVar (i,Some (f_get arr iexpr pt p))) t_void pi in let incr = mk (TUnop (Increment,Prefix,iexpr)) t_int p in let block = match e2.eexpr with | TBlock el -> mk (TBlock (aget :: incr :: el)) t_void e2.epos | _ -> mk (TBlock [aget;incr;e2]) t_void p in let ivar = Some (mk (TConst (TInt 0l)) t_int p) in let elength = f_length arr p in let el = [mk (TWhile ( mk (TBinop (OpLt, iexpr, elength)) ctx.t.tbool p, block, NormalWhile )) t_void p; ] in let el = match avars with None -> el | Some (v,eo) -> (mk (TVar (v,eo)) t_void p) :: el in let el = (mk (TVar (index,ivar)) t_void p) :: el in lblock el in let get_next_array_element arr iexpr pt p = (mk (TArray (arr,iexpr)) pt p) in let get_array_length arr p = mk (mk_field arr "length") ctx.com.basic.tint p in match e1.eexpr, follow e1.etype with | TNew ({ cl_path = ([],"IntIterator") },[],[i1;i2]) , _ -> let max = (match i1.eexpr , i2.eexpr with | TConst (TInt a), TConst (TInt b) when Int32.compare b a < 0 -> error "Range operator can't iterate backwards" p | _, TConst _ -> None | _ -> Some (gen_local ctx t_int e1.epos) ) in let tmp = gen_local ctx t_int pi in let i = add_local ctx i t_int pi in let rec check e = match e.eexpr with | TBinop (OpAssign,{ eexpr = TLocal l },_) | TBinop (OpAssignOp _,{ eexpr = TLocal l },_) | TUnop (Increment,_,{ eexpr = TLocal l }) | TUnop (Decrement,_,{ eexpr = TLocal l }) when l == i -> error "Loop variable cannot be modified" e.epos | _ -> Type.iter check e in let e2 = type_expr ctx e2 NoValue in check e2; let etmp = mk (TLocal tmp) t_int p in let incr = mk (TUnop (Increment,Postfix,etmp)) t_int p in let init = mk (TVar (i,Some incr)) t_void pi in let block = match e2.eexpr with | TBlock el -> mk (TBlock (init :: el)) t_void e2.epos | _ -> mk (TBlock [init;e2]) t_void p in (* force locals to be of Int type (to prevent Int/UInt issues) *) let i2 = match follow i2.etype with | TAbstract ({ a_path = ([],"Int") }, []) -> i2 | _ -> { i2 with eexpr = TCast(i2, None); etype = t_int } in (match max with | None -> lblock [ mk (TVar (tmp,Some i1)) t_void p; mk (TWhile ( mk (TBinop (OpLt, etmp, i2)) ctx.t.tbool p, block, NormalWhile )) t_void p; ] | Some max -> lblock [ mk (TVar (tmp,Some i1)) t_void p; mk (TVar (max,Some i2)) t_void p; mk (TWhile ( mk (TBinop (OpLt, etmp, mk (TLocal max) t_int p)) ctx.t.tbool p, block, NormalWhile )) t_void p; ]) | TArrayDecl el, TInst({ cl_path = [],"Array" },[pt]) when false -> begin try let num_expr = ref 0 in let rec loop e = match fst e with | EContinue | EBreak -> raise Exit | _ -> incr num_expr; Ast.map_expr loop e in ignore(loop e2); let v = add_local ctx i pt p in let e2 = type_expr ctx e2 NoValue in let cost = (List.length el) * !num_expr in let max_cost = try int_of_string (Common.defined_value ctx.com Define.LoopUnrollMaxCost) with Not_found -> 250 in if cost > max_cost then raise Exit; let eloc = mk (TLocal v) v.v_type p in let el = List.map (fun e -> let e_assign = mk (TBinop(OpAssign,eloc,e)) e.etype e.epos in concat e_assign e2 ) el in let ev = mk (TVar(v, None)) ctx.t.tvoid p in Some (mk (TBlock (ev :: el)) ctx.t.tvoid p) with Exit -> gen_int_iter pt get_next_array_element get_array_length end | _ , TInst({ cl_path = [],"Array" },[pt]) | _ , TInst({ cl_path = ["flash"],"Vector" },[pt]) -> gen_int_iter pt get_next_array_element get_array_length | _ , TInst({ cl_array_access = Some pt } as c,pl) when (try match follow (PMap.find "length" c.cl_fields).cf_type with TAbstract ({ a_path = [],"Int" },[]) -> true | _ -> false with Not_found -> false) && not (PMap.mem "iterator" c.cl_fields) -> gen_int_iter (apply_params c.cl_params pl pt) get_next_array_element get_array_length | _, TAbstract({a_impl = Some c} as a,tl) -> begin try let cf_length = PMap.find "get_length" c.cl_statics in let get_length e p = make_static_call ctx c cf_length (apply_params a.a_params tl) [e] ctx.com.basic.tint p in begin match follow cf_length.cf_type with | TFun(_,tr) -> begin match follow tr with | TAbstract({a_path = [],"Int"},_) -> () | _ -> raise Not_found end | _ -> raise Not_found end; begin try (* first try: do we have an @:arrayAccess getter field? *) let todo = mk (TConst TNull) ctx.t.tint p in let cf,_,r,_,_ = (!find_array_access_raise_ref) ctx a tl todo None p in let get_next e_base e_index t p = make_static_call ctx c cf (apply_params a.a_params tl) [e_base;e_index] r p in gen_int_iter r get_next get_length with Not_found -> (* second try: do we have @:arrayAccess on the abstract itself? *) if not (Meta.has Meta.ArrayAccess a.a_meta) then raise Not_found; (* let's allow this only for core-type abstracts *) if not (Meta.has Meta.CoreType a.a_meta) then raise Not_found; (* in which case we assume that a singular type parameter is the element type *) let t = match tl with [t] -> t | _ -> raise Not_found in gen_int_iter t get_next_array_element get_length end with Not_found -> None end | _ , TInst ({ cl_kind = KGenericInstance ({ cl_path = ["haxe";"ds"],"GenericStack" },[t]) } as c,[]) -> let tcell = (try (PMap.find "head" c.cl_fields).cf_type with Not_found -> assert false) in let i = add_local ctx i t p in let cell = gen_local ctx tcell p in let cexpr = mk (TLocal cell) tcell p in let e2 = type_expr ctx e2 NoValue in let evar = mk (TVar (i,Some (mk (mk_field cexpr "elt") t p))) t_void pi in let enext = mk (TBinop (OpAssign,cexpr,mk (mk_field cexpr "next") tcell p)) tcell p in let block = match e2.eexpr with | TBlock el -> mk (TBlock (evar :: enext :: el)) t_void e2.epos | _ -> mk (TBlock [evar;enext;e2]) t_void p in lblock [ mk (TVar (cell,Some (mk (mk_field e1 "head") tcell p))) t_void p; mk (TWhile ( mk (TBinop (OpNotEq, cexpr, mk (TConst TNull) tcell p)) ctx.t.tbool p, block, NormalWhile )) t_void p ] | _ -> None let optimize_for_loop_iterator ctx v e1 e2 p = let c,tl = (match follow e1.etype with TInst (c,pl) -> c,pl | _ -> raise Exit) in let _, _, fhasnext = (try raw_class_field (fun cf -> apply_params c.cl_params tl cf.cf_type) c tl "hasNext" with Not_found -> raise Exit) in if fhasnext.cf_kind <> Method MethInline then raise Exit; let tmp = gen_local ctx e1.etype e1.epos in let eit = mk (TLocal tmp) e1.etype p in let ehasnext = make_call ctx (mk (TField (eit,FInstance (c, tl, fhasnext))) (TFun([],ctx.t.tbool)) p) [] ctx.t.tbool p in let enext = mk (TVar (v,Some (make_call ctx (mk (TField (eit,quick_field_dynamic eit.etype "next")) (TFun ([],v.v_type)) p) [] v.v_type p))) ctx.t.tvoid p in let eblock = (match e2.eexpr with | TBlock el -> { e2 with eexpr = TBlock (enext :: el) } | _ -> mk (TBlock [enext;e2]) ctx.t.tvoid p ) in mk (TBlock [ mk (TVar (tmp,Some e1)) ctx.t.tvoid p; mk (TWhile (ehasnext,eblock,NormalWhile)) ctx.t.tvoid p ]) ctx.t.tvoid p (* ---------------------------------------------------------------------- *) (* SANITIZE *) (* makes sure that when an AST get generated to source code, it will not generate expressions that evaluate differently. It is then necessary to add parenthesises around some binary expressions when the AST does not correspond to the natural operand priority order for the platform *) (* this is the standard C++ operator precedence, which is also used by both JS and PHP *) let standard_precedence op = let left = true and right = false in match op with | OpMult | OpDiv | OpMod -> 5, left | OpAdd | OpSub -> 6, left | OpShl | OpShr | OpUShr -> 7, left | OpLt | OpLte | OpGt | OpGte -> 8, left | OpEq | OpNotEq -> 9, left | OpAnd -> 10, left | OpXor -> 11, left | OpOr -> 12, left | OpInterval -> 13, right (* haxe specific *) | OpBoolAnd -> 14, left | OpBoolOr -> 15, left | OpArrow -> 16, left | OpAssignOp OpAssign -> 17, right (* mimics ?: *) | OpAssign | OpAssignOp _ -> 18, right let rec need_parent e = match e.eexpr with | TConst _ | TLocal _ | TArray _ | TField _ | TEnumParameter _ | TParenthesis _ | TCall _ | TNew _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ -> false | TCast (e,None) | TMeta(_,e) -> need_parent e | TCast _ | TThrow _ | TReturn _ | TTry _ | TSwitch _ | TFor _ | TIf _ | TWhile _ | TBinop _ | TContinue | TBreak | TBlock _ | TVar _ | TFunction _ | TUnop _ -> true let sanitize_expr com e = let parent e = match e.eexpr with | TParenthesis _ -> e | _ -> mk (TParenthesis e) e.etype e.epos in let block e = match e.eexpr with | TBlock _ -> e | _ -> mk (TBlock [e]) e.etype e.epos in let complex e = (* complex expressions are the one that once generated to source consists in several expressions *) match e.eexpr with | TVar _ (* needs to be put into blocks *) | TFor _ (* a temp var is needed for holding iterator *) | TCall ({ eexpr = TLocal { v_name = "__js__" } },_) (* we never know *) -> block e | _ -> e in (* tells if the printed expresssion ends with an if without else *) let rec has_if e = match e.eexpr with | TIf (_,_,None) -> true | TWhile (_,e,NormalWhile) -> has_if e | TFor (_,_,e) -> has_if e | _ -> false in match e.eexpr with | TConst TNull -> if com.config.pf_static && not (is_nullable e.etype) then begin let rec loop t = match follow t with | TMono _ -> () (* in these cases the null will cast to default value *) | TFun _ -> () (* this is a bit a particular case, maybe flash-specific actually *) (* TODO: this should use get_underlying_type, but we do not have access to Codegen here. *) | TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> loop (apply_params a.a_params tl a.a_this) | _ -> com.error ("On static platforms, null can't be used as basic type " ^ s_type (print_context()) e.etype) e.epos in loop e.etype end; e | TBinop (op,e1,e2) -> let swap op1 op2 = let p1, left1 = standard_precedence op1 in let p2, _ = standard_precedence op2 in left1 && p1 <= p2 in let rec loop ee left = match ee.eexpr with | TBinop (op2,_,_) -> if left then not (swap op2 op) else swap op op2 | TIf _ -> if left then not (swap (OpAssignOp OpAssign) op) else swap op (OpAssignOp OpAssign) | TCast (e,None) | TMeta (_,e) -> loop e left | _ -> false in let e1 = if loop e1 true then parent e1 else e1 in let e2 = if loop e2 false then parent e2 else e2 in { e with eexpr = TBinop (op,e1,e2) } | TUnop (op,mode,e1) -> let rec loop ee = match ee.eexpr with | TBinop _ | TIf _ | TUnop _ -> parent e1 | TCast (e,None) | TMeta (_, e) -> loop e | _ -> e1 in { e with eexpr = TUnop (op,mode,loop e1)} | TIf (e1,e2,eelse) -> let e1 = parent e1 in let e2 = (if (eelse <> None && has_if e2) || (match e2.eexpr with TIf _ -> true | _ -> false) then block e2 else complex e2) in let eelse = (match eelse with None -> None | Some e -> Some (complex e)) in { e with eexpr = TIf (e1,e2,eelse) } | TWhile (e1,e2,flag) -> let e1 = parent e1 in let e2 = complex e2 in { e with eexpr = TWhile (e1,e2,flag) } | TFor (v,e1,e2) -> let e2 = complex e2 in { e with eexpr = TFor (v,e1,e2) } | TFunction f -> let f = (match f.tf_expr.eexpr with | TBlock _ -> f | _ -> { f with tf_expr = block f.tf_expr } ) in { e with eexpr = TFunction f } | TCall (e2,args) -> if need_parent e2 then { e with eexpr = TCall(parent e2,args) } else e | TEnumParameter (e2,ef,i) -> if need_parent e2 then { e with eexpr = TEnumParameter(parent e2,ef,i) } else e | TField (e2,f) -> if need_parent e2 then { e with eexpr = TField(parent e2,f) } else e | TArray (e1,e2) -> if need_parent e1 then { e with eexpr = TArray(parent e1,e2) } else e | TTry (e1,catches) -> let e1 = block e1 in let catches = List.map (fun (v,e) -> v, block e) catches in { e with eexpr = TTry (e1,catches) } | TSwitch (e1,cases,def) -> let e1 = parent e1 in let cases = List.map (fun (el,e) -> el, complex e) cases in let def = (match def with None -> None | Some e -> Some (complex e)) in { e with eexpr = TSwitch (e1,cases,def) } | _ -> e let reduce_expr com e = match e.eexpr with | TSwitch (_,cases,_) -> List.iter (fun (cl,_) -> List.iter (fun e -> match e.eexpr with | TCall ({ eexpr = TField (_,FEnum _) },_) -> error "Not-constant enum in switch cannot be matched" e.epos | _ -> () ) cl ) cases; e | TBlock l -> (match List.rev l with | [] -> e | ec :: l -> (* remove all no-ops : not-final constants in blocks *) match List.filter (fun e -> match e.eexpr with | TConst _ | TBlock [] | TObjectDecl [] -> false | _ -> true ) l with | [] -> ec | l -> { e with eexpr = TBlock (List.rev (ec :: l)) }) | TParenthesis ec -> { ec with epos = e.epos } | TTry (e,[]) -> e | _ -> e let rec sanitize com e = sanitize_expr com (reduce_expr com (Type.map_expr (sanitize com) e)) (* ---------------------------------------------------------------------- *) (* REDUCE *) let reduce_control_flow ctx e = match e.eexpr with | TIf ({ eexpr = TConst (TBool t) },e1,e2) -> (if t then e1 else match e2 with None -> { e with eexpr = TBlock [] } | Some e -> e) | TWhile ({ eexpr = TConst (TBool false) },sub,flag) -> (match flag with | NormalWhile -> { e with eexpr = TBlock [] } (* erase sub *) | DoWhile -> e) (* we cant remove while since sub can contain continue/break *) | TSwitch (e1,cases,def) -> let e = match Texpr.skip e1 with | {eexpr = TConst ct} as e1 -> let rec loop cases = match cases with | (el,e) :: cases -> if List.exists (Texpr.equal e1) el then e else loop cases | [] -> begin match def with | None -> e | Some e -> e end in loop cases | _ -> e in e | TBinop (op,e1,e2) -> optimize_binop e op e1 e2 | TUnop (op,flag,esub) -> optimize_unop e op flag esub | TCall ({ eexpr = TField (o,FClosure (c,cf)) } as f,el) -> let fmode = (match c with None -> FAnon cf | Some (c,tl) -> FInstance (c,tl,cf)) in { e with eexpr = TCall ({ f with eexpr = TField (o,fmode) },el) } | _ -> e let rec reduce_loop ctx e = let e = Type.map_expr (reduce_loop ctx) e in sanitize_expr ctx.com (match e.eexpr with | TCall ({ eexpr = TField ({ eexpr = TTypeExpr (TClassDecl c) },field) },params) -> (match api_inline ctx c (field_name field) params e.epos with | None -> reduce_expr ctx e | Some e -> reduce_loop ctx e) | TCall ({ eexpr = TFunction func } as ef,el) -> let cf = mk_field "" ef.etype e.epos null_pos in let ethis = mk (TConst TThis) t_dynamic e.epos in let rt = (match follow ef.etype with TFun (_,rt) -> rt | _ -> assert false) in let inl = (try type_inline ctx cf func ethis el rt None e.epos ~self_calling_closure:true false with Error (Custom _,_) -> None) in (match inl with | None -> reduce_expr ctx e | Some e -> reduce_loop ctx e) | _ -> reduce_expr ctx (reduce_control_flow ctx e)) let reduce_expression ctx e = if ctx.com.foptimize then reduce_loop ctx e else e let rec make_constant_expression ctx ?(concat_strings=false) e = let e = reduce_loop ctx e in match e.eexpr with | TConst _ -> Some e | TBinop ((OpAdd|OpSub|OpMult|OpDiv|OpMod|OpShl|OpShr|OpUShr|OpOr|OpAnd|OpXor) as op,e1,e2) -> (match make_constant_expression ctx e1,make_constant_expression ctx e2 with | Some ({eexpr = TConst (TString s1)}), Some ({eexpr = TConst (TString s2)}) when concat_strings -> Some (mk (TConst (TString (s1 ^ s2))) ctx.com.basic.tstring (punion e1.epos e2.epos)) | Some e1, Some e2 -> Some (mk (TBinop(op, e1, e2)) e.etype e.epos) | _ -> None) | TUnop((Neg | NegBits) as op,Prefix,e1) -> (match make_constant_expression ctx e1 with | Some e1 -> Some (mk (TUnop(op,Prefix,e1)) e.etype e.epos) | None -> None) | TCast (e1, None) -> (match make_constant_expression ctx e1 with | None -> None | Some e1 -> Some {e with eexpr = TCast(e1,None)}) | TParenthesis e1 -> begin match make_constant_expression ctx ~concat_strings e1 with | None -> None | Some e1 -> Some {e with eexpr = TParenthesis e1} end | TMeta(m,e1) -> begin match make_constant_expression ctx ~concat_strings e1 with | None -> None | Some e1 -> Some {e with eexpr = TMeta(m,e1)} end | TTypeExpr _ -> Some e (* try to inline static function calls *) (* Disabled for now, see #4254. *) (* | TCall ({ etype = TFun(_,ret); eexpr = TField (_,FStatic (c,cf)) },el) -> (try let func = match cf.cf_expr with Some ({eexpr = TFunction func}) -> func | _ -> raise Not_found in let ethis = mk (TConst TThis) t_dynamic e.epos in let inl = (try type_inline ctx cf func ethis el ret None e.epos false with Error (Custom _,_) -> None) in (match inl with | None -> None | Some e -> make_constant_expression ctx e) with Not_found -> None) *) | _ -> None (* ---------------------------------------------------------------------- *) (* INLINE CONSTRUCTORS *) (* First pass : We will look at local variables in the form var v = new .... we only capture the ones which have constructors marked as inlined then we make sure that these locals are no more referenced except for fields accesses Second pass : We replace the variables by their fields lists, and the corresponding fields accesses as well *) type inline_info_kind = | IKCtor of tclass_field * bool | IKStructure | IKArray of int type inline_info = { ii_var : tvar; ii_expr : texpr; ii_kind : inline_info_kind; mutable ii_fields : (string,tvar) PMap.t; } let inline_constructors ctx e = let vars = ref IntMap.empty in let is_valid_ident s = try if String.length s = 0 then raise Exit; begin match String.unsafe_get s 0 with | 'a'..'z' | 'A'..'Z' | '_' -> () | _ -> raise Exit end; for i = 1 to String.length s - 1 do match String.unsafe_get s i with | 'a'..'z' | 'A'..'Z' | '_' -> () | '0'..'9' when i > 0 -> () | _ -> raise Exit done; true with Exit -> false in let cancel v p = try let ii = IntMap.find v.v_id !vars in vars := IntMap.remove v.v_id !vars; v.v_id <- -v.v_id; begin match ii.ii_kind with | IKCtor(cf,true) -> display_error ctx "Extern constructor could not be inlined" p; error "Variable is used here" p; | _ -> () end; with Not_found -> () in let add v e kind = let ii = { ii_var = v; ii_fields = PMap.empty; ii_expr = e; ii_kind = kind } in v.v_id <- -v.v_id; vars := IntMap.add v.v_id ii !vars; in let get_field_var v s = let ii = IntMap.find v.v_id !vars in PMap.find s ii.ii_fields in let add_field_var v s t = let ii = IntMap.find v.v_id !vars in let v' = alloc_var (Printf.sprintf "%s_%s" v.v_name s) t v.v_pos in v'.v_meta <- (Meta.InlineConstructorVariable,[],v.v_pos) :: v'.v_meta; ii.ii_fields <- PMap.add s v' ii.ii_fields; v' in let int_field_name i = if i < 0 then "n" ^ (string_of_int (-i)) else (string_of_int i) in let is_extern_ctor c cf = c.cl_extern || Meta.has Meta.Extern cf.cf_meta in let rec find_locals e = match e.eexpr with | TVar(v,Some e1) -> find_locals e1; let rec loop el_init e1 = match e1.eexpr with | TBlock el -> begin match List.rev el with | e1 :: el -> loop (el @ el_init) e1 | [] -> () end | TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction tf})} as cf)} as c,tl,pl) when type_iseq v.v_type e1.etype -> begin match type_inline_ctor ctx c cf tf (mk (TLocal v) (TInst (c,tl)) e1.epos) pl e1.epos with | Some e -> let e' = match el_init with | [] -> e | _ -> mk (TBlock (List.rev (e :: el_init))) e.etype e.epos in add v e' (IKCtor(cf,is_extern_ctor c cf)); find_locals e | None -> () end | TObjectDecl fl when fl <> [] -> begin try let ev = mk (TLocal v) v.v_type e.epos in let el = List.fold_left (fun acc (s,e) -> if not (is_valid_ident s) then raise Exit; let ef = mk (TField(ev,FDynamic s)) e.etype e.epos in let e = mk (TBinop(OpAssign,ef,e)) e.etype e.epos in e :: acc ) el_init fl in let e = mk (TBlock (List.rev el)) ctx.t.tvoid e.epos in add v e IKStructure with Exit -> () end | TArrayDecl el -> let ev = mk (TLocal v) v.v_type e.epos in let el,_ = List.fold_left (fun (acc,i) e -> let ef = mk (TField(ev,FDynamic (string_of_int i))) e.etype e.epos in let e = mk (TBinop(OpAssign,ef,e)) e.etype e.epos in e :: acc,i + 1 ) (el_init,0) el in let e = mk (TBlock (List.rev el)) ctx.t.tvoid e.epos in add v e (IKArray (List.length el)) | TCast(e1,None) | TParenthesis e1 -> loop el_init e1 | _ -> () in loop [] e1 | TBinop(OpAssign,({eexpr = TField({eexpr = TLocal v},fa)} as e1),e2) when v.v_id < 0 -> let s = field_name fa in (try ignore(get_field_var v s) with Not_found -> ignore(add_field_var v s e1.etype)); find_locals e2 | TField({eexpr = TLocal v},fa) when v.v_id < 0 -> begin match extract_field fa with | Some ({cf_kind = Var _} as cf) -> (* Arrays are not supposed to have public var fields, besides "length" (which we handle when inlining), however, its inlined methods may generate access to private implementation fields (such as internal native array), in this case we have to cancel inlining. *) if cf.cf_name <> "length" then begin match (IntMap.find v.v_id !vars).ii_kind with | IKArray _ -> cancel v e.epos | _ -> (try ignore(get_field_var v cf.cf_name) with Not_found -> ignore(add_field_var v cf.cf_name e.etype)); end | _ -> cancel v e.epos end | TArray({eexpr = TLocal v},{eexpr = TConst (TInt i)}) when v.v_id < 0 -> let i = Int32.to_int i in begin try let ii = IntMap.find v.v_id !vars in let l = match ii.ii_kind with | IKArray l -> l | _ -> raise Not_found in if i < 0 || i >= l then raise Not_found; with Not_found -> cancel v e.epos end | TLocal v when v.v_id < 0 -> cancel v e.epos; | _ -> Type.iter find_locals e in find_locals e; (* Pass 2 *) let inline v p = try let ii = IntMap.find v.v_id !vars in let el = PMap.fold (fun v acc -> (mk (TVar(v,None)) ctx.t.tvoid p) :: acc) ii.ii_fields [] in let e = {ii.ii_expr with eexpr = TBlock (el @ [ii.ii_expr])} in Some e with Not_found -> None in let assign_or_declare v name e2 t p = try let v = get_field_var v name in let e1 = mk (TLocal v) t p in mk (TBinop(OpAssign,e1,e2)) e1.etype p with Not_found -> let v = add_field_var v name t in mk (TVar(v,Some e2)) ctx.t.tvoid e.epos in let use_local_or_null v name t p = try let v' = get_field_var v name in mk (TLocal v') t p with Not_found -> try if name <> "length" then raise Not_found; let ii = IntMap.find v.v_id !vars in begin match ii.ii_kind with | IKArray l -> mk (TConst (TInt (Int32.of_int l))) ctx.t.tint p | _ -> raise Not_found end with Not_found -> mk (TConst TNull) t p in let flatten e = let el = ref [] in let rec loop e = match e.eexpr with | TBlock el -> List.iter loop el | _ -> el := e :: !el in loop e; let e = mk (TBlock (List.rev !el)) e.etype e.epos in mk (TMeta((Meta.MergeBlock,[],e.epos),e)) e.etype e.epos in let rec loop e = match e.eexpr with | TVar(v,_) when v.v_id < 0 -> begin match inline v e.epos with | Some e -> let e = flatten e in loop e | None -> cancel v e.epos; e end | TBinop(OpAssign,({eexpr = TField({eexpr = TLocal v},fa)} as e1),e2) when v.v_id < 0 -> let e2 = loop e2 in assign_or_declare v (field_name fa) e2 e1.etype e.epos | TField({eexpr = TLocal v},fa) when v.v_id < 0 -> use_local_or_null v (field_name fa) e.etype e.epos | TBinop(OpAssign,({eexpr = TArray({eexpr = TLocal v},{eexpr = TConst (TInt i)})} as e1),e2) when v.v_id < 0 -> let e2 = loop e2 in let name = int_field_name (Int32.to_int i) in assign_or_declare v name e2 e1.etype e.epos | TArray({eexpr = TLocal v},{eexpr = TConst (TInt i)}) when v.v_id < 0 -> use_local_or_null v (int_field_name (Int32.to_int i)) e.etype e.epos | TBlock el -> let rec block acc el = match el with | e1 :: el -> begin match loop e1 with | {eexpr = TMeta((Meta.MergeBlock,_,_),{eexpr = TBlock el2})} -> let acc = block acc el2 in block acc el | e -> block (e :: acc) el end | [] -> acc in let el = block [] el in mk (TBlock (List.rev el)) e.etype e.epos | TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction _})} as cf)} as c,_,_) when is_extern_ctor c cf -> display_error ctx "Extern constructor could not be inlined" e.epos; Type.map_expr loop e | _ -> Type.map_expr loop e in loop e (* ---------------------------------------------------------------------- *) (* COMPLETION *) exception Return of Ast.expr type compl_locals = { mutable r : (string, (complex_type option * (int * Ast.expr * compl_locals) option)) PMap.t; } let optimize_completion_expr e = let iid = ref 0 in let typing_side_effect = ref false in let locals : compl_locals = { r = PMap.empty } in let save() = let old = locals.r in (fun() -> locals.r <- old) in let get_local n = PMap.find n locals.r in let maybe_typed e = match fst e with | EConst (Ident "null") -> false | _ -> true in let decl n t e = typing_side_effect := true; locals.r <- PMap.add n (t,(match e with Some e when maybe_typed e -> incr iid; Some (!iid,e,{ r = locals.r }) | _ -> None)) locals.r in let rec loop e = let p = snd e in match fst e with | EConst (Ident n) -> (try (match get_local n with | Some _ , _ -> () | _ -> typing_side_effect := true) with Not_found -> ()); e | EBinop (OpAssign,(EConst (Ident n),_),esub) -> (try (match get_local n with | None, None when maybe_typed esub -> decl n None (Some esub) | _ -> ()) with Not_found -> ()); map e | EVars vl -> let vl = List.map (fun ((v,pv),t,e) -> let e = (match e with None -> None | Some e -> Some (loop e)) in decl v (Option.map fst t) e; ((v,pv),t,e) ) vl in (EVars vl,p) | EBlock el -> let old = save() in let told = ref (!typing_side_effect) in let el = List.fold_left (fun acc e -> typing_side_effect := false; let e = loop e in if !typing_side_effect || Display.is_display_position (pos e) then begin told := true; e :: acc end else acc ) [] el in old(); typing_side_effect := !told; (EBlock (List.rev el),p) | EFunction (v,f) -> (match v with | None -> () | Some name -> decl name None (Some e)); let old = save() in List.iter (fun ((n,_),_,_,t,e) -> decl n (Option.map fst t) e) f.f_args; let e = map e in old(); e | EFor ((EIn ((EConst (Ident n),_) as id,it),p),efor) -> let it = loop it in let old = save() in let etmp = (EConst (Ident "$tmp"),p) in decl n None (Some (EBlock [ (EVars [("$tmp",null_pos),None,None],p); (EFor ((EIn (id,it),p),(EBinop (OpAssign,etmp,(EConst (Ident n),p)),p)),p); etmp ],p)); let efor = loop efor in old(); (EFor ((EIn (id,it),p),efor),p) | EReturn _ -> typing_side_effect := true; map e | ESwitch (e,cases,def) -> let e = loop e in let cases = List.map (fun (el,eg,eo,p) -> match eo with | None -> el,eg,eo,p | Some e -> let el = List.map loop el in let old = save() in List.iter (fun e -> match fst e with | ECall (_,pl) -> List.iter (fun p -> match fst p with | EConst (Ident i) -> decl i None None (* sadly *) | _ -> () ) pl | _ -> () ) el; let e = loop e in old(); el, eg, Some e, p ) cases in let def = match def with | None -> None | Some (None,p) -> Some (None,p) | Some (Some e,p) -> Some (Some (loop e),p) in (ESwitch (e,cases,def),p) | ETry (et,cl) -> let et = loop et in let cl = List.map (fun ((n,pn),(t,pt),e,p) -> let old = save() in decl n (Some t) None; let e = loop e in old(); (n,pn), (t,pt), e, p ) cl in (ETry (et,cl),p) | EDisplay (s,call) -> typing_side_effect := true; let tmp_locals = ref [] in let tmp_hlocals = ref PMap.empty in let rec subst_locals locals e = match fst e with | EConst (Ident n) -> let p = snd e in (try (match PMap.find n locals.r with | Some t , _ -> (ECheckType ((EConst (Ident "null"),p),(t,p)),p) | _, Some (id,e,lc) -> let name = (try PMap.find id (!tmp_hlocals) with Not_found -> let e = subst_locals lc e in let name = "$tmp_" ^ string_of_int id in tmp_locals := ((name,null_pos),None,Some e) :: !tmp_locals; tmp_hlocals := PMap.add id name !tmp_hlocals; name ) in (EConst (Ident name),p) | None, None -> (* we can't replace the var *) raise Exit) with Not_found -> (* not found locals are most likely to be member/static vars *) e) | EFunction (_,f) -> Ast.map_expr (subst_locals { r = PMap.foldi (fun n i acc -> if List.exists (fun ((a,_),_,_,_,_) -> a = n) f.f_args then acc else PMap.add n i acc) locals.r PMap.empty }) e | EObjectDecl [] -> (* this probably comes from { | completion so we need some context} *) raise Exit | _ -> Ast.map_expr (subst_locals locals) e in (try let e = subst_locals locals s in let e = (EBlock [(EVars (List.rev !tmp_locals),p);(EDisplay (e,call),p)],p) in raise (Return e) with Exit -> map e) | EDisplayNew _ -> raise (Return e) | _ -> map e and map e = Ast.map_expr loop e in (try loop e with Return e -> e) (* ---------------------------------------------------------------------- *) haxe_3.4.4.orig/src/optimization/optimizerTexpr.ml0000664000175000017500000002435113166552354022335 0ustar andyandy00000000000000open Ast open Type open Error open Globals (* PurityState represents whether or not something has a side-effect. Unless otherwise stated by using `@:pure` (equivalent to `@:pure(true)`) or `@:pure(false)`, fields are originally supposed to be "maybe pure". Once all types and fields are known, this is refined by AnalyzerTexpr.Purity. There's a special case for fields that override a parent class field or implement an interface field: If the overridden/implemented field is explicitly marked as pure, the type loader marks the overriding/implementing as "expected pure". If during purity inference this assumption does not hold, an error is shown. *) module PurityState = struct type t = | Pure | Impure | MaybePure | ExpectPure of pos let get_purity_from_meta meta = try begin match Meta.get Meta.Pure meta with | (_,[EConst(Ident s),p],_) -> begin match s with | "true" -> Pure | "false" -> Impure | "expect" -> ExpectPure p | _ -> error ("Unsupported purity value " ^ s ^ ", expected true or false") p end | (_,[],_) -> Pure | (_,_,p) -> error "Unsupported purity value" p end with Not_found -> MaybePure let get_purity c cf = match get_purity_from_meta cf.cf_meta with | Pure -> Pure | Impure -> Impure | ExpectPure p -> ExpectPure p | _ -> get_purity_from_meta c.cl_meta let is_pure c cf = get_purity c cf = Pure let is_pure_field_access fa = match fa with | FInstance(c,_,cf) | FClosure(Some(c,_),cf) | FStatic(c,cf) -> is_pure c cf | FAnon cf | FClosure(None,cf) -> (get_purity_from_meta cf.cf_meta = Pure) | FEnum _ -> true | FDynamic _ -> false let to_string = function | Pure -> "pure" | Impure -> "impure" | MaybePure -> "maybe" | ExpectPure _ -> "expect" end (* tells if an expression causes side effects. This does not account for potential null accesses (fields/arrays/ops) *) let has_side_effect e = let rec loop e = match e.eexpr with | TConst _ | TLocal _ | TTypeExpr _ | TFunction _ -> () | TCall({eexpr = TField(e1,fa)},el) when PurityState.is_pure_field_access fa -> loop e1; List.iter loop el | TNew(c,_,el) when (match c.cl_constructor with Some cf when PurityState.is_pure c cf -> true | _ -> false) -> List.iter loop el | TNew _ | TCall _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> raise Exit | TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> raise Exit | TArray _ | TEnumParameter _ | TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TMeta _ | TWhile _ | TFor _ | TField _ | TIf _ | TTry _ | TSwitch _ | TArrayDecl _ | TBlock _ | TObjectDecl _ | TVar _ -> Type.iter loop e in try loop e; false with Exit -> true let rec is_exhaustive e1 = match e1.eexpr with | TMeta((Meta.Exhaustive,_,_),_) -> true | TMeta(_, e1) | TParenthesis e1 -> is_exhaustive e1 | _ -> false let is_read_only_field_access e fa = match fa with | FEnum _ -> true | FDynamic _ -> false | FAnon {cf_kind = Var {v_write = AccNo}} when (match e.eexpr with TLocal v when is_unbound v -> true | _ -> false) -> true | FInstance (c,_,cf) | FStatic (c,cf) | FClosure (Some(c,_),cf) -> begin match cf.cf_kind with | Method MethDynamic -> false | Method _ -> true | Var {v_write = AccNever} when not c.cl_interface -> true | _ -> false end | FAnon cf | FClosure(None,cf) -> begin match cf.cf_kind with | Method MethDynamic -> false | Method _ -> true | _ -> false end let create_affection_checker () = let modified_locals = Hashtbl.create 0 in let rec might_be_affected e = let rec loop e = match e.eexpr with | TConst _ | TFunction _ | TTypeExpr _ -> () | TLocal v when Hashtbl.mem modified_locals v.v_id -> raise Exit | TField(e1,fa) when not (is_read_only_field_access e1 fa) -> raise Exit | TCall _ | TNew _ -> raise Exit | _ -> Type.iter loop e in try loop e; false with Exit -> true in let rec collect_modified_locals e = match e.eexpr with | TUnop((Increment | Decrement),_,{eexpr = TLocal v}) -> Hashtbl.add modified_locals v.v_id true | TBinop((OpAssign | OpAssignOp _),{eexpr = TLocal v},e2) -> collect_modified_locals e2; Hashtbl.add modified_locals v.v_id true | _ -> Type.iter collect_modified_locals e in might_be_affected,collect_modified_locals let optimize_binop e op e1 e2 = let is_float t = match follow t with | TAbstract({ a_path = [],"Float" },_) -> true | _ -> false in let is_numeric t = match follow t with | TAbstract({ a_path = [],("Float"|"Int") },_) -> true | _ -> false in let check_float op f1 f2 = let f = op f1 f2 in let fstr = Common.float_repres f in if (match classify_float f with FP_nan | FP_infinite -> false | _ -> float_of_string fstr = f) then { e with eexpr = TConst (TFloat fstr) } else e in (match e1.eexpr, e2.eexpr with | TConst (TInt 0l) , _ when op = OpAdd && is_numeric e2.etype -> e2 | TConst (TInt 1l) , _ when op = OpMult -> e2 | TConst (TFloat v) , _ when op = OpAdd && float_of_string v = 0. && is_float e2.etype -> e2 | TConst (TFloat v) , _ when op = OpMult && float_of_string v = 1. && is_float e2.etype -> e2 | _ , TConst (TInt 0l) when (match op with OpAdd -> is_numeric e1.etype | OpSub | OpShr | OpShl -> true | _ -> false) -> e1 (* bits operations might cause overflow *) | _ , TConst (TInt 1l) when op = OpMult -> e1 | _ , TConst (TFloat v) when (match op with OpAdd | OpSub -> float_of_string v = 0. && is_float e1.etype | _ -> false) -> e1 (* bits operations might cause overflow *) | _ , TConst (TFloat v) when op = OpMult && float_of_string v = 1. && is_float e1.etype -> e1 | TConst TNull, TConst TNull -> (match op with | OpEq -> { e with eexpr = TConst (TBool true) } | OpNotEq -> { e with eexpr = TConst (TBool false) } | _ -> e) | TFunction _, TConst TNull -> (match op with | OpEq -> { e with eexpr = TConst (TBool false) } | OpNotEq -> { e with eexpr = TConst (TBool true) } | _ -> e) | TConst TNull, TFunction _ -> (match op with | OpEq -> { e with eexpr = TConst (TBool false) } | OpNotEq -> { e with eexpr = TConst (TBool true) } | _ -> e) | TConst (TInt a), TConst (TInt b) -> let opt f = try { e with eexpr = TConst (TInt (f a b)) } with Exit -> e in let check_overflow f = opt (fun a b -> let v = f (Int64.of_int32 a) (Int64.of_int32 b) in let iv = Int64.to_int32 v in if Int64.compare (Int64.of_int32 iv) v <> 0 then raise Exit; iv ) in let ebool t = { e with eexpr = TConst (TBool (t (Int32.compare a b) 0)) } in (match op with | OpAdd -> check_overflow Int64.add | OpSub -> check_overflow Int64.sub | OpMult -> check_overflow Int64.mul | OpDiv -> check_float ( /. ) (Int32.to_float a) (Int32.to_float b) | OpAnd -> opt Int32.logand | OpOr -> opt Int32.logor | OpXor -> opt Int32.logxor | OpShl -> opt (fun a b -> Int32.shift_left a (Int32.to_int b)) | OpShr -> opt (fun a b -> Int32.shift_right a (Int32.to_int b)) | OpUShr -> opt (fun a b -> Int32.shift_right_logical a (Int32.to_int b)) | OpEq -> ebool (=) | OpNotEq -> ebool (<>) | OpGt -> ebool (>) | OpGte -> ebool (>=) | OpLt -> ebool (<) | OpLte -> ebool (<=) | _ -> e) | TConst ((TFloat _ | TInt _) as ca), TConst ((TFloat _ | TInt _) as cb) -> let fa = (match ca with | TFloat a -> float_of_string a | TInt a -> Int32.to_float a | _ -> assert false ) in let fb = (match cb with | TFloat b -> float_of_string b | TInt b -> Int32.to_float b | _ -> assert false ) in let fop op = check_float op fa fb in let ebool t = { e with eexpr = TConst (TBool (t (compare fa fb) 0)) } in (match op with | OpAdd -> fop (+.) | OpDiv -> fop (/.) | OpSub -> fop (-.) | OpMult -> fop ( *. ) | OpEq -> ebool (=) | OpNotEq -> ebool (<>) | OpGt -> ebool (>) | OpGte -> ebool (>=) | OpLt -> ebool (<) | OpLte -> ebool (<=) | _ -> e) | TConst (TString ""),TConst (TString s) | TConst (TString s),TConst (TString "") when op = OpAdd -> {e with eexpr = TConst (TString s)} | TConst (TBool a), TConst (TBool b) -> let ebool f = { e with eexpr = TConst (TBool (f a b)) } in (match op with | OpEq -> ebool (=) | OpNotEq -> ebool (<>) | OpBoolAnd -> ebool (&&) | OpBoolOr -> ebool (||) | _ -> e) | TConst a, TConst b when op = OpEq || op = OpNotEq -> let ebool b = { e with eexpr = TConst (TBool (if op = OpEq then b else not b)) } in (match a, b with | TInt a, TFloat b | TFloat b, TInt a -> ebool (Int32.to_float a = float_of_string b) | _ -> ebool (a = b)) | TConst (TBool a), _ -> (match op with | OpBoolAnd -> if a then e2 else { e with eexpr = TConst (TBool false) } | OpBoolOr -> if a then { e with eexpr = TConst (TBool true) } else e2 | _ -> e) | _ , TConst (TBool a) -> (match op with | OpBoolAnd when a -> e1 | OpBoolOr when not a -> e1 | _ -> e) | TField (_,FEnum (e1,f1)), TField (_,FEnum (e2,f2)) when e1 == e2 -> (match op with | OpEq -> { e with eexpr = TConst (TBool (f1 == f2)) } | OpNotEq -> { e with eexpr = TConst (TBool (f1 != f2)) } | _ -> e) | _, TCall ({ eexpr = TField (_,FEnum _) },_) | TCall ({ eexpr = TField (_,FEnum _) },_), _ -> (match op with | OpAssign -> e | _ -> error "You cannot directly compare enums with arguments. Use either 'switch' or 'Type.enumEq'" e.epos) | _ -> e) let optimize_unop e op flag esub = let is_int t = match follow t with | TAbstract({a_path = [],"Int"},_) -> true | _ -> false in match op, esub.eexpr with | Not, (TConst (TBool f) | TParenthesis({eexpr = TConst (TBool f)})) -> { e with eexpr = TConst (TBool (not f)) } | Not, (TBinop(op,e1,e2) | TParenthesis({eexpr = TBinop(op,e1,e2)})) -> begin let is_int = is_int e1.etype && is_int e2.etype in try let op = match is_int, op with | true, OpGt -> OpLte | true, OpGte -> OpLt | true, OpLt -> OpGte | true, OpLte -> OpGt | _, OpEq -> OpNotEq | _, OpNotEq -> OpEq | _ -> raise Exit in {e with eexpr = TBinop(op,e1,e2)} with Exit -> e end | Neg, TConst (TInt i) -> { e with eexpr = TConst (TInt (Int32.neg i)) } | NegBits, TConst (TInt i) -> { e with eexpr = TConst (TInt (Int32.lognot i)) } | Neg, TConst (TFloat f) -> let v = 0. -. float_of_string f in let vstr = Common.float_repres v in if float_of_string vstr = v then { e with eexpr = TConst (TFloat vstr) } else e | _ -> ehaxe_3.4.4.orig/src/path.ml0000664000175000017500000001021513166552354015470 0ustar andyandy00000000000000let get_path_parts f = (* this function is quite weird: it tries to determine whether the given argument is a .hx file path with slashes or a dotted module path and based on that it returns path "parts", which are basically a list of either folders or packages (which are folders too) appended by the module name TODO: i started doubting my sanity while writing this comment, let's somehow refactor this stuff so it doesn't mix up file and module paths and doesn't introduce the weird "path part" entity. *) let l = String.length f in if l > 3 && (String.sub f (l-3) 3) = ".hx" then let f = String.sub f 0 (l-3) in (* strip the .hx *) ExtString.String.nsplit (String.concat "/" (ExtString.String.nsplit f "\\")) "/" (* TODO: wouldn't it be faster to Str.split here? *) else ExtString.String.nsplit f "." let parse_path f = let cl = get_path_parts f in let error msg = let msg = "Could not process argument " ^ f ^ "\n" ^ msg in failwith msg in let invalid_char x = for i = 1 to String.length x - 1 do match x.[i] with | 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' -> () | c -> error ("invalid character: " ^ (String.make 1 c)) done in let rec loop = function | [] -> error "empty part" | [x] -> invalid_char x; [],x | x :: l -> if String.length x = 0 then error "empty part" else if x.[0] < 'a' || x.[0] > 'z' then error "Package name must start with a lower case character"; invalid_char x; let path,name = loop l in x :: path,name in loop cl let starts_uppercase x = x.[0] = '_' || (x.[0] >= 'A' && x.[0] <= 'Z') let check_uppercase x = if String.length x = 0 then failwith "empty part" else if not (starts_uppercase x) then failwith "Class name must start with uppercase character" let parse_type_path s = let pack,name = parse_path s in check_uppercase name; pack,name let path_regex = Str.regexp "[/\\]+" let normalize_path path = let rec normalize acc m = match m with | [] -> List.rev acc | Str.Text "." :: Str.Delim _ :: tl when acc = [] -> normalize [] tl | Str.Text ".." :: Str.Delim _ :: tl -> (match acc with | [] -> raise Exit | _ :: acc -> normalize acc tl) | Str.Text t :: Str.Delim _ :: tl -> normalize (t :: acc) tl | Str.Delim _ :: tl -> normalize ("" :: acc) tl | Str.Text t :: [] -> List.rev (t :: acc) | Str.Text _ :: Str.Text _ :: _ -> assert false in String.concat "/" (normalize [] (Str.full_split path_regex path)) let path_sep = if Globals.is_windows then "\\" else "/" (** Returns absolute path. Doesn't fix path case on Windows. *) let get_full_path f = try Extc.get_full_path f with _ -> f (** Returns absolute path (on Windows ensures proper case with drive letter upper-cased) Use for returning positions from IDE support functions *) let get_real_path = if Globals.is_windows then (fun p -> try Extc.get_real_path p with _ -> p) else get_full_path (** Returns absolute path guaranteed to be the same for different letter case. Use where equality comparison is required, lowercases the path on Windows *) let unique_full_path = if Globals.is_windows then (fun f -> String.lowercase (get_full_path f)) else get_full_path let add_trailing_slash p = let l = String.length p in if l = 0 then "./" else match p.[l-1] with | '\\' | '/' -> p | _ -> p ^ "/" let rec remove_trailing_slash p = let l = String.length p in if l = 0 then "./" else match p.[l-1] with | '\\' | '/' -> remove_trailing_slash (String.sub p 0 (l - 1)) | _ -> p open Globals let find_directories target recursive paths = let target_dirs = List.map platform_name platforms in let rec loop acc dir = try let entries = Sys.readdir dir in Array.fold_left (fun acc file -> match file with | "." | ".." -> acc | _ when Sys.is_directory (dir ^ file) && file.[0] >= 'a' && file.[0] <= 'z' -> if List.mem file target_dirs && file <> target then acc else begin let full = (dir ^ file) in if recursive then loop (full :: acc) (full ^ "/") else full :: acc end | _ -> acc ) acc entries; with Sys_error _ -> acc in List.fold_left (fun acc dir -> loop acc dir) [] pathshaxe_3.4.4.orig/src/server.ml0000664000175000017500000005336113166552354016053 0ustar andyandy00000000000000open Printf open Globals open Ast open Common open Common.DisplayMode open Type open DisplayOutput exception Dirty of module_def let measure_times = ref false let prompt = ref false let start_time = ref (get_time()) let is_debug_run() = try Sys.getenv "HAXEDEBUG" = "1" with _ -> false type context = { com : Common.context; mutable flush : unit -> unit; mutable setup : unit -> unit; mutable messages : string list; mutable has_next : bool; mutable has_error : bool; } let report_times print = let tot = ref 0. in Hashtbl.iter (fun _ t -> tot := !tot +. t.total) Common.htimers; if !tot > 0. then begin let buckets = Hashtbl.create 0 in let add id time calls = try let time',calls' = Hashtbl.find buckets id in Hashtbl.replace buckets id (time' +. time,calls' + calls) with Not_found -> Hashtbl.add buckets id (time,calls) in Hashtbl.iter (fun _ t -> let rec loop acc ids = match ids with | id :: ids -> add (List.rev (id :: acc)) t.total t.calls; loop (id :: acc) ids | [] -> () in loop [] t.id ) Common.htimers; let max_name = ref 0 in let max_calls = ref 0 in let timers = Hashtbl.fold (fun id t acc -> let name,indent = match List.rev id with | [] -> assert false | name :: l -> name,(String.make (List.length l * 2) ' ') in let name,info = try let i = String.rindex name '.' in String.sub name (i + 1) (String.length name - i - 1),String.sub name 0 i with Not_found -> name,"" in let name = indent ^ name in if String.length name > !max_name then max_name := String.length name; if snd t > !max_calls then max_calls := snd t; (id,name,info,t) :: acc ) buckets [] in let max_calls = String.length (string_of_int !max_calls) in print (Printf.sprintf "%-*s | %7s | %% | %*s | info" !max_name "name" "time(s)" max_calls "#"); let sep = String.make (!max_name + max_calls + 21) '-' in print sep; let timers = List.sort (fun (id1,_,_,_) (id2,_,_,_) -> compare id1 id2) timers in let print_timer id name info (time,calls) = print (Printf.sprintf "%-*s | %7.3f | %3.0f | %*i | %s" !max_name name time (time *. 100. /. !tot) max_calls calls info) in List.iter (fun (id,name,info,t) -> print_timer id name info t) timers; print sep; print_timer ["total"] "total" "" (!tot,0) end let default_flush ctx = List.iter prerr_endline (List.rev ctx.messages); if ctx.has_error && !prompt then begin print_endline "Press enter to exit..."; ignore(read_line()); end; if ctx.has_error then exit 1 let create_context params = let ctx = { com = Common.create version s_version params; flush = (fun()->()); setup = (fun()->()); messages = []; has_next = false; has_error = false; } in ctx.flush <- (fun() -> default_flush ctx); ctx let parse_hxml_data data = let lines = Str.split (Str.regexp "[\r\n]+") data in List.concat (List.map (fun l -> let l = unquote (ExtString.String.strip l) in if l = "" || l.[0] = '#' then [] else if l.[0] = '-' then try let a, b = ExtString.String.split l " " in [unquote a; unquote (ExtString.String.strip b)] with _ -> [l] else [l] ) lines) let parse_hxml file = let ch = IO.input_channel (try open_in_bin file with _ -> raise Not_found) in let data = IO.read_all ch in IO.close_in ch; parse_hxml_data data let ssend sock str = let rec loop pos len = if len = 0 then () else let s = Unix.send sock str pos len [] in loop (pos + s) (len - s) in loop 0 (String.length str) let rec wait_loop process_params verbose accept = Sys.catch_break false; let has_parse_error = ref false in let cs = CompilationServer.create () in let sign_string com = let sign = get_signature com in let sign_id = try CompilationServer.get_sign cs sign; with Not_found -> let i = CompilationServer.add_sign cs sign in print_endline (Printf.sprintf "Found context %s:\n%s" i (dump_context com)); i in Printf.sprintf "%2s,%3s: " sign_id (short_platform_name com.platform) in MacroContext.macro_enable_cache := true; let current_stdin = ref None in Typeload.parse_hook := (fun com2 file p -> let ffile = Path.unique_full_path file in let is_display_file = ffile = (!Parser.resume_display).pfile in match is_display_file, !current_stdin with | true, Some stdin when Common.defined com2 Define.DisplayStdin -> Typeload.parse_file_from_string com2 file p stdin | _ -> let sign = get_signature com2 in let ftime = file_time ffile in let fkey = (ffile,sign) in try let time, data = CompilationServer.find_file cs fkey in if time <> ftime then raise Not_found; data with Not_found -> has_parse_error := false; let data = Typeload.parse_file com2 file p in let info,is_unusual = if !has_parse_error then "not cached, has parse error",true else if is_display_file then "not cached, is display file",true else begin try (* We assume that when not in display mode it's okay to cache stuff that has #if display checks. The reasoning is that non-display mode has more information than display mode. *) if not com2.display.dms_display then raise Not_found; let ident = Hashtbl.find Parser.special_identifier_files ffile in Printf.sprintf "not cached, using \"%s\" define" ident,true with Not_found -> CompilationServer.cache_file cs fkey (ftime,data); "cached",false end in if verbose && is_unusual then print_endline (Printf.sprintf "%sparsed %s (%s)" (sign_string com2) ffile info); data ); let check_module_shadowing com paths m = List.iter (fun (path,_) -> let file = (path ^ (snd m.m_path)) ^ ".hx" in if Sys.file_exists file then begin let time = file_time file in if time > m.m_extra.m_time then begin if verbose then print_endline (Printf.sprintf "%smodule path might have changed: %s\n\twas: %2.0f %s\n\tnow: %2.0f %s" (sign_string com) (s_type_path m.m_path) m.m_extra.m_time m.m_extra.m_file time file); raise Not_found end end ) paths in let delays = ref [] in let changed_directories = Hashtbl.create 0 in let arguments = Hashtbl.create 0 in let stat dir = (Unix.stat (Path.remove_trailing_slash dir)).Unix.st_mtime in let get_changed_directories (ctx : Typecore.typer) = let t = Common.timer ["server";"module cache";"changed dirs"] in let com = ctx.Typecore.com in let sign = get_signature com in let dirs = try (* First, check if we already have determined changed directories for current compilation. *) Hashtbl.find changed_directories sign with Not_found -> let dirs = try (* Next, get all directories from the cache and filter the ones that haven't changed. *) let all_dirs = CompilationServer.find_directories cs sign in List.fold_left (fun acc (dir,time) -> try let time' = stat dir in if !time < time' then begin time := time'; let sub_dirs = Path.find_directories (platform_name com.platform) false [dir] in List.iter (fun dir -> if not (CompilationServer.has_directory cs sign dir) then begin let time = stat dir in if verbose then print_endline (Printf.sprintf "%sadded directory %s" (sign_string com) dir); CompilationServer.add_directory cs sign (dir,ref time) end; ) sub_dirs; (dir,time') :: acc end else acc with Unix.Unix_error _ -> CompilationServer.remove_directory cs sign dir; if verbose then print_endline (Printf.sprintf "%sremoved directory %s" (sign_string com) dir); acc ) [] all_dirs with Not_found -> (* There were no directories in the cache, so this must be a new context. Let's add an empty list to make sure no crazy recursion happens. *) CompilationServer.add_directories cs sign []; (* Register the delay that is going to populate the cache dirs. *) delays := (fun () -> let dirs = ref [] in let add_dir path = try let time = stat path in dirs := (path,ref time) :: !dirs with Unix.Unix_error _ -> () in List.iter add_dir com.class_path; List.iter add_dir (Path.find_directories (platform_name com.platform) true com.class_path); if verbose then print_endline (Printf.sprintf "%sfound %i directories" (sign_string com) (List.length !dirs)); CompilationServer.add_directories cs sign !dirs ) :: !delays; (* Returning [] should be fine here because it's a new context, so we won't do any shadowing checks anyway. *) [] in Hashtbl.add changed_directories sign dirs; dirs in t(); dirs in let compilation_step = ref 0 in let compilation_mark = ref 0 in let mark_loop = ref 0 in Typeload.type_module_hook := (fun (ctx:Typecore.typer) mpath p -> let t = Common.timer ["server";"module cache"] in let com2 = ctx.Typecore.com in let sign = get_signature com2 in let content_changed m file = let ffile = Path.unique_full_path file in let fkey = (ffile,sign) in try let _, old_data = CompilationServer.find_file cs fkey in (* We must use the module path here because the file path is absolute and would cause positions in the parsed declarations to differ. *) let new_data = Typeload.parse_module ctx m.m_path p in snd old_data <> snd new_data with Not_found -> true in incr mark_loop; let mark = !mark_loop in let start_mark = !compilation_mark in let rec check m = let check_module_path () = let directories = get_changed_directories ctx in match m.m_extra.m_kind with | MFake | MSub | MImport -> () (* don't get classpath *) | MExtern -> (* if we have a file then this will override our extern type *) let has_file = (try check_module_shadowing com2 directories m; true with Not_found -> false) in if has_file then begin if verbose then print_endline ("A file is masking the library file " ^ s_type_path m.m_path); raise Not_found; end; let rec loop = function | [] -> if verbose then print_endline ("No library file was found for " ^ s_type_path m.m_path); raise Not_found (* no extern registration *) | load :: l -> match load m.m_path p with | None -> loop l | Some (file,_) -> if Path.unique_full_path file <> m.m_extra.m_file then begin if verbose then print_endline ("Library file was changed for " ^ s_type_path m.m_path); raise Not_found; end in loop com2.load_extern_type | MCode -> check_module_shadowing com2 directories m | MMacro when ctx.Typecore.in_macro -> check_module_shadowing com2 directories m | MMacro -> let _, mctx = MacroContext.get_macro_context ctx p in check_module_shadowing mctx.Typecore.com (get_changed_directories mctx) m in let has_policy policy = List.mem policy m.m_extra.m_check_policy in let check_file () = if file_time m.m_extra.m_file <> m.m_extra.m_time then begin if has_policy CheckFileContentModification && not (content_changed m m.m_extra.m_file) then begin if verbose then print_endline (Printf.sprintf "%s%s changed time not but content, reusing" (sign_string com2) m.m_extra.m_file) end else begin if verbose then print_endline (Printf.sprintf "%s%s not cached (%s)" (sign_string com2) (s_type_path m.m_path) (if m.m_extra.m_time = -1. then "macro-in-macro" else "modified")); if m.m_extra.m_kind = MFake then Hashtbl.remove Typecore.fake_modules m.m_extra.m_file; raise Not_found; end end in let check_dependencies () = PMap.iter (fun _ m2 -> match check m2 with | None -> () | Some m -> raise (Dirty m) ) m.m_extra.m_deps; in begin match m.m_extra.m_dirty with | Some m -> Some m | None -> if m.m_extra.m_mark = mark then None else try if m.m_extra.m_mark <= start_mark then begin if not (has_policy NoCheckShadowing) then check_module_path(); if not (has_policy NoCheckFileTimeModification) then check_file(); end; m.m_extra.m_mark <- mark; if not (has_policy NoCheckDependencies) then check_dependencies(); None with | Not_found -> m.m_extra.m_dirty <- Some m; Some m | Dirty m' -> m.m_extra.m_dirty <- Some m'; Some m' end in let rec add_modules tabs m0 m = if m.m_extra.m_added < !compilation_step then begin (match m0.m_extra.m_kind, m.m_extra.m_kind with | MCode, MMacro | MMacro, MCode -> (* this was just a dependency to check : do not add to the context *) PMap.iter (Hashtbl.replace com2.resources) m.m_extra.m_binded_res; | _ -> (*if verbose then print_endline (Printf.sprintf "%s%sreusing %s" (sign_string com2) tabs (s_type_path m.m_path));*) m.m_extra.m_added <- !compilation_step; List.iter (fun t -> match t with | TClassDecl c -> c.cl_restore() | TEnumDecl e -> let rec loop acc = function | [] -> () | (Meta.RealPath,[Ast.EConst (Ast.String path),_],_) :: l -> e.e_path <- Ast.parse_path path; e.e_meta <- (List.rev acc) @ l; | x :: l -> loop (x::acc) l in loop [] e.e_meta | TAbstractDecl a -> a.a_meta <- List.filter (fun (m,_,_) -> m <> Meta.ValueUsed) a.a_meta | _ -> () ) m.m_types; if m.m_extra.m_kind <> MSub then Typeload.add_module ctx m p; PMap.iter (Hashtbl.replace com2.resources) m.m_extra.m_binded_res; if ctx.Typecore.in_macro || com2.display.dms_full_typing then PMap.iter (fun _ m2 -> add_modules (tabs ^ " ") m0 m2) m.m_extra.m_deps; List.iter (MacroContext.call_init_macro ctx) m.m_extra.m_macro_calls ) end in try let m = CompilationServer.find_module cs (mpath,sign) in let tcheck = Common.timer ["server";"module cache";"check"] in begin match check m with | None -> () | Some m' -> if verbose then print_endline (Printf.sprintf "%sskipping %s%s" (sign_string com2) (s_type_path m.m_path) (if m == m' then "" else Printf.sprintf "(%s)" (s_type_path m'.m_path))); tcheck(); raise Not_found; end; tcheck(); let tadd = Common.timer ["server";"module cache";"add modules"] in add_modules "" m m; tadd(); t(); Some m with Not_found -> t(); None ); let run_count = ref 0 in while true do let read, write, close = accept() in let rec cache_context com = let cache_module m = CompilationServer.cache_module cs (m.m_path,m.m_extra.m_sign) m; (*if verbose then print_endline (Printf.sprintf "%scached %s" (sign_string com) (s_type_path m.m_path));*) in if com.display.dms_full_typing then begin List.iter cache_module com.modules; if verbose then print_endline ("Cached " ^ string_of_int (List.length com.modules) ^ " modules"); end; match com.get_macros() with | None -> () | Some com -> cache_context com in let create params = let ctx = create_context params in ctx.flush <- (fun() -> incr compilation_step; compilation_mark := !mark_loop; List.iter (fun s -> write (s ^ "\n"); if verbose then print_endline ("> " ^ s)) (List.rev ctx.messages); if ctx.has_error then begin measure_times := false; write "\x02\n" end else cache_context ctx.com; ); ctx.setup <- (fun() -> let sign = get_signature ctx.com in if verbose then begin let defines = PMap.foldi (fun k v acc -> (k ^ "=" ^ v) :: acc) ctx.com.defines [] in print_endline ("Defines " ^ (String.concat "," (List.sort compare defines))); print_endline ("Using signature " ^ Digest.to_hex sign); print_endline ("Display position: " ^ (Printer.s_pos !Parser.resume_display)); end; Parser.display_error := (fun e p -> has_parse_error := true; ctx.com.error (Parser.error_msg e) p); if ctx.com.display.dms_display then begin let file = (!Parser.resume_display).pfile in let fkey = (file,sign) in (* force parsing again : if the completion point have been changed *) CompilationServer.remove_file cs fkey; CompilationServer.taint_modules cs file; end; try if (Hashtbl.find arguments sign) <> ctx.com.class_path then begin if verbose then print_endline (Printf.sprintf "%sclass paths changed, resetting directories" (sign_string ctx.com)); Hashtbl.replace arguments sign ctx.com.class_path; CompilationServer.clear_directories cs sign; end; with Not_found -> Hashtbl.add arguments sign ctx.com.class_path; () ); ctx.com.print <- (fun str -> write ("\x01" ^ String.concat "\x01" (ExtString.String.nsplit str "\n") ^ "\n")); ctx in (try let s = read() in let t0 = get_time() in let hxml = try let idx = String.index s '\001' in current_stdin := Some (String.sub s (idx + 1) ((String.length s) - idx - 1)); (String.sub s 0 idx) with Not_found -> s in let data = parse_hxml_data hxml in if verbose then print_endline ("Processing Arguments [" ^ String.concat "," data ^ "]"); (try Hashtbl.clear changed_directories; Common.display_default := DMNone; Parser.resume_display := null_pos; Typeload.return_partial_type := false; measure_times := false; close_times(); stats.s_files_parsed := 0; stats.s_classes_built := 0; stats.s_methods_typed := 0; stats.s_macros_called := 0; Hashtbl.clear Common.htimers; let _ = Common.timer ["other"] in incr compilation_step; compilation_mark := !mark_loop; start_time := get_time(); process_params create data; close_times(); if !measure_times then report_times (fun s -> write (s ^ "\n")) with | Completion str -> if verbose then print_endline ("Completion Response =\n" ^ str); write str | Arg.Bad msg -> print_endline ("Error: " ^ msg); ); let fl = !delays in delays := []; List.iter (fun f -> f()) fl; if verbose then begin print_endline (Printf.sprintf "Stats = %d files, %d classes, %d methods, %d macros" !(stats.s_files_parsed) !(stats.s_classes_built) !(stats.s_methods_typed) !(stats.s_macros_called)); print_endline (Printf.sprintf "Time spent : %.3fs" (get_time() -. t0)); end; with Unix.Unix_error _ -> if verbose then print_endline "Connection Aborted" | e -> let estr = Printexc.to_string e in if verbose then print_endline ("Uncaught Error : " ^ estr); (try write estr with _ -> ()); if is_debug_run() then print_endline (Printexc.get_backtrace()); ); close(); current_stdin := None; (* prevent too much fragmentation by doing some compactions every X run *) incr run_count; if !run_count mod 10 = 0 then begin let t0 = get_time() in Gc.compact(); if verbose then begin let stat = Gc.quick_stat() in let size = (float_of_int stat.Gc.heap_words) *. 4. in print_endline (Printf.sprintf "Compacted memory %.3fs %.1fMB" (get_time() -. t0) (size /. (1024. *. 1024.))); end end else Gc.minor(); done and init_wait_stdio() = set_binary_mode_in stdin true; set_binary_mode_out stderr true; let chin = IO.input_channel stdin in let cherr = IO.output_channel stderr in let berr = Buffer.create 0 in let read = fun () -> let len = IO.read_i32 chin in IO.really_nread chin len in let write = Buffer.add_string berr in let close = fun() -> IO.write_i32 cherr (Buffer.length berr); IO.nwrite cherr (Buffer.contents berr); IO.flush cherr in fun() -> Buffer.clear berr; read, write, close and init_wait_socket verbose host port = let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in (try Unix.setsockopt sock Unix.SO_REUSEADDR true with _ -> ()); (try Unix.bind sock (Unix.ADDR_INET (Unix.inet_addr_of_string host,port)) with _ -> failwith ("Couldn't wait on " ^ host ^ ":" ^ string_of_int port)); if verbose then print_endline ("Waiting on " ^ host ^ ":" ^ string_of_int port); Unix.listen sock 10; let bufsize = 1024 in let tmp = String.create bufsize in let accept() = ( let sin, _ = Unix.accept sock in Unix.set_nonblock sin; if verbose then print_endline "Client connected"; let b = Buffer.create 0 in let rec read_loop count = try let r = Unix.recv sin tmp 0 bufsize [] in if r = 0 then failwith "Incomplete request" else begin if verbose then Printf.printf "Reading %d bytes\n" r; Buffer.add_substring b tmp 0 r; if tmp.[r-1] = '\000' then Buffer.sub b 0 (Buffer.length b - 1) else read_loop 0 end with Unix.Unix_error((Unix.EWOULDBLOCK|Unix.EAGAIN),_,_) -> if count = 100 then failwith "Aborting inactive connection" else begin if verbose then print_endline "Waiting for data..."; ignore(Unix.select [] [] [] 0.05); (* wait a bit *) read_loop (count + 1); end in let read = fun() -> (let s = read_loop 0 in Unix.clear_nonblock sin; s) in let write = ssend sin in let close() = Unix.close sin in read, write, close ) in accept and do_connect host port args = let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in (try Unix.connect sock (Unix.ADDR_INET (Unix.inet_addr_of_string host,port)) with _ -> failwith ("Couldn't connect on " ^ host ^ ":" ^ string_of_int port)); let args = ("--cwd " ^ Unix.getcwd()) :: args in ssend sock (String.concat "" (List.map (fun a -> a ^ "\n") args) ^ "\000"); let has_error = ref false in let rec print line = match (if line = "" then '\x00' else line.[0]) with | '\x01' -> print_string (String.concat "\n" (List.tl (ExtString.String.nsplit line "\x01"))); flush stdout | '\x02' -> has_error := true; | _ -> prerr_endline line; in let buf = Buffer.create 0 in let process() = let lines = ExtString.String.nsplit (Buffer.contents buf) "\n" in (* the last line ends with \n *) let lines = (match List.rev lines with "" :: l -> List.rev l | _ -> lines) in List.iter print lines; in let tmp = String.create 1024 in let rec loop() = let b = Unix.recv sock tmp 0 1024 [] in Buffer.add_substring buf tmp 0 b; if b > 0 then begin if String.get tmp (b - 1) = '\n' then begin process(); Buffer.reset buf; end; loop(); end in loop(); process(); if !has_error then exit 1haxe_3.4.4.orig/src/sourcemaps.ml0000664000175000017500000002321213166552354016716 0ustar andyandy00000000000000 open Globals open Ast open Lexer open Common (** Characters used for base64 VLQ encoding *) let chars = [| 'A';'B';'C';'D';'E';'F';'G';'H';'I';'J';'K';'L';'M';'N';'O';'P'; 'Q';'R';'S';'T';'U';'V';'W';'X';'Y';'Z';'a';'b';'c';'d';'e';'f'; 'g';'h';'i';'j';'k';'l';'m';'n';'o';'p';'q';'r';'s';'t';'u';'v'; 'w';'x';'y';'z';'0';'1';'2';'3';'4';'5';'6';'7';'8';'9';'+';'/' |] (** Encode an integer in range 0...63 (including 63) *) let encode_digit digit = Array.unsafe_get chars digit (** Move the sign bit to the least significant bit. E.g.: 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) *) let to_vlq number = if number < 0 then ((-number) lsl 1) + 1 else number lsl 1 (** Writes sourcemap for a signle `generated_file` to disk. If your code generation is straightforward, you can use this class directly. Otherwise use `sourcemap_builder` (e.g. if you need to generate some middle parts of a code and then generate the beginning). *) class sourcemap_writer (generated_file:string) = object (self) (** Output buffer for generated sourcemap *) val buffer = Rbuffer.create 1024 (** Source Haxe files referenced by this sourcemap *) val files = DynArray.create() (** Positions of source Haxe files in `files` list *) val files_indexes = Hashtbl.create 100 (** Index of a source file referenced in previous `map` call *) val mutable last_src_file = 0 (** Zero-based index of a source line referenced in previous `map` call *) val mutable last_src_line = 0 (** Zero-based index of a source column in a line referenced in previous `map` call *) val mutable last_src_col = 0 (** Zero based index of a column in `generated_file` where last written string ended *) val mutable current_out_col = 0 (** `current_out_col` value as it was when previous call to `map` was performed *) val mutable last_out_col = 0 (** Indicates whether comma should be written to output buffer on next `map` call *) val mutable print_comma = false (** Last position passed to `map` *) val mutable last_mapped_pos = None (** Map specified haxe position. This method should be called right before an expression in `pos` is writtend to generated file. *) method map pos = last_mapped_pos <- Some pos; let src_file = self#get_file_index pos and src_line, src_col = match (Lexer.find_pos pos) with (line, col) -> (line - 1, col) in if print_comma then Rbuffer.add_char buffer ',' else print_comma <- true; (* We need to map the start of each line to the first expression on that line. Otherwise languages, which don't provide column in stack trace, will point one line above the correct line. *) if last_out_col = 0 then self#write_base64_vlq 0 else self#write_base64_vlq (current_out_col - last_out_col); self#write_base64_vlq (src_file - last_src_file); self#write_base64_vlq (src_line - last_src_line); self#write_base64_vlq (src_col - last_src_col); last_src_file <- src_file; last_src_line <- src_line; last_src_col <- src_col; last_out_col <- current_out_col (** Should be called every time something is written to `generated_file` *) method string_written str = let length = String.length str in let rec handle_next_new_line previous_index = let next_index = try (String.index_from str (previous_index + 1) '\n') with Not_found -> -1 in if next_index < 0 then if previous_index >= 0 then begin print_comma <- false; current_out_col <- length - previous_index; last_out_col <- 0 end else current_out_col <- current_out_col + length else begin Rbuffer.add_char buffer ';'; handle_next_new_line next_index end in handle_next_new_line (-1); () (** Write generated map to disk. If `file_name` is not provided then `generated_file` will be used with additional `.map` extension. E.g if `generated_file` is `path/to/file.js`, then sourcemap will be written to `path/to/file.js.map`. This function does not try to create missing directories. *) method generate ?file_name ?source_root com = let file_name = match file_name with Some f -> f | None -> generated_file ^ ".map" and source_root = match source_root with Some r -> r | None -> "" in let channel = open_out file_name in let sources = DynArray.to_list files in let to_url file = ExtString.String.map (fun c -> if c == '\\' then '/' else c) (Path.get_full_path file) in output_string channel "{\n"; output_string channel "\"version\":3,\n"; output_string channel ("\"file\":\"" ^ (String.concat "\\\\" (ExtString.String.nsplit generated_file "\\")) ^ "\",\n"); output_string channel ("\"sourceRoot\":\"" ^ source_root ^ "\",\n"); output_string channel ("\"sources\":[" ^ (String.concat "," (List.map (fun s -> "\"" ^ to_url s ^ "\"") sources)) ^ "],\n"); if Common.defined com Define.SourceMapContent then begin output_string channel ("\"sourcesContent\":[" ^ (String.concat "," (List.map (fun s -> try "\"" ^ Ast.s_escape (Std.input_file ~bin:true s) ^ "\"" with _ -> "null") sources)) ^ "],\n"); end; output_string channel "\"names\":[],\n"; output_string channel "\"mappings\":\""; Rbuffer.output_buffer channel buffer; output_string channel "\"\n"; output_string channel "}"; close_out channel (** Get source Haxe file position in a list of files referenced by this sourcemap *) method private get_file_index pos = try Hashtbl.find files_indexes pos.pfile with Not_found -> let index = (DynArray.length files) in Hashtbl.add files_indexes pos.pfile index; DynArray.add files pos.pfile; index (** Apply base64 VLQ encoding to `number` and write it to output buffer *) method private write_base64_vlq number = let rec loop vlq = let shift = 5 in let base = 1 lsl shift in let mask = base - 1 in let continuation_bit = base in let digit = vlq land mask in let next = vlq asr shift in Rbuffer.add_char buffer (encode_digit (if next > 0 then digit lor continuation_bit else digit)); if next > 0 then loop next else () in loop (to_vlq number) end type sm_node_data = | SMPos of pos | SMStr of string | SMNil (* this data type marks the beginning and the end of a list *) type sm_node = { mutable smn_left : sm_node option; mutable smn_right : sm_node option; smn_data : sm_node_data; } let init_sourcemap_node_list () : sm_node = let first = { smn_left = None; smn_right = None; smn_data = SMNil; } in let last = { smn_left = Some first; smn_right = None; smn_data = SMNil; } in first.smn_right <- Some last; first (** Builds data for sourcemap. *) class sourcemap_builder (generated_file:string) = object (self) (** Current node *) val mutable current = init_sourcemap_node_list() (** Add data to sourcemap. 1. `#insert (SMPos pos)` should be called right before an expression in `pos` is writtend to generated file. 2. `#insert (SMStr str)` should be called every time some string is written to generated file. *) method insert (data:sm_node_data) = (* new node which will be inserted after current one *) let inserted = { smn_left = Some current; smn_right = current.smn_right; smn_data = data; } in (* link new node with current and next to current one *) current.smn_right <- Some inserted; (match inserted.smn_right with | Some right -> right.smn_left <- current.smn_right | None -> () ); (* inserted node becomes current *) current <- inserted (** Rewind builder so that next `#insert data` call will insert data in the beginning of this sourcemap. *) method rewind = let rec loop node = match node with | Some ({ smn_data = SMNil } as node) -> current <- node | Some node -> loop node.smn_left | None -> assert false in loop (Some current) (** Fast forward builder so that next `#insert data` call will attach data to the end of this sourcemap. *) method fast_forward = let rec loop node = match node.smn_right with | Some { smn_data = SMNil } -> current <- node | Some node -> loop node | None -> assert false in loop current (** Set builder pointer to `node` so that next `#insert data` call will insert data right after this `node`. *) method seek (node:sm_node) = current <- node (** Get current node in this builder *) method get_pointer = current (** Write source map to disk. If `file_name` is not provided then `generated_file` will be used with additional `.map` extension. E.g if `generated_file` is `path/to/file.js`, then sourcemap will be written to `path/to/file.js.map`. This function does not try to create missing directories. *) method generate ?file_name ?source_root com = (* remember position *) let pointer = self#get_pointer in self#rewind; (* write source map to a buffer *) let writer = new sourcemap_writer generated_file in let rec loop node = (match node.smn_data with | SMPos pos -> writer#map pos | SMStr str -> writer#string_written str | SMNil -> () ); (match node.smn_right with | None -> () | Some node -> loop node ) in loop current; (* dump source map to a file *) let file_name = match file_name with Some f -> f | None -> generated_file ^ ".map" and source_root = match source_root with Some r -> r | None -> "" in writer#generate ~file_name:file_name ~source_root:source_root com; (* restore position *) self#seek pointer end let get_sourcemap_pointer (builder:sourcemap_builder option) = match builder with | Some builder -> Some builder#get_pointer | None -> None let set_sourcemap_pointer (builder:sourcemap_builder option) (pointer:sm_node option) = match builder with | None -> () | Some builder -> match pointer with | Some node -> builder#seek node | None -> ()haxe_3.4.4.orig/src/syntax/ast.ml0000664000175000017500000005634513166552354016667 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals 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 placed_type_path = type_path * pos and type_param_or_const = | TPType of type_hint | TPExpr of expr and complex_type = | CTPath of type_path | CTFunction of type_hint list * type_hint | CTAnonymous of class_field list | CTParent of type_hint | CTExtend of placed_type_path list * class_field list | CTOptional of type_hint and type_hint = complex_type * pos and func = { f_params : type_param list; f_args : (placed_name * bool * metadata * type_hint option * expr option) list; f_type : type_hint option; f_expr : expr option; } and placed_name = string * pos and expr_def = | EConst of constant | EArray of expr * expr | EBinop of binop * expr * expr | EField of expr * string | EParenthesis of expr | EObjectDecl of (placed_name * expr) list | EArrayDecl of expr list | ECall of expr * expr list | ENew of placed_type_path * expr list | EUnop of unop * unop_flag * expr | EVars of (placed_name * type_hint 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 * pos) list * (expr option * pos) option | ETry of expr * (placed_name * type_hint * expr * pos) list | EReturn of expr option | EBreak | EContinue | EUntyped of expr | EThrow of expr | ECast of expr * type_hint option | EDisplay of expr * bool | EDisplayNew of placed_type_path | ETernary of expr * expr * expr | ECheckType of expr * type_hint | EMeta of metadata_entry * expr and expr = expr_def * pos and type_param = { tp_name : placed_name; tp_params : type_param list; tp_constraints : type_hint list; tp_meta : metadata; } 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 type_hint option * expr option | FFun of func | FProp of placed_name * placed_name * type_hint option * expr option and class_field = { cff_name : placed_name; 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 placed_type_path | HImplements of placed_type_path type abstract_flag = | APrivAbstract | AFromType of type_hint | AToType of type_hint | AIsType of type_hint | AExtern type enum_constructor = { ec_name : placed_name; ec_doc : documentation; ec_meta : metadata; ec_args : (string * bool * type_hint) list; ec_pos : pos; ec_params : type_param list; ec_type : type_hint option; } type ('a,'b) definition = { d_name : placed_name; 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 import = placed_name list * import_mode type type_def = | EClass of (class_flag, class_field list) definition | EEnum of (enum_flag, enum_constructor list) definition | ETypedef of (enum_flag, type_hint) definition | EAbstract of (abstract_flag, class_field list) definition | EImport of import | EUsing of placed_name list type type_decl = type_def * pos type package = string list * type_decl list 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 | Not -> true | Neg | NegBits -> false let is_prefix = function | Increment | Decrement -> true | Not | Neg | NegBits -> true let base_class_name = snd 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 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 exception Invalid_escape_sequence of char * int 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 let fail () = raise (Invalid_escape_sequence(c,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 _ -> fail()) 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 _ -> fail()) 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 _ -> fail() 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; | _ -> fail()); 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 (type_hint t) | TPExpr e -> TPExpr (loop e) and cfield f = { f with cff_kind = (match f.cff_kind with | FVar (t,e) -> let t = opt type_hint t in let e = opt loop e in FVar (t,e) | FFun f -> FFun (func f) | FProp (get,set,t,e) -> let t = opt type_hint t in let e = opt loop e in FProp (get,set,t,e)) } and type_hint (t,p) = (match t with | CTPath t -> CTPath { t with tparams = List.map tparam t.tparams } | CTFunction (cl,c) -> let cl = List.map type_hint cl in let c = type_hint c in CTFunction (cl,c) | CTAnonymous fl -> CTAnonymous (List.map cfield fl) | CTParent t -> CTParent (type_hint t) | CTExtend (tl,fl) -> let tl = List.map tpath tl in let fl = List.map cfield fl in CTExtend (tl,fl) | CTOptional t -> CTOptional (type_hint t)),p and tparamdecl t = let constraints = List.map type_hint t.tp_constraints in let params = List.map tparamdecl t.tp_params in { tp_name = t.tp_name; tp_constraints = constraints; tp_params = params; tp_meta = t.tp_meta } and func f = let params = List.map tparamdecl f.f_params in let args = List.map (fun (n,o,m,t,e) -> let t = opt type_hint t in let e = opt loop e in n,o,m,t,e ) f.f_args in let t = opt type_hint f.f_type in let e = opt loop f.f_expr in { f_params = params; f_args = args; f_type = t; f_expr = e; } and tpath (t,p) = { t with tparams = List.map tparam t.tparams },p in let e = (match e with | EConst _ -> e | EArray (e1,e2) -> let e1 = loop e1 in let e2 = loop e2 in EArray (e1,e2) | EBinop (op,e1,e2) -> let e1 = loop e1 in let e2 = loop e2 in EBinop (op,e1,e2) | EField (e,f) -> EField (loop e, f) | EParenthesis e -> EParenthesis (loop e) | EObjectDecl fl -> EObjectDecl (List.map (fun ((f,p),e) -> (f,p),loop e) fl) | EArrayDecl el -> EArrayDecl (List.map loop el) | ECall (e,el) -> let e = loop e in let el = List.map loop el in ECall (e,el) | ENew (t,el) -> let t = tpath t in let el = List.map loop el in ENew (t,el) | EUnop (op,f,e) -> EUnop (op,f,loop e) | EVars vl -> EVars (List.map (fun (n,t,eo) -> let t = opt type_hint t in let eo = opt loop eo in n,t,eo ) vl) | EFunction (n,f) -> EFunction (n,func f) | EBlock el -> EBlock (List.map loop el) | EFor (e1,e2) -> let e1 = loop e1 in let e2 = loop e2 in EFor (e1,e2) | EIn (e1,e2) -> let e1 = loop e1 in let e2 = loop e2 in EIn (e1,e2) | EIf (e,e1,e2) -> let e = loop e in let e1 = loop e1 in let e2 = opt loop e2 in EIf (e,e1,e2) | EWhile (econd,e,f) -> let econd = loop econd in let e = loop e in EWhile (econd,e,f) | ESwitch (e,cases,def) -> let e = loop e in let cases = List.map (fun (el,eg,e,p) -> let el = List.map loop el in let eg = opt loop eg in let e = opt loop e in el,eg,e,p ) cases in let def = opt (fun (eo,p) -> opt loop eo,p) def in ESwitch (e, cases, def) | ETry (e,catches) -> let e = loop e in let catches = List.map (fun (n,t,e,p) -> n,type_hint t,loop e,p) catches in ETry (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) -> let e = loop e in let t = opt type_hint t in ECast (e,t) | EDisplay (e,f) -> EDisplay (loop e,f) | EDisplayNew t -> EDisplayNew (tpath t) | ETernary (e1,e2,e3) -> let e1 = loop e1 in let e2 = loop e2 in let e3 = loop e3 in ETernary (e1,e2,e3) | ECheckType (e,t) -> let e = loop e in let t = type_hint t in ECheckType (e,t) | EMeta (m,e) -> EMeta(m, loop e) ) in (e,p) let iter_expr loop (e,p) = let opt eo = match eo with None -> () | Some e -> loop e in let exprs = List.iter loop in match e with | EConst _ | EContinue | EBreak | EDisplayNew _ | EReturn None -> () | EParenthesis e1 | EField(e1,_) | EUnop(_,_,e1) | EReturn(Some e1) | EThrow e1 | EMeta(_,e1) | ECheckType(e1,_) | EDisplay(e1,_) | ECast(e1,_) | EUntyped e1 -> loop e1; | EArray(e1,e2) | EBinop(_,e1,e2) | EIn(e1,e2) | EFor(e1,e2) | EWhile(e1,e2,_) | EIf(e1,e2,None) -> loop e1; loop e2; | ETernary(e1,e2,e3) | EIf(e1,e2,Some e3) -> loop e1; loop e2; loop e3; | EArrayDecl el | ENew(_,el) | EBlock el -> List.iter loop el | ECall(e1,el) -> loop e1; exprs el; | EObjectDecl fl -> List.iter (fun (_,e) -> loop e) fl; | ETry(e1,catches) -> loop e1; List.iter (fun (_,_,e,_) -> loop e) catches | ESwitch(e1,cases,def) -> loop e1; List.iter (fun (el,eg,e,_) -> exprs el; opt eg; opt e; ) cases; (match def with None -> () | Some (e,_) -> opt e); | EFunction(_,f) -> List.iter (fun (_,_,_,_,eo) -> opt eo) f.f_args; opt f.f_expr | EVars vl -> List.iter (fun (_,_,eo) -> opt eo) vl let s_expr e = let rec s_expr_inner tabs (e,_) = match e with | EConst c -> s_constant c | EArray (e1,e2) -> s_expr_inner tabs e1 ^ "[" ^ s_expr_inner tabs e2 ^ "]" | EBinop (op,e1,e2) -> s_expr_inner tabs e1 ^ " " ^ s_binop op ^ " " ^ s_expr_inner tabs e2 | EField (e,f) -> s_expr_inner tabs e ^ "." ^ f | EParenthesis e -> "(" ^ (s_expr_inner tabs e) ^ ")" | EObjectDecl fl -> "{ " ^ (String.concat ", " (List.map (fun ((n,_),e) -> n ^ " : " ^ (s_expr_inner tabs e)) fl)) ^ " }" | EArrayDecl el -> "[" ^ s_expr_list tabs el ", " ^ "]" | ECall (e,el) -> s_expr_inner tabs e ^ "(" ^ s_expr_list tabs el ", " ^ ")" | ENew (t,el) -> "new " ^ s_complex_type_path tabs t ^ "(" ^ s_expr_list tabs el ", " ^ ")" | EUnop (op,Postfix,e) -> s_expr_inner tabs e ^ s_unop op | EUnop (op,Prefix,e) -> s_unop op ^ s_expr_inner tabs e | EFunction (Some n,f) -> "function " ^ n ^ s_func tabs f | EFunction (None,f) -> "function" ^ s_func tabs f | EVars vl -> "var " ^ String.concat ", " (List.map (s_var tabs) vl) | EBlock [] -> "{ }" | EBlock el -> s_block tabs el "{" "\n" "}" | EFor (e1,e2) -> "for (" ^ s_expr_inner tabs e1 ^ ") " ^ s_expr_inner tabs e2 | EIn (e1,e2) -> s_expr_inner tabs e1 ^ " in " ^ s_expr_inner tabs e2 | EIf (e,e1,None) -> "if (" ^ s_expr_inner tabs e ^ ") " ^ s_expr_inner tabs e1 | EIf (e,e1,Some e2) -> "if (" ^ s_expr_inner tabs e ^ ") " ^ s_expr_inner tabs e1 ^ " else " ^ s_expr_inner tabs e2 | EWhile (econd,e,NormalWhile) -> "while (" ^ s_expr_inner tabs econd ^ ") " ^ s_expr_inner tabs e | EWhile (econd,e,DoWhile) -> "do " ^ s_expr_inner tabs e ^ " while (" ^ s_expr_inner tabs econd ^ ")" | ESwitch (e,cases,def) -> "switch " ^ s_expr_inner tabs e ^ " {\n\t" ^ tabs ^ String.concat ("\n\t" ^ tabs) (List.map (s_case tabs) cases) ^ (match def with None -> "" | Some (def,_) -> "\n\t" ^ tabs ^ "default:" ^ (match def with None -> "" | Some def -> s_expr_omit_block tabs def)) ^ "\n" ^ tabs ^ "}" | ETry (e,catches) -> "try " ^ s_expr_inner tabs e ^ String.concat "" (List.map (s_catch tabs) catches) | EReturn e -> "return" ^ s_opt_expr tabs e " " | EBreak -> "break" | EContinue -> "continue" | EUntyped e -> "untyped " ^ s_expr_inner tabs e | EThrow e -> "throw " ^ s_expr_inner tabs e | ECast (e,Some (t,_)) -> "cast (" ^ s_expr_inner tabs e ^ ", " ^ s_complex_type tabs t ^ ")" | ECast (e,None) -> "cast " ^ s_expr_inner tabs e | ETernary (e1,e2,e3) -> s_expr_inner tabs e1 ^ " ? " ^ s_expr_inner tabs e2 ^ " : " ^ s_expr_inner tabs e3 | ECheckType (e,(t,_)) -> "(" ^ s_expr_inner tabs e ^ " : " ^ s_complex_type tabs t ^ ")" | EMeta (m,e) -> s_metadata tabs m ^ " " ^ s_expr_inner tabs e | EDisplay (e1,iscall) -> Printf.sprintf "#DISPLAY(%s, %b)" (s_expr_inner tabs e1) iscall | EDisplayNew tp -> Printf.sprintf "#DISPLAY_NEW(%s)" (s_complex_type_path tabs tp) and s_expr_list tabs el sep = (String.concat sep (List.map (s_expr_inner tabs) el)) and s_complex_type_path tabs (t,_) = Printf.sprintf "%s%s%s" (s_type_path (t.tpackage,t.tname)) (Option.map_default (fun s -> "." ^ s) "" t.tsub) (s_type_param_or_consts tabs t.tparams) and s_type_param_or_consts tabs pl = if List.length pl > 0 then "<" ^ (String.concat "," (List.map (s_type_param_or_const tabs) pl)) ^ ">" else "" and s_type_param_or_const tabs p = match p with | TPType (t,_) -> s_complex_type tabs t | TPExpr e -> s_expr_inner tabs e and s_complex_type tabs ct = match ct with | CTPath t -> s_complex_type_path tabs (t,null_pos) | CTFunction (cl,(c,_)) -> if List.length cl > 0 then String.concat " -> " (List.map (fun (t,_) -> s_complex_type tabs t) cl) else "Void" ^ " -> " ^ s_complex_type tabs c | CTAnonymous fl -> "{ " ^ String.concat "; " (List.map (s_class_field tabs) fl) ^ "}"; | CTParent(t,_) -> "(" ^ s_complex_type tabs t ^ ")" | CTOptional(t,_) -> "?" ^ s_complex_type tabs t | CTExtend (tl, fl) -> "{> " ^ String.concat " >, " (List.map (s_complex_type_path tabs) tl) ^ ", " ^ String.concat ", " (List.map (s_class_field tabs) fl) ^ " }" and s_class_field tabs f = match f.cff_doc with | Some s -> "/**\n\t" ^ tabs ^ s ^ "\n**/\n" | None -> "" ^ if List.length f.cff_meta > 0 then String.concat ("\n" ^ tabs) (List.map (s_metadata tabs) f.cff_meta) else "" ^ if List.length f.cff_access > 0 then String.concat " " (List.map s_access f.cff_access) else "" ^ match f.cff_kind with | FVar (t,e) -> "var " ^ (fst f.cff_name) ^ s_opt_type_hint tabs t " : " ^ s_opt_expr tabs e " = " | FProp ((get,_),(set,_),t,e) -> "var " ^ (fst f.cff_name) ^ "(" ^ get ^ "," ^ set ^ ")" ^ s_opt_type_hint tabs t " : " ^ s_opt_expr tabs e " = " | FFun func -> "function " ^ (fst f.cff_name) ^ s_func tabs func and s_metadata tabs (s,e,_) = "@" ^ Meta.to_string s ^ if List.length e > 0 then "(" ^ s_expr_list tabs e ", " ^ ")" else "" and s_opt_expr tabs e pre = match e with | Some s -> pre ^ s_expr_inner tabs s | None -> "" and s_opt_type_hint tabs t pre = match t with | Some(t,_) -> pre ^ s_complex_type tabs t | None -> "" and s_func tabs f = s_type_param_list tabs f.f_params ^ "(" ^ String.concat ", " (List.map (s_func_arg tabs) f.f_args) ^ ")" ^ s_opt_type_hint tabs f.f_type ":" ^ s_opt_expr tabs f.f_expr " " and s_type_param tabs t = fst (t.tp_name) ^ s_type_param_list tabs t.tp_params ^ if List.length t.tp_constraints > 0 then ":(" ^ String.concat ", " (List.map ((fun (t,_) -> s_complex_type tabs t)) t.tp_constraints) ^ ")" else "" and s_type_param_list tabs tl = if List.length tl > 0 then "<" ^ String.concat ", " (List.map (s_type_param tabs) tl) ^ ">" else "" and s_func_arg tabs ((n,_),o,_,t,e) = if o then "?" else "" ^ n ^ s_opt_type_hint tabs t ":" ^ s_opt_expr tabs e " = " and s_var tabs ((n,_),t,e) = n ^ (s_opt_type_hint tabs t ":") ^ s_opt_expr tabs e " = " and s_case tabs (el,e1,e2,_) = "case " ^ s_expr_list tabs el ", " ^ (match e1 with None -> ":" | Some e -> " if (" ^ s_expr_inner tabs e ^ "):") ^ (match e2 with None -> "" | Some e -> s_expr_omit_block tabs e) and s_catch tabs ((n,_),(t,_),e,_) = " catch(" ^ n ^ ":" ^ s_complex_type tabs t ^ ") " ^ s_expr_inner tabs e and s_block tabs el opn nl cls = opn ^ "\n\t" ^ tabs ^ (s_expr_list (tabs ^ "\t") el (";\n\t" ^ tabs)) ^ ";" ^ nl ^ tabs ^ cls and s_expr_omit_block tabs e = match e with | (EBlock [],_) -> "" | (EBlock el,_) -> s_block (tabs ^ "\t") el "" "" "" | _ -> s_expr_inner (tabs ^ "\t") e ^ ";" in s_expr_inner "" e 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 (* Type path related functions *) 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 let expr_of_type_path (sl,s) p = match sl with | [] -> (EConst(Ident s),p) | s1 :: sl -> let e1 = (EConst(Ident s1),p) in let e = List.fold_left (fun e s -> (EField(e,s),p)) e1 sl in EField(e,s),p let match_path recursive sl sl_pattern = let rec loop sl1 sl2 = match sl1,sl2 with | [],[] -> true (* always recurse into types of package paths *) | (s1 :: s11 :: _),[s2] when is_lower_ident s2 && not (is_lower_ident s11)-> s1 = s2 | [_],[""] -> true | _,([] | [""]) -> recursive | [],_ -> false | (s1 :: sl1),(s2 :: sl2) -> s1 = s2 && loop sl1 sl2 in loop sl sl_pattern let full_dot_path mpath tpath = if mpath = tpath then (fst tpath) @ [snd tpath] else (fst mpath) @ [snd mpath;snd tpath] let safe_for_all2 f a b = try List.for_all2 f a b with _ -> false let rec remove_duplicates f l = match l with | [] -> [] | x :: l -> x :: (remove_duplicates f (List.filter (fun x' -> f x x') l)) module Expr = struct let ensure_block e = match fst e with | EBlock _ -> e | _ -> (EBlock [e],pos e) let field_assoc name fl = let rec loop fl = match fl with | ((name',_),e) :: fl -> if name' = name then e else loop fl | [] -> raise Not_found in loop fl end haxe_3.4.4.orig/src/syntax/lexer.mll0000664000175000017500000003252713166552354017367 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) { open Lexing open Ast open Globals type error_msg = | Invalid_character of char | Unterminated_string | Unterminated_regexp | Unclosed_comment | Unclosed_code | Invalid_escape of char | Invalid_option exception Error of error_msg * pos let error_msg = function | Invalid_character c when int_of_char c > 32 && int_of_char c < 128 -> Printf.sprintf "Invalid character '%c'" c | Invalid_character c -> Printf.sprintf "Invalid character 0x%.2X" (int_of_char c) | Unterminated_string -> "Unterminated string" | Unterminated_regexp -> "Unterminated regular expression" | Unclosed_comment -> "Unclosed comment" | Unclosed_code -> "Unclosed code string" | Invalid_escape c -> Printf.sprintf "Invalid escape sequence \\%s" (Char.escaped c) | Invalid_option -> "Invalid regular expression option" type lexer_file = { lfile : string; mutable lline : int; mutable lmaxline : int; mutable llines : (int * int) list; mutable lalines : (int * int) array; mutable lstrings : int list; mutable llast : int; mutable llastindex : int; } let make_file file = { lfile = file; lline = 1; lmaxline = 1; llines = [0,1]; lalines = [|0,1|]; lstrings = []; llast = max_int; llastindex = 0; } let cur = ref (make_file "") let all_files = Hashtbl.create 0 let buf = Buffer.create 100 let error e pos = raise (Error (e,{ pmin = pos; pmax = pos; pfile = !cur.lfile })) let keywords = let h = Hashtbl.create 3 in List.iter (fun k -> Hashtbl.add h (s_keyword k) k) [Function;Class;Static;Var;If;Else;While;Do;For; Break;Return;Continue;Extends;Implements;Import; Switch;Case;Default;Public;Private;Try;Untyped; Catch;New;This;Throw;Extern;Enum;In;Interface; Cast;Override;Dynamic;Typedef;Package; Inline;Using;Null;True;False;Abstract;Macro]; h let init file do_add = let f = make_file file in cur := f; if do_add then Hashtbl.replace all_files file f let save() = !cur let restore c = cur := c let newline lexbuf = let cur = !cur in cur.lline <- cur.lline + 1; cur.llines <- (lexeme_end lexbuf,cur.lline) :: cur.llines let fmt_pos p = p.pmin + (p.pmax - p.pmin) * 1000000 let add_fmt_string p = let file = (try Hashtbl.find all_files p.pfile with Not_found -> let f = make_file p.pfile in Hashtbl.replace all_files p.pfile f; f ) in file.lstrings <- (fmt_pos p) :: file.lstrings let fast_add_fmt_string p = let cur = !cur in cur.lstrings <- (fmt_pos p) :: cur.lstrings let is_fmt_string p = try let file = Hashtbl.find all_files p.pfile in List.mem (fmt_pos p) file.lstrings with Not_found -> false let remove_fmt_string p = try let file = Hashtbl.find all_files p.pfile in file.lstrings <- List.filter ((<>) (fmt_pos p)) file.lstrings with Not_found -> () let find_line p f = (* rebuild cache if we have a new line *) if f.lmaxline <> f.lline then begin f.lmaxline <- f.lline; f.lalines <- Array.of_list (List.rev f.llines); f.llast <- max_int; f.llastindex <- 0; end; let rec loop min max = let med = (min + max) lsr 1 in let lp, line = Array.unsafe_get f.lalines med in if med = min then begin f.llast <- p; f.llastindex <- med; line, p - lp end else if lp > p then loop min med else loop med max in if p >= f.llast then begin let lp, line = Array.unsafe_get f.lalines f.llastindex in let lp2 = if f.llastindex = Array.length f.lalines - 1 then max_int else fst(Array.unsafe_get f.lalines (f.llastindex + 1)) in if p >= lp && p < lp2 then line, p - lp else loop 0 (Array.length f.lalines) end else loop 0 (Array.length f.lalines) (* resolve a position within a non-haxe file by counting newlines *) let resolve_pos file = let ch = open_in_bin file in let f = make_file file in let rec loop p = let inc i () = f.lline <- f.lline + 1; f.llines <- (p + i,f.lline) :: f.llines; i in let i = match input_char ch with | '\n' -> inc 1 | '\r' -> ignore(input_char ch); inc 2 | _ -> fun () -> 1 in loop (p + i()) in try loop 0 with End_of_file -> close_in ch; f let find_file file = try Hashtbl.find all_files file with Not_found -> try resolve_pos file with Sys_error _ -> make_file file let find_pos p = find_line p.pmin (find_file p.pfile) let get_error_line p = let l, _ = find_pos p in l let get_pos_coords p = let file = find_file p.pfile in let l1, p1 = find_line p.pmin file in let l2, p2 = find_line p.pmax file in l1, p1, l2, p2 let get_error_pos printer p = if p.pmin = -1 then "(unknown)" else let l1, p1, l2, p2 = get_pos_coords p in if l1 = l2 then begin let s = (if p1 = p2 then Printf.sprintf " %d" p1 else Printf.sprintf "s %d-%d" p1 p2) in Printf.sprintf "%s character%s" (printer p.pfile l1) s end else Printf.sprintf "%s lines %d-%d" (printer p.pfile l1) l1 l2 let reset() = Buffer.reset buf let contents() = Buffer.contents buf let store lexbuf = Buffer.add_string buf (lexeme lexbuf) let add c = Buffer.add_string buf c let mk_tok t pmin pmax = t , { pfile = !cur.lfile; pmin = pmin; pmax = pmax } let mk lexbuf t = mk_tok t (lexeme_start lexbuf) (lexeme_end lexbuf) let mk_ident lexbuf = let s = lexeme lexbuf in mk lexbuf (try Kwd (Hashtbl.find keywords s) with Not_found -> Const (Ident s)) let invalid_char lexbuf = error (Invalid_character (lexeme_char lexbuf 0)) (lexeme_start lexbuf) } let ident = ('_'* ['a'-'z'] ['_' 'a'-'z' 'A'-'Z' '0'-'9']* | '_'+ | '_'+ ['0'-'9'] ['_' 'a'-'z' 'A'-'Z' '0'-'9']* ) let idtype = '_'* ['A'-'Z'] ['_' 'a'-'z' 'A'-'Z' '0'-'9']* let integer = ['1'-'9'] ['0'-'9']* | '0' rule skip_header = parse | "\239\187\191" { skip_header lexbuf } | "#!" [^'\n' '\r']* { skip_header lexbuf } | "" | eof { } and token = parse | eof { mk lexbuf Eof } | [' ' '\t']+ { token lexbuf } | "\r\n" { newline lexbuf; token lexbuf } | '\n' | '\r' { newline lexbuf; token lexbuf } | "0x" ['0'-'9' 'a'-'f' 'A'-'F']+ { mk lexbuf (Const (Int (lexeme lexbuf))) } | integer { mk lexbuf (Const (Int (lexeme lexbuf))) } | integer '.' ['0'-'9']+ { mk lexbuf (Const (Float (lexeme lexbuf))) } | '.' ['0'-'9']+ { mk lexbuf (Const (Float (lexeme lexbuf))) } | integer ['e' 'E'] ['+' '-']? ['0'-'9']+ { mk lexbuf (Const (Float (lexeme lexbuf))) } | integer '.' ['0'-'9']* ['e' 'E'] ['+' '-']? ['0'-'9']+ { mk lexbuf (Const (Float (lexeme lexbuf))) } | integer "..." { let s = lexeme lexbuf in mk lexbuf (IntInterval (String.sub s 0 (String.length s - 3))) } | "//" [^'\n' '\r']* { let s = lexeme lexbuf in mk lexbuf (CommentLine (String.sub s 2 ((String.length s)-2))) } | "++" { mk lexbuf (Unop Increment) } | "--" { mk lexbuf (Unop Decrement) } | "~" { mk lexbuf (Unop NegBits) } | "%=" { mk lexbuf (Binop (OpAssignOp OpMod)) } | "&=" { mk lexbuf (Binop (OpAssignOp OpAnd)) } | "|=" { mk lexbuf (Binop (OpAssignOp OpOr)) } | "^=" { mk lexbuf (Binop (OpAssignOp OpXor)) } | "+=" { mk lexbuf (Binop (OpAssignOp OpAdd)) } | "-=" { mk lexbuf (Binop (OpAssignOp OpSub)) } | "*=" { mk lexbuf (Binop (OpAssignOp OpMult)) } | "/=" { mk lexbuf (Binop (OpAssignOp OpDiv)) } | "<<=" { mk lexbuf (Binop (OpAssignOp OpShl)) } | "||=" { mk lexbuf (Binop (OpAssignOp OpBoolOr)) } | "&&=" { mk lexbuf (Binop (OpAssignOp OpBoolAnd)) } (*//| ">>=" { mk lexbuf (Binop (OpAssignOp OpShr)) } *) (*//| ">>>=" { mk lexbuf (Binop (OpAssignOp OpUShr)) } *) | "==" { mk lexbuf (Binop OpEq) } | "!=" { mk lexbuf (Binop OpNotEq) } | "<=" { mk lexbuf (Binop OpLte) } (*//| ">=" { mk lexbuf (Binop OpGte) }*) | "&&" { mk lexbuf (Binop OpBoolAnd) } | "||" { mk lexbuf (Binop OpBoolOr) } | "<<" { mk lexbuf (Binop OpShl) } | "->" { mk lexbuf Arrow } | "..." { mk lexbuf (Binop OpInterval) } | "=>" { mk lexbuf (Binop OpArrow)} | "!" { mk lexbuf (Unop Not) } | "<" { mk lexbuf (Binop OpLt) } | ">" { mk lexbuf (Binop OpGt) } | ";" { mk lexbuf Semicolon } | ":" { mk lexbuf DblDot } | "," { mk lexbuf Comma } | "." { mk lexbuf Dot } | "%" { mk lexbuf (Binop OpMod) } | "&" { mk lexbuf (Binop OpAnd) } | "|" { mk lexbuf (Binop OpOr) } | "^" { mk lexbuf (Binop OpXor) } | "+" { mk lexbuf (Binop OpAdd) } | "*" { mk lexbuf (Binop OpMult) } | "/" { mk lexbuf (Binop OpDiv) } | "-" { mk lexbuf (Binop OpSub) } | "=" { mk lexbuf (Binop OpAssign) } | "[" { mk lexbuf BkOpen } | "]" { mk lexbuf BkClose } | "{" { mk lexbuf BrOpen } | "}" { mk lexbuf BrClose } | "(" { mk lexbuf POpen } | ")" { mk lexbuf PClose } | "?" { mk lexbuf Question } | "@" { mk lexbuf At } | "/*" { reset(); let pmin = lexeme_start lexbuf in let pmax = (try comment lexbuf with Exit -> error Unclosed_comment pmin) in mk_tok (Comment (contents())) pmin pmax; } | '"' { reset(); let pmin = lexeme_start lexbuf in let pmax = (try string lexbuf with Exit -> error Unterminated_string pmin) in let str = (try unescape (contents()) with Invalid_escape_sequence(c,i) -> error (Invalid_escape c) (pmin + i)) in mk_tok (Const (String str)) pmin pmax; } | "'" { reset(); let pmin = lexeme_start lexbuf in let pmax = (try string2 lexbuf with Exit -> error Unterminated_string pmin) in let str = (try unescape (contents()) with Invalid_escape_sequence(c,i) -> error (Invalid_escape c) (pmin + i)) in let t = mk_tok (Const (String str)) pmin pmax in fast_add_fmt_string (snd t); t } | "~/" { reset(); let pmin = lexeme_start lexbuf in let options, pmax = (try regexp lexbuf with Exit -> error Unterminated_regexp pmin) in let str = contents() in mk_tok (Const (Regexp (str,options))) pmin pmax; } | '#' ident { let v = lexeme lexbuf in let v = String.sub v 1 (String.length v - 1) in mk lexbuf (Sharp v) } | '$' ['_' 'a'-'z' 'A'-'Z' '0'-'9']* { let v = lexeme lexbuf in let v = String.sub v 1 (String.length v - 1) in mk lexbuf (Dollar v) } | ident { mk_ident lexbuf } | idtype { mk lexbuf (Const (Ident (lexeme lexbuf))) } | _ { invalid_char lexbuf } and comment = parse | eof { raise Exit } | '\n' | '\r' | "\r\n" { newline lexbuf; store lexbuf; comment lexbuf } | "*/" { lexeme_end lexbuf } | '*' { store lexbuf; comment lexbuf } | [^'*' '\n' '\r']+ { store lexbuf; comment lexbuf } and string = parse | eof { raise Exit } | '\n' | '\r' | "\r\n" { newline lexbuf; store lexbuf; string lexbuf } | "\\\"" { store lexbuf; string lexbuf } | "\\\\" { store lexbuf; string lexbuf } | '\\' { store lexbuf; string lexbuf } | '"' { lexeme_end lexbuf } | [^'"' '\\' '\r' '\n']+ { store lexbuf; string lexbuf } and string2 = parse | eof { raise Exit } | '\n' | '\r' | "\r\n" { newline lexbuf; store lexbuf; string2 lexbuf } | '\\' { store lexbuf; string2 lexbuf } | "\\\\" { store lexbuf; string2 lexbuf } | "\\'" { store lexbuf; string2 lexbuf } | "'" { lexeme_end lexbuf } | "$$" | "\\$" | '$' { store lexbuf; string2 lexbuf } | "${" { let pmin = lexeme_start lexbuf in store lexbuf; (try code_string lexbuf with Exit -> error Unclosed_code pmin); string2 lexbuf; } | [^'\'' '\\' '\r' '\n' '$']+ { store lexbuf; string2 lexbuf } and code_string = parse | eof { raise Exit } | '\n' | '\r' | "\r\n" { newline lexbuf; store lexbuf; code_string lexbuf } | '{' | '/' { store lexbuf; code_string lexbuf } | '}' { store lexbuf; (* stop *) } | '"' { add "\""; let pmin = lexeme_start lexbuf in (try ignore(string lexbuf) with Exit -> error Unterminated_string pmin); add "\""; code_string lexbuf; } | "'" { add "'"; let pmin = lexeme_start lexbuf in let pmax = (try string2 lexbuf with Exit -> error Unterminated_string pmin) in add "'"; fast_add_fmt_string { pfile = !cur.lfile; pmin = pmin; pmax = pmax }; code_string lexbuf; } | "/*" { let pmin = lexeme_start lexbuf in (try ignore(comment lexbuf) with Exit -> error Unclosed_comment pmin); code_string lexbuf; } | "//" [^'\n' '\r']* { store lexbuf; code_string lexbuf; } | [^'/' '"' '\'' '{' '}' '\n' '\r']+ { store lexbuf; code_string lexbuf; } and regexp = parse | eof | '\n' | '\r' { raise Exit } | '\\' '/' { add "/"; regexp lexbuf } | '\\' 'r' { add "\r"; regexp lexbuf } | '\\' 'n' { add "\n"; regexp lexbuf } | '\\' 't' { add "\t"; regexp lexbuf } | '\\' ['\\' '$' '.' '*' '+' '^' '|' '{' '}' '[' ']' '(' ')' '?' '-' '0'-'9'] { add (lexeme lexbuf); regexp lexbuf } | '\\' ['w' 'W' 'b' 'B' 's' 'S' 'd' 'D' 'x'] { add (lexeme lexbuf); regexp lexbuf } | '\\' ['u' 'U'] ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'] { add (lexeme lexbuf); regexp lexbuf } | '\\' [^ '\\'] { error (Invalid_character (lexeme lexbuf).[1]) (lexeme_end lexbuf - 1) } | '/' { regexp_options lexbuf, lexeme_end lexbuf } | [^ '\\' '/' '\r' '\n']+ { store lexbuf; regexp lexbuf } and regexp_options = parse | 'g' | 'i' | 'm' | 's' | 'u' { let l = lexeme lexbuf in l ^ regexp_options lexbuf } | ['a' - 'z'] { error Invalid_option (lexeme_start lexbuf) } | "" { "" } haxe_3.4.4.orig/src/syntax/parser.ml0000664000175000017500000016545713166552354017401 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Globals type error_msg = | Unexpected of token | Duplicate_default | Missing_semicolon | Unclosed_macro | Unimplemented | Missing_type | Custom of string exception Error of error_msg * pos exception TypePath of string list * (string * bool) option * bool (* in import *) exception Display of expr let error_msg = function | Unexpected t -> "Unexpected "^(s_token t) | Duplicate_default -> "Duplicate default" | Missing_semicolon -> "Missing ;" | Unclosed_macro -> "Unclosed macro" | Unimplemented -> "Not implemented for current platform" | Missing_type -> "Missing type declaration" | Custom s -> s let error m p = raise (Error (m,p)) let display_error : (error_msg -> pos -> unit) ref = ref (fun _ _ -> assert false) let special_identifier_files = Hashtbl.create 0 let quoted_ident_prefix = "@$__hx__" let quote_ident s = quoted_ident_prefix ^ s let unquote_ident f = let pf = quoted_ident_prefix in let pflen = String.length pf in let is_quoted = String.length f >= pflen && String.sub f 0 pflen = pf in let s = if is_quoted then String.sub f pflen (String.length f - pflen) else f in let is_valid = not is_quoted || try for i = 0 to String.length s - 1 do match String.unsafe_get s i with | 'a'..'z' | 'A'..'Z' | '_' -> () | '0'..'9' when i > 0 -> () | _ -> raise Exit done; if Hashtbl.mem Lexer.keywords s then raise Exit; true with Exit -> false in s,is_quoted,is_valid let cache = ref (DynArray.create()) let last_doc = ref None let use_doc = ref false let resume_display = ref null_pos let in_macro = ref false let last_token s = let n = Stream.count s in DynArray.get (!cache) (if n = 0 then 0 else n - 1) let serror() = raise (Stream.Error "") let do_resume() = !resume_display <> null_pos let display e = raise (Display e) let type_path sl in_import = match sl with | n :: l when n.[0] >= 'A' && n.[0] <= 'Z' -> raise (TypePath (List.rev l,Some (n,false),in_import)); | _ -> raise (TypePath (List.rev sl,None,in_import)) let is_resuming_file file = Path.unique_full_path file = !resume_display.pfile let is_resuming p = let p2 = !resume_display in p.pmax = p2.pmin && is_resuming_file p.pfile let set_resume p = resume_display := { p with pfile = Path.unique_full_path p.pfile } let is_dollar_ident e = match fst e with | EConst (Ident n) when n.[0] = '$' -> true | _ -> false let precedence op = let left = true and right = false in match op with | OpMod -> 0, left | OpMult | OpDiv -> 1, left | OpAdd | OpSub -> 2, left | OpShl | OpShr | OpUShr -> 3, left | OpOr | OpAnd | OpXor -> 4, left | OpEq | OpNotEq | OpGt | OpLt | OpGte | OpLte -> 5, left | OpInterval -> 6, left | OpBoolAnd -> 7, left | OpBoolOr -> 8, left | OpArrow -> 9, right | OpAssign | OpAssignOp _ -> 10, right let is_not_assign = function | OpAssign | OpAssignOp _ -> false | _ -> true let swap op1 op2 = let p1, left1 = precedence op1 in let p2, _ = precedence op2 in left1 && p1 <= p2 let rec make_binop op e ((v,p2) as e2) = match v with | EBinop (_op,_e,_e2) when swap op _op -> let _e = make_binop op e _e in EBinop (_op,_e,_e2) , punion (pos _e) (pos _e2) | ETernary (e1,e2,e3) when is_not_assign op -> let e = make_binop op e e1 in ETernary (e,e2,e3) , punion (pos e) (pos e3) | _ -> EBinop (op,e,e2) , punion (pos e) (pos e2) let rec make_unop op ((v,p2) as e) p1 = let neg s = if s.[0] = '-' then String.sub s 1 (String.length s - 1) else "-" ^ s in match v with | EBinop (bop,e,e2) -> EBinop (bop, make_unop op e p1 , e2) , (punion p1 p2) | ETernary (e1,e2,e3) -> ETernary (make_unop op e1 p1 , e2, e3), punion p1 p2 | EConst (Int i) when op = Neg -> EConst (Int (neg i)),punion p1 p2 | EConst (Float j) when op = Neg -> EConst (Float (neg j)),punion p1 p2 | _ -> EUnop (op,Prefix,e), punion p1 p2 let rec make_meta name params ((v,p2) as e) p1 = match v with | EBinop ((OpAssign | OpAssignOp _),_,_) -> EMeta((name,params,p1),e),punion p1 p2 | EBinop (bop,e,e2) -> EBinop (bop, make_meta name params e p1 , e2) , (punion p1 p2) | ETernary (e1,e2,e3) -> ETernary (make_meta name params e1 p1 , e2, e3), punion p1 p2 | _ -> EMeta((name,params,p1),e),punion p1 p2 let make_is e (t,p_t) p p_is = let e_is = EField((EConst(Ident "Std"),null_pos),"is"),p_is in let e2 = expr_of_type_path (t.tpackage,t.tname) p_t in ECall(e_is,[e;e2]),p let reify in_macro = let cur_pos = ref None in let mk_enum ename n vl p = let constr = (EConst (Ident n),p) in match vl with | [] -> constr | _ -> (ECall (constr,vl),p) in let to_const c p = let cst n v = mk_enum "Constant" n [EConst (String v),p] p in match c with | Int i -> cst "CInt" i | String s -> cst "CString" s | Float s -> cst "CFloat" s | Ident s -> cst "CIdent" s | Regexp (r,o) -> mk_enum "Constant" "CRegexp" [(EConst (String r),p);(EConst (String o),p)] p in let rec to_binop o p = let op n = mk_enum "Binop" n [] p in match o with | OpAdd -> op "OpAdd" | OpMult -> op "OpMult" | OpDiv -> op "OpDiv" | OpSub -> op "OpSub" | OpAssign -> op "OpAssign" | OpEq -> op "OpEq" | OpNotEq -> op "OpNotEq" | OpGt -> op "OpGt" | OpGte -> op "OpGte" | OpLt -> op "OpLt" | OpLte -> op "OpLte" | OpAnd -> op "OpAnd" | OpOr -> op "OpOr" | OpXor -> op "OpXor" | OpBoolAnd -> op "OpBoolAnd" | OpBoolOr -> op "OpBoolOr" | OpShl -> op "OpShl" | OpShr -> op "OpShr" | OpUShr -> op "OpUShr" | OpMod -> op "OpMod" | OpAssignOp o -> mk_enum "Binop" "OpAssignOp" [to_binop o p] p | OpInterval -> op "OpInterval" | OpArrow -> op "OpArrow" in let to_string s p = let len = String.length s in if len > 1 && s.[0] = '$' then (EConst (Ident (String.sub s 1 (len - 1))),p) else (EConst (String s),p) in let to_placed_name (s,p) = to_string s p in let to_array f a p = (EArrayDecl (List.map (fun s -> f s p) a),p) in let to_null p = (EConst (Ident "null"),p) in let to_opt f v p = match v with | None -> to_null p | Some v -> f v p in let to_bool o p = (EConst (Ident (if o then "true" else "false")),p) in let to_obj fields p = (EObjectDecl (List.map (fun (s,e) -> (s,null_pos),e) fields),p) in let rec to_tparam t p = let n, v = (match t with | TPType t -> "TPType", to_ctype t p | TPExpr e -> "TPExpr", to_expr e p ) in mk_enum "TypeParam" n [v] p and to_tpath (t,_) p = let len = String.length t.tname in if t.tpackage = [] && len > 1 && t.tname.[0] = '$' then begin let name = String.sub t.tname 1 (len - 1) in let ei = (EConst (Ident name),p) in match t.tparams with | [] -> ei | _ -> (* `macro : $TP` conveys the intent to use TP and overwrite the type parameters. *) let ea = to_array to_tparam t.tparams p in let fields = [ ("pack", (EField(ei,"pack"),p)); ("name", (EField(ei,"name"),p)); ("sub", (EField(ei,"sub"),p)); ("params", ea); ] in to_obj fields p end else begin let fields = [ ("pack", to_array to_string t.tpackage p); ("name", to_string t.tname p); ("params", to_array to_tparam t.tparams p); ] in to_obj (match t.tsub with None -> fields | Some s -> fields @ ["sub",to_string s p]) p end and to_ctype t p = let ct n vl = mk_enum "ComplexType" n vl p in match fst t with | CTPath ({ tpackage = []; tparams = []; tsub = None; tname = n }) when n.[0] = '$' -> to_string n p | CTPath t -> ct "TPath" [to_tpath (t,p) p] | CTFunction (args,ret) -> ct "TFunction" [to_array to_type_hint args p; to_type_hint ret p] | CTAnonymous fields -> ct "TAnonymous" [to_array to_cfield fields p] | CTParent t -> ct "TParent" [to_type_hint t p] | CTExtend (tl,fields) -> ct "TExtend" [to_array to_tpath tl p; to_array to_cfield fields p] | CTOptional t -> ct "TOptional" [to_type_hint t p] and to_type_hint (t,p) _ = (* to_obj ["type",to_ctype t p;"pos",to_pos p] p *) to_ctype (t,p) p and to_fun f p = let farg ((n,_),o,_,t,e) p = let fields = [ "name", to_string n p; "opt", to_bool o p; "type", to_opt to_type_hint t p; ] in to_obj (match e with None -> fields | Some e -> fields @ ["value",to_expr e p]) p in let rec fparam t p = let fields = [ "name", to_placed_name t.tp_name; "constraints", to_array to_ctype t.tp_constraints p; "params", to_array fparam t.tp_params p; ] in to_obj fields p in let fields = [ ("args",to_array farg f.f_args p); ("ret",to_opt to_type_hint f.f_type p); ("expr",to_opt to_expr f.f_expr p); ("params",to_array fparam f.f_params p); ] in to_obj fields p and to_cfield f p = let p = f.cff_pos in let to_access a p = let n = (match a with | APublic -> "APublic" | APrivate -> "APrivate" | AStatic -> "AStatic" | AOverride -> "AOverride" | ADynamic -> "ADynamic" | AInline -> "AInline" | AMacro -> "AMacro" ) in mk_enum "Access" n [] p in let to_kind k = let n, vl = (match k with | FVar (ct,e) -> "FVar", [to_opt to_type_hint ct p;to_opt to_expr e p] | FFun f -> "FFun", [to_fun f p] | FProp (get,set,t,e) -> "FProp", [to_placed_name get; to_placed_name set; to_opt to_type_hint t p; to_opt to_expr e p] ) in mk_enum "FieldType" n vl p in let fields = [ Some ("name", to_placed_name f.cff_name); (match f.cff_doc with None -> None | Some s -> Some ("doc", to_string s p)); (match f.cff_access with [] -> None | l -> Some ("access", to_array to_access l p)); Some ("kind", to_kind f.cff_kind); Some ("pos", to_pos f.cff_pos); (match f.cff_meta with [] -> None | l -> Some ("meta", to_meta f.cff_meta p)); ] in let fields = List.rev (List.fold_left (fun acc v -> match v with None -> acc | Some e -> e :: acc) [] fields) in to_obj fields p and to_meta m p = to_array (fun (m,el,p) _ -> let fields = [ "name", to_string (Meta.to_string m) p; "params", to_expr_array el p; "pos", to_pos p; ] in to_obj fields p ) m p and to_pos p = match !cur_pos with | Some p -> p | None -> let file = (EConst (String p.pfile),p) in let pmin = (EConst (Int (string_of_int p.pmin)),p) in let pmax = (EConst (Int (string_of_int p.pmax)),p) in if in_macro then (EUntyped (ECall ((EConst (Ident "$__mk_pos__"),p),[file;pmin;pmax]),p),p) else to_obj [("file",file);("min",pmin);("max",pmax)] p and to_expr_array a p = match a with | [EMeta ((Meta.Dollar "a",[],_),e1),_] -> (match fst e1 with EArrayDecl el -> to_expr_array el p | _ -> e1) | _ -> to_array to_expr a p and to_expr e _ = let p = snd e in let expr n vl = let e = mk_enum "ExprDef" n vl p in to_obj [("expr",e);("pos",to_pos p)] p in let loop e = to_expr e (snd e) in match fst e with | EConst (Ident n) when n.[0] = '$' && String.length n > 1 && n <> "$__mk_pos__" -> to_string n p | EConst c -> expr "EConst" [to_const c p] | EArray (e1,e2) -> expr "EArray" [loop e1;loop e2] | EBinop (op,e1,e2) -> expr "EBinop" [to_binop op p; loop e1; loop e2] | EField (e,s) -> expr "EField" [loop e; to_string s p] | EParenthesis e -> expr "EParenthesis" [loop e] | EObjectDecl fl -> expr "EObjectDecl" [to_array (fun ((f,_),e) -> to_obj [("field",to_string f p);("expr",loop e)]) fl p] | EArrayDecl el -> expr "EArrayDecl" [to_expr_array el p] | ECall (e,el) -> expr "ECall" [loop e;to_expr_array el p] | ENew (t,el) -> expr "ENew" [to_tpath t p;to_expr_array el p] | EUnop (op,flag,e) -> let op = mk_enum "Unop" (match op with | Increment -> "OpIncrement" | Decrement -> "OpDecrement" | Not -> "OpNot" | Neg -> "OpNeg" | NegBits -> "OpNegBits" ) [] p in expr "EUnop" [op;to_bool (flag = Postfix) p;loop e] | EVars vl -> expr "EVars" [to_array (fun ((n,pn),th,e) p -> let fields = [ (* "name", to_obj ["name",to_string n pn;"pos",to_pos pn] p; *) "name", to_string n pn; "type", to_opt to_type_hint th p; "expr", to_opt to_expr e p; ] in to_obj fields p ) vl p] | EFunction (name,f) -> let name = match name with | None -> to_null p | Some name -> if ExtString.String.starts_with name "inline_$" then begin let real_name = (String.sub name 7 (String.length name - 7)) in let e_name = to_string real_name p in let e_inline = to_string "inline_" p in let e_add = (EBinop(OpAdd,e_inline,e_name),p) in e_add end else to_string name p in expr "EFunction" [name; to_fun f p] | EBlock el -> expr "EBlock" [to_expr_array el p] | EFor (e1,e2) -> expr "EFor" [loop e1;loop e2] | EIn (e1,e2) -> expr "EIn" [loop e1;loop e2] | EIf (e1,e2,eelse) -> expr "EIf" [loop e1;loop e2;to_opt to_expr eelse p] | EWhile (e1,e2,flag) -> expr "EWhile" [loop e1;loop e2;to_bool (flag = NormalWhile) p] | ESwitch (e1,cases,def) -> let scase (el,eg,e,_) p = to_obj [("values",to_expr_array el p);"guard",to_opt to_expr eg p;"expr",to_opt to_expr e p] p in expr "ESwitch" [loop e1;to_array scase cases p;to_opt (fun (e,_) -> to_opt to_expr e) def p] | ETry (e1,catches) -> let scatch ((n,_),t,e,_) p = to_obj [("name",to_string n p);("type",to_ctype t p);("expr",loop e)] p in expr "ETry" [loop e1;to_array scatch catches p] | EReturn eo -> expr "EReturn" [to_opt to_expr eo p] | EBreak -> expr "EBreak" [] | EContinue -> expr "EContinue" [] | EUntyped e -> expr "EUntyped" [loop e] | EThrow e -> expr "EThrow" [loop e] | ECast (e,ct) -> expr "ECast" [loop e; to_opt to_type_hint ct p] | EDisplay (e,flag) -> expr "EDisplay" [loop e; to_bool flag p] | EDisplayNew t -> expr "EDisplayNew" [to_tpath t p] | ETernary (e1,e2,e3) -> expr "ETernary" [loop e1;loop e2;loop e3] | ECheckType (e1,ct) -> expr "ECheckType" [loop e1; to_type_hint ct p] | EMeta ((m,ml,p),e1) -> match m, ml with | Meta.Dollar ("" | "e"), _ -> e1 | Meta.Dollar "a", _ -> expr "EArrayDecl" (match fst e1 with EArrayDecl el -> [to_expr_array el p] | _ -> [e1]) | Meta.Dollar "b", _ -> expr "EBlock" [e1] (* TODO: can $v and $i be implemented better? *) | Meta.Dollar "v", _ -> begin match fst e1 with | EParenthesis (ECheckType (e2, (CTPath{tname="String";tpackage=[]},_)),_) -> expr "EConst" [mk_enum "Constant" "CString" [e2] (pos e2)] | EParenthesis (ECheckType (e2, (CTPath{tname="Int";tpackage=[]},_)),_) -> expr "EConst" [mk_enum "Constant" "CInt" [e2] (pos e2)] | EParenthesis (ECheckType (e2, (CTPath{tname="Float";tpackage=[]},_)),_) -> expr "EConst" [mk_enum "Constant" "CFloat" [e2] (pos e2)] | _ -> (ECall ((EField ((EField ((EField ((EConst (Ident "haxe"),p),"macro"),p),"Context"),p),"makeExpr"),p),[e; to_pos (pos e)]),p) end | Meta.Dollar "i", _ -> expr "EConst" [mk_enum "Constant" "CIdent" [e1] (pos e1)] | Meta.Dollar "p", _ -> (ECall ((EField ((EField ((EField ((EConst (Ident "haxe"),p),"macro"),p),"MacroStringTools"),p),"toFieldExpr"),p),[e]),p) | Meta.Custom ":pos", [pexpr] -> let old = !cur_pos in cur_pos := Some pexpr; let e = loop e1 in cur_pos := old; e | _ -> expr "EMeta" [to_obj [("name",to_string (Meta.to_string m) p);("params",to_expr_array ml p);("pos",to_pos p)] p;loop e1] and to_tparam_decl p t = to_obj [ "name", to_placed_name t.tp_name; "params", (EArrayDecl (List.map (to_tparam_decl p) t.tp_params),p); "constraints", (EArrayDecl (List.map (fun t -> to_ctype t p) t.tp_constraints),p) ] p and to_type_def (t,p) = match t with | EClass d -> let ext = ref None and impl = ref [] and interf = ref false in List.iter (function | HExtern | HPrivate -> () | HInterface -> interf := true; | HExtends t -> ext := (match !ext with | None -> Some (to_tpath t p) | Some _ -> begin impl := (to_tpath t p) :: !impl; !ext end) | HImplements i-> impl := (to_tpath i p) :: !impl ) d.d_flags; to_obj [ "pack", (EArrayDecl [],p); "name", to_string (fst d.d_name) (pos d.d_name); "pos", to_pos p; "meta", to_meta d.d_meta p; "params", (EArrayDecl (List.map (to_tparam_decl p) d.d_params),p); "isExtern", to_bool (List.mem HExtern d.d_flags) p; "kind", mk_enum "TypeDefKind" "TDClass" [(match !ext with None -> (EConst (Ident "null"),p) | Some t -> t);(EArrayDecl (List.rev !impl),p);to_bool !interf p] p; "fields", (EArrayDecl (List.map (fun f -> to_cfield f p) d.d_data),p) ] p | _ -> assert false in (fun e -> to_expr e (snd e)), to_ctype, to_type_def let next_token s = match Stream.peek s with | Some tk -> tk | _ -> last_token s let popt f = parser | [< v = f >] -> Some v | [< >] -> None let rec plist f = parser | [< v = f; l = plist f >] -> v :: l | [< >] -> [] let rec psep sep f = parser | [< v = f; s >] -> let rec loop = parser | [< '(sep2,_) when sep2 = sep; v = f; l = loop >] -> v :: l | [< >] -> [] in v :: loop s | [< >] -> [] let ident = parser | [< '(Const (Ident i),p) >] -> i,p let dollar_ident = parser | [< '(Const (Ident i),p) >] -> i,p | [< '(Dollar i,p) >] -> ("$" ^ i),p let dollar_ident_macro pack = parser | [< '(Const (Ident i),p) >] -> i,p | [< '(Dollar i,p) >] -> ("$" ^ i),p | [< '(Kwd Macro,p) when pack <> [] >] -> "macro", p | [< '(Kwd Extern,p) when pack <> [] >] -> "extern", p let lower_ident_or_macro = parser | [< '(Const (Ident i),p) when is_lower_ident i >] -> i | [< '(Kwd Macro,_) >] -> "macro" | [< '(Kwd Extern,_) >] -> "extern" let property_ident = parser | [< i,p = ident >] -> i,p | [< '(Kwd Dynamic,p) >] -> "dynamic",p | [< '(Kwd Default,p) >] -> "default",p | [< '(Kwd Null,p) >] -> "null",p let get_doc s = (* do the peek first to make sure we fetch the doc *) match Stream.peek s with | None -> None | Some (tk,p) -> match !last_doc with | None -> None | Some (d,pos) -> last_doc := None; if pos = p.pmin then Some d else None let comma = parser | [< '(Comma,_) >] -> () let semicolon s = if fst (last_token s) = BrClose then match s with parser | [< '(Semicolon,p) >] -> p | [< >] -> snd (last_token s) else match s with parser | [< '(Semicolon,p) >] -> p | [< s >] -> let pos = snd (last_token s) in if do_resume() then pos else error Missing_semicolon pos let encloses_resume p = p.pmin <= !resume_display.pmin && p.pmax >= !resume_display.pmax let would_skip_resume p1 s = match Stream.npeek 1 s with | [ (_,p2) ] -> is_resuming_file p2.pfile && encloses_resume (punion p1 p2) | _ -> false let rec parse_file s = last_doc := None; match s with parser | [< '(Kwd Package,_); pack = parse_package; s >] -> begin match s with parser | [< '(Const(Ident _),p) when pack = [] >] -> error (Custom "Package name must start with a lowercase character") p | [< _ = semicolon; l = parse_type_decls pack []; '(Eof,_) >] -> pack , l end | [< l = parse_type_decls [] []; '(Eof,_) >] -> [] , l and parse_type_decls pack acc s = try match s with parser | [< v = parse_type_decl; l = parse_type_decls pack (v :: acc) >] -> l | [< >] -> List.rev acc with TypePath ([],Some (name,false),b) -> (* resolve imports *) List.iter (fun d -> match fst d with | EImport (t,_) -> (match List.rev t with | (n,_) :: path when n = name && List.for_all (fun (i,_) -> is_lower_ident i) path -> raise (TypePath (List.map fst (List.rev path),Some (name,false),b)) | _ -> ()) | _ -> () ) acc; raise (TypePath (pack,Some(name,true),b)) and parse_type_decl s = match s with parser | [< '(Kwd Import,p1) >] -> parse_import s p1 | [< '(Kwd Using,p1) >] -> parse_using s p1 | [< doc = get_doc; meta = parse_meta; c = parse_common_flags; s >] -> match s with parser | [< n , p1 = parse_enum_flags; name = type_name; tl = parse_constraint_params; '(BrOpen,_); l = plist parse_enum; '(BrClose,p2) >] -> (EEnum { d_name = name; d_doc = doc; d_meta = meta; d_params = tl; d_flags = List.map snd c @ n; d_data = l }, punion p1 p2) | [< n , p1 = parse_class_flags; name = type_name; tl = parse_constraint_params; hl = plist parse_class_herit; '(BrOpen,_); fl, p2 = parse_class_fields false p1 >] -> (EClass { d_name = name; d_doc = doc; d_meta = meta; d_params = tl; d_flags = List.map fst c @ n @ hl; d_data = fl; }, punion p1 p2) | [< '(Kwd Typedef,p1); name = type_name; tl = parse_constraint_params; '(Binop OpAssign,p2); t = parse_complex_type; s >] -> (match s with parser | [< '(Semicolon,_) >] -> () | [< >] -> ()); (ETypedef { d_name = name; d_doc = doc; d_meta = meta; d_params = tl; d_flags = List.map snd c; d_data = t; }, punion p1 (pos t)) | [< '(Kwd Abstract,p1); name = type_name; tl = parse_constraint_params; st = parse_abstract_subtype; sl = plist parse_abstract_relations; '(BrOpen,_); fl, p2 = parse_class_fields false p1 >] -> let flags = List.map (fun (_,c) -> match c with EPrivate -> APrivAbstract | EExtern -> AExtern) c in let flags = (match st with None -> flags | Some t -> AIsType t :: flags) in (EAbstract { d_name = name; d_doc = doc; d_meta = meta; d_params = tl; d_flags = flags @ sl; d_data = fl; },punion p1 p2) and parse_class doc meta cflags need_name s = let opt_name = if need_name then type_name else (fun s -> match popt type_name s with None -> "",null_pos | Some n -> n) in match s with parser | [< n , p1 = parse_class_flags; name = opt_name; tl = parse_constraint_params; hl = plist parse_class_herit; '(BrOpen,_); fl, p2 = parse_class_fields (not need_name) p1 >] -> (EClass { d_name = name; d_doc = doc; d_meta = meta; d_params = tl; d_flags = List.map fst cflags @ n @ hl; d_data = fl; }, punion p1 p2) and parse_import s p1 = let rec loop acc = match s with parser | [< '(Dot,p) >] -> let resume() = type_path (List.map fst acc) true in if is_resuming p then resume(); (match s with parser | [< '(Const (Ident k),p) >] -> loop ((k,p) :: acc) | [< '(Kwd Macro,p) >] -> loop (("macro",p) :: acc) | [< '(Kwd Extern,p) >] -> loop (("extern",p) :: acc) | [< '(Binop OpMult,_); '(Semicolon,p2) >] -> p2, List.rev acc, IAll | [< '(Binop OpOr,_) when do_resume() >] -> set_resume p; resume() | [< >] -> serror()); | [< '(Semicolon,p2) >] -> p2, List.rev acc, INormal | [< '(Kwd In,_); '(Const (Ident name),_); '(Semicolon,p2) >] -> p2, List.rev acc, IAsName name | [< '(Const (Ident "as"),_); '(Const (Ident name),_); '(Semicolon,p2) >] -> p2, List.rev acc, IAsName name | [< >] -> serror() in let p2, path, mode = (match s with parser | [< '(Const (Ident name),p) >] -> loop [name,p] | [< >] -> if would_skip_resume p1 s then p1, [], INormal else serror() ) in (EImport (path,mode),punion p1 p2) and parse_using s p1 = let rec loop acc = match s with parser | [< '(Dot,p) >] -> begin match s with parser | [< '(Const (Ident k),p) >] -> loop ((k,p) :: acc) | [< '(Kwd Macro,p) >] -> loop (("macro",p) :: acc) | [< '(Kwd Extern,p) >] -> loop (("extern",p) :: acc) | [< >] -> if is_resuming p then type_path (List.map fst acc) false; serror() end | [< '(Semicolon,p2) >] -> p2,List.rev acc in let p2, path = (match s with parser | [< '(Const (Ident name),p) >] -> loop [name,p] | [< >] -> if would_skip_resume p1 s then p1, [] else serror() ) in (EUsing path,punion p1 p2) and parse_abstract_relations s = match s with parser | [< '(Const (Ident "to"),_); t = parse_complex_type >] -> AToType t | [< '(Const (Ident "from"),_); t = parse_complex_type >] -> AFromType t and parse_abstract_subtype s = match s with parser | [< '(POpen, _); t = parse_complex_type; '(PClose,_) >] -> Some t | [< >] -> None and parse_package s = psep Dot lower_ident_or_macro s and parse_class_fields tdecl p1 s = let l = parse_class_field_resume tdecl s in let p2 = (match s with parser | [< '(BrClose,p2) >] -> p2 | [< >] -> if do_resume() then pos (last_token s) else serror() ) in l, p2 and parse_class_field_resume tdecl s = if not (do_resume()) then plist parse_class_field s else try let c = parse_class_field s in c :: parse_class_field_resume tdecl s with Stream.Error _ | Stream.Failure -> (* look for next variable/function or next type declaration *) let rec junk k = if k <= 0 then () else begin Stream.junk s; junk (k - 1); end in (* walk back tokens which are prefixing a type/field declaration *) let rec junk_tokens k = if k = 0 then () else match List.rev_map fst (Stream.npeek k s) with | Kwd Private :: _ -> junk_tokens (k - 1) | (Const (Ident _) | Kwd _) :: DblDot :: At :: l | (Const (Ident _) | Kwd _) :: At :: l -> junk_tokens (List.length l) | PClose :: l -> (* count matching parenthesises for metadata call *) let rec loop n = function | [] -> [] | POpen :: l -> if n = 0 then l else loop (n - 1) l | PClose :: l -> loop (n + 1) l | _ :: l -> loop n l in (match loop 0 l with | (Const (Ident _) | Kwd _) :: At :: l | (Const (Ident _) | Kwd _) :: DblDot :: At :: l -> junk_tokens (List.length l) | _ -> junk k) | _ -> junk k in let rec loop k = match List.rev_map fst (Stream.npeek k s) with (* metadata *) | Kwd _ :: At :: _ | Kwd _ :: DblDot :: At :: _ -> loop (k + 1) (* field declaration *) | Const _ :: Kwd Function :: _ | Kwd New :: Kwd Function :: _ -> junk_tokens (k - 2); parse_class_field_resume tdecl s | Kwd Macro :: _ | Kwd Public :: _ | Kwd Static :: _ | Kwd Var :: _ | Kwd Override :: _ | Kwd Dynamic :: _ | Kwd Inline :: _ -> junk_tokens (k - 1); parse_class_field_resume tdecl s | BrClose :: _ when tdecl -> junk_tokens (k - 1); [] (* type declaration *) | Eof :: _ | Kwd Import :: _ | Kwd Using :: _ | Kwd Extern :: _ | Kwd Class :: _ | Kwd Interface :: _ | Kwd Enum :: _ | Kwd Typedef :: _ | Kwd Abstract :: _-> junk_tokens (k - 1); [] | [] -> [] | _ -> loop (k + 1) in loop 1 and parse_common_flags = parser | [< '(Kwd Private,_); l = parse_common_flags >] -> (HPrivate, EPrivate) :: l | [< '(Kwd Extern,_); l = parse_common_flags >] -> (HExtern, EExtern) :: l | [< >] -> [] and parse_meta_argument_expr s = try expr s with Display e -> match fst e with | EDisplay(e,_) -> begin try type_path (string_list_of_expr_path_raise e) false with Exit -> e end | _ -> e and parse_meta_params pname s = match s with parser | [< '(POpen,p) when p.pmin = pname.pmax; params = psep Comma parse_meta_argument_expr; '(PClose,_); >] -> params | [< >] -> [] and parse_meta_entry = parser [< '(At,p1); s >] -> match s with parser | [< name,p = meta_name p1; params = parse_meta_params p; s >] -> (name,params,p) | [< >] -> if is_resuming p1 then (Meta.Last,[],p1) else serror() and parse_meta = parser | [< entry = parse_meta_entry; s >] -> entry :: parse_meta s | [< >] -> [] and meta_name p1 = parser | [< '(Const (Ident i),p) when p.pmin = p1.pmax >] -> (Meta.Custom i), p | [< '(Kwd k,p) when p.pmin = p1.pmax >] -> (Meta.Custom (s_keyword k)),p | [< '(DblDot,p) when p.pmin = p1.pmax; s >] -> match s with parser | [< '(Const (Ident i),p1) when p1.pmin = p.pmax >] -> (Meta.parse i),punion p p1 | [< '(Kwd k,p1) when p1.pmin = p.pmax >] -> (Meta.parse (s_keyword k)),punion p p1 | [< >] -> if is_resuming p then Meta.Last,p else raise Stream.Failure and parse_enum_flags = parser | [< '(Kwd Enum,p) >] -> [] , p and parse_class_flags = parser | [< '(Kwd Class,p) >] -> [] , p | [< '(Kwd Interface,p) >] -> [HInterface] , p and parse_complex_type_at p = parser | [< t = parse_complex_type >] -> t | [< >] -> if is_resuming p then CTPath { tpackage = []; tname = ""; tparams = []; tsub = None },p else serror() and parse_type_hint = parser | [< '(DblDot,p1); t = parse_complex_type_at p1 >] -> t and parse_type_hint_with_pos s = match s with parser | [< '(DblDot,p1); t = parse_complex_type_at p1 >] -> t and parse_type_opt = parser | [< t = parse_type_hint >] -> Some t | [< >] -> None and parse_complex_type s = let t = parse_complex_type_inner s in parse_complex_type_next t s and parse_structural_extension = parser | [< '(Binop OpGt,_); t = parse_type_path; '(Comma,_); s >] -> t and parse_complex_type_inner = parser | [< '(POpen,p1); t = parse_complex_type; '(PClose,p2) >] -> CTParent t,punion p1 p2 | [< '(BrOpen,p1); s >] -> (match s with parser | [< l,p2 = parse_type_anonymous false >] -> CTAnonymous l,punion p1 p2 | [< t = parse_structural_extension; s>] -> let tl = t :: plist parse_structural_extension s in (match s with parser | [< l,p2 = parse_type_anonymous false >] -> CTExtend (tl,l),punion p1 p2 | [< l,p2 = parse_class_fields true p1 >] -> CTExtend (tl,l),punion p1 p2) | [< l,p2 = parse_class_fields true p1 >] -> CTAnonymous l,punion p1 p2 | [< >] -> serror()) | [< '(Question,p1); t,p2 = parse_complex_type_inner >] -> CTOptional (t,p2),punion p1 p2 | [< t,p = parse_type_path >] -> CTPath t,p and parse_type_path s = parse_type_path1 None [] s and parse_type_path1 p0 pack = parser | [< name, p1 = dollar_ident_macro pack; s >] -> if is_lower_ident name then (match s with parser | [< '(Dot,p) >] -> if is_resuming p then raise (TypePath (List.rev (name :: pack),None,false)) else parse_type_path1 (match p0 with None -> Some p1 | Some _ -> p0) (name :: pack) s | [< '(Semicolon,_) >] -> error (Custom "Type name should start with an uppercase letter") p1 | [< >] -> serror()) else let sub,p2 = (match s with parser | [< '(Dot,p); s >] -> (if is_resuming p then raise (TypePath (List.rev pack,Some (name,false),false)) else match s with parser | [< '(Const (Ident name),p2) when not (is_lower_ident name) >] -> Some name,p2 | [< '(Binop OpOr,_) when do_resume() >] -> set_resume p; raise (TypePath (List.rev pack,Some (name,false),false)) | [< >] -> serror()) | [< >] -> None,p1 ) in let params,p2 = (match s with parser | [< '(Binop OpLt,_); l = psep Comma parse_type_path_or_const; '(Binop OpGt,p2) >] -> l,p2 | [< >] -> [],p2 ) in { tpackage = List.rev pack; tname = name; tparams = params; tsub = sub; },punion (match p0 with None -> p1 | Some p -> p) p2 | [< '(Binop OpOr,_) when do_resume() >] -> raise (TypePath (List.rev pack,None,false)) and type_name = parser | [< '(Const (Ident name),p) >] -> if is_lower_ident name then error (Custom "Type name should start with an uppercase letter") p else name,p | [< '(Dollar name,p) >] -> "$" ^ name,p and parse_type_path_or_const = parser (* we can't allow (expr) here *) | [< '(BkOpen,p1); l = parse_array_decl; '(BkClose,p2); s >] -> TPExpr (EArrayDecl l, punion p1 p2) | [< t = parse_complex_type >] -> TPType t | [< '(Const c,p) >] -> TPExpr (EConst c,p) | [< e = expr >] -> TPExpr e | [< >] -> serror() and parse_complex_type_next (t : type_hint) = parser | [< '(Arrow,_); t2,p2 = parse_complex_type >] -> (match t2 with | CTFunction (args,r) -> CTFunction (t :: args,r),punion (pos t) p2 | _ -> CTFunction ([t] , (t2,p2)),punion (pos t) p2) | [< >] -> t and parse_type_anonymous opt = parser | [< '(Question,_) when not opt; s >] -> parse_type_anonymous true s | [< name, p1 = ident; t = parse_type_hint_with_pos; s >] -> let p2 = pos (last_token s) in let next acc = { cff_name = name,p1; cff_meta = if opt then [Meta.Optional,[],null_pos] else []; cff_access = []; cff_doc = None; cff_kind = FVar (Some t,None); cff_pos = punion p1 p2; } :: acc in match s with parser | [< '(BrClose,p2) >] -> next [],p2 | [< '(Comma,p2) >] -> (match s with parser | [< '(BrClose,p2) >] -> next [],p2 | [< l,p2 = parse_type_anonymous false >] -> next l,punion p1 p2 | [< >] -> serror()); | [< >] -> serror() and parse_enum s = let doc = get_doc s in let meta = parse_meta s in match s with parser | [< name, p1 = ident; params = parse_constraint_params; s >] -> let args = (match s with parser | [< '(POpen,_); l = psep Comma parse_enum_param; '(PClose,_) >] -> l | [< >] -> [] ) in let t = popt parse_type_hint_with_pos s in let p2 = (match s with parser | [< p = semicolon >] -> p | [< >] -> serror() ) in { ec_name = name,p1; ec_doc = doc; ec_meta = meta; ec_args = args; ec_params = params; ec_type = t; ec_pos = punion p1 p2; } and parse_enum_param = parser | [< '(Question,_); name, _ = ident; t = parse_type_hint_with_pos >] -> (name,true,t) | [< name, _ = ident; t = parse_type_hint_with_pos >] -> (name,false,t) and parse_class_field s = let doc = get_doc s in match s with parser | [< meta = parse_meta; al = parse_cf_rights true []; s >] -> let name, pos, k = (match s with parser | [< '(Kwd Var,p1); name = dollar_ident; s >] -> (match s with parser | [< '(POpen,_); i1 = property_ident; '(Comma,_); i2 = property_ident; '(PClose,_) >] -> let t = popt parse_type_hint_with_pos s in let e , p2 = (match s with parser | [< '(Binop OpAssign,_); e = toplevel_expr; p2 = semicolon >] -> Some e , p2 | [< p2 = semicolon >] -> None , p2 | [< >] -> serror() ) in name, punion p1 p2, FProp (i1,i2,t, e) | [< t = popt parse_type_hint_with_pos; s >] -> let e , p2 = (match s with parser | [< '(Binop OpAssign,_); e = toplevel_expr; p2 = semicolon >] -> Some e , p2 | [< p2 = semicolon >] -> None , p2 | [< >] -> serror() ) in name, punion p1 p2, FVar (t,e)) | [< '(Kwd Function,p1); name = parse_fun_name; pl = parse_constraint_params; '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = popt parse_type_hint_with_pos; s >] -> let e, p2 = (match s with parser | [< e = toplevel_expr; s >] -> (try ignore(semicolon s) with Error (Missing_semicolon,p) -> !display_error Missing_semicolon p); Some e, pos e | [< p = semicolon >] -> None, p | [< >] -> serror() ) in let f = { f_params = pl; f_args = al; f_type = t; f_expr = e; } in name, punion p1 p2, FFun f | [< >] -> if al = [] then raise Stream.Failure else serror() ) in { cff_name = name; cff_doc = doc; cff_meta = meta; cff_access = al; cff_pos = pos; cff_kind = k; } and parse_cf_rights allow_static l = parser | [< '(Kwd Static,_) when allow_static; l = parse_cf_rights false (AStatic :: l) >] -> l | [< '(Kwd Macro,_) when not(List.mem AMacro l); l = parse_cf_rights allow_static (AMacro :: l) >] -> l | [< '(Kwd Public,_) when not(List.mem APublic l || List.mem APrivate l); l = parse_cf_rights allow_static (APublic :: l) >] -> l | [< '(Kwd Private,_) when not(List.mem APublic l || List.mem APrivate l); l = parse_cf_rights allow_static (APrivate :: l) >] -> l | [< '(Kwd Override,_) when not (List.mem AOverride l); l = parse_cf_rights false (AOverride :: l) >] -> l | [< '(Kwd Dynamic,_) when not (List.mem ADynamic l); l = parse_cf_rights allow_static (ADynamic :: l) >] -> l | [< '(Kwd Inline,_); l = parse_cf_rights allow_static (AInline :: l) >] -> l | [< >] -> l and parse_fun_name = parser | [< name,p = dollar_ident >] -> name,p | [< '(Kwd New,p) >] -> "new",p and parse_fun_param s = let meta = parse_meta s in match s with parser | [< '(Question,_); name, pn = dollar_ident; t = popt parse_type_hint_with_pos; c = parse_fun_param_value >] -> ((name,pn),true,meta,t,c) | [< name, pn = dollar_ident; t = popt parse_type_hint_with_pos; c = parse_fun_param_value >] -> ((name,pn),false,meta,t,c) and parse_fun_param_value = parser | [< '(Binop OpAssign,_); e = toplevel_expr >] -> Some e | [< >] -> None and parse_fun_param_type = parser | [< '(Question,_); name = ident; t = parse_type_hint >] -> (name,true,t) | [< name = ident; t = parse_type_hint >] -> (name,false,t) and parse_constraint_params = parser | [< '(Binop OpLt,_); l = psep Comma parse_constraint_param; '(Binop OpGt,_) >] -> l | [< >] -> [] and parse_constraint_param = parser | [< meta = parse_meta; name = type_name; s >] -> let params = (match s with parser | [< >] -> [] ) in let ctl = (match s with parser | [< '(DblDot,_); s >] -> (match s with parser | [< '(POpen,_); l = psep Comma parse_complex_type; '(PClose,_) >] -> l | [< t = parse_complex_type >] -> [t] | [< >] -> serror()) | [< >] -> [] ) in { tp_name = name; tp_params = params; tp_constraints = ctl; tp_meta = meta; } and parse_type_path_or_resume p1 s = match s with parser | [< t = parse_type_path >] -> t | [< >] -> if would_skip_resume p1 s then { tpackage = []; tname = ""; tparams = []; tsub = None },null_pos else raise Stream.Failure and parse_class_herit = parser | [< '(Kwd Extends,p1); t = parse_type_path_or_resume p1 >] -> HExtends t | [< '(Kwd Implements,p1); t = parse_type_path_or_resume p1 >] -> HImplements t and block1 = parser | [< name,p = dollar_ident; s >] -> block2 (name,p) (Ident name) p s | [< '(Const (String name),p); s >] -> block2 (quote_ident name,p) (String name) p s | [< b = block [] >] -> EBlock b and block2 name ident p s = match s with parser | [< '(DblDot,_); e = expr; l = parse_obj_decl >] -> EObjectDecl ((name,e) :: l) | [< >] -> let e = expr_next (EConst ident,p) s in try let _ = semicolon s in let b = block [e] s in EBlock b with | Error (err,p) -> (!display_error) err p; EBlock (block [e] s) and block acc s = fst (block_with_pos acc null_pos s) and block_with_pos acc p s = try (* because of inner recursion, we can't put Display handling in errors below *) let e = try parse_block_elt s with Display e -> display (EBlock (List.rev (e :: acc)),snd e) in block_with_pos (e :: acc) (pos e) s with | Stream.Failure -> List.rev acc,p | Stream.Error _ -> let tk , pos = next_token s in (!display_error) (Unexpected tk) pos; block_with_pos acc pos s | Error (e,p) -> (!display_error) e p; block_with_pos acc p s and parse_block_elt = parser | [< '(Kwd Var,p1); vl = parse_var_decls p1; p2 = semicolon >] -> (EVars vl,punion p1 p2) | [< '(Kwd Inline,p1); '(Kwd Function,_); e = parse_function p1 true; _ = semicolon >] -> e | [< e = expr; _ = semicolon >] -> e and parse_obj_decl = parser | [< '(Comma,_); s >] -> (match s with parser | [< name,p = ident; '(DblDot,_); e = expr; l = parse_obj_decl >] -> ((name,p),e) :: l | [< '(Const (String name),p); '(DblDot,_); e = expr; l = parse_obj_decl >] -> ((quote_ident name,p),e) :: l | [< >] -> []) | [< >] -> [] and parse_array_decl = parser | [< e = expr; s >] -> (match s with parser | [< '(Comma,_); l = parse_array_decl >] -> e :: l | [< >] -> [e]) | [< >] -> [] and parse_var_decl_head = parser | [< name, p = dollar_ident; t = popt parse_type_hint_with_pos >] -> (name,t,p) and parse_var_assignment = parser | [< '(Binop OpAssign,p1); s >] -> begin match s with parser | [< e = expr >] -> Some e | [< >] -> error (Custom "expression expected after =") p1 end | [< >] -> None and parse_var_assignment_resume vl name pn t s = try let eo = parse_var_assignment s in ((name,pn),t,eo) with Display e -> let v = ((name,pn),t,Some e) in let e = (EVars(List.rev (v :: vl)),punion pn (pos e)) in display e and parse_var_decls_next vl = parser | [< '(Comma,p1); name,t,pn = parse_var_decl_head; s >] -> let v_decl = parse_var_assignment_resume vl name pn t s in parse_var_decls_next (v_decl :: vl) s | [< >] -> vl and parse_var_decls p1 = parser | [< name,t,pn = parse_var_decl_head; s >] -> let v_decl = parse_var_assignment_resume [] name pn t s in List.rev (parse_var_decls_next [v_decl] s) | [< s >] -> error (Custom "Missing variable identifier") p1 and parse_var_decl = parser | [< name,t,pn = parse_var_decl_head; v_decl = parse_var_assignment_resume [] name pn t >] -> v_decl and inline_function = parser | [< '(Kwd Inline,_); '(Kwd Function,p1) >] -> true, p1 | [< '(Kwd Function,p1) >] -> false, p1 and reify_expr e = let to_expr,_,_ = reify !in_macro in let e = to_expr e in (ECheckType (e,(CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = None; tparams = [] },null_pos)),pos e) and parse_macro_expr p = parser | [< '(DblDot,_); t = parse_complex_type >] -> let _, to_type, _ = reify !in_macro in let t = to_type t p in (ECheckType (t,(CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = Some "ComplexType"; tparams = [] },null_pos)),p) | [< '(Kwd Var,p1); vl = psep Comma parse_var_decl >] -> reify_expr (EVars vl,p1) | [< d = parse_class None [] [] false >] -> let _,_,to_type = reify !in_macro in (ECheckType (to_type d,(CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = Some "TypeDefinition"; tparams = [] },null_pos)),p) | [< e = secure_expr >] -> reify_expr e and parse_function p1 inl = parser | [< name = popt dollar_ident; pl = parse_constraint_params; '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = popt parse_type_hint_with_pos; s >] -> let make e = let f = { f_params = pl; f_type = t; f_args = al; f_expr = Some e; } in EFunction ((match name with None -> None | Some (name,_) -> Some (if inl then "inline_" ^ name else name)),f), punion p1 (pos e) in (try expr_next (make (secure_expr s)) s with Display e -> display (make e)) and expr = parser | [< (name,params,p) = parse_meta_entry; s >] -> begin try make_meta name params (secure_expr s) p with | Display e -> display (make_meta name params e p) | Stream.Failure | Stream.Error _ when Path.unique_full_path p.pfile = (!resume_display).pfile -> let e = EConst (Ident "null"),p in display (make_meta name params e p) end | [< '(BrOpen,p1); s >] -> if is_resuming p1 then display (EDisplay ((EObjectDecl [],p1),false),p1); (match s with parser | [< '(Binop OpOr,p2) when do_resume() >] -> set_resume p1; display (EDisplay ((EObjectDecl [],p1),false),p1); | [< b = block1; s >] -> let p2 = match s with parser | [< '(BrClose,p2) >] -> p2 | [< >] -> (* Ignore missing } if we are resuming and "guess" the last position. *) if do_resume() then pos (next_token s) else serror() in let e = (b,punion p1 p2) in (match b with | EObjectDecl _ -> expr_next e s | _ -> e)) | [< '(Kwd Macro,p); s >] -> parse_macro_expr p s | [< '(Kwd Var,p1); v = parse_var_decl >] -> (EVars [v],p1) | [< '(Const c,p); s >] -> expr_next (EConst c,p) s | [< '(Kwd This,p); s >] -> expr_next (EConst (Ident "this"),p) s | [< '(Kwd True,p); s >] -> expr_next (EConst (Ident "true"),p) s | [< '(Kwd False,p); s >] -> expr_next (EConst (Ident "false"),p) s | [< '(Kwd Null,p); s >] -> expr_next (EConst (Ident "null"),p) s | [< '(Kwd Cast,p1); s >] -> (match s with parser | [< '(POpen,pp); e = expr; s >] -> (match s with parser | [< '(Comma,pc); t = parse_complex_type; '(PClose,p2); s >] -> expr_next (ECast (e,Some t),punion p1 p2) s | [< t,pt = parse_type_hint_with_pos; '(PClose,p2); s >] -> let ep = EParenthesis (ECheckType(e,(t,pt)),punion p1 p2), punion p1 p2 in expr_next (ECast (ep,None),punion p1 (pos ep)) s | [< '(Const (Ident "is"),p_is); t = parse_type_path; '(PClose,p2); >] -> let e_is = make_is e t (punion p1 p2) p_is in expr_next (ECast (e_is,None),punion p1 (pos e_is)) s | [< '(PClose,p2); s >] -> let ep = expr_next (EParenthesis(e),punion pp p2) s in expr_next (ECast (ep,None),punion p1 (pos ep)) s | [< >] -> serror()) | [< e = secure_expr >] -> expr_next (ECast (e,None),punion p1 (pos e)) s) | [< '(Kwd Throw,p); e = expr >] -> (EThrow e,p) | [< '(Kwd New,p1); t = parse_type_path; s >] -> begin match s with parser | [< '(POpen,po); e = parse_call_params (fun el p2 -> (ENew(t,el)),punion p1 p2) po >] -> expr_next e s | [< >] -> if do_resume() then (ENew(t,[]),punion p1 (pos t)) else serror() end | [< '(POpen,p1); e = expr; s >] -> (match s with parser | [< '(PClose,p2); s >] -> expr_next (EParenthesis e, punion p1 p2) s | [< t,pt = parse_type_hint_with_pos; '(PClose,p2); s >] -> expr_next (EParenthesis (ECheckType(e,(t,pt)),punion p1 p2), punion p1 p2) s | [< '(Const (Ident "is"),p_is); t = parse_type_path; '(PClose,p2); >] -> expr_next (make_is e t (punion p1 p2) p_is) s | [< >] -> serror()) | [< '(BkOpen,p1); l = parse_array_decl; '(BkClose,p2); s >] -> expr_next (EArrayDecl l, punion p1 p2) s | [< '(Kwd Function,p1); e = parse_function p1 false; >] -> e | [< '(Unop op,p1) when is_prefix op; e = expr >] -> make_unop op e p1 | [< '(Binop OpSub,p1); e = expr >] -> make_unop Neg e p1 (*/* removed unary + : this cause too much syntax errors go unnoticed, such as "a + + 1" (missing 'b') without adding anything to the language | [< '(Binop OpAdd,p1); s >] -> (match s with parser | [< '(Const (Int i),p); e = expr_next (EConst (Int i),p) >] -> e | [< '(Const (Float f),p); e = expr_next (EConst (Float f),p) >] -> e | [< >] -> serror()) */*) | [< '(Kwd For,p); '(POpen,_); it = expr; '(PClose,_); s >] -> (try let e = secure_expr s in (EFor (it,e),punion p (pos e)) with Display e -> display (EFor (it,e),punion p (pos e))) | [< '(Kwd If,p); '(POpen,_); cond = expr; '(PClose,_); e1 = expr; s >] -> let e2 = (match s with parser | [< '(Kwd Else,_); e2 = expr; s >] -> Some e2 | [< >] -> match Stream.npeek 2 s with | [(Semicolon,_); (Kwd Else,_)] -> Stream.junk s; Stream.junk s; Some (secure_expr s) | _ -> None ) in (EIf (cond,e1,e2), punion p (match e2 with None -> pos e1 | Some e -> pos e)) | [< '(Kwd Return,p); e = popt expr >] -> (EReturn e, match e with None -> p | Some e -> punion p (pos e)) | [< '(Kwd Break,p) >] -> (EBreak,p) | [< '(Kwd Continue,p) >] -> (EContinue,p) | [< '(Kwd While,p1); '(POpen,_); cond = expr; '(PClose,_); s >] -> (try let e = secure_expr s in (EWhile (cond,e,NormalWhile),punion p1 (pos e)) with Display e -> display (EWhile (cond,e,NormalWhile),punion p1 (pos e))) | [< '(Kwd Do,p1); e = expr; '(Kwd While,_); '(POpen,_); cond = expr; '(PClose,_); s >] -> (EWhile (cond,e,DoWhile),punion p1 (pos e)) | [< '(Kwd Switch,p1); e = expr; '(BrOpen,_); cases , def = parse_switch_cases e []; '(BrClose,p2); s >] -> (ESwitch (e,cases,def),punion p1 p2) | [< '(Kwd Try,p1); e = expr; cl,p2 = parse_catches e [] (pos e) >] -> (ETry (e,cl),punion p1 p2) | [< '(IntInterval i,p1); e2 = expr >] -> make_binop OpInterval (EConst (Int i),p1) e2 | [< '(Kwd Untyped,p1); e = expr >] -> (EUntyped e,punion p1 (pos e)) | [< '(Dollar v,p); s >] -> expr_next (EConst (Ident ("$"^v)),p) s and expr_next e1 = parser | [< '(BrOpen,p1) when is_dollar_ident e1; eparam = expr; '(BrClose,p2); s >] -> (match fst e1 with | EConst(Ident n) -> expr_next (EMeta((Meta.from_string n,[],snd e1),eparam), punion p1 p2) s | _ -> assert false) | [< '(Dot,p); s >] -> if is_resuming p then display (EDisplay (e1,false),p); (match s with parser | [< '(Kwd Macro,p2) when p.pmax = p2.pmin; s >] -> expr_next (EField (e1,"macro") , punion (pos e1) p2) s | [< '(Kwd Extern,p2) when p.pmax = p2.pmin; s >] -> expr_next (EField (e1,"extern") , punion (pos e1) p2) s | [< '(Kwd New,p2) when p.pmax = p2.pmin; s >] -> expr_next (EField (e1,"new") , punion (pos e1) p2) s | [< '(Const (Ident f),p2) when p.pmax = p2.pmin; s >] -> expr_next (EField (e1,f) , punion (pos e1) p2) s | [< '(Dollar v,p2); s >] -> expr_next (EField (e1,"$"^v) , punion (pos e1) p2) s | [< '(Binop OpOr,p2) when do_resume() >] -> set_resume p; display (EDisplay (e1,false),p) (* help for debug display mode *) | [< >] -> (* turn an integer followed by a dot into a float *) match e1 with | (EConst (Int v),p2) when p2.pmax = p.pmin -> expr_next (EConst (Float (v ^ ".")),punion p p2) s | _ -> serror()) | [< '(POpen,p1); e = parse_call_params (fun el p2 -> (ECall(e1,el)),punion (pos e1) p2) p1; s >] -> expr_next e s | [< '(BkOpen,_); e2 = expr; '(BkClose,p2); s >] -> expr_next (EArray (e1,e2), punion (pos e1) p2) s | [< '(Binop OpGt,p1); s >] -> (match s with parser | [< '(Binop OpGt,p2) when p1.pmax = p2.pmin; s >] -> (match s with parser | [< '(Binop OpGt,p3) when p2.pmax = p3.pmin >] -> (match s with parser | [< '(Binop OpAssign,p4) when p3.pmax = p4.pmin; e2 = expr >] -> make_binop (OpAssignOp OpUShr) e1 e2 | [< e2 = secure_expr >] -> make_binop OpUShr e1 e2) | [< '(Binop OpAssign,p3) when p2.pmax = p3.pmin; e2 = expr >] -> make_binop (OpAssignOp OpShr) e1 e2 | [< e2 = secure_expr >] -> make_binop OpShr e1 e2) | [< '(Binop OpAssign,p2) when p1.pmax = p2.pmin; s >] -> make_binop OpGte e1 (secure_expr s) | [< e2 = secure_expr >] -> make_binop OpGt e1 e2) | [< '(Binop op,_); s >] -> (try (match s with parser | [< e2 = expr >] -> make_binop op e1 e2 | [< >] -> serror()) with Display e2 -> raise (Display (make_binop op e1 e2))) | [< '(Unop op,p) when is_postfix e1 op; s >] -> expr_next (EUnop (op,Postfix,e1), punion (pos e1) p) s | [< '(Question,_); e2 = expr; '(DblDot,_); e3 = expr >] -> (ETernary (e1,e2,e3),punion (pos e1) (pos e3)) | [< '(Kwd In,_); e2 = expr >] -> (EIn (e1,e2), punion (pos e1) (pos e2)) | [< >] -> e1 and parse_guard = parser | [< '(Kwd If,p1); '(POpen,_); e = expr; '(PClose,_); >] -> e and parse_switch_cases eswitch cases = parser | [< '(Kwd Default,p1); '(DblDot,_); s >] -> let b,p2 = (try block_with_pos [] p1 s with Display e -> display (ESwitch (eswitch,cases,Some (Some e,punion p1 (pos e))),punion (pos eswitch) (pos e))) in let b = match b with | [] -> None,p1 | _ -> let p = punion p1 p2 in Some ((EBlock b,p)),p in let l , def = parse_switch_cases eswitch cases s in (match def with None -> () | Some _ -> error Duplicate_default p1); l , Some b | [< '(Kwd Case,p1); el = psep Comma expr; eg = popt parse_guard; '(DblDot,_); s >] -> (match el with | [] -> error (Custom "case without a pattern is not allowed") p1 | _ -> let b,p2 = (try block_with_pos [] p1 s with Display e -> display (ESwitch (eswitch,List.rev ((el,eg,Some e,punion p1 (pos e)) :: cases),None),punion (pos eswitch) (pos e))) in let b,p = match b with | [] -> let p2 = match eg with Some e -> pos e | None -> match List.rev el with (_,p) :: _ -> p | [] -> p1 in None,punion p1 p2 | _ -> let p = punion p1 p2 in Some ((EBlock b,p)),p in parse_switch_cases eswitch ((el,eg,b,p) :: cases) s ) | [< >] -> List.rev cases , None and parse_catch etry = parser | [< '(Kwd Catch,p); '(POpen,_); name, pn = dollar_ident; s >] -> match s with parser | [< t,pt = parse_type_hint_with_pos; '(PClose,_); s >] -> (try let e = secure_expr s in ((name,pn),(t,pt),e,punion p (pos e)),(pos e) with Display e -> display (ETry (etry,[(name,pn),(t,pt),e,(pos e)]),punion (pos etry) (pos e))) | [< '(_,p) >] -> error Missing_type p and parse_catches etry catches pmax = parser | [< (catch,pmax) = parse_catch etry; s >] -> parse_catches etry (catch :: catches) pmax s | [< >] -> List.rev catches,pmax and parse_call_params f p1 s = let make_display_call el p2 = let e = f el p2 in display (EDisplay(e,true),pos e) in if is_resuming p1 then make_display_call [] p1; let rec parse_next_param acc p1 = let e = try expr s with | Stream.Error _ | Stream.Failure as exc -> let p2 = pos (next_token s) in if encloses_resume (punion p1 p2) then make_display_call (List.rev acc) p2 else raise exc | Display e -> display (f (List.rev (e :: acc)) (pos e)) in match s with parser | [< '(PClose,p2) >] -> f (List.rev (e :: acc)) p2 | [< '(Comma,p2) >] -> parse_next_param (e :: acc) p2 | [< '(Semicolon,p2) >] -> if encloses_resume (punion p1 p2) then make_display_call (List.rev acc) p2 else serror() | [< >] -> let p2 = pos (next_token s) in if encloses_resume (punion p1 p2) then make_display_call (List.rev (e :: acc)) p2 else serror() in match s with parser | [< '(PClose,p2) >] -> f [] p2 | [< '(Binop OpOr,p2) when do_resume() >] -> set_resume p1; make_display_call [] p2 | [< >] -> parse_next_param [] p1 and parse_macro_cond allow_op s = match s with parser | [< '(Const (Ident t),p) >] -> parse_macro_ident allow_op t p s | [< '(Const (String s),p) >] -> None, (EConst (String s),p) | [< '(Const (Int i),p) >] -> None, (EConst (Int i),p) | [< '(Const (Float f),p) >] -> None, (EConst (Float f),p) | [< '(Kwd k,p) >] -> parse_macro_ident allow_op (s_keyword k) p s | [< '(POpen, p1); _,e = parse_macro_cond true; '(PClose, p2) >] -> let e = (EParenthesis e,punion p1 p2) in if allow_op then parse_macro_op e s else None, e | [< '(Unop op,p); tk, e = parse_macro_cond allow_op >] -> tk, make_unop op e p and parse_macro_ident allow_op t p s = if t = "display" then Hashtbl.replace special_identifier_files (Path.unique_full_path p.pfile) t; let e = (EConst (Ident t),p) in if not allow_op then None, e else parse_macro_op e s and parse_macro_op e s = match Stream.peek s with | Some (Binop op,_) -> Stream.junk s; let op = match Stream.peek s with | Some (Binop OpAssign,_) when op = OpGt -> Stream.junk s; OpGte | _ -> op in let tk, e2 = (try parse_macro_cond true s with Stream.Failure -> serror()) in tk, make_binop op e e2 | tk -> tk, e and toplevel_expr s = try expr s with Display e -> e and secure_expr s = match s with parser | [< e = expr >] -> e | [< >] -> serror() (* eval *) type small_type = | TNull | TBool of bool | TFloat of float | TString of string let is_true = function | TBool false | TNull | TFloat 0. | TString "" -> false | _ -> true let cmp v1 v2 = match v1, v2 with | TNull, TNull -> 0 | TFloat a, TFloat b -> compare a b | TString a, TString b -> compare a b | TBool a, TBool b -> compare a b | TString a, TFloat b -> compare (float_of_string a) b | TFloat a, TString b -> compare a (float_of_string b) | _ -> raise Exit (* always false *) let rec eval ctx (e,p) = match e with | EConst (Ident i) -> (try TString (Common.raw_defined_value ctx i) with Not_found -> TNull) | EConst (String s) -> TString s | EConst (Int i) -> TFloat (float_of_string i) | EConst (Float f) -> TFloat (float_of_string f) | EBinop (OpBoolAnd, e1, e2) -> TBool (is_true (eval ctx e1) && is_true (eval ctx e2)) | EBinop (OpBoolOr, e1, e2) -> TBool (is_true (eval ctx e1) || is_true(eval ctx e2)) | EUnop (Not, _, e) -> TBool (not (is_true (eval ctx e))) | EParenthesis e -> eval ctx e | EBinop (op, e1, e2) -> let v1 = eval ctx e1 in let v2 = eval ctx e2 in let compare op = TBool (try op (cmp v1 v2) 0 with _ -> false) in (match op with | OpEq -> compare (=) | OpNotEq -> compare (<>) | OpGt -> compare (>) | OpGte -> compare (>=) | OpLt -> compare (<) | OpLte -> compare (<=) | _ -> error (Custom "Unsupported operation") p) | _ -> error (Custom "Invalid condition expression") p (* parse main *) let parse ctx code = let old = Lexer.save() in let old_cache = !cache in let mstack = ref [] in cache := DynArray.create(); last_doc := None; in_macro := Common.defined ctx Common.Define.Macro; Lexer.skip_header code; let sraw = Stream.from (fun _ -> Some (Lexer.token code)) in let rec next_token() = process_token (Lexer.token code) and process_token tk = match fst tk with | Comment s -> let tk = next_token() in if !use_doc then begin let l = String.length s in if l > 0 && s.[0] = '*' then last_doc := Some (String.sub s 1 (l - (if l > 1 && s.[l-1] = '*' then 2 else 1)), (snd tk).pmin); end; tk | CommentLine s -> next_token() | Sharp "end" -> (match !mstack with | [] -> tk | _ :: l -> mstack := l; next_token()) | Sharp "else" | Sharp "elseif" -> (match !mstack with | [] -> tk | _ :: l -> mstack := l; process_token (skip_tokens (snd tk) false)) | Sharp "if" -> process_token (enter_macro (snd tk)) | Sharp "error" -> (match Lexer.token code with | (Const (String s),p) -> error (Custom s) p | _ -> error Unimplemented (snd tk)) | Sharp "line" -> let line = (match next_token() with | (Const (Int s),p) -> (try int_of_string s with _ -> error (Custom ("Could not parse ridiculous line number " ^ s)) p) | (t,p) -> error (Unexpected t) p ) in !(Lexer.cur).Lexer.lline <- line - 1; next_token(); | _ -> tk and enter_macro p = let tk, e = parse_macro_cond false sraw in let tk = (match tk with None -> Lexer.token code | Some tk -> tk) in if is_true (eval ctx e) || (match fst e with EConst (Ident "macro") when Path.unique_full_path p.pfile = (!resume_display).pfile -> true | _ -> false) then begin mstack := p :: !mstack; tk end else skip_tokens_loop p true tk and skip_tokens_loop p test tk = match fst tk with | Sharp "end" -> Lexer.token code | Sharp "elseif" | Sharp "else" when not test -> skip_tokens p test | Sharp "else" -> mstack := snd tk :: !mstack; Lexer.token code | Sharp "elseif" -> enter_macro (snd tk) | Sharp "if" -> skip_tokens_loop p test (skip_tokens p false) | Eof -> if do_resume() then tk else error Unclosed_macro p | _ -> skip_tokens p test and skip_tokens p test = skip_tokens_loop p test (Lexer.token code) in let s = Stream.from (fun _ -> let t = next_token() in DynArray.add (!cache) t; Some t ) in try let l = parse_file s in (match !mstack with p :: _ when not (do_resume()) -> error Unclosed_macro p | _ -> ()); cache := old_cache; Lexer.restore old; l with | Stream.Error _ | Stream.Failure -> let last = (match Stream.peek s with None -> last_token s | Some t -> t) in Lexer.restore old; cache := old_cache; error (Unexpected (fst last)) (pos last) | e -> Lexer.restore old; cache := old_cache; raise e let parse_string com s p error inlined = let old = Lexer.save() in let old_file = (try Some (Hashtbl.find Lexer.all_files p.pfile) with Not_found -> None) in let old_display = !resume_display in let old_de = !display_error in let restore() = (match old_file with | None -> () | Some f -> Hashtbl.replace Lexer.all_files p.pfile f); if not inlined then resume_display := old_display; Lexer.restore old; display_error := old_de in Lexer.init p.pfile true; display_error := (fun e p -> raise (Error (e,p))); if not inlined then resume_display := null_pos; let pack, decls = try parse com (Lexing.from_string s) with Error (e,pe) -> restore(); error (error_msg e) (if inlined then pe else p) | Lexer.Error (e,pe) -> restore(); error (Lexer.error_msg e) (if inlined then pe else p) in restore(); pack,decls let parse_expr_string com s p error inl = let head = "class X{static function main() " in let head = (if p.pmin > String.length head then head ^ String.make (p.pmin - String.length head) ' ' else head) in let rec loop e = let e = Ast.map_expr loop e in (fst e,p) in match parse_string com (head ^ s ^ ";}") p error inl with | _,[EClass { d_data = [{ cff_name = "main",null_pos; cff_kind = FFun { f_expr = Some e } }]},_] -> if inl then e else loop e | _ -> raise Exit haxe_3.4.4.orig/src/typing/abstract.ml0000664000175000017500000000403213166552354017651 0ustar andyandy00000000000000open Meta open Type open Error let find_to ab pl b = if follow b == t_dynamic then List.find (fun (t,_) -> follow t == t_dynamic) ab.a_to_field else if List.exists (unify_to ab pl ~allow_transitive_cast:false b) ab.a_to then raise Not_found (* legacy compatibility *) else List.find (unify_to_field ab pl b) ab.a_to_field let find_from ab pl a b = if follow a == t_dynamic then List.find (fun (t,_) -> follow t == t_dynamic) ab.a_from_field else if List.exists (unify_from ab pl a ~allow_transitive_cast:false b) ab.a_from then raise Not_found (* legacy compatibility *) else List.find (unify_from_field ab pl a b) ab.a_from_field let underlying_type_stack = ref [] let rec get_underlying_type a pl = let maybe_recurse t = underlying_type_stack := (TAbstract(a,pl)) :: !underlying_type_stack; let rec loop t = match t with | TMono r -> (match !r with | Some t -> loop t | _ -> t) | TLazy f -> loop (!f()) | TType({t_path=([],"Null")} as tn,[t1]) -> TType(tn,[loop t1]) | TType (t,tl) -> loop (apply_params t.t_params tl t.t_type) | TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> if List.exists (fast_eq t) !underlying_type_stack then begin let pctx = print_context() in let s = String.concat " -> " (List.map (fun t -> s_type pctx t) (List.rev (t :: !underlying_type_stack))) in underlying_type_stack := []; error ("Abstract chain detected: " ^ s) a.a_pos end; get_underlying_type a tl | _ -> t in let t = loop t in underlying_type_stack := List.tl !underlying_type_stack; t in try if not (Meta.has Meta.MultiType a.a_meta) then raise Not_found; let m = mk_mono() in let _ = find_to a pl m in maybe_recurse (follow m) with Not_found -> if Meta.has Meta.CoreType a.a_meta then t_dynamic else maybe_recurse (apply_params a.a_params pl a.a_this) let rec follow_with_abstracts t = match follow t with | TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> follow_with_abstracts (get_underlying_type a tl) | t -> thaxe_3.4.4.orig/src/typing/error.ml0000664000175000017500000000662013166552354017204 0ustar andyandy00000000000000open Globals open Type type call_error = | Not_enough_arguments of (string * bool * t) list | Too_many_arguments | Could_not_unify of error_msg | Cannot_skip_non_nullable of string and error_msg = | Module_not_found of path | Type_not_found of path * string | Unify of unify_error list | Custom of string | Unknown_ident of string | Stack of error_msg * error_msg | Call_error of call_error | No_constructor of module_type exception Fatal_error of string * Globals.pos exception Error of error_msg * Globals.pos let string_source t = match follow t with | TInst(c,_) -> List.map (fun cf -> cf.cf_name) c.cl_ordered_fields | TAnon a -> PMap.fold (fun cf acc -> cf.cf_name :: acc) a.a_fields [] | TAbstract({a_impl = Some c},_) -> List.map (fun cf -> cf.cf_name) c.cl_ordered_statics | _ -> [] let short_type ctx t = let tstr = s_type ctx t in if String.length tstr > 150 then String.sub tstr 0 147 ^ "..." else tstr let unify_error_msg ctx = function | Cannot_unify (t1,t2) -> s_type ctx t1 ^ " should be " ^ s_type ctx t2 | Invalid_field_type s -> "Invalid type for field " ^ s ^ " :" | Has_no_field (t,n) -> StringError.string_error n (string_source t) (short_type ctx t ^ " has no field " ^ n) | Has_no_runtime_field (t,n) -> s_type ctx t ^ "." ^ n ^ " is not accessible at runtime" | Has_extra_field (t,n) -> short_type ctx t ^ " has extra field " ^ n | Invalid_kind (f,a,b) -> (match a, b with | Var va, Var vb -> let name, stra, strb = if va.v_read = vb.v_read then "setter", s_access false va.v_write, s_access false vb.v_write else if va.v_write = vb.v_write then "getter", s_access true va.v_read, s_access true vb.v_read else "access", "(" ^ s_access true va.v_read ^ "," ^ s_access false va.v_write ^ ")", "(" ^ s_access true vb.v_read ^ "," ^ s_access false vb.v_write ^ ")" in "Inconsistent " ^ name ^ " for field " ^ f ^ " : " ^ stra ^ " should be " ^ strb | _ -> "Field " ^ f ^ " is " ^ s_kind a ^ " but should be " ^ s_kind b) | Invalid_visibility n -> "The field " ^ n ^ " is not public" | Not_matching_optional n -> "Optional attribute of parameter " ^ n ^ " differs" | Cant_force_optional -> "Optional parameters can't be forced" | Invariant_parameter _ -> "Type parameters are invariant" | Constraint_failure name -> "Constraint check failure for " ^ name | Missing_overload (cf, t) -> cf.cf_name ^ " has no overload for " ^ s_type ctx t | Unify_custom msg -> msg let rec error_msg = function | Module_not_found m -> "Type not found : " ^ s_type_path m | Type_not_found (m,t) -> "Module " ^ s_type_path m ^ " does not define type " ^ t | Unify l -> let ctx = print_context() in String.concat "\n" (List.map (unify_error_msg ctx) l) | Unknown_ident s -> "Unknown identifier : " ^ s | Custom s -> s | Stack (m1,m2) -> error_msg m1 ^ "\n" ^ error_msg m2 | Call_error err -> s_call_error err | No_constructor mt -> (s_type_path (t_infos mt).mt_path ^ " does not have a constructor") and s_call_error = function | Not_enough_arguments tl -> let pctx = print_context() in "Not enough arguments, expected " ^ (String.concat ", " (List.map (fun (n,_,t) -> n ^ ":" ^ (short_type pctx t)) tl)) | Too_many_arguments -> "Too many arguments" | Could_not_unify err -> error_msg err | Cannot_skip_non_nullable s -> "Cannot skip non-nullable argument " ^ s let error msg p = raise (Error (Custom msg,p)) let raise_error err p = raise (Error(err,p))haxe_3.4.4.orig/src/typing/matcher.ml0000664000175000017500000014155113166552354017501 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open Ast open Type open Common open Error exception Internal_match_failure let s_type = s_type (print_context()) let s_expr_pretty = s_expr_pretty false "" false s_type let fake_tuple_type = TInst(mk_class null_module ([],"-Tuple") null_pos null_pos, []) let tuple_type tl = tfun tl fake_tuple_type let make_offset_list left right middle other = (ExtList.List.make left other) @ [middle] @ (ExtList.List.make right other) let type_field_access ctx ?(resume=false) e name = Typer.acc_get ctx (Typer.type_field ~resume ctx e name e.epos Typer.MGet) e.epos let unapply_type_parameters params monos = List.iter2 (fun (_,t1) t2 -> match t2,follow t2 with TMono m1,TMono m2 when m1 == m2 -> Type.unify t1 t2 | _ -> ()) params monos let get_general_module_type ctx mt p = let rec loop = function | TClassDecl _ -> "Class" | TEnumDecl _ -> "Enum" | TAbstractDecl a when Meta.has Meta.RuntimeValue a.a_meta -> "Class" | TTypeDecl t -> begin match follow (monomorphs t.t_params t.t_type) with | TInst(c,_) -> loop (TClassDecl c) | TEnum(en,_) -> loop (TEnumDecl en) | TAbstract(a,_) -> loop (TAbstractDecl a) | _ -> error "Cannot use this type as a value" p end | _ -> error "Cannot use this type as a value" p in Typeload.load_instance ctx ({tname=loop mt;tpackage=[];tsub=None;tparams=[]},null_pos) true p module Constructor = struct type t = | ConConst of tconstant | ConEnum of tenum * tenum_field | ConStatic of tclass * tclass_field | ConTypeExpr of module_type | ConFields of string list | ConArray of int let to_string con = match con with | ConConst ct -> s_const ct | ConEnum(en,ef) -> ef.ef_name | ConStatic(c,cf) -> Printf.sprintf "%s.%s" (s_type_path (match c.cl_kind with KAbstractImpl a -> a.a_path | _ -> c.cl_path)) cf.cf_name | ConTypeExpr mt -> s_type_path (t_infos mt).mt_path | ConFields fields -> Printf.sprintf "{ %s }" (String.concat ", " fields) | ConArray i -> Printf.sprintf "" i let equal con1 con2 = match con1,con2 with | ConConst ct1,ConConst ct2 -> ct1 = ct2 | ConEnum(en1,ef1),ConEnum(en2,ef2) -> en1 == en2 && ef1 == ef2 | ConStatic(c1,cf1),ConStatic(c2,cf2) -> c1 == c2 && cf1 == cf2 | ConTypeExpr mt1,ConTypeExpr mt2 -> mt1 == mt2 | ConFields _,ConFields _ -> true | ConArray i1,ConArray i2 -> i1 = i2 | _ -> false let arity con = match con with | ConEnum (_,{ef_type = TFun(args,_)}) -> List.length args | ConEnum _ -> 0 | ConConst _ -> 0 | ConFields fields -> List.length fields | ConArray i -> i | ConTypeExpr _ -> 0 | ConStatic _ -> 0 let compare con1 con2 = match con1,con2 with | ConConst ct1,ConConst ct2 -> compare ct1 ct2 | ConEnum(en1,ef1),ConEnum(en2,ef2) -> compare ef1.ef_index ef2.ef_index | ConStatic(c1,cf1),ConStatic(c2,cf2) -> compare cf1.cf_name cf2.cf_name | ConTypeExpr mt1,ConTypeExpr mt2 -> compare (t_infos mt1).mt_path (t_infos mt2).mt_path | ConFields _,ConFields _ -> 0 | ConArray i1,ConArray i2 -> i1 - i2 | _ -> -1 (* Could assert... *) open Typecore let to_texpr ctx match_debug p con = match con with | ConEnum(en,ef) -> if Meta.has Meta.FakeEnum en.e_meta then begin let e_mt = !type_module_type_ref ctx (TEnumDecl en) None p in mk (TField(e_mt,FEnum(en,ef))) ef.ef_type p end else if match_debug then mk (TConst (TString ef.ef_name)) ctx.t.tstring p else mk (TConst (TInt (Int32.of_int ef.ef_index))) ctx.t.tint p | ConConst ct -> Codegen.ExprBuilder.make_const_texpr ctx.com ct p | ConArray i -> Codegen.ExprBuilder.make_int ctx.com i p | ConTypeExpr mt -> Typer.type_module_type ctx mt None p | ConStatic(c,cf) -> Codegen.ExprBuilder.make_static_field c cf p | ConFields _ -> error "Something went wrong" p let hash = Hashtbl.hash end module Pattern = struct open Typecore open Constructor type t = | PatConstructor of Constructor.t * pattern list | PatVariable of tvar | PatAny | PatBind of tvar * pattern | PatOr of pattern * pattern | PatTuple of pattern list | PatExtractor of tvar * texpr * pattern and pattern = t * pos type pattern_context = { ctx : typer; or_locals : (string, tvar * pos) PMap.t option; mutable current_locals : (string, tvar * pos) PMap.t; mutable in_reification : bool; } exception Bad_pattern of string let rec to_string pat = match fst pat with | PatConstructor(con,patterns) -> Printf.sprintf "%s(%s)" (Constructor.to_string con) (String.concat ", " (List.map to_string patterns)) | PatVariable v -> Printf.sprintf "%s<%i>" v.v_name v.v_id | PatAny -> "_" | PatBind(v,pat1) -> Printf.sprintf "%s = %s" v.v_name (to_string pat1) | PatOr(pat1,pat2) -> Printf.sprintf "(%s) | (%s)" (to_string pat1) (to_string pat2) | PatTuple pl -> Printf.sprintf "[%s]" (String.concat ", " (List.map to_string pl)) | PatExtractor(v,e,pat1) -> Printf.sprintf "%s => %s" (s_expr_pretty e) (to_string pat1) let unify_type_pattern ctx mt t p = let tcl = get_general_module_type ctx mt p in match tcl with | TAbstract(a,_) -> unify ctx (TAbstract(a,[mk_mono()])) t p | _ -> assert false let rec make pctx t e = let ctx = pctx.ctx in let p = pos e in let fail () = error ("Unrecognized pattern: " ^ (Ast.s_expr e)) p in let unify_expected t' = unify ctx t' t p in let verror name p = error (Printf.sprintf "Variable %s must appear exactly once in each sub-pattern" name) p in let add_local name p = let is_wildcard_local = name = "_" in if not is_wildcard_local && PMap.mem name pctx.current_locals then error (Printf.sprintf "Variable %s is bound multiple times" name) p; match pctx.or_locals with | Some map when not is_wildcard_local -> let v,p = try PMap.find name map with Not_found -> verror name p in unify ctx t v.v_type p; pctx.current_locals <- PMap.add name (v,p) pctx.current_locals; v | _ -> let v = alloc_var name t p in pctx.current_locals <- PMap.add name (v,p) pctx.current_locals; ctx.locals <- PMap.add name v ctx.locals; v in let check_expr e = let rec loop e = match e.eexpr with | TField(_,FEnum(en,ef)) -> (* Let the unification afterwards fail so we don't recover. *) (* (match follow ef.ef_type with TFun _ -> raise Exit | _ -> ()); *) PatConstructor(ConEnum(en,ef),[]) | TField(_,FStatic(c,({cf_kind = Var {v_write = AccNever}} as cf))) -> PatConstructor(ConStatic(c,cf),[]) | TConst ct -> PatConstructor(ConConst ct,[]) | TCast(e1,None) -> loop e1 | TField _ -> raise (Bad_pattern "Only inline or read-only (default, never) fields can be used as a pattern") | _ -> raise Exit in loop e in let try_typing e = let old = ctx.untyped in ctx.untyped <- true; let e = try type_expr ctx e (WithType t) with exc -> ctx.untyped <- old; raise exc in ctx.untyped <- old; match e.eexpr with | TTypeExpr mt -> unify_type_pattern ctx mt t e.epos; PatConstructor(ConTypeExpr mt,[]) | _ -> let pat = check_expr e in begin try Type.unify e.etype t with (Unify_error l) -> (* Hack: Allow matching the underlying type against its abstract. *) begin match follow e.etype with | TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) && type_iseq t (Abstract.get_underlying_type a tl) -> () | _ -> raise_or_display ctx l p end end; pat in let handle_ident s p = let save = let old = ctx.locals in ctx.locals <- (try PMap.add "this" (PMap.find "this" old) PMap.empty with Not_found -> PMap.empty); (fun () -> ctx.locals <- old; ) in try let pat = try_typing (EConst (Ident s),p) in save(); pat with | Exit | Bad_pattern _ -> begin try let mt = module_type_of_type t in let e_mt = Typer.type_module_type ctx mt None p in let e = type_field_access ctx ~resume:true e_mt s in let pat = check_expr e in save(); pat with _ -> save(); if not (is_lower_ident s) && (match s.[0] with '`' | '_' -> false | _ -> true) then begin display_error ctx "Capture variables must be lower-case" p; end; let v = add_local s p in PatVariable v end | exc -> save(); raise exc in let rec loop e = match fst e with | EParenthesis e1 | ECast(e1,None) -> loop e1 | ECheckType(e, (CTPath({tpackage=["haxe";"macro"]; tname="Expr"}),_)) -> let old = pctx.in_reification in pctx.in_reification <- true; let e = loop e in pctx.in_reification <- old; e | EConst((Ident ("false" | "true") | Int _ | String _ | Float _) as ct) -> let e = Codegen.type_constant ctx.com ct p in unify_expected e.etype; let ct = match e.eexpr with TConst ct -> ct | _ -> assert false in PatConstructor(ConConst ct,[]) | EConst (Ident i) -> begin match i with | "_" -> begin match follow t with | TFun(ta,tr) when tr == fake_tuple_type -> PatTuple(List.map (fun (_,_,t) -> (PatAny,pos e)) ta) | _ -> PatAny end | _ -> handle_ident i (pos e) end | EVars([(s,p),None,None]) -> let v = add_local s p in PatVariable v | ECall(e1,el) -> let t = tfun (List.map (fun _ -> mk_mono()) el) t in let e1 = type_expr ctx e1 (WithType t) in begin match e1.eexpr,follow e1.etype with | TField(_, FEnum(en,ef)),TFun(_,TEnum(_,tl)) -> let monos = List.map (fun _ -> mk_mono()) ef.ef_params in let map t = apply_params en.e_params tl (apply_params ef.ef_params monos t) in (* We cannot use e1.etype here because it has applied type parameters (issue #1310). *) let args = match follow (map ef.ef_type) with | TFun(args,r) -> unify_expected r; args | _ -> assert false in let rec loop el tl = match el,tl with | [EConst (Ident "_"),p],(_,_,t) :: tl -> (* Allow using final _ to match "multiple" arguments *) (PatAny,p) :: (match tl with [] -> [] | _ -> loop el tl) | e :: el,(_,_,t) :: tl -> make pctx t e :: loop el tl | [],(_,true,t) :: tl -> (PatAny,pos e) :: loop [] tl | [],[] -> [] | [],_ -> error "Not enough arguments" p | _,[] -> error "Too many arguments" p in let patterns = loop el args in (* We want to change the original monomorphs back to type parameters, but we don't want to do that if they are bound to other monomorphs (issue #4578). *) unapply_type_parameters ef.ef_params monos; PatConstructor(ConEnum(en,ef),patterns) | _ -> fail() end | EField _ -> begin try try_typing e with | Exit -> fail() | Bad_pattern s -> error s p end | EArrayDecl el -> begin match follow t with | TFun(tl,tr) when tr == fake_tuple_type -> let rec loop el tl = match el,tl with | e :: el,(_,_,t) :: tl -> let pat = make pctx t e in pat :: loop el tl | [],[] -> [] | [],_ -> error "Not enough arguments" p | (_,p) :: _,[] -> error "Too many arguments" p in let patterns = loop el tl in PatTuple patterns | TInst({cl_path=[],"Array"},[t2]) | (TDynamic _ as t2) -> let patterns = ExtList.List.mapi (fun i e -> make pctx t2 e ) el in PatConstructor(ConArray (List.length patterns),patterns) | _ -> fail() end | EObjectDecl fl -> let known_fields = match follow t with | TAnon an -> PMap.fold (fun cf acc -> (cf,cf.cf_type) :: acc) an.a_fields [] | TInst(c,tl) -> let rec loop fields c tl = let fields = List.fold_left (fun acc cf -> (cf,apply_params c.cl_params tl cf.cf_type) :: acc) fields c.cl_ordered_fields in match c.cl_super with | None -> fields | Some (csup,tlsup) -> loop fields csup (List.map (apply_params c.cl_params tl) tlsup) in loop [] c tl | TAbstract({a_impl = Some c} as a,tl) -> let fields = List.fold_left (fun acc cf -> if Meta.has Meta.Impl cf.cf_meta then (cf,apply_params a.a_params tl cf.cf_type) :: acc else acc ) [] c.cl_ordered_statics in fields | _ -> error (Printf.sprintf "Cannot field-match against %s" (s_type t)) (pos e) in let is_matchable cf = match cf.cf_kind with Method _ -> false | _ -> true in let patterns,fields = List.fold_left (fun (patterns,fields) (cf,t) -> try if pctx.in_reification && cf.cf_name = "pos" then raise Not_found; let e1 = Expr.field_assoc cf.cf_name fl in make pctx t e1 :: patterns,cf.cf_name :: fields with Not_found -> if is_matchable cf then (PatAny,cf.cf_pos) :: patterns,cf.cf_name :: fields else patterns,fields ) ([],[]) known_fields in List.iter (fun ((s,_),e) -> if not (List.mem s fields) then error (Printf.sprintf "%s has no field %s" (s_type t) s) (pos e)) fl; PatConstructor(ConFields fields,patterns) | EBinop(OpOr,e1,e2) -> let pctx1 = {pctx with current_locals = PMap.empty} in let pat1 = make pctx1 t e1 in let pctx2 = {pctx with current_locals = PMap.empty; or_locals = Some (pctx1.current_locals)} in let pat2 = make pctx2 t e2 in PMap.iter (fun name (v,p) -> if not (PMap.mem name pctx2.current_locals) then verror name p; pctx.current_locals <- PMap.add name (v,p) pctx.current_locals ) pctx1.current_locals; PatOr(pat1,pat2) | EBinop(OpAssign,(EConst (Ident s),p),e2) -> let pat = make pctx t e2 in let v = add_local s p in PatBind(v,pat) | EBinop(OpArrow,e1,e2) -> let v = add_local "_" null_pos in let e1 = type_expr ctx e1 Value in v.v_name <- "tmp"; let pat = make pctx e1.etype e2 in PatExtractor(v,e1,pat) | EDisplay(e,iscall) -> let pat = loop e in let _ = if iscall then Typer.handle_signature_display ctx e (WithType t) else Typer.handle_display ctx e (WithType t) in pat | _ -> fail() in let pat = loop e in pat,p let make ctx t e = let pctx = { ctx = ctx; current_locals = PMap.empty; or_locals = None; in_reification = false; } in make pctx t e end module Case = struct open Typecore type t = { case_guard : texpr option; case_expr : texpr option; case_pos : pos; } let make ctx t el eg eo_ast with_type p = let rec collapse_case el = match el with | e :: [] -> e | e :: el -> let e2 = collapse_case el in EBinop(OpOr,e,e2),punion (pos e) (pos e2) | [] -> assert false in let e = collapse_case el in let monos = List.map (fun _ -> mk_mono()) ctx.type_params in let map = apply_params ctx.type_params monos in let save = save_locals ctx in let old_types = PMap.fold (fun v acc -> let t_old = v.v_type in v.v_type <- map v.v_type; (v,t_old) :: acc ) ctx.locals [] in let old_ret = ctx.ret in ctx.ret <- map ctx.ret; let pat = Pattern.make ctx (map t) e in unapply_type_parameters ctx.type_params monos; let eg = match eg with | None -> None | Some e -> Some (type_expr ctx e Value) in let eo = match eo_ast,with_type with | None,WithType t -> unify ctx ctx.t.tvoid t (pos e); None | None,_ -> None | Some e,WithType t -> let e = type_expr ctx e (WithType (map t)) in let e = AbstractCast.cast_or_unify ctx (map t) e e.epos in Some e | Some e,_ -> let e = type_expr ctx e with_type in Some e in ctx.ret <- old_ret; List.iter (fun (v,t) -> v.v_type <- t) old_types; save(); if ctx.is_display_file && Display.is_display_position p then begin match eo,eo_ast with | Some e,Some e_ast -> ignore(Typer.display_expr ctx e_ast e with_type p) | None,None -> ignore(Typer.display_expr ctx (EBlock [],p) (mk (TBlock []) ctx.t.tvoid p) with_type p) | _ -> assert false end; { case_guard = eg; case_expr = eo; case_pos = p; },[],pat end module Decision_tree = struct open Case type subject = texpr type type_finiteness = | Infinite (* type has inifite constructors (e.g. Int, String) *) | CompileTimeFinite (* type is considered finite only at compile-time but has inifite possible run-time values (enum abstracts) *) | RunTimeFinite (* type is truly finite (Bool, enums) *) type t = | Leaf of Case.t | Switch of subject * (Constructor.t * bool * dt) list * dt | Bind of (tvar * pos * texpr) list * dt | Guard of texpr * dt * dt | GuardNull of texpr * dt * dt | Fail and dt = { dt_t : t; dt_i : int; dt_pos : pos; mutable dt_goto_target : bool; } let s_case_expr tabs case = match case.case_expr with | None -> "" | Some e -> Type.s_expr_pretty false tabs false s_type e let rec to_string tabs dt = match dt.dt_t with | Leaf case -> s_case_expr tabs case | Switch(e,cases,dt) -> let s_case (con,b,dt) = Printf.sprintf "\n\t%scase %s%s: %s" tabs (Constructor.to_string con) (if b then "(unguarded) " else "") (to_string (tabs ^ "\t") dt) in let s_cases = String.concat "" (List.map s_case cases) in let s_default = to_string (tabs ^ "\t") dt in Printf.sprintf "switch (%s) {%s\n%s\tdefault: %s\n%s}" (Type.s_expr_pretty false tabs false s_type e) s_cases tabs s_default tabs | Bind(bl,dt) -> (String.concat "" (List.map (fun (v,_,e) -> if v.v_name = "_" then "" else Printf.sprintf "%s<%i> = %s; " v.v_name v.v_id (s_expr_pretty e)) bl)) ^ to_string tabs dt | Guard(e,dt1,dt2) -> Printf.sprintf "if (%s) {\n\t%s%s\n%s} else {\n\t%s%s\n%s}" (s_expr_pretty e) tabs (to_string (tabs ^ "\t") dt1) tabs tabs (to_string (tabs ^ "\t") dt2) tabs | GuardNull(e,dt1,dt2) -> Printf.sprintf "if (%s == null) {\n\t%s%s\n%s} else {\n\t%s%s\n%s}" (s_expr_pretty e) tabs (to_string (tabs ^ "\t") dt1) tabs tabs (to_string (tabs ^ "\t") dt2) tabs | Fail -> "" let equal_dt dt1 dt2 = dt1.dt_i = dt2.dt_i let equal dt1 dt2 = match dt1,dt2 with | Leaf case1,Leaf case2 -> case1 == case2 | Switch(subject1,cases1,dt1),Switch(subject2,cases2,dt2) -> subject1 == subject2 && safe_for_all2 (fun (con1,b1,dt1) (con2,b2,dt2) -> Constructor.equal con1 con2 && b1 = b2 && equal_dt dt1 dt2) cases1 cases2 && equal_dt dt1 dt2 | Bind(l1,dt1),Bind(l2,dt2) -> safe_for_all2 (fun (v1,_,e1) (v2,_,e2) -> v1 == v2 && e1 == e2) l1 l2 && equal_dt dt1 dt2 | Fail,Fail -> true | (Guard(e1,dt11,dt12),Guard(e2,dt21,dt22)) | (GuardNull(e1,dt11,dt12),GuardNull(e2,dt21,dt22)) -> e1 == e2 && equal_dt dt11 dt21 && equal_dt dt12 dt22 | _ -> false let hash = Hashtbl.hash end module ConTable = Hashtbl.Make(Constructor) (* Implements checks for useless patterns based on http://moscova.inria.fr/~maranget/papers/warn/index.html. *) module Useless = struct open Pattern open Constructor open Case type useless = | False | Pos of pos | True (* U part *) let specialize is_tuple con pM = let rec loop acc pM = match pM with | patterns :: pM -> begin match patterns with | (PatConstructor(con',patterns1),_) :: patterns2 when not is_tuple && Constructor.equal con con' -> loop ((patterns1 @ patterns2) :: acc) pM | (PatTuple patterns1,_) :: patterns2 when is_tuple -> loop ((patterns1 @ patterns2) :: acc) pM | (PatAny,p) :: patterns2 -> let patterns1 = ExtList.List.make (arity con) (PatAny,p) in loop ((patterns1 @ patterns2) :: acc) pM | (PatBind(_,pat1),_) :: patterns2 -> loop acc ((pat1 :: patterns2) :: pM) | _ -> loop acc pM end | [] -> List.rev acc in loop [] pM let default pM = let rec loop acc pM = match pM with | patterns :: pM -> begin match patterns with | ((PatConstructor _ | PatTuple _),_) :: _ -> loop acc pM | ((PatVariable _ | PatAny),_) :: patterns -> loop (patterns :: acc) pM | _ -> loop acc pM end | [] -> List.rev acc in loop [] pM let rec u pM q = match q,pM with | [],[] -> true | [],_ -> false | (q1 :: ql),_ -> let rec loop pat = match fst pat with | PatConstructor(con,patterns) -> let s = specialize false con pM in u s (patterns @ ql) | PatTuple patterns -> let s = specialize true (ConConst TNull) pM in u s (patterns @ ql) | (PatVariable _ | PatAny) -> let d = default pM in u d ql | PatOr(pat1,pat2) -> u pM (pat1 :: ql) || u pM (pat2 :: ql) | PatBind(_,pat1) -> loop pat1 | PatExtractor _ -> true (* ? *) in loop q1 (* U' part *) let transfer_column source target = let source,target = List.fold_left2 (fun (source,target) patterns1 patterns2 -> match patterns1 with | pat :: patterns -> patterns :: source,(pat :: patterns2) :: target | [] -> source,target ) ([],[]) source target in List.rev source,List.rev target let copy p = List.map (fun _ -> []) p let rec specialize' is_tuple con pM qM rM = let arity = arity con in let rec loop pAcc qAcc rAcc pM qM rM = match pM,qM,rM with | p1 :: pM,q1 :: qM,r1 :: rM -> let rec loop2 p1 = match p1 with | (PatConstructor(con',patterns1),_) :: patterns2 when not is_tuple && Constructor.equal con con' -> loop ((patterns1 @ patterns2) :: pAcc) (q1 :: qAcc) (r1 :: rAcc) pM qM rM | (PatTuple patterns1,_) :: patterns2 when is_tuple -> loop ((patterns1 @ patterns2) :: pAcc) (q1 :: qAcc) (r1 :: rAcc) pM qM rM | ((PatVariable _ | PatAny),p) :: patterns2 -> let patterns1 = ExtList.List.make arity (PatAny,p) in loop ((patterns1 @ patterns2) :: pAcc) (q1 :: qAcc) (r1 :: rAcc) pM qM rM | ((PatOr(pat1,pat2)),_) :: patterns2 -> loop pAcc qAcc rAcc (((pat1 :: patterns2) :: (pat2 :: patterns2) :: pM)) (q1 :: q1 :: qM) (r1 :: r1 :: rM) | (PatBind(_,pat1),_) :: patterns2 -> loop2 (pat1 :: patterns2) | _ -> loop pAcc qAcc rAcc pM qM rM in loop2 p1 | [],_,_ -> List.rev pAcc,List.rev qAcc,List.rev rAcc | _ -> assert false in loop [] [] [] pM qM rM let combine et1 et2 = match fst et1,fst et2 with | True,True -> True | False,False -> False | True,False -> Pos (pos et2) | False,True -> Pos (pos et1) | True,Pos _ -> fst et2 | Pos _,True -> fst et1 | False,Pos _ -> Pos (pos et1) | Pos _,_ -> fst et1 let rec u' pM qM rM p q r = match p with | [] -> begin match r with | [] -> if u qM q then True else False | _ -> snd (List.fold_left (fun (i,et) pat -> match fst pat with | PatOr(pat1,pat2) -> let process_row i l q = let rec loop acc k l = match l with | x :: l when i = k -> x,(List.rev acc) @ l @ q | x :: l -> loop (x :: acc) (k + 1) l | [] -> assert false in loop [] 0 l in let col,mat = List.fold_left2 (fun (col,mat) r q -> let x,l = process_row i r q in ([x] :: col,l :: mat) ) ([],[]) rM qM in let col,mat = List.rev col,List.rev mat in let _,r = process_row i r q in let et1 = u' col mat (copy mat) [pat1] r [] in let qM = (mat @ [r]) in let et2 = u' (col @ [[pat1]]) qM (copy qM) [pat2] r [] in let et3 = combine (et1,pos pat1) (et2,pos pat2) in let p = punion (pos pat1) (pos pat2) in let et = combine (et,p) (et3,p) in (i + 1,et) | _ -> assert false ) (0,True) r) end | (pat :: pl) -> let rec loop pat = match fst pat with | PatConstructor(con,patterns) -> let pM,qM,rM = specialize' false con pM qM rM in u' pM qM rM (patterns @ pl) q r | PatTuple patterns -> let pM,qM,rM = specialize' true (ConConst TNull) pM qM rM in u' pM qM rM (patterns @ pl) q r | PatAny | PatVariable _ -> let pM,qM = transfer_column pM qM in u' pM qM rM pl (pat :: q) r | PatOr _ -> let pM,rM = transfer_column pM rM in u' pM qM rM pl q (pat :: r) | PatBind(_,pat1) -> loop pat1 | PatExtractor _ -> True in loop pat (* Sane part *) let check_case com p (case,bindings,patterns) = let p = List.map (fun (_,_,patterns) -> patterns) p in match u' p (copy p) (copy p) patterns [] [] with | False -> com.warning "This case is unused" case.case_pos | Pos p -> com.warning "This pattern is unused" p | True -> () let check com cases = ignore(List.fold_left (fun acc (case,bindings,patterns) -> check_case com acc (case,bindings,patterns); if case.case_guard = None then acc @ [case,bindings,patterns] else acc ) [] cases) end module DtTable = Hashtbl.Make(Decision_tree) module Compile = struct open Typecore open Decision_tree open Case open Constructor open Pattern exception Extractor type matcher_context = { ctx : typer; dt_table : dt DtTable.t; match_pos : pos; match_debug : bool; mutable dt_count : int; } let rec hashcons mctx dt p = try DtTable.find mctx.dt_table dt with Not_found -> let dti = {dt_t = dt; dt_i = mctx.dt_count; dt_pos = p; dt_goto_target = false } in DtTable.add mctx.dt_table dt dti; mctx.dt_count <- mctx.dt_count + 1; dti let leaf mctx case = hashcons mctx (Leaf case) case.case_pos let fail mctx p = hashcons mctx Fail p let switch mctx subject cases default = hashcons mctx (Switch(subject,cases,default)) subject.epos let bind mctx bindings dt = hashcons mctx (Bind(bindings,dt)) dt.dt_pos let guard mctx e dt1 dt2 = hashcons mctx (Guard(e,dt1,dt2)) (punion dt1.dt_pos dt2.dt_pos) let guard_null mctx e dt1 dt2 = hashcons mctx (GuardNull(e,dt1,dt2)) (punion dt1.dt_pos dt2.dt_pos) let rec get_sub_subjects mctx e con = match con with | ConEnum(en,ef) -> let tl = List.map (fun _ -> mk_mono()) en.e_params in let t_en = TEnum(en,tl) in let e = if not (type_iseq t_en e.etype) then mk (TCast(e,None)) t_en e.epos else e in begin match follow ef.ef_type with | TFun(args,_) -> ExtList.List.mapi (fun i (_,_,t) -> mk (TEnumParameter(e,ef,i)) (apply_params en.e_params tl (monomorphs ef.ef_params t)) e.epos) args | _ -> [] end | ConFields sl -> List.map (type_field_access mctx.ctx e) sl | ConArray 0 -> [] | ConArray i -> let t = match follow e.etype with TInst({cl_path=[],"Array"},[t]) -> t | TDynamic _ as t -> t | _ -> assert false in ExtList.List.init i (fun i -> let ei = Codegen.ExprBuilder.make_int mctx.ctx.com i e.epos in mk (TArray(e,ei)) t e.epos ) | ConConst _ | ConTypeExpr _ | ConStatic _ -> [] let specialize subject con cases = let arity = arity con in let rec loop acc cases = match cases with | (case,bindings,patterns) :: cases -> begin match patterns with | (PatConstructor(con',patterns1),_) :: patterns2 when Constructor.equal con con' -> loop ((case,bindings,patterns1 @ patterns2) :: acc) cases | (PatVariable v,p) :: patterns2 -> let patterns1 = ExtList.List.make arity (PatAny,p) in loop ((case,((v,p,subject) :: bindings),patterns1 @ patterns2) :: acc) cases | ((PatAny,_)) as pat :: patterns2 -> let patterns1 = ExtList.List.make arity pat in loop ((case,bindings,patterns1 @ patterns2) :: acc) cases | ((PatBind(v,pat),p)) :: patterns -> loop acc ((case,((v,p,subject) :: bindings),pat :: patterns) :: cases) | _ -> loop acc cases end | [] -> List.rev acc in loop [] cases let default subject cases = let rec loop acc cases = match cases with | (case,bindings,patterns) :: cases -> begin match patterns with | (PatConstructor _,_) :: _ -> loop acc cases | (PatVariable v,p) :: patterns -> loop ((case,((v,p,subject) :: bindings),patterns) :: acc) cases | (PatAny,_) :: patterns -> loop ((case,bindings,patterns) :: acc) cases | (PatBind(v,pat),p) :: patterns -> loop acc ((case,((v,p,subject) :: bindings),pat :: patterns) :: cases) | _ -> loop acc cases end | [] -> List.rev acc in loop [] cases let rec is_wildcard_pattern pat = match fst pat with | PatVariable _ | PatAny -> true | _ -> false let rec expand cases = let changed,cases = List.fold_left (fun (changed,acc) (case,bindings,patterns) -> let rec loop f patterns = match patterns with | (PatOr(pat1,pat2),_) :: patterns -> true,(case,bindings,f pat2 :: patterns) :: (case,bindings,f pat1 :: patterns) :: acc | (PatBind(v,pat1),p) :: patterns -> loop (fun pat2 -> f (PatBind(v,pat2),p)) (pat1 :: patterns) | (PatTuple patterns1,_) :: patterns2 -> loop f (patterns1 @ patterns2) | pat :: patterns -> changed,(case,bindings,f pat :: patterns) :: acc | [] -> changed,((case,bindings,patterns) :: acc) in loop (fun pat -> pat) patterns ) (false,[]) cases in let cases = List.rev cases in if changed then expand cases else cases let s_subjects subjects = String.concat " " (List.map s_expr_pretty subjects) let s_case (case,bindings,patterns) = let s_bindings = String.concat ", " (List.map (fun (v,_,e) -> Printf.sprintf "%s<%i> = %s" v.v_name v.v_id (s_expr_pretty e)) bindings) in let s_patterns = String.concat " " (List.map Pattern.to_string patterns) in let s_expr = match case.case_expr with None -> "" | Some e -> Type.s_expr_pretty false "\t\t" false s_type e in let s_guard = match case.case_guard with None -> "" | Some e -> Type.s_expr_pretty false "\t\t" false s_type e in Printf.sprintf "\n\t\tbindings: %s\n\t\tpatterns: %s\n\t\tguard: %s\n\t\texpr: %s" s_bindings s_patterns s_guard s_expr let s_cases cases = String.concat "\n" (List.map s_case cases) let select_column subjects cases = let rec loop i patterns = match patterns with | ((PatVariable _ | PatAny | PatExtractor _),_) :: patterns -> loop (i + 1) patterns | [] -> 0 | _ -> i in let _,_,patterns = List.hd cases in let i = loop 0 patterns in let subjects,cases = if i = 0 then subjects,cases else begin let rec sort i cur acc l = match l with | x :: l -> if i = cur then x :: acc @ l else sort i (cur + 1) (x :: acc) l | [] -> acc in let subjects = sort i 0 [] subjects in let cases = List.map (fun (case,bindings,patterns) -> let patterns = sort i 0 [] patterns in case,bindings,patterns ) cases in subjects,cases end in subjects,cases let rec compile mctx subjects cases = match cases with | [] -> fail mctx (match subjects with e :: _ -> e.epos | _ -> mctx.match_pos); | (_,_,patterns) as case :: cases when List.for_all is_wildcard_pattern patterns -> compile_leaf mctx subjects case cases | _ -> let cases = expand cases in let subjects,cases = select_column subjects cases in let cases = expand cases in (* TODO: is this really necessary? *) try compile_switch mctx subjects cases with Extractor -> compile_extractors mctx subjects cases and compile_leaf mctx subjects (case,bindings,patterns) cases = if mctx.match_debug then print_endline (Printf.sprintf "compile_leaf:\n\tsubjects: %s\n\tcase: %s\n\tcases: %s" (s_subjects subjects) (s_case (case,bindings,patterns)) (s_cases cases)); let dt = leaf mctx case in let dt = match case.case_guard with | None -> dt | Some e -> let dt2 = compile mctx subjects cases in guard mctx e dt dt2 in let rec loop patterns el = match patterns,el with | [PatAny,_],_ -> [] | (PatVariable v,p) :: patterns,e :: el -> (v,p,e) :: loop patterns el | _ :: patterns,_ :: el -> loop patterns el | [],[] -> [] | [],e :: _ -> error "Invalid match: Not enough patterns" e.epos | (_,p) :: _,[] -> error "Invalid match: Too many patterns" p in let bindings = bindings @ loop patterns subjects in if bindings = [] then dt else bind mctx bindings dt and compile_switch mctx subjects cases = let subject,subjects = match subjects with | [] -> raise Internal_match_failure | subject :: subjects -> subject,subjects in let get_column_sigma cases = let sigma = ConTable.create 0 in let unguarded = ConTable.create 0 in let null = ref [] in List.iter (fun (case,bindings,patterns) -> let rec loop pat = match fst pat with | PatConstructor(ConConst TNull,_) -> null := (case,bindings,List.tl patterns) :: !null; | PatConstructor(con,_) -> if case.case_guard = None then ConTable.replace unguarded con true; ConTable.replace sigma con true; | PatBind(_,pat) -> loop pat | PatVariable _ | PatAny -> () | PatExtractor _ -> raise Extractor | _ -> error ("Unexpected pattern: " ^ (Pattern.to_string pat)) case.case_pos; in loop (List.hd patterns) ) cases; let sigma = ConTable.fold (fun con _ acc -> (con,ConTable.mem unguarded con) :: acc) sigma [] in sigma,List.rev !null in let sigma,null = get_column_sigma cases in if mctx.match_debug then print_endline (Printf.sprintf "compile_switch:\n\tsubject: %s\n\ttsubjects: %s\n\tcases: %s" (s_expr_pretty subject) (s_subjects subjects) (s_cases cases)); let switch_cases = List.map (fun (con,unguarded) -> let subjects = get_sub_subjects mctx subject con @ subjects in let spec = specialize subject con cases in let dt = compile mctx subjects spec in con,unguarded,dt ) sigma in let default = default subject cases in let switch_default = compile mctx subjects default in let dt = if switch_cases = [] then switch_default else switch mctx subject switch_cases switch_default in let null_guard dt_null = guard_null mctx subject dt_null dt in match null with | [] -> if is_explicit_null subject.etype then null_guard switch_default else dt | cases -> let dt_null = compile mctx subjects (cases @ default) in null_guard dt_null and compile_extractors mctx subjects cases = let subject,subjects = match subjects with | [] -> raise Internal_match_failure | subject :: subjects -> subject,subjects in if mctx.match_debug then print_endline (Printf.sprintf "compile_extractor:\n\tsubject: %s\n\ttsubjects: %s\n\tcases: %s" (s_expr_pretty subject) (s_subjects subjects) (s_cases cases)); let num_extractors,extractors = List.fold_left (fun (i,extractors) (_,_,patterns) -> let rec loop bindings pat = match pat with | (PatExtractor(v,e1,pat),_) -> i + 1,Some (v,e1,pat,bindings) :: extractors | (PatBind(v,pat1),_) -> loop (v :: bindings) pat1 | _ -> i,None :: extractors in loop [] (List.hd patterns) ) (0,[]) cases in let pat_any = (PatAny,null_pos) in let _,_,ex_subjects,cases,bindings = List.fold_left2 (fun (left,right,subjects,cases,ex_bindings) (case,bindings,patterns) extractor -> match extractor,patterns with | Some(v,e1,pat,vars), _ :: patterns -> let patterns = make_offset_list (left + 1) (right - 1) pat pat_any @ patterns in let rec loop e = match e.eexpr with | TLocal v' when v' == v -> subject | _ -> Type.map_expr loop e in let e1 = loop e1 in let bindings = List.map (fun v -> v,subject.epos,subject) vars @ bindings in let v,ex_bindings = try let v,_,_ = List.find (fun (_,_,e2) -> Texpr.equal e1 e2) ex_bindings in v,ex_bindings with Not_found -> let v = alloc_var "_hx_tmp" e1.etype e1.epos in v.v_meta <- (Meta.Custom ":extractorVariable",[],v.v_pos) :: v.v_meta; v,(v,e1.epos,e1) :: ex_bindings in let ev = mk (TLocal v) v.v_type e1.epos in (left + 1, right - 1,ev :: subjects,((case,bindings,patterns) :: cases),ex_bindings) | None,pat :: patterns -> let patterns = make_offset_list 0 num_extractors pat pat_any @ patterns in (left,right,subjects,((case,bindings,patterns) :: cases),ex_bindings) | _,[] -> assert false ) (0,num_extractors,[],[],[]) cases (List.rev extractors) in let dt = compile mctx ((subject :: List.rev ex_subjects) @ subjects) (List.rev cases) in bind mctx bindings dt let compile ctx match_debug subjects cases p = let mctx = { ctx = ctx; match_debug = match_debug; dt_table = DtTable.create 7; match_pos = p; dt_count = 0; } in let subjects,vars = List.fold_left (fun (subjects,vars) e -> match e.eexpr with | TConst _ | TLocal _ -> (e :: subjects,vars) | _ -> let v = gen_local ctx e.etype e.epos in let ev = mk (TLocal v) e.etype e.epos in (ev :: subjects,(v,e.epos,e) :: vars) ) ([],[]) subjects in let dt = compile mctx subjects cases in Useless.check mctx.ctx.com cases; match vars with | [] -> dt | _ -> bind mctx vars dt end module TexprConverter = struct open Typecore open Decision_tree open Constructor open Case type match_kind = | SKValue | SKEnum | SKFakeEnum | SKLength exception Not_exhaustive let s_subject s e = let rec loop s e = match e.eexpr with | TField(e1,fa) -> loop (Printf.sprintf "{ %s: %s }" (field_name fa) s) e1 | TEnumParameter(e1,ef,i) -> let arity = match follow ef.ef_type with TFun(args,_) -> List.length args | _ -> assert false in let l = make_offset_list i (arity - i - 1) s "_" in loop (Printf.sprintf "%s(%s)" ef.ef_name (String.concat ", " l)) e1 | _ -> s in loop s e let s_match_kind = function | SKValue -> "value" | SKEnum -> "enum" | SKFakeEnum -> "fakeEnum" | SKLength -> "length" let unify_constructor ctx params t con = match con with | ConEnum(en,ef) -> let t_ef = match follow ef.ef_type with TFun(_,t) -> t | _ -> ef.ef_type in let t_ef = apply_params ctx.type_params params (monomorphs en.e_params (monomorphs ef.ef_params t_ef)) in let monos = List.map (fun t -> match follow t with | TInst({cl_kind = KTypeParameter _},_) -> mk_mono() | _ -> t ) params in let rec duplicate_monos t = match follow t with | TMono _ -> mk_mono() | _ -> Type.map duplicate_monos t in let t_e = apply_params ctx.type_params monos (duplicate_monos t) in begin try Type.unify t_ef t_e; Some(con,monos) with Unify_error _ -> None end | _ -> Some(con,params) let all_ctors ctx e cases = let infer_type() = match cases with | [] -> e,e.etype,false | (con,_,_) :: _ -> let fail() = (* error "Could not determine switch kind, make sure the type is known" e.epos; *) t_dynamic in let t = match con with | ConEnum(en,_) -> TEnum(en,List.map snd en.e_params) | ConArray _ -> ctx.t.tarray t_dynamic | ConConst ct -> begin match ct with | TString _ -> ctx.t.tstring | TInt _ -> ctx.t.tint | TFloat _ -> ctx.t.tfloat | TBool _ -> ctx.t.tbool | _ -> fail() end | ConStatic({cl_kind = KAbstractImpl a},_) -> (TAbstract(a,List.map snd a.a_params)) | ConTypeExpr mt -> get_general_module_type ctx mt e.epos | ConFields _ | ConStatic _ -> fail() in mk (TCast(e,None)) t e.epos,t,true in let e,t,inferred = match follow e.etype with | TDynamic _ | TMono _ -> infer_type() | _ -> e,e.etype,false in let h = ConTable.create 0 in let add constructor = ConTable.replace h constructor true in let rec loop t = match follow t with | TAbstract({a_path = [],"Bool"},_) -> add (ConConst(TBool true)); add (ConConst(TBool false)); SKValue,RunTimeFinite | TAbstract({a_impl = Some c} as a,pl) when Meta.has Meta.Enum a.a_meta -> List.iter (fun cf -> ignore(follow cf.cf_type); if Meta.has Meta.Impl cf.cf_meta && Meta.has Meta.Enum cf.cf_meta then match cf.cf_expr with | Some {eexpr = TConst ct | TCast ({eexpr = TConst ct},None)} -> if ct != TNull then add (ConConst ct) | _ -> add (ConStatic(c,cf)) ) c.cl_ordered_statics; SKValue,CompileTimeFinite | TAbstract(a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> loop (Abstract.get_underlying_type a pl) | TInst({cl_path=[],"String"},_) | TInst({cl_kind = KTypeParameter _ },_) -> SKValue,Infinite | TInst({cl_path=[],"Array"},_) -> SKLength,Infinite | TEnum(en,pl) -> PMap.iter (fun _ ef -> add (ConEnum(en,ef))) en.e_constrs; if Meta.has Meta.FakeEnum en.e_meta then SKFakeEnum,CompileTimeFinite else SKEnum,RunTimeFinite | TAnon _ -> SKValue,CompileTimeFinite | TInst(_,_) -> SKValue,CompileTimeFinite | _ -> SKValue,Infinite in let kind,finiteness = loop t in let compatible_kind con = match con with | ConEnum _ -> kind = SKEnum || kind = SKFakeEnum | ConArray _ -> kind = SKLength | _ -> kind = SKValue in List.iter (fun (con,unguarded,dt) -> if not (compatible_kind con) then error "Incompatible pattern" dt.dt_pos; if unguarded then ConTable.remove h con ) cases; let unmatched = ConTable.fold (fun con _ acc -> con :: acc) h [] in e,unmatched,kind,finiteness let report_not_exhaustive e_subject unmatched = let sl = match follow e_subject.etype with | TAbstract({a_impl = Some c} as a,tl) when Meta.has Meta.Enum a.a_meta -> List.map (fun (con,_) -> match con with | ConConst ct1 -> let cf = List.find (fun cf -> match cf.cf_expr with | Some ({eexpr = TConst ct2 | TCast({eexpr = TConst ct2},None)}) -> ct1 = ct2 | _ -> false ) c.cl_ordered_statics in cf.cf_name | _ -> Constructor.to_string con ) unmatched | _ -> List.map (fun (con,_) -> Constructor.to_string con) unmatched in let s = match unmatched with | [] -> "_" | _ -> String.concat " | " (List.sort Pervasives.compare sl) in error (Printf.sprintf "Unmatched patterns: %s" (s_subject s e_subject)) e_subject.epos let to_texpr ctx t_switch match_debug with_type dt = let com = ctx.com in let p = dt.dt_pos in let c_type = match follow (Typeload.load_instance ctx ({ tpackage = ["std"]; tname="Type"; tparams=[]; tsub = None},null_pos) true p) with TInst(c,_) -> c | t -> assert false in let mk_index_call e = if not ctx.in_macro && not ctx.com.display.DisplayMode.dms_full_typing then (* If we are in display mode there's a chance that these fields don't exist. Let's just use a (correctly typed) neutral value because it doesn't actually matter. *) mk (TConst (TInt (Int32.of_int 0))) ctx.t.tint e.epos else let cf = PMap.find "enumIndex" c_type.cl_statics in make_static_call ctx c_type cf (fun t -> t) [e] com.basic.tint e.epos in let mk_name_call e = if not ctx.in_macro && not ctx.com.display.DisplayMode.dms_full_typing then mk (TConst (TString "")) ctx.t.tstring e.epos else let cf = PMap.find "enumConstructor" c_type.cl_statics in make_static_call ctx c_type cf (fun t -> t) [e] com.basic.tstring e.epos in let rec loop toplevel params dt = match dt.dt_t with | Leaf case -> begin match case.case_expr with | Some e -> e | None -> mk (TBlock []) ctx.t.tvoid case.case_pos end | Switch(_,[ConFields _,_,dt],_) -> (* TODO: Can we improve this by making it more general? *) loop false params dt | Switch(e_subject,cases,default) -> let e_subject,unmatched,kind,finiteness = all_ctors ctx e_subject cases in let unmatched = ExtList.List.filter_map (unify_constructor ctx params e_subject.etype) unmatched in let loop toplevel params dt = try Some (loop toplevel params dt) with Not_exhaustive -> match with_type,finiteness with | NoValue,Infinite -> None | _,CompileTimeFinite when unmatched = [] -> None | _ when ctx.com.display.DisplayMode.dms_error_policy = DisplayMode.EPIgnore -> None | _ -> report_not_exhaustive e_subject unmatched in let cases = ExtList.List.filter_map (fun (con,_,dt) -> match unify_constructor ctx params e_subject.etype con with | Some(_,params) -> Some (con,dt,params) | None -> None ) cases in let group cases = let h = DtTable.create 0 in List.iter (fun (con,dt,params) -> let l,_,_ = try DtTable.find h dt.dt_t with Not_found -> [],dt,params in DtTable.replace h dt.dt_t (con :: l,dt,params) ) cases; DtTable.fold (fun _ (cons,dt,params) acc -> (cons,dt,params) :: acc) h [] in let cases = group cases in let cases = List.sort (fun (cons1,_,_) (cons2,_,_) -> match cons1,cons2 with | (con1 :: _),con2 :: _ -> Constructor.compare con1 con2 | _ -> -1 ) cases in let e_default = match unmatched,finiteness with | [],RunTimeFinite -> None | _ -> loop false params default in let cases = ExtList.List.filter_map (fun (cons,dt,params) -> let eo = loop false params dt in begin match eo with | None -> None | Some e -> Some (List.map (Constructor.to_texpr ctx match_debug dt.dt_pos) (List.sort Constructor.compare cons),e) end ) cases in let e_subject = match kind with | SKValue | SKFakeEnum -> e_subject | SKEnum -> if match_debug then mk_name_call e_subject else mk_index_call e_subject | SKLength -> type_field_access ctx e_subject "length" in begin match cases with | [_,e2] when e_default = None && (match finiteness with RunTimeFinite -> true | _ -> false) -> e2 | [[e1],e2] when (with_type = NoValue || e_default <> None) && ctx.com.platform <> Java (* TODO: problem with TestJava.hx:285 *) -> let e_op = mk (TBinop(OpEq,e_subject,e1)) ctx.t.tbool e_subject.epos in mk (TIf(e_op,e2,e_default)) t_switch dt.dt_pos | _ -> let e_subject = match finiteness with | RunTimeFinite | CompileTimeFinite when e_default = None -> let meta = (Meta.Exhaustive,[],dt.dt_pos) in mk (TMeta(meta,e_subject)) e_subject.etype e_subject.epos | _ -> e_subject in mk (TSwitch(e_subject,cases,e_default)) t_switch dt.dt_pos end | Guard(e,dt1,dt2) -> let e_then = loop false params dt1 in begin try let e_else = loop false params dt2 in mk (TIf(e,e_then,Some e_else)) t_switch (punion e_then.epos e_else.epos) with Not_exhaustive when with_type = NoValue -> mk (TIf(e,e_then,None)) ctx.t.tvoid (punion e.epos e_then.epos) end | GuardNull(e,dt1,dt2) -> let e_null = Codegen.ExprBuilder.make_null e.etype e.epos in let f = try let e_then = loop false params dt1 in (fun () -> let e_else = loop false params dt2 in let e_op = mk (TBinop(OpEq,e,e_null)) ctx.t.tbool e.epos in mk (TIf(e_op,e_then,Some e_else)) t_switch (punion e_then.epos e_else.epos) ) with Not_exhaustive -> if toplevel then (fun () -> loop false params dt2) else if ctx.com.display.DisplayMode.dms_error_policy = DisplayMode.EPIgnore then (fun () -> mk (TConst TNull) (mk_mono()) dt2.dt_pos) else report_not_exhaustive e [ConConst TNull,dt.dt_pos] in f() | Bind(bl,dt) -> let el = List.rev_map (fun (v,p,e) -> mk (TVar(v,Some e)) com.basic.tvoid p ) bl in let e = loop toplevel params dt in mk (TBlock (el @ [e])) e.etype dt.dt_pos | Fail -> raise Not_exhaustive in let params = List.map snd ctx.type_params in let e = loop true params dt in Texpr.duplicate_tvars e end module Match = struct open Typecore let match_expr ctx e cases def with_type p = let match_debug = Meta.has (Meta.Custom ":matchDebug") ctx.curfield.cf_meta in let rec loop e = match fst e with | EArrayDecl el when (match el with [(EFor _ | EWhile _),_] -> false | _ -> true) -> let el = List.map (fun e -> type_expr ctx e Value) el in let t = tuple_type (List.map (fun e -> e.etype) el) in t,el | EParenthesis e1 -> loop e1 | _ -> let e = type_expr ctx e Value in e.etype,[e] in let t,subjects = loop e in let subjects = List.rev subjects in let cases = match def with | None -> cases | Some (eo,p) -> cases @ [[EConst (Ident "_"),p],None,eo,p] in let tmono,with_type = match with_type with | WithType t -> (match follow t with TMono _ -> Some t,Value | _ -> None,with_type) | _ -> None,with_type in let cases = List.map (fun (el,eg,eo,p) -> let case,bindings,pat = Case.make ctx t el eg eo with_type p in case,bindings,[pat] ) cases in let infer_switch_type () = match with_type with | NoValue -> mk_mono() | Value -> let el = List.map (fun (case,_,_) -> match case.Case.case_expr with Some e -> e | None -> mk (TBlock []) ctx.t.tvoid p) cases in unify_min ctx el | WithType t -> t in if match_debug then begin print_endline "CASES BEGIN"; List.iter (fun (case,_,patterns) -> print_endline (String.concat "" (List.map (Pattern.to_string) patterns)); ) cases; print_endline "CASES END"; end; let dt = Compile.compile ctx match_debug subjects cases p in if match_debug then begin print_endline "DECISION TREE BEGIN"; print_endline (Decision_tree.to_string "" dt); print_endline "DECISION TREE END"; end; let e = try let t_switch = infer_switch_type() in (match tmono with Some t -> unify ctx t_switch t p | _ -> ()); TexprConverter.to_texpr ctx t_switch match_debug with_type dt with TexprConverter.Not_exhaustive -> error "Unmatched patterns: _" p; in if match_debug then begin print_endline "TEXPR BEGIN"; print_endline (s_expr_pretty e); print_endline "TEXPR END"; end; {e with epos = p} end ;; Typecore.match_expr_ref := Match.match_exprhaxe_3.4.4.orig/src/typing/overloads.ml0000664000175000017500000002050413166552354020046 0ustar andyandy00000000000000open Type let same_overload_args ?(get_vmtype) t1 t2 f1 f2 = let get_vmtype = match get_vmtype with | None -> (fun f -> f) | Some f -> f in if List.length f1.cf_params <> List.length f2.cf_params then false else let rec follow_skip_null t = match t with | TMono r -> (match !r with | Some t -> follow_skip_null t | _ -> t) | TLazy f -> follow_skip_null (!f()) | TType ({ t_path = [],"Null" } as t, [p]) -> TType(t,[follow p]) | TType (t,tl) -> follow_skip_null (apply_params t.t_params tl t.t_type) | _ -> t in let same_arg t1 t2 = let t1 = get_vmtype (follow_skip_null t1) in let t2 = get_vmtype (follow_skip_null t2) in match t1, t2 with | TType _, TType _ -> type_iseq t1 t2 | TType _, _ | _, TType _ -> false | _ -> type_iseq t1 t2 in match follow (apply_params f1.cf_params (List.map (fun (_,t) -> t) f2.cf_params) t1), follow t2 with | TFun(a1,_), TFun(a2,_) -> (try List.for_all2 (fun (_,_,t1) (_,_,t2) -> same_arg t1 t2) a1 a2 with | Invalid_argument("List.for_all2") -> false) | _ -> assert false (** retrieves all overloads from class c and field i, as (Type.t * tclass_field) list *) let rec get_overloads c i = let ret = try let f = PMap.find i c.cl_fields in match f.cf_kind with | Var _ -> (* @:libType may generate classes that have a variable field in a superclass of an overloaded method *) [] | Method _ -> (f.cf_type, f) :: (List.map (fun f -> f.cf_type, f) f.cf_overloads) with | Not_found -> [] in let rsup = match c.cl_super with | None when c.cl_interface -> let ifaces = List.concat (List.map (fun (c,tl) -> List.map (fun (t,f) -> apply_params c.cl_params tl t, f) (get_overloads c i) ) c.cl_implements) in ret @ ifaces | None -> ret | Some (c,tl) -> ret @ ( List.map (fun (t,f) -> apply_params c.cl_params tl t, f) (get_overloads c i) ) in ret @ (List.filter (fun (t,f) -> not (List.exists (fun (t2,f2) -> same_overload_args t t2 f f2) ret)) rsup) (** Overload resolution **) module Resolution = 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 endhaxe_3.4.4.orig/src/typing/type.ml0000664000175000017500000026304413166552354017041 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Globals type path = string list * string type field_kind = | Var of var_kind | Method of method_kind and var_kind = { v_read : var_access; v_write : var_access; } and var_access = | AccNormal | AccNo (* can't be accessed outside of the class itself and its subclasses *) | AccNever (* can't be accessed, even in subclasses *) | AccResolve (* call resolve("field") when accessed *) | AccCall (* perform a method call when accessed *) | AccInline (* similar to Normal but inline when accessed *) | AccRequire of string * string option (* set when @:require(cond) fails *) and method_kind = | MethNormal | MethInline | MethDynamic | MethMacro type module_check_policy = | NoCheckFileTimeModification | CheckFileContentModification | NoCheckDependencies | NoCheckShadowing type t = | TMono of t option ref | TEnum of tenum * tparams | TInst of tclass * tparams | TType of tdef * tparams | TFun of tsignature | TAnon of tanon | TDynamic of t | TLazy of (unit -> t) ref | TAbstract of tabstract * tparams and tsignature = (string * bool * t) list * t and tparams = t list and type_params = (string * t) list and tconstant = | TInt of int32 | TFloat of string | TString of string | TBool of bool | TNull | TThis | TSuper and tvar_extra = (type_params * texpr option) option and tvar = { mutable v_id : int; mutable v_name : string; mutable v_type : t; mutable v_capture : bool; mutable v_extra : tvar_extra; mutable v_meta : metadata; v_pos : pos; } and tfunc = { tf_args : (tvar * tconstant option) list; tf_type : t; tf_expr : texpr; } and anon_status = | Closed | Opened | Const | Extend of t list | Statics of tclass | EnumStatics of tenum | AbstractStatics of tabstract and tanon = { mutable a_fields : (string, tclass_field) PMap.t; a_status : anon_status ref; } and texpr_expr = | TConst of tconstant | TLocal of tvar | TArray of texpr * texpr | TBinop of Ast.binop * texpr * texpr | TField of texpr * tfield_access | TTypeExpr of module_type | TParenthesis of texpr | TObjectDecl of (string * texpr) list | TArrayDecl of texpr list | TCall of texpr * texpr list | TNew of tclass * tparams * texpr list | TUnop of Ast.unop * Ast.unop_flag * texpr | TFunction of tfunc | TVar of tvar * texpr option | TBlock of texpr list | TFor of tvar * texpr * texpr | TIf of texpr * texpr * texpr option | TWhile of texpr * texpr * Ast.while_flag | TSwitch of texpr * (texpr list * texpr) list * texpr option | TTry of texpr * (tvar * texpr) list | TReturn of texpr option | TBreak | TContinue | TThrow of texpr | TCast of texpr * module_type option | TMeta of metadata_entry * texpr | TEnumParameter of texpr * tenum_field * int and tfield_access = | FInstance of tclass * tparams * tclass_field | FStatic of tclass * tclass_field | FAnon of tclass_field | FDynamic of string | FClosure of (tclass * tparams) option * tclass_field (* None class = TAnon *) | FEnum of tenum * tenum_field and texpr = { eexpr : texpr_expr; etype : t; epos : pos; } and tclass_field = { mutable cf_name : string; mutable cf_type : t; mutable cf_public : bool; cf_pos : pos; cf_name_pos : pos; mutable cf_doc : Ast.documentation; mutable cf_meta : metadata; mutable cf_kind : field_kind; mutable cf_params : type_params; mutable cf_expr : texpr option; mutable cf_expr_unoptimized : tfunc option; mutable cf_overloads : tclass_field list; } and tclass_kind = | KNormal | KTypeParameter of t list | KExpr of Ast.expr | KGeneric | KGenericInstance of tclass * tparams | KMacroType | KGenericBuild of class_field list | KAbstractImpl of tabstract and metadata = Ast.metadata and tinfos = { mt_path : path; mt_module : module_def; mt_pos : pos; mt_name_pos : pos; mt_private : bool; mt_doc : Ast.documentation; mutable mt_meta : metadata; mt_params : type_params; } and tclass = { mutable cl_path : path; mutable cl_module : module_def; mutable cl_pos : pos; mutable cl_name_pos : pos; mutable cl_private : bool; mutable cl_doc : Ast.documentation; mutable cl_meta : metadata; mutable cl_params : type_params; (* do not insert any fields above *) mutable cl_kind : tclass_kind; mutable cl_extern : bool; mutable cl_interface : bool; mutable cl_super : (tclass * tparams) option; mutable cl_implements : (tclass * tparams) list; mutable cl_fields : (string, tclass_field) PMap.t; mutable cl_statics : (string, tclass_field) PMap.t; mutable cl_ordered_statics : tclass_field list; mutable cl_ordered_fields : tclass_field list; mutable cl_dynamic : t option; mutable cl_array_access : t option; mutable cl_constructor : tclass_field option; mutable cl_init : texpr option; mutable cl_overrides : tclass_field list; mutable cl_build : unit -> build_state; mutable cl_restore : unit -> unit; } and tenum_field = { ef_name : string; ef_type : t; ef_pos : pos; ef_name_pos : pos; ef_doc : Ast.documentation; ef_index : int; ef_params : type_params; mutable ef_meta : metadata; } and tenum = { mutable e_path : path; e_module : module_def; e_pos : pos; e_name_pos : pos; e_private : bool; e_doc : Ast.documentation; mutable e_meta : metadata; mutable e_params : type_params; (* do not insert any fields above *) e_type : tdef; mutable e_extern : bool; mutable e_constrs : (string , tenum_field) PMap.t; mutable e_names : string list; } and tdef = { t_path : path; t_module : module_def; t_pos : pos; t_name_pos : pos; t_private : bool; t_doc : Ast.documentation; mutable t_meta : metadata; mutable t_params : type_params; (* do not insert any fields above *) mutable t_type : t; } and tabstract = { mutable a_path : path; a_module : module_def; a_pos : pos; a_name_pos : pos; a_private : bool; a_doc : Ast.documentation; mutable a_meta : metadata; mutable a_params : type_params; (* do not insert any fields above *) mutable a_ops : (Ast.binop * tclass_field) list; mutable a_unops : (Ast.unop * unop_flag * tclass_field) list; mutable a_impl : tclass option; mutable a_this : t; mutable a_from : t list; mutable a_from_field : (t * tclass_field) list; mutable a_to : t list; mutable a_to_field : (t * tclass_field) list; mutable a_array : tclass_field list; mutable a_resolve : tclass_field option; } and module_type = | TClassDecl of tclass | TEnumDecl of tenum | TTypeDecl of tdef | TAbstractDecl of tabstract and module_def = { m_id : int; m_path : path; mutable m_types : module_type list; m_extra : module_def_extra; } and module_def_extra = { m_file : string; m_sign : string; mutable m_check_policy : module_check_policy list; mutable m_time : float; mutable m_dirty : module_def option; mutable m_added : int; mutable m_mark : int; mutable m_deps : (int,module_def) PMap.t; mutable m_processed : int; mutable m_kind : module_kind; mutable m_binded_res : (string, string) PMap.t; mutable m_macro_calls : string list; mutable m_if_feature : (string *(tclass * tclass_field * bool)) list; mutable m_features : (string,bool) Hashtbl.t; } and module_kind = | MCode | MMacro | MFake | MSub | MExtern | MImport and build_state = | Built | Building | BuildMacro of (unit -> unit) list ref (* ======= General utility ======= *) let alloc_var = let uid = ref 0 in (fun n t p -> incr uid; { v_name = n; v_type = t; v_id = !uid; v_capture = false; v_extra = None; v_meta = []; v_pos = p }) let alloc_unbound_var n t p = let v = alloc_var n t p in v.v_meta <- [Meta.Unbound,[],null_pos]; v let alloc_mid = let mid = ref 0 in (fun() -> incr mid; !mid) let mk e t p = { eexpr = e; etype = t; epos = p } let mk_block e = match e.eexpr with | TBlock _ -> e | _ -> mk (TBlock [e]) e.etype e.epos let is_unbound v = Meta.has Meta.Unbound v.v_meta let mk_cast e t p = mk (TCast(e,None)) t p let null t p = mk (TConst TNull) t p let mk_mono() = TMono (ref None) let rec t_dynamic = TDynamic t_dynamic let not_opened = ref Closed let mk_anon fl = TAnon { a_fields = fl; a_status = not_opened; } (* We use this for display purposes because otherwise we never see the Dynamic type that is defined in StdTypes.hx. This is set each time a typer is created, but this is fine because Dynamic is the same in all contexts. If this ever changes we'll have to review how we handle this. *) let t_dynamic_def = ref t_dynamic let tfun pl r = TFun (List.map (fun t -> "",false,t) pl,r) let fun_args l = List.map (fun (a,c,t) -> a, c <> None, t) l let mk_class m path pos name_pos = { cl_path = path; cl_module = m; cl_pos = pos; cl_name_pos = name_pos; cl_doc = None; cl_meta = []; cl_private = false; cl_kind = KNormal; cl_extern = false; cl_interface = false; cl_params = []; cl_super = None; cl_implements = []; cl_fields = PMap.empty; cl_ordered_statics = []; cl_ordered_fields = []; cl_statics = PMap.empty; cl_dynamic = None; cl_array_access = None; cl_constructor = None; cl_init = None; cl_overrides = []; cl_build = (fun() -> Built); cl_restore = (fun() -> ()); } let module_extra file sign time kind policy = { m_file = file; m_sign = sign; m_dirty = None; m_added = 0; m_mark = 0; m_time = time; m_processed = 0; m_deps = PMap.empty; m_kind = kind; m_binded_res = PMap.empty; m_macro_calls = []; m_if_feature = []; m_features = Hashtbl.create 0; m_check_policy = policy; } let mk_field name t p name_pos = { cf_name = name; cf_type = t; cf_pos = p; cf_name_pos = name_pos; cf_doc = None; cf_meta = []; cf_public = true; cf_kind = Var { v_read = AccNormal; v_write = AccNormal }; cf_expr = None; cf_expr_unoptimized = None; cf_params = []; cf_overloads = []; } let null_module = { m_id = alloc_mid(); m_path = [] , ""; m_types = []; m_extra = module_extra "" "" 0. MFake []; } let null_class = let c = mk_class null_module ([],"") null_pos null_pos in c.cl_private <- true; c let null_field = mk_field "" t_dynamic null_pos null_pos let null_abstract = { a_path = ([],""); a_module = null_module; a_pos = null_pos; a_name_pos = null_pos; a_private = true; a_doc = None; a_meta = []; a_params = []; a_ops = []; a_unops = []; a_impl = None; a_this = t_dynamic; a_from = []; a_from_field = []; a_to = []; a_to_field = []; a_array = []; a_resolve = None; } let add_dependency m mdep = if m != null_module && m != mdep then m.m_extra.m_deps <- PMap.add mdep.m_id mdep m.m_extra.m_deps let arg_name (a,_) = a.v_name let t_infos t : tinfos = match t with | TClassDecl c -> Obj.magic c | TEnumDecl e -> Obj.magic e | TTypeDecl t -> Obj.magic t | TAbstractDecl a -> Obj.magic a let t_path t = (t_infos t).mt_path let rec is_parent csup c = if c == csup || List.exists (fun (i,_) -> is_parent csup i) c.cl_implements then true else match c.cl_super with | None -> false | Some (c,_) -> is_parent csup c let map loop t = match t with | TMono r -> (match !r with | None -> t | Some t -> loop t) (* erase*) | TEnum (_,[]) | TInst (_,[]) | TType (_,[]) -> t | TEnum (e,tl) -> TEnum (e, List.map loop tl) | TInst (c,tl) -> TInst (c, List.map loop tl) | TType (t2,tl) -> TType (t2,List.map loop tl) | TAbstract (a,tl) -> TAbstract (a,List.map loop tl) | TFun (tl,r) -> TFun (List.map (fun (s,o,t) -> s, o, loop t) tl,loop r) | TAnon a -> let fields = PMap.map (fun f -> { f with cf_type = loop f.cf_type }) a.a_fields in begin match !(a.a_status) with | Opened -> a.a_fields <- fields; t | _ -> TAnon { a_fields = fields; a_status = a.a_status; } end | TLazy f -> let ft = !f() in let ft2 = loop ft in if ft == ft2 then t else ft2 | TDynamic t2 -> if t == t2 then t else TDynamic (loop t2) let dup t = let monos = ref [] in let rec loop t = match t with | TMono { contents = None } -> (try List.assq t !monos with Not_found -> let m = mk_mono() in monos := (t,m) :: !monos; m) | _ -> map loop t in loop t (* substitute parameters with other types *) let apply_params cparams params t = match cparams with | [] -> t | _ -> 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 subst = loop cparams params in let rec loop t = try List.assq t subst with Not_found -> match t with | TMono r -> (match !r with | None -> t | Some t -> loop t) | TEnum (e,tl) -> (match tl with | [] -> t | _ -> TEnum (e,List.map loop tl)) | TType (t2,tl) -> (match tl with | [] -> t | _ -> TType (t2,List.map loop tl)) | TAbstract (a,tl) -> (match tl with | [] -> t | _ -> TAbstract (a,List.map loop tl)) | TInst (c,tl) -> (match tl with | [] -> t | [TMono r] -> (match !r with | Some tt when t == tt -> (* for dynamic *) let pt = mk_mono() in let t = TInst (c,[pt]) in (match pt with TMono r -> r := Some t | _ -> assert false); t | _ -> TInst (c,List.map loop tl)) | _ -> TInst (c,List.map loop tl)) | TFun (tl,r) -> TFun (List.map (fun (s,o,t) -> s, o, loop t) tl,loop r) | TAnon a -> let fields = PMap.map (fun f -> { f with cf_type = loop f.cf_type }) a.a_fields in begin match !(a.a_status) with | Opened -> a.a_fields <- fields; t | _ -> TAnon { a_fields = fields; a_status = a.a_status; } end | TLazy f -> let ft = !f() in let ft2 = loop ft in if ft == ft2 then t else ft2 | TDynamic t2 -> if t == t2 then t else TDynamic (loop t2) in loop t let monomorphs eparams t = apply_params eparams (List.map (fun _ -> mk_mono()) eparams) t let rec follow t = match t with | TMono r -> (match !r with | Some t -> follow t | _ -> t) | TLazy f -> follow (!f()) | TType (t,tl) -> follow (apply_params t.t_params tl t.t_type) | _ -> t let rec is_nullable = function | TMono r -> (match !r with None -> false | Some t -> is_nullable t) | TType ({ t_path = ([],"Null") },[_]) -> true | TLazy f -> is_nullable (!f()) | TType (t,tl) -> is_nullable (apply_params t.t_params tl t.t_type) | TFun _ -> false (* Type parameters will most of the time be nullable objects, so we don't want to make it hard for users to have to specify Null all over the place, so while they could be a basic type, let's assume they will not. This will still cause issues with inlining and haxe.rtti.Generic. In that case proper explicit Null is required to work correctly with basic types. This could still be fixed by redoing a nullability inference on the typed AST. | TInst ({ cl_kind = KTypeParameter },_) -> false *) | TAbstract (a,_) when Meta.has Meta.CoreType a.a_meta -> not (Meta.has Meta.NotNull a.a_meta) | TAbstract (a,tl) -> not (Meta.has Meta.NotNull a.a_meta) && is_nullable (apply_params a.a_params tl a.a_this) | _ -> true let rec is_null ?(no_lazy=false) = function | TMono r -> (match !r with None -> false | Some t -> is_null t) | TType ({ t_path = ([],"Null") },[t]) -> not (is_nullable (follow t)) | TLazy f -> if no_lazy then raise Exit else is_null (!f()) | TType (t,tl) -> is_null (apply_params t.t_params tl t.t_type) | _ -> false (* Determines if we have a Null. Unlike is_null, this returns true even if the wrapped type is nullable itself. *) let rec is_explicit_null = function | TMono r -> (match !r with None -> false | Some t -> is_null t) | TType ({ t_path = ([],"Null") },[t]) -> true | TLazy f -> is_null (!f()) | TType (t,tl) -> is_null (apply_params t.t_params tl t.t_type) | _ -> false let rec has_mono t = match t with | TMono r -> (match !r with None -> true | Some t -> has_mono t) | TInst(_,pl) | TEnum(_,pl) | TAbstract(_,pl) | TType(_,pl) -> List.exists has_mono pl | TDynamic _ -> false | TFun(args,r) -> has_mono r || List.exists (fun (_,_,t) -> has_mono t) args | TAnon a -> PMap.fold (fun cf b -> has_mono cf.cf_type || b) a.a_fields false | TLazy r -> has_mono (!r()) let concat e1 e2 = let e = (match e1.eexpr, e2.eexpr with | TBlock el1, TBlock el2 -> TBlock (el1@el2) | TBlock el, _ -> TBlock (el @ [e2]) | _, TBlock el -> TBlock (e1 :: el) | _ , _ -> TBlock [e1;e2] ) in mk e e2.etype (punion e1.epos e2.epos) let is_closed a = !(a.a_status) <> Opened let type_of_module_type = function | TClassDecl c -> TInst (c,List.map snd c.cl_params) | TEnumDecl e -> TEnum (e,List.map snd e.e_params) | TTypeDecl t -> TType (t,List.map snd t.t_params) | TAbstractDecl a -> TAbstract (a,List.map snd a.a_params) let rec module_type_of_type = function | TInst(c,_) -> TClassDecl c | TEnum(en,_) -> TEnumDecl en | TType(t,_) -> TTypeDecl t | TAbstract(a,_) -> TAbstractDecl a | TLazy f -> module_type_of_type (!f()) | TMono r -> (match !r with | Some t -> module_type_of_type t | _ -> raise Exit) | _ -> raise Exit let tconst_to_const = function | TInt i -> Int (Int32.to_string i) | TFloat s -> Float s | TString s -> String s | TBool b -> Ident (if b then "true" else "false") | TNull -> Ident "null" | TThis -> Ident "this" | TSuper -> Ident "super" 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 | TAbstract({a_path=["haxe"],"Constructible"},_) -> true | _ -> false ) tl; | _ -> false (* ======= Field utility ======= *) let field_name f = match f with | FAnon f | FInstance (_,_,f) | FStatic (_,f) | FClosure (_,f) -> f.cf_name | FEnum (_,f) -> f.ef_name | FDynamic n -> n let extract_field = function | FAnon f | FInstance (_,_,f) | FStatic (_,f) | FClosure (_,f) -> Some f | _ -> None let is_extern_field f = match f.cf_kind with | Method _ -> false | Var { v_read = AccNormal | AccInline | AccNo } | Var { v_write = AccNormal | AccNo } -> false | _ -> not (Meta.has Meta.IsVar f.cf_meta) let field_type f = match f.cf_params with | [] -> f.cf_type | l -> monomorphs l f.cf_type let rec raw_class_field build_type c tl i = let apply = apply_params c.cl_params tl in try let f = PMap.find i c.cl_fields in Some (c,tl), build_type f , f with Not_found -> try (match c.cl_constructor with | Some ctor when i = "new" -> Some (c,tl), build_type ctor,ctor | _ -> raise Not_found) with Not_found -> try match c.cl_super with | None -> raise Not_found | Some (c,tl) -> let c2 , t , f = raw_class_field build_type c (List.map apply tl) i in c2, apply_params c.cl_params tl t , f with Not_found -> match c.cl_kind with | KTypeParameter tl -> let rec loop = function | [] -> raise Not_found | t :: ctl -> match follow t with | TAnon a -> (try let f = PMap.find i a.a_fields in None, build_type f, f with Not_found -> loop ctl) | TInst (c,tl) -> (try let c2, t , f = raw_class_field build_type c (List.map apply tl) i in c2, apply_params c.cl_params tl t, f with Not_found -> loop ctl) | _ -> loop ctl in loop tl | _ -> if not c.cl_interface then raise Not_found; (* an interface can implements other interfaces without having to redeclare its fields *) let rec loop = function | [] -> raise Not_found | (c,tl) :: l -> try let c2, t , f = raw_class_field build_type c (List.map apply tl) i in c2, apply_params c.cl_params tl t, f with Not_found -> loop l in loop c.cl_implements let class_field = raw_class_field field_type let quick_field t n = match follow t with | TInst (c,tl) -> let c, _, f = raw_class_field (fun f -> f.cf_type) c tl n in (match c with None -> FAnon f | Some (c,tl) -> FInstance (c,tl,f)) | TAnon a -> (match !(a.a_status) with | EnumStatics e -> let ef = PMap.find n e.e_constrs in FEnum(e,ef) | Statics c -> FStatic (c,PMap.find n c.cl_statics) | AbstractStatics a -> begin match a.a_impl with | Some c -> let cf = PMap.find n c.cl_statics in FStatic(c,cf) (* is that right? *) | _ -> raise Not_found end | _ -> FAnon (PMap.find n a.a_fields)) | TDynamic _ -> FDynamic n | TEnum _ | TMono _ | TAbstract _ | TFun _ -> raise Not_found | TLazy _ | TType _ -> assert false let quick_field_dynamic t s = try quick_field t s with Not_found -> FDynamic s let rec get_constructor build_type c = match c.cl_constructor, c.cl_super with | Some c, _ -> build_type c, c | None, None -> raise Not_found | None, Some (csup,cparams) -> let t, c = get_constructor build_type csup in apply_params csup.cl_params cparams t, c (* ======= Printing ======= *) let print_context() = ref [] let rec s_type_kind t = let map tl = String.concat ", " (List.map s_type_kind tl) in match t with | TMono r -> begin match !r with | None -> "TMono (None)" | Some t -> "TMono (Some (" ^ (s_type_kind t) ^ "))" end | TEnum(en,tl) -> Printf.sprintf "TEnum(%s, [%s])" (s_type_path en.e_path) (map tl) | TInst(c,tl) -> Printf.sprintf "TInst(%s, [%s])" (s_type_path c.cl_path) (map tl) | TType(t,tl) -> Printf.sprintf "TType(%s, [%s])" (s_type_path t.t_path) (map tl) | TAbstract(a,tl) -> Printf.sprintf "TAbstract(%s, [%s])" (s_type_path a.a_path) (map tl) | TFun(tl,r) -> Printf.sprintf "TFun([%s], %s)" (String.concat ", " (List.map (fun (n,b,t) -> Printf.sprintf "%s%s:%s" (if b then "?" else "") n (s_type_kind t)) tl)) (s_type_kind r) | TAnon an -> "TAnon" | TDynamic t2 -> "TDynamic" | TLazy _ -> "TLazy" let s_module_type_kind = function | TClassDecl c -> "TClassDecl(" ^ (s_type_path c.cl_path) ^ ")" | TEnumDecl en -> "TEnumDecl(" ^ (s_type_path en.e_path) ^ ")" | TAbstractDecl a -> "TAbstractDecl(" ^ (s_type_path a.a_path) ^ ")" | TTypeDecl t -> "TTypeDecl(" ^ (s_type_path t.t_path) ^ ")" let rec s_type ctx t = match t with | TMono r -> (match !r with | None -> Printf.sprintf "Unknown<%d>" (try List.assq t (!ctx) with Not_found -> let n = List.length !ctx in ctx := (t,n) :: !ctx; n) | Some t -> s_type ctx t) | TEnum (e,tl) -> s_type_path e.e_path ^ s_type_params ctx tl | TInst (c,tl) -> (match c.cl_kind with | KExpr e -> Ast.s_expr e | _ -> s_type_path c.cl_path ^ s_type_params ctx tl) | TType (t,tl) -> s_type_path t.t_path ^ s_type_params ctx tl | TAbstract (a,tl) -> s_type_path a.a_path ^ s_type_params ctx tl | TFun ([],t) -> "Void -> " ^ s_fun ctx t false | TFun (l,t) -> String.concat " -> " (List.map (fun (s,b,t) -> (if b then "?" else "") ^ (if s = "" then "" else s ^ " : ") ^ s_fun ctx t true ) l) ^ " -> " ^ s_fun ctx t false | TAnon a -> let fl = PMap.fold (fun f acc -> ((if Meta.has Meta.Optional f.cf_meta then " ?" else " ") ^ f.cf_name ^ " : " ^ s_type ctx f.cf_type) :: acc) a.a_fields [] in "{" ^ (if not (is_closed a) then "+" else "") ^ String.concat "," fl ^ " }" | TDynamic t2 -> "Dynamic" ^ s_type_params ctx (if t == t2 then [] else [t2]) | TLazy f -> s_type ctx (!f()) and s_fun ctx t void = match t with | TFun _ -> "(" ^ s_type ctx t ^ ")" | TAbstract ({ a_path = ([],"Void") },[]) when void -> "(" ^ s_type ctx t ^ ")" | TMono r -> (match !r with | None -> s_type ctx t | Some t -> s_fun ctx t void) | TLazy f -> s_fun ctx (!f()) void | _ -> s_type ctx t and s_type_params ctx = function | [] -> "" | l -> "<" ^ String.concat ", " (List.map (s_type ctx) l) ^ ">" let s_access is_read = function | AccNormal -> "default" | AccNo -> "null" | AccNever -> "never" | AccResolve -> "resolve" | AccCall -> if is_read then "get" else "set" | AccInline -> "inline" | AccRequire (n,_) -> "require " ^ n let s_kind = function | Var { v_read = AccNormal; v_write = AccNormal } -> "var" | Var v -> "(" ^ s_access true v.v_read ^ "," ^ s_access false v.v_write ^ ")" | Method m -> match m with | MethNormal -> "method" | MethDynamic -> "dynamic method" | MethInline -> "inline method" | MethMacro -> "macro method" let s_expr_kind e = match e.eexpr with | TConst _ -> "Const" | TLocal _ -> "Local" | TArray (_,_) -> "Array" | TBinop (_,_,_) -> "Binop" | TEnumParameter (_,_,_) -> "EnumParameter" | TField (_,_) -> "Field" | TTypeExpr _ -> "TypeExpr" | TParenthesis _ -> "Parenthesis" | TObjectDecl _ -> "ObjectDecl" | TArrayDecl _ -> "ArrayDecl" | TCall (_,_) -> "Call" | TNew (_,_,_) -> "New" | TUnop (_,_,_) -> "Unop" | TFunction _ -> "Function" | TVar _ -> "Vars" | TBlock _ -> "Block" | TFor (_,_,_) -> "For" | TIf (_,_,_) -> "If" | TWhile (_,_,_) -> "While" | TSwitch (_,_,_) -> "Switch" | TTry (_,_) -> "Try" | TReturn _ -> "Return" | TBreak -> "Break" | TContinue -> "Continue" | TThrow _ -> "Throw" | TCast _ -> "Cast" | TMeta _ -> "Meta" let s_const = function | TInt i -> Int32.to_string i | TFloat s -> s | TString s -> Printf.sprintf "\"%s\"" (Ast.s_escape s) | TBool b -> if b then "true" else "false" | TNull -> "null" | TThis -> "this" | TSuper -> "super" let rec s_expr s_type e = let sprintf = Printf.sprintf in let slist f l = String.concat "," (List.map f l) in let loop = s_expr s_type in let s_var v = v.v_name ^ ":" ^ string_of_int v.v_id ^ if v.v_capture then "[c]" else "" in let str = (match e.eexpr with | TConst c -> "Const " ^ s_const c | TLocal v -> "Local " ^ s_var v | TArray (e1,e2) -> sprintf "%s[%s]" (loop e1) (loop e2) | TBinop (op,e1,e2) -> sprintf "(%s %s %s)" (loop e1) (s_binop op) (loop e2) | TEnumParameter (e1,_,i) -> sprintf "%s[%i]" (loop e1) i | TField (e,f) -> let fstr = (match f with | FStatic (c,f) -> "static(" ^ s_type_path c.cl_path ^ "." ^ f.cf_name ^ ")" | FInstance (c,_,f) -> "inst(" ^ s_type_path c.cl_path ^ "." ^ f.cf_name ^ " : " ^ s_type f.cf_type ^ ")" | FClosure (c,f) -> "closure(" ^ (match c with None -> f.cf_name | Some (c,_) -> s_type_path c.cl_path ^ "." ^ f.cf_name) ^ ")" | FAnon f -> "anon(" ^ f.cf_name ^ ")" | FEnum (en,f) -> "enum(" ^ s_type_path en.e_path ^ "." ^ f.ef_name ^ ")" | FDynamic f -> "dynamic(" ^ f ^ ")" ) in sprintf "%s.%s" (loop e) fstr | TTypeExpr m -> sprintf "TypeExpr %s" (s_type_path (t_path m)) | TParenthesis e -> sprintf "Parenthesis %s" (loop e) | TObjectDecl fl -> sprintf "ObjectDecl {%s}" (slist (fun (f,e) -> sprintf "%s : %s" f (loop e)) fl) | TArrayDecl el -> sprintf "ArrayDecl [%s]" (slist loop el) | TCall (e,el) -> sprintf "Call %s(%s)" (loop e) (slist loop el) | TNew (c,pl,el) -> sprintf "New %s%s(%s)" (s_type_path c.cl_path) (match pl with [] -> "" | l -> sprintf "<%s>" (slist s_type l)) (slist loop el) | TUnop (op,f,e) -> (match f with | Prefix -> sprintf "(%s %s)" (s_unop op) (loop e) | Postfix -> sprintf "(%s %s)" (loop e) (s_unop op)) | TFunction f -> let args = slist (fun (v,o) -> sprintf "%s : %s%s" (s_var v) (s_type v.v_type) (match o with None -> "" | Some c -> " = " ^ s_const c)) f.tf_args in sprintf "Function(%s) : %s = %s" args (s_type f.tf_type) (loop f.tf_expr) | TVar (v,eo) -> sprintf "Vars %s" (sprintf "%s : %s%s" (s_var v) (s_type v.v_type) (match eo with None -> "" | Some e -> " = " ^ loop e)) | TBlock el -> sprintf "Block {\n%s}" (String.concat "" (List.map (fun e -> sprintf "%s;\n" (loop e)) el)) | TFor (v,econd,e) -> sprintf "For (%s : %s in %s,%s)" (s_var v) (s_type v.v_type) (loop econd) (loop e) | TIf (e,e1,e2) -> sprintf "If (%s,%s%s)" (loop e) (loop e1) (match e2 with None -> "" | Some e -> "," ^ loop e) | TWhile (econd,e,flag) -> (match flag with | NormalWhile -> sprintf "While (%s,%s)" (loop econd) (loop e) | DoWhile -> sprintf "DoWhile (%s,%s)" (loop e) (loop econd)) | TSwitch (e,cases,def) -> sprintf "Switch (%s,(%s)%s)" (loop e) (slist (fun (cl,e) -> sprintf "case %s: %s" (slist loop cl) (loop e)) cases) (match def with None -> "" | Some e -> "," ^ loop e) | TTry (e,cl) -> sprintf "Try %s(%s) " (loop e) (slist (fun (v,e) -> sprintf "catch( %s : %s ) %s" (s_var v) (s_type v.v_type) (loop e)) cl) | TReturn None -> "Return" | TReturn (Some e) -> sprintf "Return %s" (loop e) | TBreak -> "Break" | TContinue -> "Continue" | TThrow e -> "Throw " ^ (loop e) | TCast (e,t) -> sprintf "Cast %s%s" (match t with None -> "" | Some t -> s_type_path (t_path t) ^ ": ") (loop e) | TMeta ((n,el,_),e) -> sprintf "@%s%s %s" (Meta.to_string n) (match el with [] -> "" | _ -> "(" ^ (String.concat ", " (List.map Ast.s_expr el)) ^ ")") (loop e) ) in sprintf "(%s : %s)" str (s_type e.etype) let rec s_expr_pretty print_var_ids tabs top_level s_type e = let sprintf = Printf.sprintf in let loop = s_expr_pretty print_var_ids tabs false s_type in let slist c f l = String.concat c (List.map f l) in let clist f l = slist ", " f l in let local v = if print_var_ids then sprintf "%s<%i>" v.v_name v.v_id else v.v_name in match e.eexpr with | TConst c -> s_const c | TLocal v -> local v | TArray (e1,e2) -> sprintf "%s[%s]" (loop e1) (loop e2) | TBinop (op,e1,e2) -> sprintf "%s %s %s" (loop e1) (s_binop op) (loop e2) | TEnumParameter (e1,_,i) -> sprintf "%s[%i]" (loop e1) i | TField (e1,s) -> sprintf "%s.%s" (loop e1) (field_name s) | TTypeExpr mt -> (s_type_path (t_path mt)) | TParenthesis e1 -> sprintf "(%s)" (loop e1) | TObjectDecl fl -> sprintf "{%s}" (clist (fun (f,e) -> sprintf "%s : %s" f (loop e)) fl) | TArrayDecl el -> sprintf "[%s]" (clist loop el) | TCall (e1,el) -> sprintf "%s(%s)" (loop e1) (clist loop el) | TNew (c,pl,el) -> sprintf "new %s(%s)" (s_type_path c.cl_path) (clist loop el) | TUnop (op,f,e) -> (match f with | Prefix -> sprintf "%s %s" (s_unop op) (loop e) | Postfix -> sprintf "%s %s" (loop e) (s_unop op)) | TFunction f -> let args = clist (fun (v,o) -> sprintf "%s:%s%s" (local v) (s_type v.v_type) (match o with None -> "" | Some c -> " = " ^ s_const c)) f.tf_args in sprintf "%s(%s) %s" (if top_level then "" else "function") args (loop f.tf_expr) | TVar (v,eo) -> sprintf "var %s" (sprintf "%s%s" (local v) (match eo with None -> "" | Some e -> " = " ^ loop e)) | TBlock el -> let ntabs = tabs ^ "\t" in let s = sprintf "{\n%s" (String.concat "" (List.map (fun e -> sprintf "%s%s;\n" ntabs (s_expr_pretty print_var_ids ntabs top_level s_type e)) el)) in (match el with | [] -> "{}" | _ -> s ^ tabs ^ "}") | TFor (v,econd,e) -> sprintf "for (%s in %s) %s" (local v) (loop econd) (loop e) | TIf (e,e1,e2) -> sprintf "if (%s) %s%s" (loop e) (loop e1) (match e2 with None -> "" | Some e -> " else " ^ loop e) | TWhile (econd,e,flag) -> (match flag with | NormalWhile -> sprintf "while (%s) %s" (loop econd) (loop e) | DoWhile -> sprintf "do (%s) while(%s)" (loop e) (loop econd)) | TSwitch (e,cases,def) -> let ntabs = tabs ^ "\t" in let s = sprintf "switch (%s) {\n%s%s" (loop e) (slist "" (fun (cl,e) -> sprintf "%scase %s: %s;\n" ntabs (clist loop cl) (s_expr_pretty print_var_ids ntabs top_level s_type e)) cases) (match def with None -> "" | Some e -> ntabs ^ "default: " ^ (s_expr_pretty print_var_ids ntabs top_level s_type e) ^ "\n") in s ^ tabs ^ "}" | TTry (e,cl) -> sprintf "try %s%s" (loop e) (clist (fun (v,e) -> sprintf " catch (%s:%s) %s" (local v) (s_type v.v_type) (loop e)) cl) | TReturn None -> "return" | TReturn (Some e) -> sprintf "return %s" (loop e) | TBreak -> "break" | TContinue -> "continue" | TThrow e -> "throw " ^ (loop e) | TCast (e,None) -> sprintf "cast %s" (loop e) | TCast (e,Some mt) -> sprintf "cast (%s,%s)" (loop e) (s_type_path (t_path mt)) | TMeta ((n,el,_),e) -> sprintf "@%s%s %s" (Meta.to_string n) (match el with [] -> "" | _ -> "(" ^ (String.concat ", " (List.map Ast.s_expr el)) ^ ")") (loop e) let rec s_expr_ast print_var_ids tabs s_type e = let sprintf = Printf.sprintf in let loop ?(extra_tabs="") = s_expr_ast print_var_ids (tabs ^ "\t" ^ extra_tabs) s_type in let tag_args tabs sl = match sl with | [] -> "" | [s] when not (String.contains s '\n') -> " " ^ s | _ -> let tabs = "\n" ^ tabs ^ "\t" in tabs ^ (String.concat tabs sl) in let tag s ?(t=None) ?(extra_tabs="") sl = let st = match t with | None -> s_type e.etype | Some t -> s_type t in sprintf "[%s:%s]%s" s st (tag_args (tabs ^ extra_tabs) sl) in let var_id v = if print_var_ids then v.v_id else 0 in let const c t = tag "Const" ~t [s_const c] in let local v = sprintf "[Local %s(%i):%s]" v.v_name (var_id v) (s_type v.v_type) in let var v sl = sprintf "[Var %s(%i):%s]%s" v.v_name (var_id v) (s_type v.v_type) (tag_args tabs sl) in let module_type mt = sprintf "[TypeExpr %s:%s]" (s_type_path (t_path mt)) (s_type e.etype) in match e.eexpr with | TConst c -> const c (Some e.etype) | TLocal v -> local v | TArray (e1,e2) -> tag "Array" [loop e1; loop e2] | TBinop (op,e1,e2) -> tag "Binop" [loop e1; s_binop op; loop e2] | TUnop (op,flag,e1) -> tag "Unop" [s_unop op; if flag = Postfix then "Postfix" else "Prefix"; loop e1] | TEnumParameter (e1,ef,i) -> tag "EnumParameter" [loop e1; ef.ef_name; string_of_int i] | TField (e1,fa) -> let sfa = match fa with | FInstance(c,tl,cf) -> tag "FInstance" ~extra_tabs:"\t" [s_type (TInst(c,tl)); cf.cf_name] | FStatic(c,cf) -> tag "FStatic" ~extra_tabs:"\t" [s_type_path c.cl_path; cf.cf_name] | FClosure(co,cf) -> tag "FClosure" ~extra_tabs:"\t" [(match co with None -> "None" | Some (c,tl) -> s_type (TInst(c,tl))); cf.cf_name] | FAnon cf -> tag "FAnon" ~extra_tabs:"\t" [cf.cf_name] | FDynamic s -> tag "FDynamic" ~extra_tabs:"\t" [s] | FEnum(en,ef) -> tag "FEnum" ~extra_tabs:"\t" [s_type_path en.e_path; ef.ef_name] in tag "Field" [loop e1; sfa] | TTypeExpr mt -> module_type mt | TParenthesis e1 -> tag "Parenthesis" [loop e1] | TObjectDecl fl -> tag "ObjectDecl" (List.map (fun (s,e) -> sprintf "%s: %s" s (loop e)) fl) | TArrayDecl el -> tag "ArrayDecl" (List.map loop el) | TCall (e1,el) -> tag "Call" (loop e1 :: (List.map loop el)) | TNew (c,tl,el) -> tag "New" ((s_type (TInst(c,tl))) :: (List.map loop el)) | TFunction f -> let arg (v,cto) = tag "Arg" ~t:(Some v.v_type) ~extra_tabs:"\t" (match cto with None -> [local v] | Some ct -> [local v;const ct None]) in tag "Function" ((List.map arg f.tf_args) @ [loop f.tf_expr]) | TVar (v,eo) -> var v (match eo with None -> [] | Some e -> [loop e]) | TBlock el -> tag "Block" (List.map loop el) | TIf (e,e1,e2) -> tag "If" (loop e :: (Printf.sprintf "[Then:%s] %s" (s_type e1.etype) (loop e1)) :: (match e2 with None -> [] | Some e -> [Printf.sprintf "[Else:%s] %s" (s_type e.etype) (loop e)])) | TCast (e1,None) -> tag "Cast" [loop e1] | TCast (e1,Some mt) -> tag "Cast" [loop e1; module_type mt] | TThrow e1 -> tag "Throw" [loop e1] | TBreak -> tag "Break" [] | TContinue -> tag "Continue" [] | TReturn None -> tag "Return" [] | TReturn (Some e1) -> tag "Return" [loop e1] | TWhile (e1,e2,NormalWhile) -> tag "While" [loop e1; loop e2] | TWhile (e1,e2,DoWhile) -> tag "Do" [loop e1; loop e2] | TFor (v,e1,e2) -> tag "For" [local v; loop e1; loop e2] | TTry (e1,catches) -> let sl = List.map (fun (v,e) -> sprintf "Catch %s%s" (local v) (tag_args (tabs ^ "\t") [loop ~extra_tabs:"\t" e]); ) catches in tag "Try" ((loop e1) :: sl) | TSwitch (e1,cases,eo) -> let sl = List.map (fun (el,e) -> tag "Case" ~t:(Some e.etype) ~extra_tabs:"\t" ((List.map loop el) @ [loop ~extra_tabs:"\t" e]) ) cases in let sl = match eo with | None -> sl | Some e -> sl @ [tag "Default" ~t:(Some e.etype) ~extra_tabs:"\t" [loop ~extra_tabs:"\t" e]] in tag "Switch" ((loop e1) :: sl) | TMeta ((m,el,_),e1) -> let s = Meta.to_string m in let s = match el with | [] -> s | _ -> sprintf "%s(%s)" s (String.concat ", " (List.map Ast.s_expr el)) in tag "Meta" [s; loop e1] let s_types ?(sep = ", ") tl = let pctx = print_context() in String.concat sep (List.map (s_type pctx) tl) let s_class_kind = function | KNormal -> "KNormal" | KTypeParameter tl -> Printf.sprintf "KTypeParameter [%s]" (s_types tl) | KExpr _ -> "KExpr" | KGeneric -> "KGeneric" | KGenericInstance(c,tl) -> Printf.sprintf "KGenericInstance %s<%s>" (s_type_path c.cl_path) (s_types tl) | KMacroType -> "KMacroType" | KGenericBuild _ -> "KGenericBuild" | KAbstractImpl a -> Printf.sprintf "KAbstractImpl %s" (s_type_path a.a_path) module Printer = struct let s_type = s_type (print_context()) let s_pair s1 s2 = Printf.sprintf "(%s,%s)" s1 s2 let s_record_field name value = Printf.sprintf "%s = %s;" name value let s_pos p = Printf.sprintf "%s: %i-%i" p.pfile p.pmin p.pmax let s_record_fields tabs fields = let sl = List.map (fun (name,value) -> s_record_field name value) fields in Printf.sprintf "{\n%s\t%s\n%s}" tabs (String.concat ("\n\t" ^ tabs) sl) tabs let s_list sep f l = "[" ^ (String.concat sep (List.map f l)) ^ "]" let s_opt f o = match o with | None -> "None" | Some v -> f v let s_pmap fk fv pm = "{" ^ (String.concat ", " (PMap.foldi (fun k v acc -> (Printf.sprintf "%s = %s" (fk k) (fv v)) :: acc) pm [])) ^ "}" let s_doc = s_opt (fun s -> s) let s_metadata_entry (s,el,_) = Printf.sprintf "@%s%s" (Meta.to_string s) (match el with [] -> "" | el -> "(" ^ (String.concat ", " (List.map Ast.s_expr el)) ^ ")") let s_metadata metadata = s_list " " s_metadata_entry metadata let s_type_param (s,t) = match follow t with | TInst({cl_kind = KTypeParameter tl1},tl2) -> begin match tl1 with | [] -> s | _ -> Printf.sprintf "%s:%s" s (String.concat ", " (List.map s_type tl1)) end | _ -> assert false let s_type_params tl = s_list ", " s_type_param tl let s_tclass_field tabs cf = s_record_fields tabs [ "cf_name",cf.cf_name; "cf_doc",s_doc cf.cf_doc; "cf_type",s_type_kind (follow cf.cf_type); "cf_public",string_of_bool cf.cf_public; "cf_pos",s_pos cf.cf_pos; "cf_name_pos",s_pos cf.cf_name_pos; "cf_meta",s_metadata cf.cf_meta; "cf_kind",s_kind cf.cf_kind; "cf_params",s_type_params cf.cf_params; "cf_expr",s_opt (s_expr_ast true "\t\t" s_type) cf.cf_expr; ] let s_tclass tabs c = s_record_fields tabs [ "cl_path",s_type_path c.cl_path; "cl_module",s_type_path c.cl_module.m_path; "cl_pos",s_pos c.cl_pos; "cl_name_pos",s_pos c.cl_name_pos; "cl_private",string_of_bool c.cl_private; "cl_doc",s_doc c.cl_doc; "cl_meta",s_metadata c.cl_meta; "cl_params",s_type_params c.cl_params; "cl_kind",s_class_kind c.cl_kind; "cl_extern",string_of_bool c.cl_extern; "cl_interface",string_of_bool c.cl_interface; "cl_super",s_opt (fun (c,tl) -> s_type (TInst(c,tl))) c.cl_super; "cl_implements",s_list ", " (fun (c,tl) -> s_type (TInst(c,tl))) c.cl_implements; "cl_dynamic",s_opt s_type c.cl_dynamic; "cl_array_access",s_opt s_type c.cl_array_access; "cl_overrides",s_list "," (fun cf -> cf.cf_name) c.cl_overrides; "cl_init",s_opt (s_expr_ast true "" s_type) c.cl_init; "cl_constructor",s_opt (s_tclass_field (tabs ^ "\t")) c.cl_constructor; "cl_ordered_fields",s_list "\n\t" (s_tclass_field (tabs ^ "\t")) c.cl_ordered_fields; "cl_ordered_statics",s_list "\n\t" (s_tclass_field (tabs ^ "\t")) c.cl_ordered_statics; ] let s_tdef tabs t = s_record_fields tabs [ "t_path",s_type_path t.t_path; "t_module",s_type_path t.t_module.m_path; "t_pos",s_pos t.t_pos; "t_name_pos",s_pos t.t_name_pos; "t_private",string_of_bool t.t_private; "t_doc",s_doc t.t_doc; "t_meta",s_metadata t.t_meta; "t_params",s_type_params t.t_params; "t_type",s_type_kind t.t_type ] let s_tenum_field tabs ef = s_record_fields tabs [ "ef_name",ef.ef_name; "ef_doc",s_doc ef.ef_doc; "ef_pos",s_pos ef.ef_pos; "ef_name_pos",s_pos ef.ef_name_pos; "ef_type",s_type_kind ef.ef_type; "ef_index",string_of_int ef.ef_index; "ef_params",s_type_params ef.ef_params; "ef_meta",s_metadata ef.ef_meta ] let s_tenum tabs en = s_record_fields tabs [ "e_path",s_type_path en.e_path; "e_module",s_type_path en.e_module.m_path; "e_pos",s_pos en.e_pos; "e_name_pos",s_pos en.e_name_pos; "e_private",string_of_bool en.e_private; "d_doc",s_doc en.e_doc; "e_meta",s_metadata en.e_meta; "e_params",s_type_params en.e_params; "e_type",s_tdef "\t" en.e_type; "e_extern",string_of_bool en.e_extern; "e_constrs",s_list "\n\t" (s_tenum_field (tabs ^ "\t")) (PMap.fold (fun ef acc -> ef :: acc) en.e_constrs []); "e_names",String.concat ", " en.e_names ] let s_tabstract tabs a = s_record_fields tabs [ "a_path",s_type_path a.a_path; "a_modules",s_type_path a.a_module.m_path; "a_pos",s_pos a.a_pos; "a_name_pos",s_pos a.a_name_pos; "a_private",string_of_bool a.a_private; "a_doc",s_doc a.a_doc; "a_meta",s_metadata a.a_meta; "a_params",s_type_params a.a_params; "a_ops",s_list ", " (fun (op,cf) -> Printf.sprintf "%s: %s" (s_binop op) cf.cf_name) a.a_ops; "a_unops",s_list ", " (fun (op,flag,cf) -> Printf.sprintf "%s (%s): %s" (s_unop op) (if flag = Postfix then "postfix" else "prefix") cf.cf_name) a.a_unops; "a_impl",s_opt (fun c -> s_type_path c.cl_path) a.a_impl; "a_this",s_type_kind a.a_this; "a_from",s_list ", " s_type_kind a.a_from; "a_to",s_list ", " s_type_kind a.a_to; "a_from_field",s_list ", " (fun (t,cf) -> Printf.sprintf "%s: %s" (s_type_kind t) cf.cf_name) a.a_from_field; "a_to_field",s_list ", " (fun (t,cf) -> Printf.sprintf "%s: %s" (s_type_kind t) cf.cf_name) a.a_to_field; "a_array",s_list ", " (fun cf -> cf.cf_name) a.a_array; "a_resolve",s_opt (fun cf -> cf.cf_name) a.a_resolve; ] let s_tvar_extra (tl,eo) = Printf.sprintf "Some(%s, %s)" (s_type_params tl) (s_opt (s_expr_ast true "" s_type) eo) let s_tvar v = s_record_fields "" [ "v_id",string_of_int v.v_id; "v_name",v.v_name; "v_type",s_type v.v_type; "v_capture",string_of_bool v.v_capture; "v_extra",s_opt s_tvar_extra v.v_extra; "v_meta",s_metadata v.v_meta; ] let s_module_kind = function | MCode -> "MCode" | MMacro -> "MMacro" | MFake -> "MFake" | MSub -> "MSub" | MExtern -> "MExtern" | MImport -> "MImport" let s_module_def_extra tabs me = s_record_fields tabs [ "m_file",me.m_file; "m_sign",me.m_sign; "m_time",string_of_float me.m_time; "m_dirty",s_opt (fun m -> s_type_path m.m_path) me.m_dirty; "m_added",string_of_int me.m_added; "m_mark",string_of_int me.m_mark; "m_deps",s_pmap string_of_int (fun m -> snd m.m_path) me.m_deps; "m_processed",string_of_int me.m_processed; "m_kind",s_module_kind me.m_kind; "m_binded_res",""; (* TODO *) "m_macro_calls",String.concat ", " me.m_macro_calls; "m_if_feature",""; (* TODO *) "m_features",""; (* TODO *) ] let s_module_def m = s_record_fields "" [ "m_id",string_of_int m.m_id; "m_path",s_type_path m.m_path; "m_extra",s_module_def_extra "\t" m.m_extra ] let s_type_path tp = s_record_fields "" [ "tpackage",s_list "." (fun s -> s) tp.tpackage; "tname",tp.tname; "tparams",""; "tsub",s_opt (fun s -> s) tp.tsub; ] let s_class_flag = function | HInterface -> "HInterface" | HExtern -> "HExtern" | HPrivate -> "HPrivate" | HExtends tp -> "HExtends " ^ (s_type_path (fst tp)) | HImplements tp -> "HImplements " ^ (s_type_path (fst tp)) let s_placed f (x,p) = s_pair (f x) (s_pos p) let s_class_field cff = s_record_fields "" [ "cff_name",s_placed (fun s -> s) cff.cff_name; "cff_doc",s_opt (fun s -> s) cff.cff_doc; "cff_pos",s_pos cff.cff_pos; "cff_meta",s_metadata cff.cff_meta; "cff_access",s_list ", " Ast.s_access cff.cff_access; ] end (* ======= Unification ======= *) let rec link e a b = (* tell if setting a == b will create a type-loop *) let rec loop t = if t == a then true else match t with | TMono t -> (match !t with None -> false | Some t -> loop t) | TEnum (_,tl) -> List.exists loop tl | TInst (_,tl) | TType (_,tl) | TAbstract (_,tl) -> List.exists loop tl | TFun (tl,t) -> List.exists (fun (_,_,t) -> loop t) tl || loop t | TDynamic t2 -> if t == t2 then false else loop t2 | TLazy f -> loop (!f()) | TAnon a -> try PMap.iter (fun _ f -> if loop f.cf_type then raise Exit) a.a_fields; false with Exit -> true in (* tell is already a ~= b *) if loop b then (follow b) == a else if b == t_dynamic then true else begin e := Some b; true end let link_dynamic a b = match follow a,follow b with | TMono r,TDynamic _ -> r := Some b | TDynamic _,TMono r -> r := Some a | _ -> () let rec fast_eq a b = if a == b then true else match a , b with | TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 -> List.for_all2 (fun (_,_,t1) (_,_,t2) -> fast_eq t1 t2) l1 l2 && fast_eq r1 r2 | TType (t1,l1), TType (t2,l2) -> t1 == t2 && List.for_all2 fast_eq l1 l2 | TEnum (e1,l1), TEnum (e2,l2) -> e1 == e2 && List.for_all2 fast_eq l1 l2 | TInst (c1,l1), TInst (c2,l2) -> c1 == c2 && List.for_all2 fast_eq l1 l2 | TAbstract (a1,l1), TAbstract (a2,l2) -> a1 == a2 && List.for_all2 fast_eq l1 l2 | _ , _ -> false let rec fast_eq_mono ml a b = if a == b then true else match a , b with | TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 -> List.for_all2 (fun (_,_,t1) (_,_,t2) -> fast_eq_mono ml t1 t2) l1 l2 && fast_eq_mono ml r1 r2 | TType (t1,l1), TType (t2,l2) -> t1 == t2 && List.for_all2 (fast_eq_mono ml) l1 l2 | TEnum (e1,l1), TEnum (e2,l2) -> e1 == e2 && List.for_all2 (fast_eq_mono ml) l1 l2 | TInst (c1,l1), TInst (c2,l2) -> c1 == c2 && List.for_all2 (fast_eq_mono ml) l1 l2 | TAbstract (a1,l1), TAbstract (a2,l2) -> a1 == a2 && List.for_all2 (fast_eq_mono ml) l1 l2 | TMono _, _ -> List.memq a ml | _ , _ -> false (* perform unification with subtyping. the first type is always the most down in the class hierarchy it's also the one that is pointed by the position. It's actually a typecheck of A :> B where some mutations can happen *) type unify_error = | Cannot_unify of t * t | Invalid_field_type of string | Has_no_field of t * string | Has_no_runtime_field of t * string | Has_extra_field of t * string | Invalid_kind of string * field_kind * field_kind | Invalid_visibility of string | Not_matching_optional of string | Cant_force_optional | Invariant_parameter of t * t | Constraint_failure of string | Missing_overload of tclass_field * t | Unify_custom of string exception Unify_error of unify_error list let cannot_unify a b = Cannot_unify (a,b) let invalid_field n = Invalid_field_type n let invalid_kind n a b = Invalid_kind (n,a,b) let invalid_visibility n = Invalid_visibility n let has_no_field t n = Has_no_field (t,n) let has_extra_field t n = Has_extra_field (t,n) let error l = raise (Unify_error l) let has_meta m ml = List.exists (fun (m2,_,_) -> m = m2) ml let get_meta m ml = List.find (fun (m2,_,_) -> m = m2) ml let no_meta = [] (* we can restrict access as soon as both are runtime-compatible *) let unify_access a1 a2 = a1 = a2 || match a1, a2 with | _, AccNo | _, AccNever -> true | AccInline, AccNormal -> true | _ -> false let direct_access = function | AccNo | AccNever | AccNormal | AccInline | AccRequire _ -> true | AccResolve | AccCall -> false let unify_kind k1 k2 = k1 = k2 || match k1, k2 with | Var v1, Var v2 -> unify_access v1.v_read v2.v_read && unify_access v1.v_write v2.v_write | Var v, Method m -> (match v.v_read, v.v_write, m with | AccNormal, _, MethNormal -> true | AccNormal, AccNormal, MethDynamic -> true | _ -> false) | Method m, Var v -> (match m with | MethDynamic -> direct_access v.v_read && direct_access v.v_write | MethMacro -> false | MethNormal | MethInline -> match v.v_read,v.v_write with | AccNormal,(AccNo | AccNever) -> true | _ -> false) | Method m1, Method m2 -> match m1,m2 with | MethInline, MethNormal | MethDynamic, MethNormal -> true | _ -> false let eq_stack = ref [] type eq_kind = | EqStrict | EqCoreType | EqRightDynamic | EqBothDynamic | EqDoNotFollowNull (* like EqStrict, but does not follow Null *) let rec type_eq param a b = let can_follow t = match param with | EqCoreType -> false | EqDoNotFollowNull -> not (is_explicit_null t) | _ -> true in if a == b then () else match a , b with | TLazy f , _ -> type_eq param (!f()) b | _ , TLazy f -> type_eq param a (!f()) | TMono t , _ -> (match !t with | None -> if param = EqCoreType || not (link t a b) then error [cannot_unify a b] | Some t -> type_eq param t b) | _ , TMono t -> (match !t with | None -> if param = EqCoreType || not (link t b a) then error [cannot_unify a b] | Some t -> type_eq param a t) | TType (t1,tl1), TType (t2,tl2) when (t1 == t2 || (param = EqCoreType && t1.t_path = t2.t_path)) && List.length tl1 = List.length tl2 -> List.iter2 (type_eq param) tl1 tl2 | TType (t,tl) , _ when can_follow a -> type_eq param (apply_params t.t_params tl t.t_type) b | _ , TType (t,tl) when can_follow b -> if List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!eq_stack) then () else begin eq_stack := (a,b) :: !eq_stack; try type_eq param a (apply_params t.t_params tl t.t_type); eq_stack := List.tl !eq_stack; with Unify_error l -> eq_stack := List.tl !eq_stack; error (cannot_unify a b :: l) end | TEnum (e1,tl1) , TEnum (e2,tl2) -> if e1 != e2 && not (param = EqCoreType && e1.e_path = e2.e_path) then error [cannot_unify a b]; List.iter2 (type_eq param) tl1 tl2 | TInst (c1,tl1) , TInst (c2,tl2) -> if c1 != c2 && not (param = EqCoreType && c1.cl_path = c2.cl_path) && (match c1.cl_kind, c2.cl_kind with KExpr _, KExpr _ -> false | _ -> true) then error [cannot_unify a b]; List.iter2 (type_eq param) tl1 tl2 | TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 -> (try type_eq param r1 r2; List.iter2 (fun (n,o1,t1) (_,o2,t2) -> if o1 <> o2 then error [Not_matching_optional n]; type_eq param t1 t2 ) l1 l2 with Unify_error l -> error (cannot_unify a b :: l)) | TDynamic a , TDynamic b -> type_eq param a b | TAbstract (a1,tl1) , TAbstract (a2,tl2) -> if a1 != a2 && not (param = EqCoreType && a1.a_path = a2.a_path) then error [cannot_unify a b]; List.iter2 (type_eq param) tl1 tl2 | TAnon a1, TAnon a2 -> (try PMap.iter (fun n f1 -> try let f2 = PMap.find n a2.a_fields in if f1.cf_kind <> f2.cf_kind && (param = EqStrict || param = EqCoreType || not (unify_kind f1.cf_kind f2.cf_kind)) then error [invalid_kind n f1.cf_kind f2.cf_kind]; let a = f1.cf_type and b = f2.cf_type in if not (List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!eq_stack)) then begin eq_stack := (a,b) :: !eq_stack; try type_eq param a b; eq_stack := List.tl !eq_stack; with Unify_error l -> eq_stack := List.tl !eq_stack; error (invalid_field n :: l) end; with Not_found -> if is_closed a2 then error [has_no_field b n]; if not (link (ref None) b f1.cf_type) then error [cannot_unify a b]; a2.a_fields <- PMap.add n f1 a2.a_fields ) a1.a_fields; PMap.iter (fun n f2 -> if not (PMap.mem n a1.a_fields) then begin if is_closed a1 then error [has_no_field a n]; if not (link (ref None) a f2.cf_type) then error [cannot_unify a b]; a1.a_fields <- PMap.add n f2 a1.a_fields end; ) a2.a_fields; with Unify_error l -> error (cannot_unify a b :: l)) | _ , _ -> if b == t_dynamic && (param = EqRightDynamic || param = EqBothDynamic) then () else if a == t_dynamic && param = EqBothDynamic then () else error [cannot_unify a b] let type_iseq a b = try type_eq EqStrict a b; true with Unify_error _ -> false let type_iseq_strict a b = try type_eq EqDoNotFollowNull a b; true with Unify_error _ -> false let unify_stack = ref [] let abstract_cast_stack = ref [] let unify_new_monos = ref [] let print_stacks() = let ctx = print_context() in let st = s_type ctx in print_endline "unify_stack"; List.iter (fun (a,b) -> Printf.printf "\t%s , %s\n" (st a) (st b)) !unify_stack; print_endline "monos"; List.iter (fun m -> print_endline ("\t" ^ st m)) !unify_new_monos; print_endline "abstract_cast_stack"; List.iter (fun (a,b) -> Printf.printf "\t%s , %s\n" (st a) (st b)) !abstract_cast_stack let rec unify a b = if a == b then () else match a, b with | TLazy f , _ -> unify (!f()) b | _ , TLazy f -> unify a (!f()) | TMono t , _ -> (match !t with | None -> if not (link t a b) then error [cannot_unify a b] | Some t -> unify t b) | _ , TMono t -> (match !t with | None -> if not (link t b a) then error [cannot_unify a b] | Some t -> unify a t) | TType (t,tl) , _ -> if not (List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!unify_stack)) then begin try unify_stack := (a,b) :: !unify_stack; unify (apply_params t.t_params tl t.t_type) b; unify_stack := List.tl !unify_stack; with Unify_error l -> unify_stack := List.tl !unify_stack; error (cannot_unify a b :: l) end | _ , TType (t,tl) -> if not (List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!unify_stack)) then begin try unify_stack := (a,b) :: !unify_stack; unify a (apply_params t.t_params tl t.t_type); unify_stack := List.tl !unify_stack; with Unify_error l -> unify_stack := List.tl !unify_stack; error (cannot_unify a b :: l) end | TEnum (ea,tl1) , TEnum (eb,tl2) -> if ea != eb then error [cannot_unify a b]; unify_type_params a b tl1 tl2 | TAbstract (a1,tl1) , TAbstract (a2,tl2) when a1 == a2 -> begin try unify_type_params a b tl1 tl2 with Unify_error _ as err -> (* the type could still have a from/to relation to itself (issue #3494) *) begin try unify_abstracts a b a1 tl1 a2 tl2 with Unify_error _ -> raise err end end | TAbstract ({a_path=[],"Void"},_) , _ | _ , TAbstract ({a_path=[],"Void"},_) -> error [cannot_unify a b] | TAbstract (a1,tl1) , TAbstract (a2,tl2) -> unify_abstracts a b a1 tl1 a2 tl2 | TInst (c1,tl1) , TInst (c2,tl2) -> let rec loop c tl = if c == c2 then begin unify_type_params a b tl tl2; true end else (match c.cl_super with | None -> false | Some (cs,tls) -> loop cs (List.map (apply_params c.cl_params tl) tls) ) || List.exists (fun (cs,tls) -> loop cs (List.map (apply_params c.cl_params tl) tls) ) c.cl_implements || (match c.cl_kind with | KTypeParameter pl -> List.exists (fun t -> match follow t with | TInst (cs,tls) -> loop cs (List.map (apply_params c.cl_params tl) tls) | TAbstract(aa,tl) -> List.exists (unify_to aa tl b) aa.a_to | _ -> false ) pl | _ -> false) in if not (loop c1 tl1) then error [cannot_unify a b] | TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 -> let i = ref 0 in (try (match r2 with | TAbstract ({a_path=[],"Void"},_) -> incr i | _ -> unify r1 r2; incr i); List.iter2 (fun (_,o1,t1) (_,o2,t2) -> if o1 && not o2 then error [Cant_force_optional]; unify t1 t2; incr i ) l2 l1 (* contravariance *) with Unify_error l -> let msg = if !i = 0 then "Cannot unify return types" else "Cannot unify argument " ^ (string_of_int !i) in error (cannot_unify a b :: Unify_custom msg :: l)) | TInst (c,tl) , TAnon an -> if PMap.is_empty an.a_fields then (match c.cl_kind with | KTypeParameter pl -> (* one of the constraints must unify with { } *) if not (List.exists (fun t -> match follow t with TInst _ | TAnon _ -> true | _ -> false) pl) then error [cannot_unify a b] | _ -> ()); (try PMap.iter (fun n f2 -> (* introducing monomorphs while unifying might create infinite loops - see #2315 let's store these monomorphs and make sure we reach a fixed point *) let monos = ref [] in let make_type f = match f.cf_params with | [] -> f.cf_type | l -> let ml = List.map (fun _ -> mk_mono()) l in monos := ml; apply_params f.cf_params ml f.cf_type in let _, ft, f1 = (try raw_class_field make_type c tl n with Not_found -> error [has_no_field a n]) in let ft = apply_params c.cl_params tl ft in if not (unify_kind f1.cf_kind f2.cf_kind) then error [invalid_kind n f1.cf_kind f2.cf_kind]; if f2.cf_public && not f1.cf_public then error [invalid_visibility n]; (match f2.cf_kind with | Var { v_read = AccNo } | Var { v_read = AccNever } -> (* we will do a recursive unification, so let's check for possible recursion *) let old_monos = !unify_new_monos in unify_new_monos := !monos @ !unify_new_monos; if not (List.exists (fun (a2,b2) -> fast_eq b2 f2.cf_type && fast_eq_mono !unify_new_monos ft a2) (!unify_stack)) then begin unify_stack := (ft,f2.cf_type) :: !unify_stack; (try unify_with_access ft f2 with Unify_error l -> unify_new_monos := old_monos; unify_stack := List.tl !unify_stack; error (invalid_field n :: l)); unify_stack := List.tl !unify_stack; end; unify_new_monos := old_monos; | Method MethNormal | Method MethInline | Var { v_write = AccNo } | Var { v_write = AccNever } -> (* same as before, but unification is reversed (read-only var) *) let old_monos = !unify_new_monos in unify_new_monos := !monos @ !unify_new_monos; if not (List.exists (fun (a2,b2) -> fast_eq b2 ft && fast_eq_mono !unify_new_monos f2.cf_type a2) (!unify_stack)) then begin unify_stack := (f2.cf_type,ft) :: !unify_stack; (try unify_with_access ft f2 with Unify_error l -> unify_new_monos := old_monos; unify_stack := List.tl !unify_stack; error (invalid_field n :: l)); unify_stack := List.tl !unify_stack; end; unify_new_monos := old_monos; | _ -> (* will use fast_eq, which have its own stack *) try unify_with_access ft f2 with Unify_error l -> error (invalid_field n :: l)); List.iter (fun f2o -> if not (List.exists (fun f1o -> type_iseq f1o.cf_type f2o.cf_type) (f1 :: f1.cf_overloads)) then error [Missing_overload (f1, f2o.cf_type)] ) f2.cf_overloads; (* we mark the field as :?used because it might be used through the structure *) if not (Meta.has Meta.MaybeUsed f1.cf_meta) then f1.cf_meta <- (Meta.MaybeUsed,[],f1.cf_pos) :: f1.cf_meta; (match f1.cf_kind with | Method MethInline -> if (c.cl_extern || Meta.has Meta.Extern f1.cf_meta) && not (Meta.has Meta.Runtime f1.cf_meta) then error [Has_no_runtime_field (a,n)]; | _ -> ()); ) an.a_fields; (match !(an.a_status) with | Opened -> an.a_status := Closed; | Statics _ | EnumStatics _ | AbstractStatics _ -> error [] | Closed | Extend _ | Const -> ()) with Unify_error l -> error (cannot_unify a b :: l)) | TAnon a1, TAnon a2 -> unify_anons a b a1 a2 | TAnon an, TAbstract ({ a_path = [],"Class" },[pt]) -> (match !(an.a_status) with | Statics cl -> unify (TInst (cl,List.map (fun _ -> mk_mono()) cl.cl_params)) pt | _ -> error [cannot_unify a b]) | TAnon an, TAbstract ({ a_path = [],"Enum" },[pt]) -> (match !(an.a_status) with | EnumStatics e -> unify (TEnum (e,List.map (fun _ -> mk_mono()) e.e_params)) pt | _ -> error [cannot_unify a b]) | TEnum _, TAbstract ({ a_path = [],"EnumValue" },[]) -> () | TEnum(en,_), TAbstract ({ a_path = ["haxe"],"FlatEnum" },[]) when Meta.has Meta.FlatEnum en.e_meta -> () | TFun _, TAbstract ({ a_path = ["haxe"],"Function" },[]) -> () | TInst(c,tl),TAbstract({a_path = ["haxe"],"Constructible"},[t1]) -> begin try begin match c.cl_kind with | KTypeParameter tl -> (* type parameters require an equal Constructible constraint *) if not (List.exists (fun t -> match follow t with TAbstract({a_path = ["haxe"],"Constructible"},[t2]) -> type_iseq t1 t2 | _ -> false) tl) then error [cannot_unify a b] | _ -> let _,t,cf = class_field c tl "new" in if not cf.cf_public then error [invalid_visibility "new"]; begin try unify t1 t with Unify_error l -> error (cannot_unify a b :: l) end end with Not_found -> error [has_no_field a "new"] end | TDynamic t , _ -> if t == a then () else (match b with | TDynamic t2 -> if t2 != b then (try type_eq EqRightDynamic t t2 with Unify_error l -> error (cannot_unify a b :: l)); | TAbstract(bb,tl) when (List.exists (unify_from bb tl a b) bb.a_from) -> () | _ -> error [cannot_unify a b]) | _ , TDynamic t -> if t == b then () else (match a with | TDynamic t2 -> if t2 != a then (try type_eq EqRightDynamic t t2 with Unify_error l -> error (cannot_unify a b :: l)); | TAnon an -> (try (match !(an.a_status) with | Statics _ | EnumStatics _ -> error [] | Opened -> an.a_status := Closed | _ -> ()); PMap.iter (fun _ f -> try type_eq EqStrict (field_type f) t with Unify_error l -> error (invalid_field f.cf_name :: l) ) an.a_fields with Unify_error l -> error (cannot_unify a b :: l)) | TAbstract(aa,tl) when (List.exists (unify_to aa tl b) aa.a_to) -> () | _ -> error [cannot_unify a b]) | TAbstract (aa,tl), _ -> if not (List.exists (unify_to aa tl b) aa.a_to) then error [cannot_unify a b]; | TInst ({ cl_kind = KTypeParameter ctl } as c,pl), TAbstract (bb,tl) -> (* one of the constraints must satisfy the abstract *) if not (List.exists (fun t -> let t = apply_params c.cl_params pl t in try unify t b; true with Unify_error _ -> false ) ctl) && not (List.exists (unify_from bb tl a b) bb.a_from) then error [cannot_unify a b]; | _, TAbstract (bb,tl) -> if not (List.exists (unify_from bb tl a b) bb.a_from) then error [cannot_unify a b] | _ , _ -> error [cannot_unify a b] and unify_abstracts a b a1 tl1 a2 tl2 = let f1 = unify_to a1 tl1 b in let f2 = unify_from a2 tl2 a b in if (List.exists (f1 ~allow_transitive_cast:false) a1.a_to) || (List.exists (f2 ~allow_transitive_cast:false) a2.a_from) || (((Meta.has Meta.CoreType a1.a_meta) || (Meta.has Meta.CoreType a2.a_meta)) && ((List.exists f1 a1.a_to) || (List.exists f2 a2.a_from))) then () else error [cannot_unify a b] and unify_anons a b a1 a2 = (try PMap.iter (fun n f2 -> try let f1 = PMap.find n a1.a_fields in if not (unify_kind f1.cf_kind f2.cf_kind) then (match !(a1.a_status), f1.cf_kind, f2.cf_kind with | Opened, Var { v_read = AccNormal; v_write = AccNo }, Var { v_read = AccNormal; v_write = AccNormal } -> f1.cf_kind <- f2.cf_kind; | _ -> error [invalid_kind n f1.cf_kind f2.cf_kind]); if f2.cf_public && not f1.cf_public then error [invalid_visibility n]; try unify_with_access f1.cf_type f2; (match !(a1.a_status) with | Statics c when not (Meta.has Meta.MaybeUsed f1.cf_meta) -> f1.cf_meta <- (Meta.MaybeUsed,[],f1.cf_pos) :: f1.cf_meta | _ -> ()); with Unify_error l -> error (invalid_field n :: l) with Not_found -> match !(a1.a_status) with | Opened -> if not (link (ref None) a f2.cf_type) then error []; a1.a_fields <- PMap.add n f2 a1.a_fields | Const when Meta.has Meta.Optional f2.cf_meta -> () | _ -> error [has_no_field a n]; ) a2.a_fields; (match !(a1.a_status) with | Const when not (PMap.is_empty a2.a_fields) -> PMap.iter (fun n _ -> if not (PMap.mem n a2.a_fields) then error [has_extra_field a n]) a1.a_fields; | Opened -> a1.a_status := Closed | _ -> ()); (match !(a2.a_status) with | Statics c -> (match !(a1.a_status) with Statics c2 when c == c2 -> () | _ -> error []) | EnumStatics e -> (match !(a1.a_status) with EnumStatics e2 when e == e2 -> () | _ -> error []) | AbstractStatics a -> (match !(a1.a_status) with AbstractStatics a2 when a == a2 -> () | _ -> error []) | Opened -> a2.a_status := Closed | Const | Extend _ | Closed -> ()) with Unify_error l -> error (cannot_unify a b :: l)) and unify_from ab tl a b ?(allow_transitive_cast=true) t = if (List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!abstract_cast_stack)) then false else begin abstract_cast_stack := (a,b) :: !abstract_cast_stack; let t = apply_params ab.a_params tl t in let unify_func = if allow_transitive_cast then unify else type_eq EqStrict in let b = try unify_func a t; true with Unify_error _ -> false in abstract_cast_stack := List.tl !abstract_cast_stack; b end and unify_to ab tl b ?(allow_transitive_cast=true) t = let t = apply_params ab.a_params tl t in let unify_func = if allow_transitive_cast then unify else type_eq EqStrict in try unify_func t b; true with Unify_error _ -> false and unify_from_field ab tl a b ?(allow_transitive_cast=true) (t,cf) = if (List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!abstract_cast_stack)) then false else begin abstract_cast_stack := (a,b) :: !abstract_cast_stack; let unify_func = if allow_transitive_cast then unify else type_eq EqStrict in let b = try begin match follow cf.cf_type with | TFun(_,r) -> let monos = List.map (fun _ -> mk_mono()) cf.cf_params in let map t = apply_params ab.a_params tl (apply_params cf.cf_params monos t) in unify_func a (map t); 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 []) | _ -> unify m (map tc) ) constr | _ -> () ) monos cf.cf_params; unify_func (map r) b; | _ -> assert false end; true with Unify_error _ -> false in abstract_cast_stack := List.tl !abstract_cast_stack; b end and unify_to_field ab tl b ?(allow_transitive_cast=true) (t,cf) = let a = TAbstract(ab,tl) in if (List.exists (fun (b2,a2) -> fast_eq a a2 && fast_eq b b2) (!abstract_cast_stack)) then false else begin abstract_cast_stack := (b,a) :: !abstract_cast_stack; let unify_func = if allow_transitive_cast then unify else type_eq EqStrict in let r = try begin match follow cf.cf_type with | TFun((_,_,ta) :: _,_) -> let monos = List.map (fun _ -> mk_mono()) cf.cf_params in let map t = apply_params ab.a_params tl (apply_params cf.cf_params monos t) in let athis = map ab.a_this in (* we cannot allow implicit casts when the this type is not completely known yet *) (* if has_mono athis then raise (Unify_error []); *) with_variance (type_eq EqStrict) athis (map ta); (* immediate constraints checking is ok here because we know there are no monomorphs *) 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 []) | _ -> unify m (map tc) ) constr | _ -> () ) monos cf.cf_params; unify_func (map t) b; | _ -> assert false end; true with Unify_error _ -> false in abstract_cast_stack := List.tl !abstract_cast_stack; r end and unify_with_variance f t1 t2 = let allows_variance_to t tf = type_iseq tf t in match follow t1,follow t2 with | TInst(c1,tl1),TInst(c2,tl2) when c1 == c2 -> List.iter2 f tl1 tl2 | TEnum(en1,tl1),TEnum(en2,tl2) when en1 == en2 -> List.iter2 f tl1 tl2 | TAbstract(a1,tl1),TAbstract(a2,tl2) when a1 == a2 && Meta.has Meta.CoreType a1.a_meta -> List.iter2 f tl1 tl2 | TAbstract(a1,pl1),TAbstract(a2,pl2) -> if (Meta.has Meta.CoreType a1.a_meta) && (Meta.has Meta.CoreType a2.a_meta) then begin let ta1 = apply_params a1.a_params pl1 a1.a_this in let ta2 = apply_params a2.a_params pl2 a2.a_this in type_eq EqStrict ta1 ta2; end; if not (List.exists (allows_variance_to t2) a1.a_to) && not (List.exists (allows_variance_to t1) a2.a_from) then error [cannot_unify t1 t2] | TAbstract(a,pl),t -> type_eq EqBothDynamic (apply_params a.a_params pl a.a_this) t; if not (List.exists (fun t2 -> allows_variance_to t (apply_params a.a_params pl t2)) a.a_to) then error [cannot_unify t1 t2] | t,TAbstract(a,pl) -> type_eq EqBothDynamic t (apply_params a.a_params pl a.a_this); if not (List.exists (fun t2 -> allows_variance_to t (apply_params a.a_params pl t2)) a.a_from) then error [cannot_unify t1 t2] | TAnon a1,TAnon a2 -> unify_anons t1 t2 a1 a2 | _ -> error [cannot_unify t1 t2] and unify_type_params a b tl1 tl2 = List.iter2 (fun t1 t2 -> try with_variance (type_eq EqRightDynamic) t1 t2 with Unify_error l -> let err = cannot_unify a b in error (err :: (Invariant_parameter (t1,t2)) :: l) ) tl1 tl2 and with_variance f t1 t2 = try f t1 t2 with Unify_error l -> try unify_with_variance (with_variance f) t1 t2 with Unify_error _ -> raise (Unify_error l) and unify_with_access t1 f2 = match f2.cf_kind with (* write only *) | Var { v_read = AccNo } | Var { v_read = AccNever } -> unify f2.cf_type t1 (* read only *) | Method MethNormal | Method MethInline | Var { v_write = AccNo } | Var { v_write = AccNever } -> unify t1 f2.cf_type (* read/write *) | _ -> with_variance (type_eq EqBothDynamic) t1 f2.cf_type (* ======= Mapping and iterating ======= *) let 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 e1; f e2; | TThrow e | TField (e,_) | TEnumParameter (e,_,_) | TParenthesis e | TCast (e,_) | TUnop (_,_,e) | TMeta(_,e) -> f e | TArrayDecl el | TNew (_,_,el) | TBlock el -> List.iter f el | TObjectDecl fl -> List.iter (fun (_,e) -> f e) fl | TCall (e,el) -> f e; List.iter f el | TVar (v,eo) -> (match eo with None -> () | Some e -> f e) | TFunction fu -> f fu.tf_expr | TIf (e,e1,e2) -> f e; f e1; (match e2 with None -> () | Some e -> f e) | TSwitch (e,cases,def) -> f e; List.iter (fun (el,e2) -> List.iter f el; f e2) cases; (match def with None -> () | Some e -> f e) | TTry (e,catches) -> f e; List.iter (fun (_,e) -> f e) catches | TReturn eo -> (match eo with None -> () | Some e -> f e) let map_expr f e = match e.eexpr with | TConst _ | TLocal _ | TBreak | TContinue | TTypeExpr _ -> e | TArray (e1,e2) -> let e1 = f e1 in { e with eexpr = TArray (e1,f e2) } | TBinop (op,e1,e2) -> let e1 = f e1 in { e with eexpr = TBinop (op,e1,f e2) } | TFor (v,e1,e2) -> let e1 = f e1 in { e with eexpr = TFor (v,e1,f e2) } | TWhile (e1,e2,flag) -> let e1 = f e1 in { e with eexpr = TWhile (e1,f e2,flag) } | TThrow e1 -> { e with eexpr = TThrow (f e1) } | TEnumParameter (e1,ef,i) -> { e with eexpr = TEnumParameter(f e1,ef,i) } | TField (e1,v) -> { e with eexpr = TField (f e1,v) } | TParenthesis e1 -> { e with eexpr = TParenthesis (f e1) } | TUnop (op,pre,e1) -> { e with eexpr = TUnop (op,pre,f e1) } | TArrayDecl el -> { e with eexpr = TArrayDecl (List.map f el) } | TNew (t,pl,el) -> { e with eexpr = TNew (t,pl,List.map f el) } | TBlock el -> { e with eexpr = TBlock (List.map f el) } | TObjectDecl el -> { e with eexpr = TObjectDecl (List.map (fun (v,e) -> v, f e) el) } | TCall (e1,el) -> let e1 = f e1 in { e with eexpr = TCall (e1, List.map f el) } | TVar (v,eo) -> { e with eexpr = TVar (v, match eo with None -> None | Some e -> Some (f e)) } | TFunction fu -> { e with eexpr = TFunction { fu with tf_expr = f fu.tf_expr } } | TIf (ec,e1,e2) -> let ec = f ec in let e1 = f e1 in { e with eexpr = TIf (ec,e1,match e2 with None -> None | Some e -> Some (f e)) } | TSwitch (e1,cases,def) -> let e1 = f e1 in let cases = List.map (fun (el,e2) -> List.map f el, f e2) cases in { e with eexpr = TSwitch (e1, cases, match def with None -> None | Some e -> Some (f e)) } | TTry (e1,catches) -> let e1 = f e1 in { e with eexpr = TTry (e1, List.map (fun (v,e) -> v, f e) catches) } | TReturn eo -> { e with eexpr = TReturn (match eo with None -> None | Some e -> Some (f e)) } | TCast (e1,t) -> { e with eexpr = TCast (f e1,t) } | TMeta (m,e1) -> {e with eexpr = TMeta(m,f e1)} let map_expr_type f ft fv e = match e.eexpr with | TConst _ | TBreak | TContinue | TTypeExpr _ -> { e with etype = ft e.etype } | TLocal v -> { e with eexpr = TLocal (fv v); etype = ft e.etype } | TArray (e1,e2) -> let e1 = f e1 in { e with eexpr = TArray (e1,f e2); etype = ft e.etype } | TBinop (op,e1,e2) -> let e1 = f e1 in { e with eexpr = TBinop (op,e1,f e2); etype = ft e.etype } | TFor (v,e1,e2) -> let v = fv v in let e1 = f e1 in { e with eexpr = TFor (v,e1,f e2); etype = ft e.etype } | TWhile (e1,e2,flag) -> let e1 = f e1 in { e with eexpr = TWhile (e1,f e2,flag); etype = ft e.etype } | TThrow e1 -> { e with eexpr = TThrow (f e1); etype = ft e.etype } | TEnumParameter (e1,ef,i) -> { e with eexpr = TEnumParameter(f e1,ef,i); etype = ft e.etype } | TField (e1,v) -> let e1 = f e1 in let v = try let n = match v with | FClosure _ -> raise Not_found | FAnon f | FInstance (_,_,f) | FStatic (_,f) -> f.cf_name | FEnum (_,f) -> f.ef_name | FDynamic n -> n in quick_field e1.etype n with Not_found -> v in { e with eexpr = TField (e1,v); etype = ft e.etype } | TParenthesis e1 -> { e with eexpr = TParenthesis (f e1); etype = ft e.etype } | TUnop (op,pre,e1) -> { e with eexpr = TUnop (op,pre,f e1); etype = ft e.etype } | TArrayDecl el -> { e with eexpr = TArrayDecl (List.map f el); etype = ft e.etype } | TNew (c,pl,el) -> let et = ft e.etype in (* make sure that we use the class corresponding to the replaced type *) let t = match c.cl_kind with | KTypeParameter _ | KGeneric -> et | _ -> ft (TInst(c,pl)) in let c, pl = (match follow t with TInst (c,pl) -> (c,pl) | TAbstract({a_impl = Some c},pl) -> c,pl | t -> error [has_no_field t "new"]) in { e with eexpr = TNew (c,pl,List.map f el); etype = et } | TBlock el -> { e with eexpr = TBlock (List.map f el); etype = ft e.etype } | TObjectDecl el -> { e with eexpr = TObjectDecl (List.map (fun (v,e) -> v, f e) el); etype = ft e.etype } | TCall (e1,el) -> let e1 = f e1 in { e with eexpr = TCall (e1, List.map f el); etype = ft e.etype } | TVar (v,eo) -> { e with eexpr = TVar (fv v, match eo with None -> None | Some e -> Some (f e)); etype = ft e.etype } | TFunction fu -> let fu = { tf_expr = f fu.tf_expr; tf_args = List.map (fun (v,o) -> fv v, o) fu.tf_args; tf_type = ft fu.tf_type; } in { e with eexpr = TFunction fu; etype = ft e.etype } | TIf (ec,e1,e2) -> let ec = f ec in let e1 = f e1 in { e with eexpr = TIf (ec,e1,match e2 with None -> None | Some e -> Some (f e)); etype = ft e.etype } | TSwitch (e1,cases,def) -> let e1 = f e1 in let cases = List.map (fun (el,e2) -> List.map f el, f e2) cases in { e with eexpr = TSwitch (e1, cases, match def with None -> None | Some e -> Some (f e)); etype = ft e.etype } | TTry (e1,catches) -> let e1 = f e1 in { e with eexpr = TTry (e1, List.map (fun (v,e) -> fv v, f e) catches); etype = ft e.etype } | TReturn eo -> { e with eexpr = TReturn (match eo with None -> None | Some e -> Some (f e)); etype = ft e.etype } | TCast (e1,t) -> { e with eexpr = TCast (f e1,t); etype = ft e.etype } | TMeta (m,e1) -> {e with eexpr = TMeta(m, f e1); etype = ft e.etype } let resolve_typedef t = match t with | TClassDecl _ | TEnumDecl _ | TAbstractDecl _ -> t | TTypeDecl td -> match follow td.t_type with | TEnum (e,_) -> TEnumDecl e | TInst (c,_) -> TClassDecl c | TAbstract (a,_) -> TAbstractDecl a | _ -> t module TExprToExpr = struct let tpath p mp pl = if snd mp = snd p then CTPath { tpackage = fst p; tname = snd p; tparams = List.map (fun t -> TPType t) pl; tsub = None; } else CTPath { tpackage = fst mp; tname = snd mp; tparams = List.map (fun t -> TPType t) pl; tsub = Some (snd p); } let rec convert_type = function | TMono r -> (match !r with | None -> raise Exit | Some t -> convert_type t) | TInst ({cl_private = true; cl_path=_,name},tl) | TEnum ({e_private = true; e_path=_,name},tl) | TType ({t_private = true; t_path=_,name},tl) | TAbstract ({a_private = true; a_path=_,name},tl) -> CTPath { tpackage = []; tname = name; tparams = List.map (fun t -> TPType (convert_type' t)) tl; tsub = None; } | TEnum (e,pl) -> tpath e.e_path e.e_module.m_path (List.map convert_type' pl) | TInst({cl_kind = KTypeParameter _} as c,pl) -> tpath ([],snd c.cl_path) ([],snd c.cl_path) (List.map convert_type' pl) | TInst (c,pl) -> tpath c.cl_path c.cl_module.m_path (List.map convert_type' pl) | TType (t,pl) as tf -> (* recurse on type-type *) if (snd t.t_path).[0] = '#' then convert_type (follow tf) else tpath t.t_path t.t_module.m_path (List.map convert_type' pl) | TAbstract (a,pl) -> tpath a.a_path a.a_module.m_path (List.map convert_type' pl) | TFun (args,ret) -> CTFunction (List.map (fun (_,_,t) -> convert_type' t) args, (convert_type' ret)) | TAnon a -> begin match !(a.a_status) with | Statics c -> tpath ([],"Class") ([],"Class") [tpath c.cl_path c.cl_path [],null_pos] | EnumStatics e -> tpath ([],"Enum") ([],"Enum") [tpath e.e_path e.e_path [],null_pos] | _ -> CTAnonymous (PMap.foldi (fun _ f acc -> { cff_name = f.cf_name,null_pos; cff_kind = FVar (mk_type_hint f.cf_type null_pos,None); cff_pos = f.cf_pos; cff_doc = f.cf_doc; cff_meta = f.cf_meta; cff_access = []; } :: acc ) a.a_fields []) end | (TDynamic t2) as t -> tpath ([],"Dynamic") ([],"Dynamic") (if t == t_dynamic then [] else [convert_type' t2]) | TLazy f -> convert_type ((!f)()) and convert_type' t = convert_type t,null_pos and mk_type_hint t p = match follow t with | TMono _ -> None | _ -> (try Some (convert_type t,p) with Exit -> None) let rec convert_expr e = let full_type_path t = let mp,p = match t with | TClassDecl c -> c.cl_module.m_path,c.cl_path | TEnumDecl en -> en.e_module.m_path,en.e_path | TAbstractDecl a -> a.a_module.m_path,a.a_path | TTypeDecl t -> t.t_module.m_path,t.t_path in if snd mp = snd p then p else (fst mp) @ [snd mp],snd p in let mk_path = expr_of_type_path in let mk_ident = function | "`trace" -> Ident "trace" | n -> Ident n in let eopt = function None -> None | Some e -> Some (convert_expr e) in ((match e.eexpr with | TConst c -> EConst (tconst_to_const c) | TLocal v -> EConst (mk_ident v.v_name) | TArray (e1,e2) -> EArray (convert_expr e1,convert_expr e2) | TBinop (op,e1,e2) -> EBinop (op, convert_expr e1, convert_expr e2) | TField (e,f) -> EField (convert_expr e, field_name f) | TTypeExpr t -> fst (mk_path (full_type_path t) e.epos) | TParenthesis e -> EParenthesis (convert_expr e) | TObjectDecl fl -> EObjectDecl (List.map (fun (f,e) -> (f,null_pos), convert_expr e) fl) | TArrayDecl el -> EArrayDecl (List.map convert_expr el) | TCall (e,el) -> ECall (convert_expr e,List.map convert_expr el) | TNew (c,pl,el) -> ENew ((match (try convert_type (TInst (c,pl)) with Exit -> convert_type (TInst (c,[]))) with CTPath p -> p,null_pos | _ -> assert false),List.map convert_expr el) | TUnop (op,p,e) -> EUnop (op,p,convert_expr e) | TFunction f -> let arg (v,c) = (v.v_name,v.v_pos), false, v.v_meta, mk_type_hint v.v_type null_pos, (match c with None -> None | Some c -> Some (EConst (tconst_to_const c),e.epos)) in EFunction (None,{ f_params = []; f_args = List.map arg f.tf_args; f_type = mk_type_hint f.tf_type null_pos; f_expr = Some (convert_expr f.tf_expr) }) | TVar (v,eo) -> EVars ([(v.v_name,v.v_pos), mk_type_hint v.v_type v.v_pos, eopt eo]) | TBlock el -> EBlock (List.map convert_expr el) | TFor (v,it,e) -> let ein = (EIn ((EConst (Ident v.v_name),it.epos),convert_expr it),it.epos) in EFor (ein,convert_expr e) | TIf (e,e1,e2) -> EIf (convert_expr e,convert_expr e1,eopt e2) | TWhile (e1,e2,flag) -> EWhile (convert_expr e1, convert_expr e2, flag) | TSwitch (e,cases,def) -> let cases = List.map (fun (vl,e) -> List.map convert_expr vl,None,(match e.eexpr with TBlock [] -> None | _ -> Some (convert_expr e)),e.epos ) cases in let def = match eopt def with None -> None | Some (EBlock [],_) -> Some (None,null_pos) | Some e -> Some (Some e,pos e) in ESwitch (convert_expr e,cases,def) | TEnumParameter _ -> (* these are considered complex, so the AST is handled in TMeta(Meta.Ast) *) assert false | TTry (e,catches) -> let e1 = convert_expr e in let catches = List.map (fun (v,e) -> let ct = try convert_type v.v_type,null_pos with Exit -> assert false in let e = convert_expr e in (v.v_name,v.v_pos),ct,e,(pos e) ) catches in ETry (e1,catches) | TReturn e -> EReturn (eopt e) | TBreak -> EBreak | TContinue -> EContinue | TThrow e -> EThrow (convert_expr e) | TCast (e,t) -> let t = (match t with | None -> None | Some t -> let t = (match t with TClassDecl c -> TInst (c,[]) | TEnumDecl e -> TEnum (e,[]) | TTypeDecl t -> TType (t,[]) | TAbstractDecl a -> TAbstract (a,[])) in Some (try convert_type t,null_pos with Exit -> assert false) ) in ECast (convert_expr e,t) | TMeta ((Meta.Ast,[e1,_],_),_) -> e1 | TMeta (m,e) -> EMeta(m,convert_expr e)) ,e.epos) end module Texpr = struct let equal_fa fa1 fa2 = match fa1,fa2 with | FStatic(c1,cf1),FStatic(c2,cf2) -> c1 == c2 && cf1 == cf2 | FInstance(c1,tl1,cf1),FInstance(c2,tl2,cf2) -> c1 == c2 && safe_for_all2 type_iseq tl1 tl2 && cf1 == cf2 (* TODO: This is technically not correct but unfortunately the compiler makes a distinct tclass_field for each anon field access. *) | FAnon cf1,FAnon cf2 -> cf1.cf_name = cf2.cf_name | FDynamic s1,FDynamic s2 -> s1 = s2 | FClosure(None,cf1),FClosure(None,cf2) -> cf1 == cf2 | FClosure(Some(c1,tl1),cf1),FClosure(Some(c2,tl2),cf2) -> c1 == c2 && safe_for_all2 type_iseq tl1 tl2 && cf1 == cf2 | FEnum(en1,ef1),FEnum(en2,ef2) -> en1 == en2 && ef1 == ef2 | _ -> false let rec equal e1 e2 = match e1.eexpr,e2.eexpr with | TConst ct1,TConst ct2 -> ct1 = ct2 | TLocal v1,TLocal v2 -> v1 == v2 | TArray(eb1,ei1),TArray(eb2,ei2) -> equal eb1 eb2 && equal ei1 ei2 | TBinop(op1,lhs1,rhs1),TBinop(op2,lhs2,rhs2) -> op1 = op2 && equal lhs1 lhs2 && equal rhs1 rhs2 | TField(e1,fa1),TField(e2,fa2) -> equal e1 e2 && equal_fa fa1 fa2 | TTypeExpr mt1,TTypeExpr mt2 -> mt1 == mt2 | TParenthesis e1,TParenthesis e2 -> equal e1 e2 | TObjectDecl fl1,TObjectDecl fl2 -> safe_for_all2 (fun (s1,e1) (s2,e2) -> s1 = s2 && equal e1 e2) fl1 fl2 | (TArrayDecl el1,TArrayDecl el2) | (TBlock el1,TBlock el2) -> safe_for_all2 equal el1 el2 | TCall(e1,el1),TCall(e2,el2) -> equal e1 e2 && safe_for_all2 equal el1 el2 | TNew(c1,tl1,el1),TNew(c2,tl2,el2) -> c1 == c2 && safe_for_all2 type_iseq tl1 tl2 && safe_for_all2 equal el1 el2 | TUnop(op1,flag1,e1),TUnop(op2,flag2,e2) -> op1 = op2 && flag1 = flag2 && equal e1 e2 | TFunction tf1,TFunction tf2 -> tf1 == tf2 | TVar(v1,None),TVar(v2,None) -> v1 == v2 | TVar(v1,Some e1),TVar(v2,Some e2) -> v1 == v2 && equal e1 e2 | TFor(v1,ec1,eb1),TFor(v2,ec2,eb2) -> v1 == v2 && equal ec1 ec2 && equal eb1 eb2 | TIf(e1,ethen1,None),TIf(e2,ethen2,None) -> equal e1 e2 && equal ethen1 ethen2 | TIf(e1,ethen1,Some eelse1),TIf(e2,ethen2,Some eelse2) -> equal e1 e2 && equal ethen1 ethen2 && equal eelse1 eelse2 | TWhile(e1,eb1,flag1),TWhile(e2,eb2,flag2) -> equal e1 e2 && equal eb2 eb2 && flag1 = flag2 | TSwitch(e1,cases1,eo1),TSwitch(e2,cases2,eo2) -> equal e1 e2 && safe_for_all2 (fun (el1,e1) (el2,e2) -> safe_for_all2 equal el1 el2 && equal e1 e2) cases1 cases2 && (match eo1,eo2 with None,None -> true | Some e1,Some e2 -> equal e1 e2 | _ -> false) | TTry(e1,catches1),TTry(e2,catches2) -> equal e1 e2 && safe_for_all2 (fun (v1,e1) (v2,e2) -> v1 == v2 && equal e1 e2) catches1 catches2 | TReturn None,TReturn None -> true | TReturn(Some e1),TReturn(Some e2) -> equal e1 e2 | TThrow e1,TThrow e2 -> equal e1 e2 | TCast(e1,None),TCast(e2,None) -> equal e1 e2 | TCast(e1,Some mt1),TCast(e2,Some mt2) -> equal e1 e2 && mt1 == mt2 | TMeta((m1,el1,_),e1),TMeta((m2,el2,_),e2) -> m1 = m2 && safe_for_all2 (fun e1 e2 -> (* TODO: cheating? *) (Ast.s_expr e1) = (Ast.s_expr e2)) el1 el2 && equal e1 e2 | (TBreak,TBreak) | (TContinue,TContinue) -> true | TEnumParameter(e1,ef1,i1),TEnumParameter(e2,ef2,i2) -> equal e1 e2 && ef1 == ef2 && i1 = i2 | _ -> false let duplicate_tvars e = let vars = Hashtbl.create 0 in let copy_var v = let v2 = alloc_var v.v_name v.v_type v.v_pos 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 | TVar (v,eo) -> let v2 = copy_var v in {e with eexpr = TVar(v2, Option.map build_expr eo)} | TFor (v,e1,e2) -> let v2 = copy_var v in {e with eexpr = TFor(v2, build_expr e1, build_expr e2)} | TTry (e1,cl) -> let cl = List.map (fun (v,e) -> let v2 = copy_var v in v2, build_expr e ) cl in {e with eexpr = TTry(build_expr e1, cl)} | TFunction f -> let args = List.map (fun (v,c) -> copy_var v, c) f.tf_args in let f = { tf_args = args; tf_type = f.tf_type; tf_expr = build_expr f.tf_expr; } in {e with eexpr = TFunction f} | TLocal v -> (try let v2 = Hashtbl.find vars v.v_id in {e with eexpr = TLocal v2} with _ -> e) | _ -> map_expr build_expr e in build_expr e let rec skip e = match e.eexpr with | TParenthesis e1 | TMeta(_,e1) | TBlock [e1] | TCast(e1,None) -> skip e1 | _ -> e let foldmap_list f acc el = let rec loop acc el acc2 = (match el with | [] -> acc,(List.rev acc2) | e1 :: el -> let acc,e1 = f acc e1 in loop acc el (e1 :: acc2)) in loop acc el [] let foldmap_opt f acc eo = match eo with | Some(e) -> let acc,e = f acc e in acc,Some(e) | None -> acc,eo let foldmap_pairs f acc pairs = let acc,pairs = List.fold_left (fun (acc,el) (v,e) -> let acc,e = f acc e in (acc,(v,e) :: el)) (acc,[]) pairs in acc,(List.rev pairs) let foldmap f acc e = begin match e.eexpr with | TConst _ | TLocal _ | TBreak | TContinue | TTypeExpr _ -> acc,e | TArray (e1,e2) -> let acc,e1 = f acc e1 in let acc,e2 = f acc e2 in acc,{ e with eexpr = TArray (e1, e2) } | TBinop (op,e1,e2) -> let acc,e1 = f acc e1 in let acc,e2 = f acc e2 in acc,{ e with eexpr = TBinop (op,e1,e2) } | TFor (v,e1,e2) -> let acc,e1 = f acc e1 in let acc,e2 = f acc e2 in acc,{ e with eexpr = TFor (v,e1,e2) } | TWhile (e1,e2,flag) -> let acc,e1 = f acc e1 in let acc,e2 = f acc e2 in acc,{ e with eexpr = TWhile (e1,e2,flag) } | TThrow e1 -> let acc,e1 = f acc e1 in acc,{ e with eexpr = TThrow (e1) } | TEnumParameter (e1,ef,i) -> let acc,e1 = f acc e1 in acc,{ e with eexpr = TEnumParameter(e1,ef,i) } | TField (e1,v) -> let acc,e1 = f acc e1 in acc,{ e with eexpr = TField (e1,v) } | TParenthesis e1 -> let acc,e1 = f acc e1 in acc,{ e with eexpr = TParenthesis (e1) } | TUnop (op,pre,e1) -> let acc,e1 = f acc e1 in acc,{ e with eexpr = TUnop (op,pre,e1) } | TArrayDecl el -> let acc,el = foldmap_list f acc el in acc,{ e with eexpr = TArrayDecl el } | TNew (t,pl,el) -> let acc,el = foldmap_list f acc el in acc,{ e with eexpr = TNew (t,pl,el) } | TBlock el -> let acc,el = foldmap_list f acc el in acc,{ e with eexpr = TBlock (el) } | TObjectDecl el -> let acc,el = foldmap_pairs f acc el in acc,{ e with eexpr = TObjectDecl el } | TCall (e1,el) -> let acc,e1 = f acc e1 in let acc,el = foldmap_list f acc el in acc,{ e with eexpr = TCall (e1,el) } | TVar (v,eo) -> let acc,eo = foldmap_opt f acc eo in acc,{ e with eexpr = TVar (v, eo) } | TFunction fu -> let acc,e1 = f acc fu.tf_expr in acc,{ e with eexpr = TFunction { fu with tf_expr = e1 } } | TIf (ec,e1,eo) -> let acc,ec = f acc ec in let acc,e1 = f acc e1 in let acc,eo = foldmap_opt f acc eo in acc,{ e with eexpr = TIf (ec,e1,eo)} | TSwitch (e1,cases,def) -> let acc,e1 = f acc e1 in let acc,cases = List.fold_left (fun (acc,cases) (el,e2) -> let acc,el = foldmap_list f acc el in let acc,e2 = f acc e2 in acc,((el,e2) :: cases) ) (acc,[]) cases in let acc,def = foldmap_opt f acc def in acc,{ e with eexpr = TSwitch (e1, cases, def) } | TTry (e1,catches) -> let acc,e1 = f acc e1 in let acc,catches = foldmap_pairs f acc catches in acc,{ e with eexpr = TTry (e1, catches) } | TReturn eo -> let acc,eo = foldmap_opt f acc eo in acc,{ e with eexpr = TReturn eo } | TCast (e1,t) -> let acc,e1 = f acc e1 in acc,{ e with eexpr = TCast (e1,t) } | TMeta (m,e1) -> let acc,e1 = f acc e1 in acc,{ e with eexpr = TMeta(m,e1)} end end module ExtType = struct let is_void = function | TAbstract({a_path=[],"Void"},_) -> true | _ -> false end module StringError = struct (* Source: http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Levenshtein_distance#OCaml *) let levenshtein a b = let x = Array.init (String.length a) (fun i -> a.[i]) in let y = Array.init (String.length b) (fun i -> b.[i]) in let minimum (x:int) y z = let m' (a:int) b = if a < b then a else b in m' (m' x y) z in let init_matrix n m = let init_col = Array.init m in Array.init n (function | 0 -> init_col (function j -> j) | i -> init_col (function 0 -> i | _ -> 0) ) in match Array.length x, Array.length y with | 0, n -> n | m, 0 -> m | m, n -> let matrix = init_matrix (m + 1) (n + 1) in for i = 1 to m do let s = matrix.(i) and t = matrix.(i - 1) in for j = 1 to n do let cost = abs (compare x.(i - 1) y.(j - 1)) in s.(j) <- minimum (t.(j) + 1) (s.(j - 1) + 1) (t.(j - 1) + cost) done done; matrix.(m).(n) let filter_similar f cl = let rec loop sl = match sl with | (x,i) :: sl when f x i -> x :: loop sl | _ -> [] in loop cl let string_error_raise s sl msg = if sl = [] then msg else let cl = List.map (fun s2 -> s2,levenshtein s s2) sl in let cl = List.sort (fun (_,c1) (_,c2) -> compare c1 c2) cl in let cl = filter_similar (fun s2 i -> i <= (min (String.length s) (String.length s2)) / 3) cl in match cl with | [] -> raise Not_found | [s] -> Printf.sprintf "%s (Suggestion: %s)" msg s | sl -> Printf.sprintf "%s (Suggestions: %s)" msg (String.concat ", " sl) let string_error s sl msg = try string_error_raise s sl msg with Not_found -> msg end haxe_3.4.4.orig/src/typing/typecore.ml0000664000175000017500000005571213166552354017713 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Globals open Ast open Common open Type open Error type with_type = | NoValue | Value | WithType of t type type_patch = { mutable tp_type : complex_type option; mutable tp_remove : bool; mutable tp_meta : metadata; } type current_fun = | FunMember | FunStatic | FunConstructor | FunMemberAbstract | FunMemberClassLocal | FunMemberAbstractLocal type macro_mode = | MExpr | MBuild | MMacroType | MDisplay type typer_pass = | PBuildModule (* build the module structure and setup module type parameters *) | PBuildClass (* build the class structure *) | PTypeField (* type the class field, allow access to types structures *) | PCheckConstraint (* perform late constraint checks with inferred types *) | PForce (* usually ensure that lazy have been evaluated *) | PFinal (* not used, only mark for finalize *) type typer_module = { curmod : module_def; mutable module_types : (module_type * pos) list; mutable module_using : (tclass * pos) list; mutable module_globals : (string, (module_type * string * pos)) PMap.t; mutable wildcard_packages : (string list * pos) list; mutable module_imports : import list; } type typer_globals = { types_module : (path, path) Hashtbl.t; modules : (path , module_def) Hashtbl.t; mutable delayed : (typer_pass * (unit -> unit) list) list; mutable debug_delayed : (typer_pass * ((unit -> unit) * string * typer) list) list; doinline : bool; mutable core_api : typer option; mutable macros : ((unit -> unit) * typer) option; mutable std : module_def; mutable hook_generate : (unit -> unit) list; type_patches : (path, (string * bool, type_patch) Hashtbl.t * type_patch) Hashtbl.t; mutable global_metadata : (string list * metadata_entry * (bool * bool * bool)) list; mutable module_check_policies : (string list * module_check_policy list * bool) list; mutable get_build_infos : unit -> (module_type * t list * class_field list) option; delayed_macros : (unit -> unit) DynArray.t; mutable global_using : (tclass * pos) list; (* api *) do_inherit : typer -> Type.tclass -> pos -> (bool * placed_type_path) -> bool; do_create : Common.context -> typer; do_macro : typer -> macro_mode -> path -> string -> expr list -> pos -> expr option; do_load_module : typer -> path -> pos -> module_def; do_optimize : typer -> texpr -> texpr; do_build_instance : typer -> module_type -> pos -> ((string * t) list * path * (t list -> t)); do_format_string : typer -> string -> pos -> Ast.expr; do_finalize : typer -> unit; do_generate : typer -> (texpr option * module_type list * module_def list); } and typer = { (* shared *) com : context; t : basic_types; g : typer_globals; mutable meta : metadata; mutable this_stack : texpr list; mutable with_type_stack : with_type list; mutable call_argument_stack : expr list list; (* variable *) mutable pass : typer_pass; (* per-module *) mutable m : typer_module; mutable is_display_file : bool; (* per-class *) mutable curclass : tclass; mutable tthis : t; mutable type_params : (string * t) list; (* per-function *) mutable curfield : tclass_field; mutable untyped : bool; mutable in_loop : bool; mutable in_display : bool; mutable in_macro : bool; mutable macro_depth : int; mutable curfun : current_fun; mutable ret : t; mutable locals : (string, tvar) PMap.t; mutable opened : anon_status ref list; mutable vthis : tvar option; mutable in_call_args : bool; (* events *) mutable on_error : typer -> string -> pos -> unit; } exception Forbid_package of (string * path * pos) * pos list * string exception WithTypeError of error_msg * pos let make_call_ref : (typer -> texpr -> texpr list -> t -> pos -> texpr) ref = ref (fun _ _ _ _ _ -> assert false) let type_expr_ref : (typer -> expr -> with_type -> texpr) ref = ref (fun _ _ _ -> assert false) let type_module_type_ref : (typer -> module_type -> t list option -> pos -> texpr) ref = ref (fun _ _ _ _ -> assert false) let unify_min_ref : (typer -> texpr list -> t) ref = ref (fun _ _ -> assert false) let match_expr_ref : (typer -> expr -> (expr list * expr option * expr option * pos) list -> (expr option * pos) option -> with_type -> pos -> texpr) ref = ref (fun _ _ _ _ _ _ -> assert false) let get_pattern_locals_ref : (typer -> expr -> Type.t -> (string, tvar * pos) PMap.t) ref = ref (fun _ _ _ -> assert false) let get_constructor_ref : (typer -> tclass -> t list -> pos -> (t * tclass_field)) ref = ref (fun _ _ _ _ -> assert false) let cast_or_unify_ref : (typer -> t -> texpr -> pos -> texpr) ref = ref (fun _ _ _ _ -> assert false) let find_array_access_raise_ref : (typer -> tabstract -> tparams -> texpr -> texpr option -> pos -> (tclass_field * t * t * texpr * texpr option)) ref = ref (fun _ _ _ _ _ _ -> assert false) let analyzer_run_on_expr_ref : (Common.context -> texpr -> texpr) ref = ref (fun _ _ -> assert false) let merge_core_doc_ref : (typer -> tclass -> unit) ref = ref (fun _ _ -> assert false) let pass_name = function | PBuildModule -> "build-module" | PBuildClass -> "build-class" | PTypeField -> "type-field" | PCheckConstraint -> "check-constraint" | PForce -> "force" | PFinal -> "final" let display_error ctx msg p = match ctx.com.display.DisplayMode.dms_error_policy with | DisplayMode.EPShow | DisplayMode.EPIgnore -> ctx.on_error ctx msg p | DisplayMode.EPCollect -> add_diagnostics_message ctx.com msg p DisplayTypes.DiagnosticsSeverity.Error let make_call ctx e el t p = (!make_call_ref) ctx e el t p let type_expr ctx e with_type = (!type_expr_ref) ctx e with_type let unify_min ctx el = (!unify_min_ref) ctx el let match_expr ctx e cases def with_type p = !match_expr_ref ctx e cases def with_type p let make_static_this c p = let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in mk (TTypeExpr (TClassDecl c)) ta p let make_static_field_access c cf t p = let ethis = make_static_this c p in mk (TField (ethis,(FStatic (c,cf)))) t p let make_static_call ctx c cf map args t p = let monos = List.map (fun _ -> mk_mono()) cf.cf_params in let map t = map (apply_params cf.cf_params monos t) in let ef = make_static_field_access c cf (map cf.cf_type) p in make_call ctx ef args (map t) p let raise_or_display ctx l p = if ctx.untyped then () else if ctx.in_call_args then raise (WithTypeError(Unify l,p)) else display_error ctx (error_msg (Unify l)) p let raise_or_display_message ctx msg p = if ctx.in_call_args then raise (WithTypeError (Custom msg,p)) else display_error ctx msg p let unify ctx t1 t2 p = try Type.unify t1 t2 with Unify_error l -> raise_or_display ctx l p let unify_raise ctx t1 t2 p = try Type.unify t1 t2 with Unify_error l -> (* no untyped check *) raise (Error (Unify l,p)) let save_locals ctx = let locals = ctx.locals in (fun() -> ctx.locals <- locals) let add_local ctx n t p = let v = alloc_var n t p in ctx.locals <- PMap.add n v ctx.locals; v let add_unbound_local ctx n t p = let v = add_local ctx n t p in v.v_meta <- (Meta.Unbound,[],null_pos) :: v.v_meta; v let gen_local_prefix = "`" let gen_local ctx t p = (* ensure that our generated local does not mask an existing one *) let rec loop n = let nv = (if n = 0 then gen_local_prefix else gen_local_prefix ^ string_of_int n) in if PMap.mem nv ctx.locals then loop (n+1) else nv in add_local ctx (loop 0) t p let is_gen_local v = String.unsafe_get v.v_name 0 = String.unsafe_get gen_local_prefix 0 let delay ctx p f = let rec loop = function | [] -> [p,[f]] | (p2,l) :: rest -> if p2 = p then (p, f :: l) :: rest else if p2 < p then (p2,l) :: loop rest else (p,[f]) :: (p2,l) :: rest in ctx.g.delayed <- loop ctx.g.delayed let delay_late ctx p f = let rec loop = function | [] -> [p,[f]] | (p2,l) :: rest -> if p2 <= p then (p2,l) :: loop rest else (p,[f]) :: (p2,l) :: rest in ctx.g.delayed <- loop ctx.g.delayed let rec flush_pass ctx p (where:string) = match ctx.g.delayed with | (p2,l) :: rest when p2 <= p -> (match l with | [] -> ctx.g.delayed <- rest; | f :: l -> ctx.g.delayed <- (p2,l) :: rest; f()); flush_pass ctx p where | _ -> () let make_pass ctx f = f let init_class_done ctx = ctx.pass <- PTypeField let exc_protect ctx f (where:string) = let rec r = ref (fun() -> try f r with | Error (m,p) -> raise (Fatal_error ((error_msg m),p)) ) in r let fake_modules = Hashtbl.create 0 let create_fake_module ctx file = let file = Path.unique_full_path file in let mdep = (try Hashtbl.find fake_modules file with Not_found -> let mdep = { m_id = alloc_mid(); m_path = (["$DEP"],file); m_types = []; m_extra = module_extra file (Common.get_signature ctx.com) (file_time file) MFake []; } in Hashtbl.add fake_modules file mdep; mdep ) in Hashtbl.replace ctx.g.modules mdep.m_path mdep; mdep let push_this ctx e = match e.eexpr with | TConst ((TInt _ | TFloat _ | TString _ | TBool _) as ct) -> (EConst (tconst_to_const ct),e.epos),fun () -> () | _ -> ctx.this_stack <- e :: ctx.this_stack; let er = EMeta((Meta.This,[],e.epos), (EConst(Ident "this"),e.epos)),e.epos in er,fun () -> ctx.this_stack <- List.tl ctx.this_stack 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) (* -------------------------------------------------------------------------- *) (* ABSTRACT CASTS *) module AbstractCast = struct let cast_stack = ref [] let make_static_call ctx c cf a pl args t p = if cf.cf_kind = Method MethMacro then begin match args with | [e] -> let e,f = push_this ctx e in ctx.with_type_stack <- (WithType t) :: ctx.with_type_stack; let e = match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name [e] p with | Some e -> type_expr ctx e Value | None -> type_expr ctx (EConst (Ident "null"),p) Value in ctx.with_type_stack <- List.tl ctx.with_type_stack; f(); e | _ -> assert false end else 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 (* can't do that anymore because this might miss macro calls (#4315) *) (* 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 l,p) -> raise_or_display ctx l 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 -> 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 -> let rec loop f e = match fst e with | EConst(Ident s) -> Hashtbl.replace relevant s f | EMeta((Meta.Custom ":followWithAbstracts",_,_),e1) -> loop Abstract.follow_with_abstracts e1; | _ -> error "Type parameter expected" (pos e) in loop (fun t -> t) e ) el; let tl = List.map2 (fun (n,_) t -> try (Hashtbl.find relevant n) t with Not_found -> if not (has_mono t) then t else t_dynamic ) a.a_params pl in if com.platform = Globals.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) -> if not (Meta.has Meta.MultiType a.a_meta) then begin (* This must have been a @:generic expansion with a { new } constraint (issue #4364). In this case let's construct the underlying type. *) match Abstract.get_underlying_type a pl with | TInst(c,tl) as t -> {e with eexpr = TNew(c,tl,el); etype = t} | _ -> error ("Cannot construct " ^ (s_type (print_context()) (TAbstract(a,pl)))) e.epos end else begin (* 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} end | 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 t = match follow t,e.eexpr with | TAbstract(a,pl),_ when Meta.has Meta.MultiType a.a_meta -> a,pl,e | _,TCast(e1,None) -> find_abstract e1 e1.etype | _,TLocal {v_extra = Some(_,Some e')} -> begin match follow e'.etype with | TAbstract(a,pl) when Meta.has Meta.MultiType a.a_meta -> a,pl,mk (TCast(e,None)) e'.etype e.epos | _ -> raise Not_found end | _ -> 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 e2.etype 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 (* -------------- debug functions to activate when debugging typer passes ------------------------------- *) (*/* let delay_tabs = ref "" let context_ident ctx = if Common.defined ctx.com Common.Define.CoreApi then " core " else if Common.defined ctx.com Common.Define.Macro then "macro " else " out " let debug ctx str = if Common.raw_defined ctx.com "cdebug" then prerr_endline (context_ident ctx ^ !delay_tabs ^ str) let init_class_done ctx = debug ctx ("init_class_done " ^ s_type_path ctx.curclass.cl_path); init_class_done ctx let ctx_pos ctx = let inf = s_type_path ctx.m.curmod.m_path in let inf = (match snd ctx.curclass.cl_path with "" -> inf | n when n = snd ctx.m.curmod.m_path -> inf | n -> inf ^ "." ^ n) in let inf = (match ctx.curfield.cf_name with "" -> inf | n -> inf ^ ":" ^ n) in inf let pass_infos ctx p = let inf = pass_name p ^ " (" ^ ctx_pos ctx ^ ")" in let inf = if ctx.pass > p then inf ^ " ??CURPASS=" ^ pass_name ctx.pass else inf in inf let delay ctx p f = let inf = pass_infos ctx p in let rec loop = function | [] -> [p,[f,inf,ctx]] | (p2,l) :: rest -> if p2 = p then (p, (f,inf,ctx) :: l) :: rest else if p2 < p then (p2,l) :: loop rest else (p,[f,inf,ctx]) :: (p2,l) :: rest in ctx.g.debug_delayed <- loop ctx.g.debug_delayed; debug ctx ("add " ^ inf) let pending_passes ctx = let rec loop acc = function | (p,l) :: pl when p < ctx.pass -> loop (acc @ l) pl | _ -> acc in match loop [] ctx.g.debug_delayed with | [] -> "" | l -> " ??PENDING[" ^ String.concat ";" (List.map (fun (_,i,_) -> i) l) ^ "]" let display_error ctx msg p = debug ctx ("ERROR " ^ msg); display_error ctx msg p let make_pass ?inf ctx f = let inf = (match inf with None -> pass_infos ctx ctx.pass | Some inf -> inf) in (fun v -> debug ctx ("run " ^ inf ^ pending_passes ctx); let old = !delay_tabs in delay_tabs := !delay_tabs ^ "\t"; let t = (try f v with | Fatal_error (e,p) -> delay_tabs := old; raise (Fatal_error (e,p)) | exc when not (Common.raw_defined ctx.com "stack") -> debug ctx ("FATAL " ^ Printexc.to_string exc); delay_tabs := old; raise exc ) in delay_tabs := old; t ) let rec flush_pass ctx p where = let rec loop() = match ctx.g.debug_delayed with | (p2,l) :: rest when p2 <= p -> (match l with | [] -> ctx.g.debug_delayed <- rest | (f,inf,ctx2) :: l -> ctx.g.debug_delayed <- (p2,l) :: rest; match p2 with | PTypeField | PBuildClass -> f() | _ -> (make_pass ~inf ctx f)()); loop() | _ -> () in match ctx.g.debug_delayed with | (p2,_) :: _ when p2 <= p -> let old = !delay_tabs in debug ctx ("flush " ^ pass_name p ^ "(" ^ where ^ ")"); delay_tabs := !delay_tabs ^ "\t"; loop(); delay_tabs := old; debug ctx "flush-done"; | _ -> () let make_where ctx where = where ^ " (" ^ ctx_pos ctx ^ ")" let exc_protect ctx f (where:string) = let f = make_pass ~inf:(make_where ctx where) ctx f in let rec r = ref (fun() -> try f r with | Error (m,p) -> raise (Fatal_error (error_msg m,p)) ) in r */*) (* --------------------------------------------------- *) haxe_3.4.4.orig/src/typing/typeload.ml0000664000175000017500000047174313166552354017710 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Common open Common.DisplayMode open Type open Typecore open Error open Globals exception Build_canceled of build_state let locate_macro_error = ref true let transform_abstract_field com this_t a_t a f = let stat = List.mem AStatic f.cff_access in let p = f.cff_pos in match f.cff_kind with | FProp ((("get" | "never"),_),(("set" | "never"),_),_,_) when not stat -> (* TODO: hack to avoid issues with abstract property generation on As3 *) if Common.defined com Define.As3 then f.cff_meta <- (Meta.Extern,[],null_pos) :: f.cff_meta; { f with cff_access = AStatic :: f.cff_access; cff_meta = (Meta.Impl,[],null_pos) :: f.cff_meta } | FProp _ when not stat -> error "Member property accessors must be get/set or never" p; | FFun fu when fst f.cff_name = "new" && not stat -> let init p = (EVars [("this",null_pos),Some this_t,None],p) in let cast e = (ECast(e,None)),pos e in let ret p = (EReturn (Some (cast (EConst (Ident "this"),p))),p) in let meta = (Meta.Impl,[],null_pos) :: f.cff_meta in let meta = if Meta.has Meta.MultiType a.a_meta then begin if List.mem AInline f.cff_access then error "MultiType constructors cannot be inline" f.cff_pos; if fu.f_expr <> None then error "MultiType constructors cannot have a body" f.cff_pos; (Meta.Extern,[],null_pos) :: meta end else meta in (* We don't want the generated expression positions to shadow the real code. *) let p = { p with pmax = p.pmin } in let fu = { fu with f_expr = (match fu.f_expr with | None -> if Meta.has Meta.MultiType a.a_meta then Some (EConst (Ident "null"),p) else None | Some (EBlock el,_) -> Some (EBlock (init p :: el @ [ret p]),p) | Some e -> Some (EBlock [init p;e;ret p],p) ); f_type = Some a_t; } in { f with cff_name = "_new",pos f.cff_name; cff_access = AStatic :: f.cff_access; cff_kind = FFun fu; cff_meta = meta } | FFun fu when not stat -> if Meta.has Meta.From f.cff_meta then error "@:from cast functions must be static" f.cff_pos; let fu = { fu with f_args = (if List.mem AMacro f.cff_access then fu.f_args else (("this",null_pos),false,[],Some this_t,None) :: fu.f_args) } in { f with cff_kind = FFun fu; cff_access = AStatic :: f.cff_access; cff_meta = (Meta.Impl,[],null_pos) :: f.cff_meta } | _ -> f let get_policy ctx mpath = let sl1 = full_dot_path mpath mpath in List.fold_left (fun acc (sl2,policy,recursive) -> if match_path recursive sl1 sl2 then policy @ acc else acc) [] ctx.g.module_check_policies let make_module ctx mpath file loadp = let m = { m_id = alloc_mid(); m_path = mpath; m_types = []; m_extra = module_extra (Path.unique_full_path file) (Common.get_signature ctx.com) (file_time file) (if ctx.in_macro then MMacro else MCode) (get_policy ctx mpath); } in m (* Build module structure : should be atomic - no type loading is possible *) let module_pass_1 ctx m tdecls loadp = let com = ctx.com in let decls = ref [] in let make_path name priv = if List.exists (fun (t,_) -> snd (t_path t) = name) !decls then error ("Type name " ^ name ^ " is already defined in this module") loadp; if priv then (fst m.m_path @ ["_" ^ snd m.m_path], name) else (fst m.m_path, name) in let pt = ref None in let rec make_decl acc decl = let p = snd decl in let acc = (match fst decl with | EImport _ | EUsing _ -> (match !pt with | None -> acc | Some _ -> error "import and using may not appear after a type declaration" p) | EClass d -> let name = fst d.d_name in if String.length name > 0 && name.[0] = '$' then error "Type names starting with a dollar are not allowed" p; pt := Some p; let priv = List.mem HPrivate d.d_flags in let path = make_path name priv in let c = mk_class m path p (pos d.d_name) in (* we shouldn't load any other type until we propertly set cl_build *) c.cl_build <- (fun() -> error (s_type_path c.cl_path ^ " is not ready to be accessed, separate your type declarations in several files") p); c.cl_module <- m; c.cl_private <- priv; c.cl_doc <- d.d_doc; c.cl_meta <- d.d_meta; decls := (TClassDecl c, decl) :: !decls; acc | EEnum d -> let name = fst d.d_name in if String.length name > 0 && name.[0] = '$' then error "Type names starting with a dollar are not allowed" p; pt := Some p; let priv = List.mem EPrivate d.d_flags in let path = make_path name priv in let e = { e_path = path; e_module = m; e_pos = p; e_name_pos = (pos d.d_name); e_doc = d.d_doc; e_meta = d.d_meta; e_params = []; e_private = priv; e_extern = List.mem EExtern d.d_flags; e_constrs = PMap.empty; e_names = []; e_type = { t_path = [], "Enum<" ^ (s_type_path path) ^ ">"; t_module = m; t_doc = None; t_pos = p; t_name_pos = null_pos; t_type = mk_mono(); t_private = true; t_params = []; t_meta = []; }; } in decls := (TEnumDecl e, decl) :: !decls; acc | ETypedef d -> let name = fst d.d_name in if String.length name > 0 && name.[0] = '$' then error "Type names starting with a dollar are not allowed" p; pt := Some p; let priv = List.mem EPrivate d.d_flags in let path = make_path name priv in let t = { t_path = path; t_module = m; t_pos = p; t_name_pos = pos d.d_name; t_doc = d.d_doc; t_private = priv; t_params = []; t_type = mk_mono(); t_meta = d.d_meta; } in (* failsafe in case the typedef is not initialized (see #3933) *) delay ctx PBuildModule (fun () -> match t.t_type with | TMono r -> (match !r with None -> r := Some com.basic.tvoid | _ -> ()) | _ -> () ); decls := (TTypeDecl t, decl) :: !decls; acc | EAbstract d -> let name = fst d.d_name in if String.length name > 0 && name.[0] = '$' then error "Type names starting with a dollar are not allowed" p; let priv = List.mem APrivAbstract d.d_flags in let path = make_path name priv in let a = { a_path = path; a_private = priv; a_module = m; a_pos = p; a_name_pos = pos d.d_name; a_doc = d.d_doc; a_params = []; a_meta = d.d_meta; a_from = []; a_to = []; a_from_field = []; a_to_field = []; a_ops = []; a_unops = []; a_impl = None; a_array = []; a_this = mk_mono(); a_resolve = None; } in decls := (TAbstractDecl a, decl) :: !decls; match d.d_data with | [] when Meta.has Meta.CoreType a.a_meta -> a.a_this <- t_dynamic; acc | fields -> let a_t = let params = List.map (fun t -> TPType (CTPath { tname = fst t.tp_name; tparams = []; tsub = None; tpackage = [] },null_pos)) d.d_params in CTPath { tpackage = []; tname = fst d.d_name; tparams = params; tsub = None },null_pos in let rec loop = function | [] -> a_t | AIsType t :: _ -> t | _ :: l -> loop l in let this_t = loop d.d_flags in let fields = List.map (transform_abstract_field com this_t a_t a) fields in let meta = ref [] in if has_meta Meta.Dce a.a_meta then meta := (Meta.Dce,[],null_pos) :: !meta; let acc = make_decl acc (EClass { d_name = (fst d.d_name) ^ "_Impl_",snd d.d_name; d_flags = [HPrivate]; d_data = fields; d_doc = None; d_params = []; d_meta = !meta },p) in (match !decls with | (TClassDecl c,_) :: _ -> List.iter (fun m -> match m with | ((Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce | Meta.Native | Meta.JsRequire | Meta.PythonImport | Meta.Expose | Meta.Deprecated | Meta.PhpConstants | Meta.PhpGlobal),_,_) -> c.cl_meta <- m :: c.cl_meta; | _ -> () ) a.a_meta; a.a_impl <- Some c; c.cl_kind <- KAbstractImpl a; c.cl_meta <- (Meta.Final,[],null_pos) :: c.cl_meta | _ -> assert false); acc ) in decl :: acc in let tdecls = List.fold_left make_decl [] tdecls in let decls = List.rev !decls in decls, List.rev tdecls let parse_file_from_lexbuf com file p lexbuf = let t = Common.timer ["parsing"] in Lexer.init file true; incr stats.s_files_parsed; let data = (try Parser.parse com lexbuf with e -> t(); raise e) in begin match !display_default with | DMModuleSymbols filter when filter <> None || Display.is_display_file file -> let ds = Display.DocumentSymbols.collect_module_symbols data in com.shared.shared_display_information.document_symbols <- (file,ds) :: com.shared.shared_display_information.document_symbols; | _ -> () end; t(); Common.log com ("Parsed " ^ file); data let parse_file_from_string com file p string = parse_file_from_lexbuf com file p (Lexing.from_string string) let current_stdin = ref None (* TODO: we're supposed to clear this at some point *) let parse_file com file p = let use_stdin = (Common.defined com Define.DisplayStdin) && Display.is_display_file file in if use_stdin then let s = match !current_stdin with | Some s -> s | None -> let s = Std.input_all stdin in close_in stdin; current_stdin := Some s; s in parse_file_from_string com file p s else let ch = try open_in_bin file with _ -> error ("Could not open " ^ file) p in Std.finally (fun() -> close_in ch) (parse_file_from_lexbuf com file p) (Lexing.from_channel ch) let parse_hook = ref parse_file let type_module_hook = ref (fun _ _ _ -> None) let type_function_params_rec = ref (fun _ _ _ _ -> assert false) let return_partial_type = ref false let type_function_arg ctx t e opt p = if opt then let e = (match e with None -> Some (EConst (Ident "null"),p) | _ -> e) in ctx.t.tnull t, e else let t = match e with Some (EConst (Ident "null"),p) -> ctx.t.tnull t | _ -> t in t, e let type_var_field ctx t e stat do_display p = if stat then ctx.curfun <- FunStatic else ctx.curfun <- FunMember; let e = if do_display then Display.ExprPreprocessing.process_expr ctx.com e else e in let e = type_expr ctx e (WithType t) in let e = (!cast_or_unify_ref) ctx t e p in match t with | TType ({ t_path = ([],"UInt") },[]) | TAbstract ({ a_path = ([],"UInt") },[]) when stat -> { e with etype = t } | _ -> e let apply_macro ctx mode path el p = let cpath, meth = (match List.rev (ExtString.String.nsplit path ".") with | meth :: name :: pack -> (List.rev pack,name), meth | _ -> error "Invalid macro path" p ) in ctx.g.do_macro ctx mode cpath meth el p (** since load_type_def and load_instance are used in PASS2, they should not access the structure of a type **) (* load a type or a subtype definition *) let rec load_type_def ctx p t = let no_pack = t.tpackage = [] in let tname = (match t.tsub with None -> t.tname | Some n -> n) in if tname = "" then raise (Display.DisplayToplevel (Display.ToplevelCollector.run ctx true)); try if t.tsub <> None then raise Not_found; let path_matches t2 = let tp = t_path t2 in tp = (t.tpackage,tname) || (no_pack && snd tp = tname) in try List.find path_matches ctx.m.curmod.m_types with Not_found -> let t,pi = List.find (fun (t2,pi) -> path_matches t2) ctx.m.module_types in Display.ImportHandling.mark_import_position ctx.com pi; t with Not_found -> let next() = let t, m = (try t, ctx.g.do_load_module ctx (t.tpackage,t.tname) p with Error (Module_not_found _,p2) as e when p == p2 -> match t.tpackage with | "std" :: l -> let t = { t with tpackage = l } in t, ctx.g.do_load_module ctx (t.tpackage,t.tname) p | _ -> raise e ) in let tpath = (t.tpackage,tname) in try List.find (fun t -> not (t_infos t).mt_private && t_path t = tpath) m.m_types with Not_found -> raise (Error (Type_not_found (m.m_path,tname),p)) in (* lookup in wildcard imported packages *) try if not no_pack then raise Exit; let rec loop l = match l with | [] -> raise Exit | (wp,pi) :: l -> try let t = load_type_def ctx p { t with tpackage = wp } in Display.ImportHandling.mark_import_position ctx.com pi; t with | Error (Module_not_found _,p2) | Error (Type_not_found _,p2) when p == p2 -> loop l in loop ctx.m.wildcard_packages with Exit -> (* lookup in our own package - and its upper packages *) let rec loop = function | [] -> raise Exit | (_ :: lnext) as l -> try load_type_def ctx p { t with tpackage = List.rev l } with | Error (Module_not_found _,p2) | Error (Type_not_found _,p2) when p == p2 -> loop lnext in try if not no_pack then raise Exit; (match fst ctx.m.curmod.m_path with | [] -> raise Exit | x :: _ -> (* this can occur due to haxe remoting : a module can be already defined in the "js" package and is not allowed to access the js classes *) try (match PMap.find x ctx.com.package_rules with | Forbidden -> raise Exit | _ -> ()) with Not_found -> ()); loop (List.rev (fst ctx.m.curmod.m_path)); with Exit -> next() let resolve_position_by_path ctx path p = let mt = load_type_def ctx p path in let p = (t_infos mt).mt_pos in raise (Display.DisplayPosition [p]) let check_param_constraints ctx types t pl c p = match follow t with | TMono _ -> () | _ -> let ctl = (match c.cl_kind with KTypeParameter l -> l | _ -> []) in List.iter (fun ti -> let ti = apply_params types pl ti in let ti = (match follow ti with | TInst ({ cl_kind = KGeneric } as c,pl) -> (* if we solve a generic contraint, let's substitute with the actual generic instance before unifying *) let _,_, f = ctx.g.do_build_instance ctx (TClassDecl c) p in f pl | _ -> ti ) in try unify_raise ctx t ti p with Error(Unify l,p) -> if not ctx.untyped then display_error ctx (error_msg (Unify (Constraint_failure (s_type_path c.cl_path) :: l))) p; ) ctl let requires_value_meta com co = Common.defined com Define.DocGen || (match co with | None -> false | Some c -> c.cl_extern || Meta.has Meta.Rtti c.cl_meta) let generate_value_meta com co cf args = if requires_value_meta com co then begin let values = List.fold_left (fun acc ((name,p),_,_,_,eo) -> match eo with Some e -> ((name,p),e) :: acc | _ -> acc) [] args in match values with | [] -> () | _ -> cf.cf_meta <- ((Meta.Value,[EObjectDecl values,cf.cf_pos],null_pos) :: cf.cf_meta) end let pselect p1 p2 = if p1 = null_pos then p2 else p1 (* build an instance from a full type *) let rec load_instance ?(allow_display=false) ctx (t,pn) allow_no_params p = let p = pselect pn p in let t = try if t.tpackage <> [] || t.tsub <> None then raise Not_found; let pt = List.assoc t.tname ctx.type_params in if t.tparams <> [] then error ("Class type parameter " ^ t.tname ^ " can't have parameters") p; pt with Not_found -> let mt = load_type_def ctx p t in let is_generic,is_generic_build = match mt with | TClassDecl {cl_kind = KGeneric} -> true,false | TClassDecl {cl_kind = KGenericBuild _} -> false,true | _ -> false,false in let types , path , f = ctx.g.do_build_instance ctx mt p in let is_rest = is_generic_build && (match types with ["Rest",_] -> true | _ -> false) in if allow_no_params && t.tparams = [] && not is_rest then begin let pl = ref [] in pl := List.map (fun (name,t) -> match follow t with | TInst (c,_) -> let t = mk_mono() in if c.cl_kind <> KTypeParameter [] || is_generic then delay ctx PCheckConstraint (fun() -> check_param_constraints ctx types t (!pl) c p); t; | _ -> assert false ) types; f (!pl) end else if path = ([],"Dynamic") then match t.tparams with | [] -> t_dynamic | [TPType t] -> TDynamic (load_complex_type ctx true p t) | _ -> error "Too many parameters for Dynamic" p else begin if not is_rest && ctx.com.display.dms_error_policy <> EPIgnore && List.length types <> List.length t.tparams then error ("Invalid number of type parameters for " ^ s_type_path path) p; let tparams = List.map (fun t -> match t with | TPExpr e -> let name = (match fst e with | EConst (String s) -> "S" ^ s | EConst (Int i) -> "I" ^ i | EConst (Float f) -> "F" ^ f | _ -> "Expr" ) in let c = mk_class null_module ([],name) p (pos e) in c.cl_kind <- KExpr e; TInst (c,[]) | TPType t -> load_complex_type ctx true p t ) t.tparams in let rec loop tl1 tl2 is_rest = match tl1,tl2 with | t :: tl1,(name,t2) :: tl2 -> let check_const c = let is_expression = (match t with TInst ({ cl_kind = KExpr _ },_) -> true | _ -> false) in let expects_expression = name = "Const" || Meta.has Meta.Const c.cl_meta in let accepts_expression = name = "Rest" in if is_expression then begin if not expects_expression && not accepts_expression then error "Constant value unexpected here" p end else if expects_expression then error "Type parameter is expected to be a constant value" p in let is_rest = is_rest || name = "Rest" && is_generic_build in let t = match follow t2 with | TInst ({ cl_kind = KTypeParameter [] } as c, []) when not is_generic -> check_const c; t | TInst (c,[]) -> check_const c; let r = exc_protect ctx (fun r -> r := (fun() -> t); delay ctx PCheckConstraint (fun() -> check_param_constraints ctx types t tparams c p); t ) "constraint" in delay ctx PForce (fun () -> ignore(!r())); TLazy r | _ -> assert false in t :: loop tl1 tl2 is_rest | [],[] -> [] | [],["Rest",_] when is_generic_build -> [] | [],(_,t) :: tl when ctx.com.display.dms_error_policy = EPIgnore -> t :: loop [] tl is_rest | [],_ -> error ("Not enough type parameters for " ^ s_type_path path) p | t :: tl,[] -> if is_rest then t :: loop tl [] true else error ("Too many parameters for " ^ s_type_path path) p in let params = loop tparams types false in f params end in if allow_display then Display.DisplayEmitter.check_display_type ctx t pn; t (* build an instance from a complex type *) and load_complex_type ctx allow_display p (t,pn) = let p = pselect pn p in match t with | CTParent t -> load_complex_type ctx allow_display p t | CTPath t -> load_instance ~allow_display ctx (t,pn) false p | CTOptional _ -> error "Optional type not allowed here" p | CTExtend (tl,l) -> (match load_complex_type ctx allow_display p (CTAnonymous l,p) with | TAnon a as ta -> let is_redefined cf1 a2 = try let cf2 = PMap.find cf1.cf_name a2.a_fields in let st = s_type (print_context()) in if not (type_iseq cf1.cf_type cf2.cf_type) then begin display_error ctx ("Cannot redefine field " ^ cf1.cf_name ^ " with different type") p; display_error ctx ("First type was " ^ (st cf1.cf_type)) cf1.cf_pos; error ("Second type was " ^ (st cf2.cf_type)) cf2.cf_pos end else true with Not_found -> false in let mk_extension t = match follow t with | TInst ({cl_kind = KTypeParameter _},_) -> error "Cannot structurally extend type parameters" p | TMono _ -> error "Loop found in cascading signatures definitions. Please change order/import" p | TAnon a2 -> PMap.iter (fun _ cf -> ignore(is_redefined cf a2)) a.a_fields; TAnon { a_fields = (PMap.foldi PMap.add a.a_fields a2.a_fields); a_status = ref (Extend [t]); } | _ -> error "Can only extend structures" p in let loop t = match follow t with | TAnon a2 -> PMap.iter (fun f cf -> if not (is_redefined cf a) then a.a_fields <- PMap.add f cf a.a_fields ) a2.a_fields | _ -> error "Can only extend structures" p in let il = List.map (fun (t,pn) -> load_instance ctx ~allow_display (t,pn) false p) tl in let tr = ref None in let t = TMono tr in let r = exc_protect ctx (fun r -> r := (fun _ -> t); tr := Some (match il with | [i] -> mk_extension i | _ -> List.iter loop il; a.a_status := Extend il; ta); t ) "constraint" in delay ctx PForce (fun () -> ignore(!r())); TLazy r | _ -> assert false) | CTAnonymous l -> let rec loop acc f = let n = fst f.cff_name in let p = f.cff_pos in if PMap.mem n acc then error ("Duplicate field declaration : " ^ n) p; let topt = function | None -> error ("Explicit type required for field " ^ n) p | Some t -> load_complex_type ctx allow_display p t in if n = "new" then ctx.com.warning "Structures with new are deprecated, use haxe.Constraints.Constructible instead" p; let no_expr = function | None -> () | Some (_,p) -> error "Expression not allowed here" p in let pub = ref true in let dyn = ref false in let params = ref [] in List.iter (fun a -> match a with | APublic -> () | APrivate -> pub := false; | ADynamic when (match f.cff_kind with FFun _ -> true | _ -> false) -> dyn := true | AStatic | AOverride | AInline | ADynamic | AMacro -> error ("Invalid access " ^ Ast.s_access a) p ) f.cff_access; let t , access = (match f.cff_kind with | FVar (Some (CTPath({tpackage=[];tname="Void"}),_), _) | FProp (_,_,Some (CTPath({tpackage=[];tname="Void"}),_),_) -> error "Fields of type Void are not allowed in structures" p | FVar (t, e) -> no_expr e; topt t, Var { v_read = AccNormal; v_write = AccNormal } | FFun fd -> params := (!type_function_params_rec) ctx fd (fst f.cff_name) p; no_expr fd.f_expr; let old = ctx.type_params in ctx.type_params <- !params @ old; let args = List.map (fun ((name,_),o,_,t,e) -> no_expr e; name, o, topt t) fd.f_args in let t = TFun (args,topt fd.f_type), Method (if !dyn then MethDynamic else MethNormal) in ctx.type_params <- old; t | FProp (i1,i2,t,e) -> no_expr e; let access (m,_) get = match m with | "null" -> AccNo | "never" -> AccNever | "default" -> AccNormal | "dynamic" -> AccCall | "get" when get -> AccCall | "set" when not get -> AccCall | x when get && x = "get_" ^ n -> AccCall | x when not get && x = "set_" ^ n -> AccCall | _ -> error "Custom property access is no longer supported in Haxe 3" f.cff_pos; in let t = (match t with None -> error "Type required for structure property" p | Some t -> t) in load_complex_type ctx allow_display p t, Var { v_read = access i1 true; v_write = access i2 false } ) in let t = if Meta.has Meta.Optional f.cff_meta then ctx.t.tnull t else t in let cf = { cf_name = n; cf_type = t; cf_pos = p; cf_name_pos = (pos f.cff_name); cf_public = !pub; cf_kind = access; cf_params = !params; cf_expr = None; cf_expr_unoptimized = None; cf_doc = f.cff_doc; cf_meta = f.cff_meta; cf_overloads = []; } in init_meta_overloads ctx None cf; if ctx.is_display_file then begin Display.DisplayEmitter.check_display_metadata ctx cf.cf_meta; Display.DisplayEmitter.maybe_display_field ctx (cf.cf_name_pos) cf; end; PMap.add n cf acc in mk_anon (List.fold_left loop PMap.empty l) | CTFunction (args,r) -> match args with | [CTPath { tpackage = []; tparams = []; tname = "Void" },_] -> TFun ([],load_complex_type ctx allow_display p r) | _ -> TFun (List.map (fun t -> let t, opt = (match fst t with CTOptional t -> t, true | _ -> t,false) in "",opt,load_complex_type ctx allow_display p t ) args,load_complex_type ctx allow_display p r) and init_meta_overloads ctx co cf = let overloads = ref [] in let filter_meta m = match m with | ((Meta.Overload | Meta.Value),_,_) -> false | _ -> true in let cf_meta = List.filter filter_meta cf.cf_meta in cf.cf_meta <- List.filter (fun m -> match m with | (Meta.Overload,[(EFunction (fname,f),p)],_) -> if fname <> None then error "Function name must not be part of @:overload" p; (match f.f_expr with Some (EBlock [], _) -> () | _ -> error "Overload must only declare an empty method body {}" p); let old = ctx.type_params in (match cf.cf_params with | [] -> () | l -> ctx.type_params <- List.filter (fun t -> not (List.mem t l)) ctx.type_params); let params = (!type_function_params_rec) ctx f cf.cf_name p in ctx.type_params <- params @ ctx.type_params; let topt = function None -> error "Explicit type required" p | Some t -> load_complex_type ctx true p t in let args = List.map (fun ((a,_),opt,_,t,_) -> a,opt,topt t) f.f_args in let cf = { cf with cf_type = TFun (args,topt f.f_type); cf_params = params; cf_meta = cf_meta} in generate_value_meta ctx.com co cf f.f_args; overloads := cf :: !overloads; ctx.type_params <- old; false | (Meta.Overload,[],_) when ctx.com.config.pf_overload -> let topt (n,_,t) = match t with | TMono t when !t = None -> error ("Explicit type required for overload functions\nFor function argument '" ^ n ^ "'") cf.cf_pos | _ -> () in (match follow cf.cf_type with | TFun (args,_) -> List.iter topt args | _ -> () (* could be a variable *)); true | (Meta.Overload,[],p) -> error "This platform does not support this kind of overload declaration. Try @:overload(function()... {}) instead" p | (Meta.Overload,_,p) -> error "Invalid @:overload metadata format" p | _ -> true ) cf.cf_meta; cf.cf_overloads <- (List.rev !overloads) let hide_params ctx = let old_m = ctx.m in let old_type_params = ctx.type_params in let old_deps = ctx.g.std.m_extra.m_deps in ctx.m <- { curmod = ctx.g.std; module_types = []; module_using = []; module_globals = PMap.empty; wildcard_packages = []; module_imports = []; }; ctx.type_params <- []; (fun() -> ctx.m <- old_m; ctx.type_params <- old_type_params; (* restore dependencies that might be have been wronly inserted *) ctx.g.std.m_extra.m_deps <- old_deps; ) (* load a type while ignoring the current imports or local types *) let load_core_type ctx name = let show = hide_params ctx in let t = load_instance ctx ({ tpackage = []; tname = name; tparams = []; tsub = None; },null_pos) false null_pos in show(); add_dependency ctx.m.curmod (match t with | TInst (c,_) -> c.cl_module | TType (t,_) -> t.t_module | TAbstract (a,_) -> a.a_module | TEnum (e,_) -> e.e_module | _ -> assert false); t let t_iterator ctx = let show = hide_params ctx in match load_type_def ctx null_pos { tpackage = []; tname = "Iterator"; tparams = []; tsub = None } with | TTypeDecl t -> show(); add_dependency ctx.m.curmod t.t_module; if List.length t.t_params <> 1 then assert false; let pt = mk_mono() in apply_params t.t_params [pt] t.t_type, pt | _ -> assert false (* load either a type t or Null if not defined *) let load_type_hint ?(opt=false) ctx pcur t = let t = match t with | None -> mk_mono() | Some (t,p) -> try load_complex_type ctx true pcur (t,p) with Error(Module_not_found(([],name)),p) as exc -> if Display.Diagnostics.is_diagnostics_run ctx then Display.ToplevelCollector.handle_unresolved_identifier ctx name p true; (* Default to Dynamic in display mode *) if ctx.com.display.dms_display then t_dynamic else raise exc in if opt then ctx.t.tnull t else t (* ---------------------------------------------------------------------- *) (* Structure check *) let valid_redefinition ctx f1 t1 f2 t2 = (* child, parent *) let valid t1 t2 = Type.unify t1 t2; if is_null t1 <> is_null t2 || ((follow t1) == t_dynamic && (follow t2) != t_dynamic) then raise (Unify_error [Cannot_unify (t1,t2)]); in let open OptimizerTexpr in begin match PurityState.get_purity_from_meta f2.cf_meta,PurityState.get_purity_from_meta f1.cf_meta with | PurityState.Pure,PurityState.MaybePure -> f1.cf_meta <- (Meta.Pure,[EConst(Ident "expect"),f2.cf_pos],null_pos) :: f1.cf_meta | PurityState.ExpectPure p,PurityState.MaybePure -> f1.cf_meta <- (Meta.Pure,[EConst(Ident "expect"),p],null_pos) :: f1.cf_meta | _ -> () end; let t1, t2 = (match f1.cf_params, f2.cf_params with | [], [] -> t1, t2 | l1, l2 when List.length l1 = List.length l2 -> let to_check = ref [] in let monos = List.map2 (fun (name,p1) (_,p2) -> (match follow p1, follow p2 with | TInst ({ cl_kind = KTypeParameter ct1 } as c1,pl1), TInst ({ cl_kind = KTypeParameter ct2 } as c2,pl2) -> (match ct1, ct2 with | [], [] -> () | _, _ when List.length ct1 = List.length ct2 -> (* if same constraints, they are the same type *) let check monos = List.iter2 (fun t1 t2 -> try let t1 = apply_params l1 monos (apply_params c1.cl_params pl1 t1) in let t2 = apply_params l2 monos (apply_params c2.cl_params pl2 t2) in type_eq EqStrict t1 t2 with Unify_error l -> raise (Unify_error (Unify_custom "Constraints differ" :: l)) ) ct1 ct2 in to_check := check :: !to_check; | _ -> raise (Unify_error [Unify_custom "Different number of constraints"])) | _ -> ()); TInst (mk_class null_module ([],name) null_pos null_pos,[]) ) l1 l2 in List.iter (fun f -> f monos) !to_check; apply_params l1 monos t1, apply_params l2 monos t2 | _ -> (* ignore type params, will create other errors later *) t1, t2 ) in match f1.cf_kind,f2.cf_kind with | Method m1, Method m2 when not (m1 = MethDynamic) && not (m2 = MethDynamic) -> begin match follow t1, follow t2 with | TFun (args1,r1) , TFun (args2,r2) -> ( if not (List.length args1 = List.length args2) then raise (Unify_error [Unify_custom "Different number of function arguments"]); try List.iter2 (fun (n,o1,a1) (_,o2,a2) -> if o1 <> o2 then raise (Unify_error [Not_matching_optional n]); (try valid a2 a1 with Unify_error _ -> raise (Unify_error [Cannot_unify(a1,a2)])) ) args1 args2; valid r1 r2 with Unify_error l -> raise (Unify_error (Cannot_unify (t1,t2) :: l))) | _ -> assert false end | _,(Var { v_write = AccNo | AccNever }) -> (* write variance *) valid t1 t2 | _,(Var { v_read = AccNo | AccNever }) -> (* read variance *) valid t2 t1 | _ , _ -> (* in case args differs, or if an interface var *) type_eq EqStrict t1 t2; if is_null t1 <> is_null t2 then raise (Unify_error [Cannot_unify (t1,t2)]) let copy_meta meta_src meta_target sl = let meta = ref meta_target in List.iter (fun (m,e,p) -> if List.mem m sl then meta := (m,e,p) :: !meta ) meta_src; !meta let check_overriding ctx c = match c.cl_super with | None -> (match c.cl_overrides with | [] -> () | i :: _ -> display_error ctx ("Field " ^ i.cf_name ^ " is declared 'override' but doesn't override any field") i.cf_pos) | _ when c.cl_extern && Meta.has Meta.CsNative c.cl_meta -> () (* -net-lib specific: do not check overrides on extern CsNative classes *) | Some (csup,params) -> PMap.iter (fun i f -> let p = f.cf_pos in let check_field f get_super_field is_overload = try (if is_overload && not (Meta.has Meta.Overload f.cf_meta) then display_error ctx ("Missing @:overload declaration for field " ^ i) p); let t, f2 = get_super_field csup i in (* allow to define fields that are not defined for this platform version in superclass *) (match f2.cf_kind with | Var { v_read = AccRequire _ } -> raise Not_found; | _ -> ()); if ctx.com.config.pf_overload && (Meta.has Meta.Overload f2.cf_meta && not (Meta.has Meta.Overload f.cf_meta)) then display_error ctx ("Field " ^ i ^ " should be declared with @:overload since it was already declared as @:overload in superclass") p else if not (List.memq f c.cl_overrides) then display_error ctx ("Field " ^ i ^ " should be declared with 'override' since it is inherited from superclass " ^ s_type_path csup.cl_path) p else if not f.cf_public && f2.cf_public then display_error ctx ("Field " ^ i ^ " has less visibility (public/private) than superclass one") p else (match f.cf_kind, f2.cf_kind with | _, Method MethInline -> display_error ctx ("Field " ^ i ^ " is inlined and cannot be overridden") p | a, b when a = b -> () | Method MethInline, Method MethNormal -> () (* allow to redefine a method as inlined *) | _ -> display_error ctx ("Field " ^ i ^ " has different property access than in superclass") p); if has_meta Meta.Final f2.cf_meta then display_error ctx ("Cannot override @:final method " ^ i) p; try let t = apply_params csup.cl_params params t in valid_redefinition ctx f f.cf_type f2 t with Unify_error l -> display_error ctx ("Field " ^ i ^ " overloads parent class with different or incomplete type") p; display_error ctx ("Base field is defined here") f2.cf_pos; display_error ctx (error_msg (Unify l)) p; with Not_found -> if List.memq f c.cl_overrides then let msg = if is_overload then ("Field " ^ i ^ " is declared 'override' but no compatible overload was found") else ("Field " ^ i ^ " is declared 'override' but doesn't override any field") in display_error ctx msg p in if ctx.com.config.pf_overload && Meta.has Meta.Overload f.cf_meta then begin let overloads = Overloads.get_overloads csup i in List.iter (fun (t,f2) -> (* check if any super class fields are vars *) match f2.cf_kind with | Var _ -> display_error ctx ("A variable named '" ^ f2.cf_name ^ "' was already declared in a superclass") f.cf_pos | _ -> () ) overloads; List.iter (fun f -> (* find the exact field being overridden *) check_field f (fun csup i -> List.find (fun (t,f2) -> Overloads.same_overload_args f.cf_type (apply_params csup.cl_params params t) f f2 ) overloads ) true ) (f :: f.cf_overloads) end else check_field f (fun csup i -> let _, t, f2 = raw_class_field (fun f -> f.cf_type) csup params i in t, f2) false ) c.cl_fields let class_field_no_interf c i = try let f = PMap.find i c.cl_fields in f.cf_type , f with Not_found -> match c.cl_super with | None -> raise Not_found | Some (c,tl) -> (* rec over class_field *) let _, t , f = raw_class_field (fun f -> f.cf_type) c tl i in apply_params c.cl_params tl t , f let rec return_flow ctx e = let error() = display_error ctx (Printf.sprintf "Missing return: %s" (s_type (print_context()) ctx.ret)) e.epos; raise Exit in let return_flow = return_flow ctx in let rec uncond e = match e.eexpr with | TIf _ | TWhile _ | TSwitch _ | TTry _ | TFunction _ -> () | TReturn _ | TThrow _ -> raise Exit | _ -> Type.iter uncond e in let has_unconditional_flow e = try uncond e; false with Exit -> true in match e.eexpr with | TReturn _ | TThrow _ -> () | TParenthesis e | TMeta(_,e) -> return_flow e | TBlock el -> let rec loop = function | [] -> error() | [e] -> return_flow e | e :: _ when has_unconditional_flow e -> () | _ :: l -> loop l in loop el | TIf (_,e1,Some e2) -> return_flow e1; return_flow e2; | TSwitch (v,cases,Some e) -> List.iter (fun (_,e) -> return_flow e) cases; return_flow e | TSwitch ({eexpr = TMeta((Meta.Exhaustive,_,_),_)},cases,None) -> List.iter (fun (_,e) -> return_flow e) cases; | TTry (e,cases) -> return_flow e; List.iter (fun (_,e) -> return_flow e) cases; | TWhile({eexpr = (TConst (TBool true))},e,_) -> (* a special case for "inifite" while loops that have no break *) let rec loop e = match e.eexpr with (* ignore nested loops to not accidentally get one of its breaks *) | TWhile _ | TFor _ -> () | TBreak -> error() | _ -> Type.iter loop e in loop e | _ -> error() (* ---------------------------------------------------------------------- *) (* PASS 1 & 2 : Module and Class Structure *) let is_generic_parameter ctx c = (* first check field parameters, then class parameters *) try ignore (List.assoc (snd c.cl_path) ctx.curfield.cf_params); Meta.has Meta.Generic ctx.curfield.cf_meta with Not_found -> try ignore(List.assoc (snd c.cl_path) ctx.type_params); (match ctx.curclass.cl_kind with | KGeneric -> true | _ -> false); with Not_found -> false let type_function_arg_value ctx t c do_display = match c with | None -> None | Some e -> let p = pos e in let e = if do_display then Display.ExprPreprocessing.process_expr ctx.com e else e in let e = ctx.g.do_optimize ctx (type_expr ctx e (WithType t)) in unify ctx e.etype t p; let rec loop e = match e.eexpr with | TConst c -> Some c | TCast(e,None) -> loop e | _ -> if not ctx.com.display.dms_display || ctx.com.display.dms_inline && ctx.com.display.dms_error_policy = EPCollect then display_error ctx "Parameter default value should be constant" p; None in loop e (**** strict meta ****) let get_native_repr md pos = let path, meta = match md with | TClassDecl cl -> cl.cl_path, cl.cl_meta | TEnumDecl e -> e.e_path, e.e_meta | TTypeDecl t -> t.t_path, t.t_meta | TAbstractDecl a -> a.a_path, a.a_meta in let rec loop acc = function | (Meta.JavaCanonical,[EConst(String pack),_; EConst(String name),_],_) :: _ -> ExtString.String.nsplit pack ".", name | (Meta.Native,[EConst(String name),_],_) :: meta -> loop (Ast.parse_path name) meta | _ :: meta -> loop acc meta | [] -> acc in let pack, name = loop path meta in match pack with | [] -> (EConst(Ident(name)), pos) | hd :: tl -> let rec loop pack expr = match pack with | hd :: tl -> loop tl (EField(expr,hd),pos) | [] -> (EField(expr,name),pos) in loop tl (EConst(Ident(hd)),pos) let rec process_meta_argument ?(toplevel=true) ctx expr = match expr.eexpr with | TField(e,f) -> (EField(process_meta_argument ~toplevel:false ctx e,field_name f),expr.epos) | TConst(TInt i) -> (EConst(Int (Int32.to_string i)), expr.epos) | TConst(TFloat f) -> (EConst(Float f), expr.epos) | TConst(TString s) -> (EConst(String s), expr.epos) | TConst TNull -> (EConst(Ident "null"), expr.epos) | TConst(TBool b) -> (EConst(Ident (string_of_bool b)), expr.epos) | TCast(e,_) | TMeta(_,e) | TParenthesis(e) -> process_meta_argument ~toplevel ctx e | TTypeExpr md when toplevel -> let p = expr.epos in if ctx.com.platform = Cs then (ECall( (EConst(Ident "typeof"), p), [get_native_repr md expr.epos] ), p) else (EField(get_native_repr md expr.epos, "class"), p) | TTypeExpr md -> get_native_repr md expr.epos | _ -> display_error ctx "This expression is too complex to be a strict metadata argument" expr.epos; (EConst(Ident "null"), expr.epos) let make_meta ctx texpr extra = match texpr.eexpr with | TNew(c,_,el) -> ECall(get_native_repr (TClassDecl c) texpr.epos, (List.map (process_meta_argument ctx) el) @ extra), texpr.epos | TTypeExpr(md) -> ECall(get_native_repr md texpr.epos, extra), texpr.epos | _ -> display_error ctx "Unexpected expression" texpr.epos; assert false let field_to_type_path ctx e = let rec loop e pack name = match e with | EField(e,f),p when Char.lowercase (String.get f 0) <> String.get f 0 -> (match name with | [] | _ :: [] -> loop e pack (f :: name) | _ -> (* too many name paths *) display_error ctx ("Unexpected " ^ f) p; raise Exit) | EField(e,f),_ -> loop e (f :: pack) name | EConst(Ident f),_ -> let pack, name, sub = match name with | [] -> let fchar = String.get f 0 in if Char.uppercase fchar = fchar then pack, f, None else begin display_error ctx "A class name must start with an uppercase character" (snd e); raise Exit end | [name] -> f :: pack, name, None | [name; sub] -> f :: pack, name, Some sub | _ -> assert false in { tpackage=pack; tname=name; tparams=[]; tsub=sub } | _,pos -> display_error ctx "Unexpected expression when building strict meta" pos; raise Exit in loop e [] [] let handle_fields ctx fields_to_check with_type_expr = List.map (fun ((name,_),expr) -> let pos = snd expr in let field = (EField(with_type_expr,name), pos) in let fieldexpr = (EConst(Ident name),pos) in let left_side = match ctx.com.platform with | Cs -> field | Java -> (ECall(field,[]),pos) | _ -> assert false in let left = type_expr ctx left_side NoValue in let right = type_expr ctx expr (WithType left.etype) in unify ctx left.etype right.etype (snd expr); (EBinop(Ast.OpAssign,fieldexpr,process_meta_argument ctx right), pos) ) fields_to_check let get_strict_meta ctx params pos = let pf = ctx.com.platform in let changed_expr, fields_to_check, ctype = match params with | [ECall(ef, el),p] -> (* check last argument *) let el, fields = match List.rev el with | (EObjectDecl(decl),_) :: el -> List.rev el, decl | _ -> el, [] in let tpath = field_to_type_path ctx ef in if pf = Cs then (ENew((tpath,snd ef), el), p), fields, CTPath tpath else ef, fields, CTPath tpath | [EConst(Ident i),p as expr] -> let tpath = { tpackage=[]; tname=i; tparams=[]; tsub=None } in if pf = Cs then (ENew((tpath,p), []), p), [], CTPath tpath else expr, [], CTPath tpath | [ (EField(_),p as field) ] -> let tpath = field_to_type_path ctx field in if pf = Cs then (ENew((tpath,p), []), p), [], CTPath tpath else field, [], CTPath tpath | _ -> display_error ctx "A @:strict metadata must contain exactly one parameter. Please check the documentation for more information" pos; raise Exit in let texpr = type_expr ctx changed_expr NoValue in let with_type_expr = (ECheckType( (EConst (Ident "null"), pos), (ctype,null_pos) ), pos) in let extra = handle_fields ctx fields_to_check with_type_expr in Meta.Meta, [make_meta ctx texpr extra], pos let check_strict_meta ctx metas = let pf = ctx.com.platform in match pf with | Cs | Java -> let ret = ref [] in List.iter (function | Meta.Strict,params,pos -> (try ret := get_strict_meta ctx params pos :: !ret with | Exit -> ()) | _ -> () ) metas; !ret | _ -> [] (**** end of strict meta handling *****) let add_constructor ctx c force_constructor p = match c.cl_constructor, c.cl_super with | None, Some ({ cl_constructor = Some cfsup } as csup,cparams) when not c.cl_extern -> let cf = { cfsup with cf_pos = p; cf_meta = List.filter (fun (m,_,_) -> m = Meta.CompilerGenerated) cfsup.cf_meta; cf_doc = None; cf_expr = None; } in let r = exc_protect ctx (fun r -> let t = mk_mono() in r := (fun() -> t); let ctx = { ctx with curfield = cf; pass = PTypeField; } in ignore (follow cfsup.cf_type); (* make sure it's typed *) (if ctx.com.config.pf_overload then List.iter (fun cf -> ignore (follow cf.cf_type)) cf.cf_overloads); let map_arg (v,def) = (* let's optimize a bit the output by not always copying the default value into the inherited constructor when it's not necessary for the platform *) match ctx.com.platform, def with | _, Some _ when not ctx.com.config.pf_static -> v, (Some TNull) | Flash, Some (TString _) -> v, (Some TNull) | Cpp, Some (TString _) -> v, def | Cpp, Some _ -> { v with v_type = ctx.t.tnull v.v_type }, (Some TNull) | _ -> v, def in let args = (match cfsup.cf_expr with | Some { eexpr = TFunction f } -> List.map map_arg f.tf_args | _ -> let values = get_value_meta cfsup.cf_meta in match follow cfsup.cf_type with | TFun (args,_) -> List.map (fun (n,o,t) -> let def = try type_function_arg_value ctx t (Some (PMap.find n values)) false with Not_found -> if o then Some TNull else None in map_arg (alloc_var n (if o then ctx.t.tnull t else t) p,def) (* TODO: var pos *) ) args | _ -> assert false ) in let p = c.cl_pos in let vars = List.map (fun (v,def) -> alloc_var v.v_name (apply_params csup.cl_params cparams v.v_type) v.v_pos, def) args in let super_call = mk (TCall (mk (TConst TSuper) (TInst (csup,cparams)) p,List.map (fun (v,_) -> mk (TLocal v) v.v_type p) vars)) ctx.t.tvoid p in let constr = mk (TFunction { tf_args = vars; tf_type = ctx.t.tvoid; tf_expr = super_call; }) (TFun (List.map (fun (v,c) -> v.v_name, c <> None, v.v_type) vars,ctx.t.tvoid)) p in cf.cf_expr <- Some constr; cf.cf_type <- t; unify ctx t constr.etype p; t ) "add_constructor" in cf.cf_type <- TLazy r; c.cl_constructor <- Some cf; delay ctx PForce (fun() -> ignore((!r)())); | None,_ when force_constructor -> let constr = mk (TFunction { tf_args = []; tf_type = ctx.t.tvoid; tf_expr = mk (TBlock []) ctx.t.tvoid p; }) (tfun [] ctx.t.tvoid) p in let cf = mk_field "new" constr.etype p null_pos in cf.cf_expr <- Some constr; cf.cf_type <- constr.etype; cf.cf_meta <- [Meta.CompilerGenerated,[],null_pos]; cf.cf_kind <- Method MethNormal; c.cl_constructor <- Some cf; | _ -> (* nothing to do *) () let check_struct_init_constructor ctx c p = match c.cl_constructor with | Some _ -> () | None -> let params = List.map snd c.cl_params in let ethis = mk (TConst TThis) (TInst(c,params)) p in let args,el,tl = List.fold_left (fun (args,el,tl) cf -> match cf.cf_kind with | Var _ -> let opt = Meta.has Meta.Optional cf.cf_meta in let t = if opt then ctx.t.tnull cf.cf_type else cf.cf_type in let v = alloc_var cf.cf_name t p in let ef = mk (TField(ethis,FInstance(c,params,cf))) t p in let ev = mk (TLocal v) v.v_type p in let e = mk (TBinop(OpAssign,ef,ev)) ev.etype p in (v,None) :: args,e :: el,(cf.cf_name,opt,t) :: tl | Method _ -> args,el,tl ) ([],[],[]) (List.rev c.cl_ordered_fields) in let tf = { tf_args = args; tf_type = ctx.t.tvoid; tf_expr = mk (TBlock el) ctx.t.tvoid p } in let e = mk (TFunction tf) (TFun(tl,ctx.t.tvoid)) p in let cf = mk_field "new" e.etype p null_pos in cf.cf_expr <- Some e; cf.cf_type <- e.etype; cf.cf_meta <- [Meta.CompilerGenerated,[],null_pos]; cf.cf_kind <- Method MethNormal; c.cl_constructor <- Some cf module Inheritance = struct let check_extends ctx c t p = match follow t with | TInst ({ cl_path = [],"Array"; cl_extern = basic_extern },_) | TInst ({ cl_path = [],"String"; cl_extern = basic_extern },_) | TInst ({ cl_path = [],"Date"; cl_extern = basic_extern },_) | TInst ({ cl_path = [],"Xml"; cl_extern = basic_extern },_) when not (c.cl_extern && basic_extern) -> error "Cannot extend basic class" p; | TInst (csup,params) -> if is_parent c csup then error "Recursive class" p; begin match csup.cl_kind with | KTypeParameter _ when not (is_generic_parameter ctx csup) -> error "Cannot extend non-generic type parameters" p | _ -> csup,params end | _ -> error "Should extend by using a class" p let rec check_interface ctx c intf params = let p = c.cl_pos in let rec check_field i f = (if ctx.com.config.pf_overload then List.iter (function | f2 when f != f2 -> check_field i f2 | _ -> ()) f.cf_overloads); let is_overload = ref false in try let t2, f2 = class_field_no_interf c i in let t2, f2 = if ctx.com.config.pf_overload && (f2.cf_overloads <> [] || Meta.has Meta.Overload f2.cf_meta) then let overloads = Overloads.get_overloads c i in is_overload := true; let t = (apply_params intf.cl_params params f.cf_type) in List.find (fun (t1,f1) -> Overloads.same_overload_args t t1 f f1) overloads else t2, f2 in if ctx.com.display.dms_collect_data then begin let h = ctx.com.display_information in h.interface_field_implementations <- (intf,f,c,Some f2) :: h.interface_field_implementations; end; ignore(follow f2.cf_type); (* force evaluation *) let p = (match f2.cf_expr with None -> p | Some e -> e.epos) in let mkind = function | MethNormal | MethInline -> 0 | MethDynamic -> 1 | MethMacro -> 2 in if f.cf_public && not f2.cf_public && not (Meta.has Meta.CompilerGenerated f.cf_meta) then display_error ctx ("Field " ^ i ^ " should be public as requested by " ^ s_type_path intf.cl_path) p else if not (unify_kind f2.cf_kind f.cf_kind) || not (match f.cf_kind, f2.cf_kind with Var _ , Var _ -> true | Method m1, Method m2 -> mkind m1 = mkind m2 | _ -> false) then display_error ctx ("Field " ^ i ^ " has different property access than in " ^ s_type_path intf.cl_path ^ " (" ^ s_kind f2.cf_kind ^ " should be " ^ s_kind f.cf_kind ^ ")") p else try valid_redefinition ctx f2 t2 f (apply_params intf.cl_params params f.cf_type) with Unify_error l -> if not (Meta.has Meta.CsNative c.cl_meta && c.cl_extern) then begin display_error ctx ("Field " ^ i ^ " has different type than in " ^ s_type_path intf.cl_path) p; display_error ctx ("Interface field is defined here") f.cf_pos; display_error ctx (error_msg (Unify l)) p; end with | Not_found when not c.cl_interface -> let msg = if !is_overload then let ctx = print_context() in let args = match follow f.cf_type with | TFun(args,_) -> String.concat ", " (List.map (fun (n,o,t) -> (if o then "?" else "") ^ n ^ " : " ^ (s_type ctx t)) args) | _ -> assert false in "No suitable overload for " ^ i ^ "( " ^ args ^ " ), as needed by " ^ s_type_path intf.cl_path ^ " was found" else ("Field " ^ i ^ " needed by " ^ s_type_path intf.cl_path ^ " is missing") in display_error ctx msg p | Not_found -> () in PMap.iter check_field intf.cl_fields; List.iter (fun (i2,p2) -> check_interface ctx c i2 (List.map (apply_params intf.cl_params params) p2) ) intf.cl_implements let check_interfaces ctx c = match c.cl_path with | "Proxy" :: _ , _ -> () | _ when c.cl_extern && Meta.has Meta.CsNative c.cl_meta -> () | _ -> List.iter (fun (intf,params) -> check_interface ctx c intf params) c.cl_implements let set_heritance ctx c herits p = let is_lib = Meta.has Meta.LibType c.cl_meta in let ctx = { ctx with curclass = c; type_params = c.cl_params; } in let old_meta = c.cl_meta in let process_meta csup = List.iter (fun m -> match m with | Meta.Final, _, _ -> if not (Meta.has Meta.Hack c.cl_meta || (match c.cl_kind with KTypeParameter _ -> true | _ -> false)) then error "Cannot extend a final class" p; | Meta.AutoBuild, el, p -> c.cl_meta <- (Meta.Build,el,null_pos) :: m :: c.cl_meta | _ -> () ) csup.cl_meta in let check_cancel_build csup = match csup.cl_build() with | Built -> () | state -> (* for macros reason, our super class is not yet built - see #2177 *) (* let's reset our build and delay it until we are done *) c.cl_meta <- old_meta; raise (Build_canceled state) in let has_interf = ref false in (* resolve imports before calling build_inheritance, since it requires full paths. that means that typedefs are not working, but that's a fair limitation *) let resolve_imports (t,p) = match t.tpackage with | _ :: _ -> t,p | [] -> try let path_matches lt = snd (t_path lt) = t.tname in let lt = try List.find path_matches ctx.m.curmod.m_types with Not_found -> let t,pi = List.find (fun (lt,_) -> path_matches lt) ctx.m.module_types in Display.ImportHandling.mark_import_position ctx.com pi; t in { t with tpackage = fst (t_path lt) },p with Not_found -> t,p in let herits = ExtList.List.filter_map (function | HExtends t -> Some(true,resolve_imports t) | HImplements t -> Some(false,resolve_imports t) | t -> None ) herits in let herits = List.filter (ctx.g.do_inherit ctx c p) herits in (* Pass 1: Check and set relations *) let check_herit t is_extends = if is_extends then begin if c.cl_super <> None then error "Cannot extend several classes" p; let csup,params = check_extends ctx c t p in if c.cl_interface then begin if not csup.cl_interface then error "Cannot extend by using a class" p; c.cl_implements <- (csup,params) :: c.cl_implements; if not !has_interf then begin if not is_lib then delay ctx PForce (fun() -> check_interfaces ctx c); has_interf := true; end end else begin if csup.cl_interface then error "Cannot extend by using an interface" p; c.cl_super <- Some (csup,params) end; (fun () -> check_cancel_build csup; process_meta csup; ) end else begin match follow t with | TInst ({ cl_path = [],"ArrayAccess"; cl_extern = true; },[t]) -> if c.cl_array_access <> None then error "Duplicate array access" p; c.cl_array_access <- Some t; (fun () -> ()) | TInst (intf,params) -> if is_parent c intf then error "Recursive class" p; if c.cl_interface then error "Interfaces cannot implement another interface (use extends instead)" p; if not intf.cl_interface then error "You can only implement an interface" p; c.cl_implements <- (intf, params) :: c.cl_implements; if not !has_interf && not is_lib && not (Meta.has (Meta.Custom "$do_not_check_interf") c.cl_meta) then begin delay ctx PForce (fun() -> check_interfaces ctx c); has_interf := true; end; (fun () -> check_cancel_build intf; process_meta intf; ) | TDynamic t -> if c.cl_dynamic <> None then error "Cannot have several dynamics" p; c.cl_dynamic <- Some t; (fun () -> ()) | _ -> error "Should implement by using an interface" p end in let fl = ExtList.List.filter_map (fun (is_extends,t) -> try let t = load_instance ~allow_display:true ctx t false p in Some (check_herit t is_extends) with Error(Module_not_found(([],name)),p) when ctx.com.display.dms_display -> if Display.Diagnostics.is_diagnostics_run ctx then Display.ToplevelCollector.handle_unresolved_identifier ctx name p true; None ) herits in fl end let rec type_type_param ?(enum_constructor=false) ctx path get_params p tp = let n = fst tp.tp_name in let c = mk_class ctx.m.curmod (fst path @ [snd path],n) (pos tp.tp_name) (pos tp.tp_name) in c.cl_params <- type_type_params ctx c.cl_path get_params p tp.tp_params; c.cl_kind <- KTypeParameter []; c.cl_meta <- tp.Ast.tp_meta; if enum_constructor then c.cl_meta <- (Meta.EnumConstructorParam,[],null_pos) :: c.cl_meta; let t = TInst (c,List.map snd c.cl_params) in if ctx.is_display_file && Display.is_display_position (pos tp.tp_name) then Display.DisplayEmitter.display_type ctx.com.display t (pos tp.tp_name); match tp.tp_constraints with | [] -> n, t | _ -> let r = exc_protect ctx (fun r -> r := (fun _ -> t); let ctx = { ctx with type_params = ctx.type_params @ get_params() } in let constr = List.map (load_complex_type ctx true p) tp.tp_constraints in (* check against direct recursion *) let rec loop t = match follow t with | TInst (c2,_) when c == c2 -> error "Recursive constraint parameter is not allowed" p | TInst ({ cl_kind = KTypeParameter cl },_) -> List.iter loop cl | _ -> () in List.iter loop constr; c.cl_kind <- KTypeParameter constr; t ) "constraint" in delay ctx PForce (fun () -> ignore(!r())); n, TLazy r and type_type_params ?(enum_constructor=false) ctx path get_params p tpl = let names = ref [] in List.map (fun tp -> if List.exists (fun name -> name = fst tp.tp_name) !names then display_error ctx ("Duplicate type parameter name: " ^ fst tp.tp_name) (pos tp.tp_name); names := (fst tp.tp_name) :: !names; type_type_param ~enum_constructor ctx path get_params p tp ) tpl let type_function_params ctx fd fname p = let params = ref [] in params := type_type_params ctx ([],fname) (fun() -> !params) p fd.f_params; !params let type_function ctx args ret fmode f do_display p = let locals = save_locals ctx in let fargs = List.map2 (fun (n,c,t) ((_,pn),_,m,_,_) -> if n.[0] = '$' then error "Function argument names starting with a dollar are not allowed" p; let c = type_function_arg_value ctx t c do_display in let v,c = add_local ctx n t pn, c in v.v_meta <- m; if do_display && Display.is_display_position pn then Display.DisplayEmitter.display_variable ctx.com.display v pn; if n = "this" then v.v_meta <- (Meta.This,[],null_pos) :: v.v_meta; v,c ) args f.f_args in let old_ret = ctx.ret in let old_fun = ctx.curfun in let old_opened = ctx.opened in ctx.curfun <- fmode; ctx.ret <- ret; ctx.opened <- []; let e = match f.f_expr with | None -> if ctx.com.display.dms_error_policy = EPIgnore then (* when we don't care because we're in display mode, just act like the function has an empty block body. this is fine even if function defines a return type, because returns aren't checked in this mode *) EBlock [],p else error "Function body required" p | Some e -> e in let e = if not do_display then type_expr ctx e NoValue else begin let e = Display.ExprPreprocessing.process_expr ctx.com e in try if Common.defined ctx.com Define.NoCOpt then raise Exit; type_expr ctx (Optimizer.optimize_completion_expr e) NoValue with | Parser.TypePath (_,None,_) | Exit -> type_expr ctx e NoValue | Display.DisplayType (t,_,_) when (match follow t with TMono _ -> true | _ -> false) -> type_expr ctx (if ctx.com.display.dms_kind = DMToplevel then Display.ExprPreprocessing.find_enclosing ctx.com e else e) NoValue end in let e = match e.eexpr with | TMeta((Meta.MergeBlock,_,_), ({eexpr = TBlock el} as e1)) -> e1 | _ -> e in let has_return e = let rec loop e = match e.eexpr with | TReturn (Some _) -> raise Exit | TFunction _ -> () | _ -> Type.iter loop e in try loop e; false with Exit -> true in begin match follow ret with | TAbstract({a_path=[],"Void"},_) -> () (* We have to check for the presence of return expressions here because in the case of Dynamic ctx.ret is still a monomorph. If we indeed don't have a return expression we can link the monomorph to Void. We can _not_ use type_iseq to avoid the Void check above because that would turn Dynamic returns to Void returns. *) | TMono t when not (has_return e) -> ignore(link t ret ctx.t.tvoid) | _ when ctx.com.display.dms_error_policy = EPIgnore -> () | _ -> (try return_flow ctx e with Exit -> ()) end; let rec loop e = match e.eexpr with | TCall ({ eexpr = TConst TSuper },_) -> raise Exit | TFunction _ -> () | _ -> Type.iter loop e in let has_super_constr() = match ctx.curclass.cl_super with | None -> None | Some (csup,tl) -> try let _,cf = get_constructor (fun f->f.cf_type) csup in Some (Meta.has Meta.CompilerGenerated cf.cf_meta,TInst(csup,tl)) with Not_found -> None in let e = if fmode <> FunConstructor then e else match has_super_constr() with | Some (was_forced,t_super) -> (try loop e; if was_forced then let e_super = mk (TConst TSuper) t_super e.epos in let e_super_call = mk (TCall(e_super,[])) ctx.t.tvoid e.epos in concat e_super_call e else begin display_error ctx "Missing super constructor call" p; e end with Exit -> e); | None -> e in locals(); let e = match ctx.curfun, ctx.vthis with | (FunMember|FunConstructor), Some v -> let ev = mk (TVar (v,Some (mk (TConst TThis) ctx.tthis p))) ctx.t.tvoid p in (match e.eexpr with | TBlock l -> { e with eexpr = TBlock (ev::l) } | _ -> mk (TBlock [ev;e]) e.etype p) | _ -> e in List.iter (fun r -> r := Closed) ctx.opened; ctx.ret <- old_ret; ctx.curfun <- old_fun; ctx.opened <- old_opened; e , fargs let load_core_class ctx c = let ctx2 = (match ctx.g.core_api with | None -> let com2 = Common.clone ctx.com in com2.defines <- PMap.empty; Common.define com2 Define.CoreApi; Common.define com2 Define.Sys; if ctx.in_macro then Common.define com2 Define.Macro; com2.class_path <- ctx.com.std_path; let ctx2 = ctx.g.do_create com2 in ctx.g.core_api <- Some ctx2; ctx2 | Some c -> c ) in let tpath = match c.cl_kind with | KAbstractImpl a -> { tpackage = fst a.a_path; tname = snd a.a_path; tparams = []; tsub = None; } | _ -> { tpackage = fst c.cl_path; tname = snd c.cl_path; tparams = []; tsub = None; } in let t = load_instance ctx2 (tpath,c.cl_pos) true c.cl_pos in flush_pass ctx2 PFinal "core_final"; match t with | TInst (ccore,_) | TAbstract({a_impl = Some ccore}, _) -> ccore | _ -> assert false let init_core_api ctx c = let ccore = load_core_class ctx c in begin try List.iter2 (fun (n1,t1) (n2,t2) -> match follow t1, follow t2 with | TInst({cl_kind = KTypeParameter l1},_),TInst({cl_kind = KTypeParameter l2},_) -> begin try List.iter2 (fun t1 t2 -> type_eq EqCoreType t2 t1) l1 l2 with | Invalid_argument _ -> error "Type parameters must have the same number of constraints as core type" c.cl_pos | Unify_error l -> display_error ctx ("Type parameter " ^ n2 ^ " has different constraint than in core type") c.cl_pos; display_error ctx (error_msg (Unify l)) c.cl_pos end | t1,t2 -> Printf.printf "%s %s" (s_type (print_context()) t1) (s_type (print_context()) t2); assert false ) ccore.cl_params c.cl_params; with Invalid_argument _ -> error "Class must have the same number of type parameters as core type" c.cl_pos end; (match c.cl_doc with | None -> c.cl_doc <- ccore.cl_doc | Some _ -> ()); let compare_fields f f2 = let p = (match f2.cf_expr with None -> c.cl_pos | Some e -> e.epos) in (try type_eq EqCoreType (apply_params ccore.cl_params (List.map snd c.cl_params) f.cf_type) f2.cf_type with Unify_error l -> display_error ctx ("Field " ^ f.cf_name ^ " has different type than in core type") p; display_error ctx (error_msg (Unify l)) p); if f2.cf_public <> f.cf_public then error ("Field " ^ f.cf_name ^ " has different visibility than core type") p; (match f2.cf_doc with | None -> f2.cf_doc <- f.cf_doc | Some _ -> ()); if f2.cf_kind <> f.cf_kind then begin match f2.cf_kind, f.cf_kind with | Method MethInline, Method MethNormal -> () (* allow to add 'inline' *) | Method MethNormal, Method MethInline -> () (* allow to disable 'inline' *) | _ -> error ("Field " ^ f.cf_name ^ " has different property access than core type") p; end; (match follow f.cf_type, follow f2.cf_type with | TFun (pl1,_), TFun (pl2,_) -> if List.length pl1 != List.length pl2 then error "Argument count mismatch" p; List.iter2 (fun (n1,_,_) (n2,_,_) -> if n1 <> n2 then error ("Method parameter name '" ^ n2 ^ "' should be '" ^ n1 ^ "'") p; ) pl1 pl2; | _ -> ()); in let check_fields fcore fl = PMap.iter (fun i f -> if not f.cf_public then () else let f2 = try PMap.find f.cf_name fl with Not_found -> error ("Missing field " ^ i ^ " required by core type") c.cl_pos in compare_fields f f2; ) fcore; PMap.iter (fun i f -> let p = (match f.cf_expr with None -> c.cl_pos | Some e -> e.epos) in if f.cf_public && not (Meta.has Meta.Hack f.cf_meta) && not (PMap.mem f.cf_name fcore) && not (List.memq f c.cl_overrides) then error ("Public field " ^ i ^ " is not part of core type") p; ) fl; in check_fields ccore.cl_fields c.cl_fields; check_fields ccore.cl_statics c.cl_statics; (match ccore.cl_constructor, c.cl_constructor with | None, None -> () | Some { cf_public = false }, _ -> () | Some f, Some f2 -> compare_fields f f2 | None, Some { cf_public = false } -> () | _ -> error "Constructor differs from core type" c.cl_pos) let check_global_metadata ctx meta f_add mpath tpath so = let sl1 = full_dot_path mpath tpath in let sl1,field_mode = match so with None -> sl1,false | Some s -> sl1 @ [s],true in List.iter (fun (sl2,m,(recursive,to_types,to_fields)) -> let add = ((field_mode && to_fields) || (not field_mode && to_types)) && (match_path recursive sl1 sl2) in if add then f_add m ) ctx.g.global_metadata; if ctx.is_display_file then Display.DisplayEmitter.check_display_metadata ctx meta let patch_class ctx c fields = let path = match c.cl_kind with | KAbstractImpl a -> a.a_path | _ -> c.cl_path in let h = (try Some (Hashtbl.find ctx.g.type_patches path) with Not_found -> None) in match h with | None -> fields | Some (h,hcl) -> c.cl_meta <- c.cl_meta @ hcl.tp_meta; let rec loop acc = function | [] -> acc | f :: l -> (* patch arguments types *) (match f.cff_kind with | FFun ff -> let param (((n,pn),opt,m,_,e) as p) = try let t2 = (try Hashtbl.find h (("$" ^ (fst f.cff_name) ^ "__" ^ n),false) with Not_found -> Hashtbl.find h (("$" ^ n),false)) in (n,pn), opt, m, (match t2.tp_type with None -> None | Some t -> Some (t,null_pos)), e with Not_found -> p in f.cff_kind <- FFun { ff with f_args = List.map param ff.f_args } | _ -> ()); (* other patches *) match (try Some (Hashtbl.find h (fst f.cff_name,List.mem AStatic f.cff_access)) with Not_found -> None) with | None -> loop (f :: acc) l | Some { tp_remove = true } -> loop acc l | Some p -> f.cff_meta <- f.cff_meta @ p.tp_meta; (match p.tp_type with | None -> () | Some t -> f.cff_kind <- match f.cff_kind with | FVar (_,e) -> FVar (Some (t,null_pos),e) | FProp (get,set,_,eo) -> FProp (get,set,Some (t,null_pos),eo) | FFun f -> FFun { f with f_type = Some (t,null_pos) }); loop (f :: acc) l in List.rev (loop [] fields) let string_list_of_expr_path (e,p) = try string_list_of_expr_path_raise (e,p) with Exit -> error "Invalid path" p let build_enum_abstract ctx c a fields p = List.iter (fun field -> match field.cff_kind with | FVar(ct,eo) when not (List.mem AStatic field.cff_access) -> field.cff_access <- [AStatic; if (List.mem APrivate field.cff_access) then APrivate else APublic]; field.cff_meta <- (Meta.Enum,[],null_pos) :: (Meta.Impl,[],null_pos) :: field.cff_meta; let ct = match ct with | Some _ -> ct | None -> Some (TExprToExpr.convert_type (TAbstract(a,List.map snd a.a_params)),null_pos) in begin match eo with | None -> if not c.cl_extern then error "Value required" field.cff_pos else field.cff_kind <- FProp(("default",null_pos),("never",null_pos),ct,None) | Some e -> field.cff_access <- AInline :: field.cff_access; let e = (ECast(e,None),(pos e)) in field.cff_kind <- FVar(ct,Some e) end | _ -> () ) fields; EVars [("",null_pos),Some (CTAnonymous fields,p),None],p let is_java_native_function meta = try match Meta.get Meta.Native meta with | (Meta.Native,[],_) -> true | _ -> false with | Not_found -> false let build_module_def ctx mt meta fvars context_init fbuild = let loop (f_build,f_enum) = function | Meta.Build,args,p -> (fun () -> let epath, el = (match args with | [ECall (epath,el),p] -> epath, el | _ -> error "Invalid build parameters" p ) in let s = try String.concat "." (List.rev (string_list_of_expr_path epath)) with Error (_,p) -> error "Build call parameter must be a class path" p in if ctx.in_macro then error "You cannot use @:build inside a macro : make sure that your type is not used in macro" p; let old = ctx.g.get_build_infos in ctx.g.get_build_infos <- (fun() -> Some (mt, List.map snd (t_infos mt).mt_params, fvars())); context_init(); let r = try apply_macro ctx MBuild s el p with e -> ctx.g.get_build_infos <- old; raise e in ctx.g.get_build_infos <- old; (match r with | None -> error "Build failure" p | Some e -> fbuild e) ) :: f_build,f_enum | Meta.Enum,_,p -> f_build,Some (fun () -> begin match mt with | TClassDecl ({cl_kind = KAbstractImpl a} as c) -> context_init(); let e = build_enum_abstract ctx c a (fvars()) p in fbuild e; | _ -> () end ) | _ -> f_build,f_enum in (* let errors go through to prevent resume if build fails *) let f_build,f_enum = List.fold_left loop ([],None) meta in List.iter (fun f -> f()) (List.rev f_build); (match f_enum with None -> () | Some f -> f()) module ClassInitializer = struct type class_init_ctx = { tclass : tclass; (* I don't trust ctx.curclass because it's mutable. *) is_lib : bool; is_native : bool; is_core_api : bool; is_class_debug : bool; extends_public : bool; abstract : tabstract option; context_init : unit -> unit; mutable delayed_expr : (typer * (unit -> t) ref option) list; mutable force_constructor : bool; } type field_kind = | FKNormal | FKConstructor | FKInit type field_init_ctx = { is_inline : bool; is_static : bool; is_override : bool; is_extern : bool; is_macro : bool; is_abstract_member : bool; is_display_field : bool; is_field_debug : bool; field_kind : field_kind; mutable do_bind : bool; mutable do_add : bool; } let dump_class_context cctx = Printer.s_record_fields "" [ "tclass",Printer.s_tclass "\t" cctx.tclass; "is_lib",string_of_bool cctx.is_lib; "is_native",string_of_bool cctx.is_native; "is_core_api",string_of_bool cctx.is_core_api; "is_class_debug",string_of_bool cctx.is_class_debug; "extends_public",string_of_bool cctx.extends_public; "abstract",Printer.s_opt (Printer.s_tabstract "\t") cctx.abstract; "force_constructor",string_of_bool cctx.force_constructor; ] let s_field_kind = function | FKNormal -> "FKNormal" | FKConstructor -> "FKConstructor" | FKInit -> "FKInit" let dump_field_context fctx = Printer.s_record_fields "" [ "is_inline",string_of_bool fctx.is_inline; "is_static",string_of_bool fctx.is_static; "is_override",string_of_bool fctx.is_override; "is_extern",string_of_bool fctx.is_extern; "is_macro",string_of_bool fctx.is_macro; "is_abstract_member",string_of_bool fctx.is_abstract_member; "is_display_field",string_of_bool fctx.is_display_field; "is_field_debug",string_of_bool fctx.is_field_debug; "field_kind",s_field_kind fctx.field_kind; "do_bind",string_of_bool fctx.do_bind; "do_add",string_of_bool fctx.do_add; ] let create_class_context ctx c context_init p = locate_macro_error := true; incr stats.s_classes_built; let abstract = match c.cl_kind with | KAbstractImpl a -> Some a | _ -> None in let ctx = { ctx with curclass = c; type_params = c.cl_params; pass = PBuildClass; tthis = (match abstract with | Some a -> (match a.a_this with | TMono r when !r = None -> TAbstract (a,List.map snd c.cl_params) | t -> t) | None -> TInst (c,List.map snd c.cl_params)); on_error = (fun ctx msg ep -> ctx.com.error msg ep; (* macros expressions might reference other code, let's recall which class we are actually compiling *) if !locate_macro_error && (ep.pfile <> c.cl_pos.pfile || ep.pmax < c.cl_pos.pmin || ep.pmin > c.cl_pos.pmax) then ctx.com.error "Defined in this class" c.cl_pos ); } in (* a lib type will skip most checks *) let is_lib = Meta.has Meta.LibType c.cl_meta in if is_lib && not c.cl_extern then ctx.com.error "@:libType can only be used in extern classes" c.cl_pos; (* a native type will skip one check: the static vs non-static field *) let is_native = Meta.has Meta.JavaNative c.cl_meta || Meta.has Meta.CsNative c.cl_meta in if Meta.has Meta.Macro c.cl_meta then display_error ctx "Macro classes are no longer allowed in haxe 3" c.cl_pos; let rec extends_public c = Meta.has Meta.PublicFields c.cl_meta || match c.cl_super with | None -> false | Some (c,_) -> extends_public c in let cctx = { tclass = c; is_lib = is_lib; is_native = is_native; is_core_api = Meta.has Meta.CoreApi c.cl_meta; is_class_debug = false; extends_public = extends_public c; abstract = abstract; context_init = context_init; force_constructor = false; delayed_expr = []; } in ctx,cctx let create_field_context (ctx,cctx) c cff = let ctx = { ctx with pass = PBuildClass; (* will be set later to PTypeExpr *) } in let is_static = List.mem AStatic cff.cff_access in let is_extern = Meta.has Meta.Extern cff.cff_meta || c.cl_extern in let allow_inline = cctx.abstract <> None || match cff.cff_kind with | FFun _ -> ctx.g.doinline || is_extern | _ -> true in let is_inline = allow_inline && List.mem AInline cff.cff_access in let is_override = List.mem AOverride cff.cff_access in let is_macro = List.mem AMacro cff.cff_access in let field_kind = match fst cff.cff_name with | "new" -> FKConstructor | "__init__" when is_static -> FKInit | _ -> FKNormal in let fctx = { is_inline = is_inline; is_static = is_static; is_override = is_override; is_macro = is_macro; is_extern = is_extern; is_display_field = ctx.is_display_file && Display.is_display_position cff.cff_pos; is_field_debug = cctx.is_class_debug; is_abstract_member = cctx.abstract <> None && Meta.has Meta.Impl cff.cff_meta; field_kind = field_kind; do_bind = (((not c.cl_extern || is_inline) && not c.cl_interface) || field_kind = FKInit); do_add = true; } in ctx,fctx let is_public (ctx,cctx) access parent = let c = cctx.tclass in if List.mem APrivate access then false else if List.mem APublic access then true else match parent with | Some { cf_public = p } -> p | _ -> c.cl_extern || c.cl_interface || cctx.extends_public let rec get_parent c name = match c.cl_super with | None -> None | Some (csup,_) -> try Some (PMap.find name csup.cl_fields) with Not_found -> get_parent csup name let add_field c cf is_static = if is_static then begin c.cl_statics <- PMap.add cf.cf_name cf c.cl_statics; c.cl_ordered_statics <- cf :: c.cl_ordered_statics; end else begin c.cl_fields <- PMap.add cf.cf_name cf c.cl_fields; c.cl_ordered_fields <- cf :: c.cl_ordered_fields; end let type_opt (ctx,cctx) p t = let c = cctx.tclass in match t with | None when c.cl_extern || c.cl_interface -> display_error ctx "Type required for extern classes and interfaces" p; t_dynamic | None when cctx.is_core_api -> display_error ctx "Type required for core api classes" p; t_dynamic | _ -> load_type_hint ctx p t let build_fields (ctx,cctx) c fields = let fields = ref fields in let get_fields() = !fields in let pending = ref [] in c.cl_build <- (fun() -> BuildMacro pending); build_module_def ctx (TClassDecl c) c.cl_meta get_fields cctx.context_init (fun (e,p) -> match e with | EVars [_,Some (CTAnonymous f,p),None] -> let f = List.map (fun f -> let f = match cctx.abstract with | Some a -> let a_t = TExprToExpr.convert_type' (TAbstract(a,List.map snd a.a_params)) in let this_t = TExprToExpr.convert_type' a.a_this in (* TODO: better pos? *) transform_abstract_field ctx.com this_t a_t a f | None -> f in if List.mem AMacro f.cff_access then (match ctx.g.macros with | Some (_,mctx) when Hashtbl.mem mctx.g.types_module c.cl_path -> (* assume that if we had already a macro with the same name, it has not been changed during the @:build operation *) if not (List.exists (fun f2 -> f2.cff_name = f.cff_name && List.mem AMacro f2.cff_access) (!fields)) then error "Class build macro cannot return a macro function when the class has already been compiled into the macro context" p | _ -> ()); f ) f in fields := f | _ -> error "Class build macro must return a single variable with anonymous fields" p ); c.cl_build <- (fun() -> Building); List.iter (fun f -> f()) !pending; !fields let bind_type (ctx,cctx,fctx) cf r p = let c = cctx.tclass in let rec is_full_type t = match t with | TFun (args,ret) -> is_full_type ret && List.for_all (fun (_,_,t) -> is_full_type t) args | TMono r -> (match !r with None -> false | Some t -> is_full_type t) | TAbstract _ | TInst _ | TEnum _ | TLazy _ | TDynamic _ | TAnon _ | TType _ -> true in let force_macro () = (* force macro system loading of this class in order to get completion *) delay ctx PTypeField (fun() -> try ignore(ctx.g.do_macro ctx MDisplay c.cl_path cf.cf_name [] p) with Exit | Error _ -> ()) in let handle_display_field () = if fctx.is_macro && not ctx.in_macro then force_macro() else begin cf.cf_type <- TLazy r; cctx.delayed_expr <- (ctx,Some r) :: cctx.delayed_expr; end in if ctx.com.display.dms_full_typing then begin if fctx.is_macro && not ctx.in_macro then () else begin cf.cf_type <- TLazy r; (* is_lib ? *) cctx.delayed_expr <- (ctx,Some r) :: cctx.delayed_expr; end end else if ctx.com.display.dms_force_macro_typing && fctx.is_macro && not ctx.in_macro then force_macro() else begin if fctx.is_display_field then begin handle_display_field() end else begin if not (is_full_type cf.cf_type) then begin cctx.delayed_expr <- (ctx, None) :: cctx.delayed_expr; cf.cf_type <- TLazy r; end; end end let bind_var (ctx,cctx,fctx) cf e = let c = cctx.tclass in let p = cf.cf_pos in let rec get_declared f = function | None -> None | Some (c,a) when PMap.exists f c.cl_fields -> Some (c,a) | Some (c,_) -> let ret = get_declared f c.cl_super in match ret with | Some r -> Some r | None -> let rec loop ifaces = match ifaces with | [] -> None | i :: ifaces -> match get_declared f (Some i) with | Some r -> Some r | None -> loop ifaces in loop c.cl_implements in if not fctx.is_static && not cctx.is_lib then begin match get_declared cf.cf_name c.cl_super with | None -> () | Some (csup,_) -> (* this can happen on -net-lib generated classes if a combination of explicit interfaces and variables with the same name happens *) if not (csup.cl_interface && Meta.has Meta.CsNative c.cl_meta) then error ("Redefinition of variable " ^ cf.cf_name ^ " in subclass is not allowed. Previously declared at " ^ (s_type_path csup.cl_path) ) p end; let t = cf.cf_type in match e with | None -> if fctx.is_display_field then Display.DisplayEmitter.maybe_display_field ctx (cf.cf_name_pos) cf; | Some e -> if requires_value_meta ctx.com (Some c) then cf.cf_meta <- ((Meta.Value,[e],null_pos) :: cf.cf_meta); let check_cast e = (* insert cast to keep explicit field type (issue #1901) *) if type_iseq e.etype cf.cf_type then e else begin match e.eexpr,follow cf.cf_type with | TConst (TInt i),TAbstract({a_path=[],"Float"},_) -> (* turn int constant to float constant if expected type is float *) {e with eexpr = TConst (TFloat (Int32.to_string i))} | _ -> mk_cast e cf.cf_type e.epos end in let r = exc_protect ctx (fun r -> (* type constant init fields (issue #1956) *) if not !return_partial_type || (match fst e with EConst _ -> true | _ -> false) then begin r := (fun() -> t); cctx.context_init(); if ctx.com.verbose then Common.log ctx.com ("Typing " ^ (if ctx.in_macro then "macro " else "") ^ s_type_path c.cl_path ^ "." ^ cf.cf_name); let e = type_var_field ctx t e fctx.is_static fctx.is_display_field p in let maybe_run_analyzer e = match e.eexpr with | TConst _ | TLocal _ | TFunction _ -> e | _ -> !analyzer_run_on_expr_ref ctx.com e in let require_constant_expression e msg = if ctx.com.display.dms_display && ctx.com.display.dms_error_policy <> EPCollect then e else match Optimizer.make_constant_expression ctx (maybe_run_analyzer e) with | Some e -> e | None -> display_error ctx msg p; e in let e = (match cf.cf_kind with | Var v when c.cl_extern || Meta.has Meta.Extern cf.cf_meta -> if not fctx.is_static then begin display_error ctx "Extern non-static variables may not be initialized" p; e end else if not fctx.is_inline then begin display_error ctx "Extern non-inline variables may not be initialized" p; e end else require_constant_expression e "Extern variable initialization must be a constant value" | Var v when is_extern_field cf -> (* disallow initialization of non-physical fields (issue #1958) *) display_error ctx "This field cannot be initialized because it is not a real variable" p; e | Var v when not fctx.is_static -> let e = if ctx.com.display.dms_display && ctx.com.display.dms_error_policy <> EPCollect then e else match Optimizer.make_constant_expression ctx (maybe_run_analyzer e) with | Some e -> e | None -> let rec has_this e = match e.eexpr with | TConst TThis -> display_error ctx "Cannot access this or other member field in variable initialization" e.epos; | TLocal v when (match ctx.vthis with Some v2 -> v == v2 | None -> false) -> display_error ctx "Cannot access this or other member field in variable initialization" e.epos; | _ -> Type.iter has_this e in has_this e; e in e | Var v when v.v_read = AccInline -> let e = require_constant_expression e "Inline variable initialization must be a constant value" in begin match c.cl_kind with | KAbstractImpl a when Meta.has Meta.Enum cf.cf_meta && Meta.has Meta.Enum a.a_meta -> unify ctx t (TAbstract(a,(List.map (fun _ -> mk_mono()) a.a_params))) p; begin match e.eexpr with | TCast(e1,None) -> unify ctx e1.etype a.a_this e1.epos | _ -> assert false end | _ -> () end; e | _ -> e ) in let e = check_cast e in cf.cf_expr <- Some e; cf.cf_type <- t; if fctx.is_display_field then Display.DisplayEmitter.maybe_display_field ctx (cf.cf_name_pos) cf; end; t ) "bind_var" in if not fctx.is_static then cctx.force_constructor <- true; bind_type (ctx,cctx,fctx) cf r (snd e) let create_variable (ctx,cctx,fctx) c f t eo p = if not fctx.is_static && cctx.abstract <> None then error (fst f.cff_name ^ ": Cannot declare member variable in abstract") p; if fctx.is_inline && not fctx.is_static then error (fst f.cff_name ^ ": Inline variable must be static") p; if fctx.is_inline && eo = None then error (fst f.cff_name ^ ": Inline variable must be initialized") p; let t = (match t with | None when not fctx.is_static && eo = None -> error ("Type required for member variable " ^ fst f.cff_name) p; | None -> mk_mono() | Some t -> (* TODO is_lib: only load complex type if needed *) let old = ctx.type_params in if fctx.is_static then ctx.type_params <- (match cctx.abstract with | Some a -> a.a_params | _ -> [] ); let t = load_complex_type ctx true p t in if fctx.is_static then ctx.type_params <- old; t ) in let cf = { cf_name = fst f.cff_name; cf_doc = f.cff_doc; cf_meta = f.cff_meta; cf_type = t; cf_pos = f.cff_pos; cf_name_pos = pos f.cff_name; cf_kind = Var (if fctx.is_inline then { v_read = AccInline ; v_write = AccNever } else { v_read = AccNormal; v_write = AccNormal }); cf_expr = None; cf_expr_unoptimized = None; cf_public = is_public (ctx,cctx) f.cff_access None; cf_params = []; cf_overloads = []; } in ctx.curfield <- cf; bind_var (ctx,cctx,fctx) cf eo; cf let check_abstract (ctx,cctx,fctx) c cf fd t ret p = match cctx.abstract with | Some a -> let m = mk_mono() in let ta = TAbstract(a, List.map (fun _ -> mk_mono()) a.a_params) in let tthis = if fctx.is_abstract_member || Meta.has Meta.To cf.cf_meta then monomorphs a.a_params a.a_this else a.a_this in let allows_no_expr = ref (Meta.has Meta.CoreType a.a_meta) in let rec loop ml = match ml with | (Meta.From,_,_) :: _ -> let r = fun () -> (* the return type of a from-function must be the abstract, not the underlying type *) if not fctx.is_macro then (try type_eq EqStrict ret ta with Unify_error l -> error (error_msg (Unify l)) p); match t with | TFun([_,_,t],_) -> t | _ -> error (cf.cf_name ^ ": @:from cast functions must accept exactly one argument") p in a.a_from_field <- (TLazy (ref r),cf) :: a.a_from_field; | (Meta.To,_,_) :: _ -> if fctx.is_macro then error (cf.cf_name ^ ": Macro cast functions are not supported") p; (* TODO: this doesn't seem quite right... *) if not (Meta.has Meta.Impl cf.cf_meta) then cf.cf_meta <- (Meta.Impl,[],null_pos) :: cf.cf_meta; let resolve_m args = (try unify_raise ctx t (tfun (tthis :: args) m) cf.cf_pos with Error (Unify l,p) -> error (error_msg (Unify l)) p); match follow m with | TMono _ when (match t with TFun(_,r) -> r == t_dynamic | _ -> false) -> t_dynamic | m -> m in let r = exc_protect ctx (fun r -> let args = if Meta.has Meta.MultiType a.a_meta then begin let ctor = try PMap.find "_new" c.cl_statics with Not_found -> error "Constructor of multi-type abstract must be defined before the individual @:to-functions are" cf.cf_pos in (* delay ctx PFinal (fun () -> unify ctx m tthis f.cff_pos); *) let args = match follow (monomorphs a.a_params ctor.cf_type) with | TFun(args,_) -> List.map (fun (_,_,t) -> t) args | _ -> assert false in args end else [] in let t = resolve_m args in r := (fun() -> t); t ) "@:to" in delay ctx PForce (fun() -> ignore ((!r)())); a.a_to_field <- (TLazy r, cf) :: a.a_to_field | ((Meta.ArrayAccess,_,_) | (Meta.Op,[(EArrayDecl _),_],_)) :: _ -> if fctx.is_macro then error (cf.cf_name ^ ": Macro array-access functions are not supported") p; a.a_array <- cf :: a.a_array; | (Meta.Op,[EBinop(op,_,_),_],_) :: _ -> if fctx.is_macro then error (cf.cf_name ^ ": Macro operator functions are not supported") p; let targ = if fctx.is_abstract_member then tthis else ta in let left_eq,right_eq = match follow t with | TFun([(_,_,t1);(_,_,t2)],_) -> type_iseq targ t1,type_iseq targ t2 | _ -> if fctx.is_abstract_member then error (cf.cf_name ^ ": Member @:op functions must accept exactly one argument") cf.cf_pos else error (cf.cf_name ^ ": Static @:op functions must accept exactly two arguments") cf.cf_pos in if not (left_eq || right_eq) then error (cf.cf_name ^ ": The left or right argument type must be " ^ (s_type (print_context()) targ)) cf.cf_pos; if right_eq && Meta.has Meta.Commutative cf.cf_meta then error (cf.cf_name ^ ": @:commutative is only allowed if the right argument is not " ^ (s_type (print_context()) targ)) cf.cf_pos; a.a_ops <- (op,cf) :: a.a_ops; allows_no_expr := true; | (Meta.Op,[EUnop(op,flag,_),_],_) :: _ -> if fctx.is_macro then error (cf.cf_name ^ ": Macro operator functions are not supported") p; let targ = if fctx.is_abstract_member then tthis else ta in (try type_eq EqStrict t (tfun [targ] (mk_mono())) with Unify_error l -> raise (Error ((Unify l),cf.cf_pos))); a.a_unops <- (op,flag,cf) :: a.a_unops; allows_no_expr := true; | (Meta.Impl,_,_) :: ml when cf.cf_name <> "_new" && not fctx.is_macro -> begin match follow t with | TFun((_,_,t1) :: _, _) when type_iseq tthis t1 -> () | _ -> display_error ctx ("First argument of implementation function must be " ^ (s_type (print_context()) tthis)) cf.cf_pos end; loop ml | ((Meta.Resolve,_,_) | (Meta.Op,[EField _,_],_)) :: _ -> if a.a_resolve <> None then error "Multiple resolve methods are not supported" cf.cf_pos; let targ = if fctx.is_abstract_member then tthis else ta in begin match follow t with | TFun([(_,_,t1);(_,_,t2)],_) -> if not fctx.is_macro then begin if not (type_iseq targ t1) then error ("First argument type must be " ^ (s_type (print_context()) targ)) cf.cf_pos; if not (type_iseq ctx.t.tstring t2) then error ("Second argument type must be String") cf.cf_pos end | _ -> error ("Field type of resolve must be " ^ (s_type (print_context()) targ) ^ " -> String -> T") cf.cf_pos end; a.a_resolve <- Some cf; | _ :: ml -> loop ml | [] -> () in loop cf.cf_meta; let check_bind () = if fd.f_expr = None then begin if fctx.is_inline then error (cf.cf_name ^ ": Inline functions must have an expression") cf.cf_pos; begin match fd.f_type with | None -> error (cf.cf_name ^ ": Functions without expressions must have an explicit return type") cf.cf_pos | Some _ -> () end; cf.cf_meta <- (Meta.NoExpr,[],null_pos) :: cf.cf_meta; fctx.do_bind <- false; if not (Meta.has Meta.CoreType a.a_meta) then fctx.do_add <- false; end in if cf.cf_name = "_new" && Meta.has Meta.MultiType a.a_meta then fctx.do_bind <- false; if !allows_no_expr then check_bind() | _ -> () let create_method (ctx,cctx,fctx) c f fd p = let params = type_function_params ctx fd (fst f.cff_name) p in if Meta.has Meta.Generic f.cff_meta then begin if params = [] then error (fst f.cff_name ^ ": Generic functions must have type parameters") p; end; let fd = if fctx.is_macro && not ctx.in_macro && not fctx.is_static then (* remove display of first argument which will contain the "this" expression *) { fd with f_args = match fd.f_args with [] -> [] | _ :: l -> l } else fd in let fd = if not fctx.is_macro then fd else begin if ctx.in_macro then begin (* a class with a macro cannot be extern in macro context (issue #2015) *) c.cl_extern <- false; let texpr = CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tparams = []; tsub = None } in (* ExprOf type parameter might contain platform-specific type, let's replace it by Expr *) let no_expr_of (t,p) = match t with | CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = Some ("ExprOf"); tparams = [TPType _] } | CTPath { tpackage = []; tname = ("ExprOf"); tsub = None; tparams = [TPType _] } -> Some (texpr,p) | t -> Some (t,p) in { f_params = fd.f_params; f_type = (match fd.f_type with None -> Some (texpr,null_pos) | Some t -> no_expr_of t); f_args = List.map (fun (a,o,m,t,e) -> a,o,m,(match t with None -> Some (texpr,null_pos) | Some t -> no_expr_of t),e) fd.f_args; f_expr = fd.f_expr; } end else let tdyn = Some (CTPath { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None },null_pos) in let to_dyn p t = match t with | { tpackage = ["haxe";"macro"]; tname = "Expr"; tsub = Some ("ExprOf"); tparams = [TPType t] } -> Some t | { tpackage = []; tname = ("ExprOf"); tsub = None; tparams = [TPType t] } -> Some t | { tpackage = ["haxe"]; tname = ("PosInfos"); tsub = None; tparams = [] } -> error "haxe.PosInfos is not allowed on macro functions, use Context.currentPos() instead" p | _ -> tdyn in { f_params = fd.f_params; f_type = (match fd.f_type with Some (CTPath t,p) -> to_dyn p t | _ -> tdyn); f_args = List.map (fun (a,o,m,t,_) -> a,o,m,(match t with Some (CTPath t,p) -> to_dyn p t | _ -> tdyn),None) fd.f_args; f_expr = None; } end in begin match c.cl_interface,fctx.field_kind with | true,FKConstructor -> error "An interface cannot have a constructor" p; | true,_ -> if not fctx.is_static && fd.f_expr <> None then error (fst f.cff_name ^ ": An interface method cannot have a body") p; if fctx.is_inline && c.cl_interface then error (fst f.cff_name ^ ": You can't declare inline methods in interfaces") p; | false,FKConstructor -> if fctx.is_static then error "A constructor must not be static" p; begin match fd.f_type with | None | Some (CTPath { tpackage = []; tname = "Void" },_) -> () | _ -> error "A class constructor can't have a return value" p; end | false,_ -> () end; let parent = (if not fctx.is_static then get_parent c (fst f.cff_name) else None) in let dynamic = List.mem ADynamic f.cff_access || (match parent with Some { cf_kind = Method MethDynamic } -> true | _ -> false) in if fctx.is_inline && dynamic then error (fst f.cff_name ^ ": You can't have both 'inline' and 'dynamic'") p; ctx.type_params <- (match cctx.abstract with | Some a when fctx.is_abstract_member -> params @ a.a_params | _ -> if fctx.is_static then params else params @ ctx.type_params); (* TODO is_lib: avoid forcing the return type to be typed *) let ret = if fctx.field_kind = FKConstructor then ctx.t.tvoid else type_opt (ctx,cctx) p fd.f_type in let rec loop args = match args with | ((name,p),opt,m,t,ct) :: args -> (* TODO is_lib: avoid forcing the field to be typed *) let t, ct = type_function_arg ctx (type_opt (ctx,cctx) p t) ct opt p in delay ctx PTypeField (fun() -> match follow t with | TAbstract({a_path = ["haxe";"extern"],"Rest"},_) -> if not c.cl_extern then error "Rest argument are only supported for extern methods" p; if opt then error "Rest argument cannot be optional" p; begin match ct with None -> () | Some (_,p) -> error "Rest argument cannot have default value" p end; if args <> [] then error "Rest should only be used for the last function argument" p; | _ -> () ); (name, ct, t) :: (loop args) | [] -> [] in let args = loop fd.f_args in let t = TFun (fun_args args,ret) in let cf = { cf_name = fst f.cff_name; cf_doc = f.cff_doc; cf_meta = f.cff_meta; cf_type = t; cf_pos = f.cff_pos; cf_name_pos = pos f.cff_name; cf_kind = Method (if fctx.is_macro then MethMacro else if fctx.is_inline then MethInline else if dynamic then MethDynamic else MethNormal); cf_expr = None; cf_expr_unoptimized = None; cf_public = is_public (ctx,cctx) f.cff_access parent; cf_params = params; cf_overloads = []; } in cf.cf_meta <- List.map (fun (m,el,p) -> match m,el with | Meta.AstSource,[] -> (m,(match fd.f_expr with None -> [] | Some e -> [e]),p) | _ -> m,el,p ) cf.cf_meta; generate_value_meta ctx.com (Some c) cf fd.f_args; check_abstract (ctx,cctx,fctx) c cf fd t ret p; init_meta_overloads ctx (Some c) cf; ctx.curfield <- cf; let r = exc_protect ctx (fun r -> if not !return_partial_type then begin r := (fun() -> t); cctx.context_init(); incr stats.s_methods_typed; if ctx.com.verbose then Common.log ctx.com ("Typing " ^ (if ctx.in_macro then "macro " else "") ^ s_type_path c.cl_path ^ "." ^ fst f.cff_name); let fmode = (match cctx.abstract with | Some _ -> (match args with | ("this",_,_) :: _ -> FunMemberAbstract | _ when fst f.cff_name = "_new" -> FunMemberAbstract | _ -> FunStatic) | None -> if fctx.field_kind = FKConstructor then FunConstructor else if fctx.is_static then FunStatic else FunMember ) in match ctx.com.platform with | Java when is_java_native_function cf.cf_meta -> if fd.f_expr <> None then ctx.com.warning "@:native function definitions shouldn't include an expression. This behaviour is deprecated." cf.cf_pos; cf.cf_expr <- None; cf.cf_type <- t | _ -> let e , fargs = type_function ctx args ret fmode fd fctx.is_display_field p in let tf = { tf_args = fargs; tf_type = ret; tf_expr = e; } in if fctx.field_kind = FKInit then (match e.eexpr with | TBlock [] | TBlock [{ eexpr = TConst _ }] | TConst _ | TObjectDecl [] -> () | _ -> c.cl_init <- Some e); cf.cf_expr <- Some (mk (TFunction tf) t p); cf.cf_type <- t; if fctx.is_display_field then Display.DisplayEmitter.maybe_display_field ctx (cf.cf_name_pos) cf; end; t ) "type_fun" in if fctx.do_bind then bind_type (ctx,cctx,fctx) cf r (match fd.f_expr with Some e -> snd e | None -> f.cff_pos); cf let create_property (ctx,cctx,fctx) c f (get,set,t,eo) p = let name = fst f.cff_name in (match cctx.abstract with | Some a when fctx.is_abstract_member -> ctx.type_params <- a.a_params; | _ -> ()); (* TODO is_lib: lazify load_complex_type *) let ret = (match t, eo with | None, None -> error (name ^ ": Property must either define a type or a default value") p; | None, _ -> mk_mono() | Some t, _ -> load_complex_type ctx true p t ) in let t_get,t_set = match cctx.abstract with | Some a when fctx.is_abstract_member -> if Meta.has Meta.IsVar f.cff_meta then error (name ^ ": Abstract properties cannot be real variables") f.cff_pos; let ta = apply_params a.a_params (List.map snd a.a_params) a.a_this in tfun [ta] ret, tfun [ta;ret] ret | _ -> tfun [] ret, TFun(["value",false,ret],ret) in let find_accessor m = (* on pf_overload platforms, the getter/setter may have been defined as an overloaded function; get all overloads *) if ctx.com.config.pf_overload then if fctx.is_static then let f = PMap.find m c.cl_statics in (f.cf_type, f) :: (List.map (fun f -> f.cf_type, f) f.cf_overloads) else Overloads.get_overloads c m else [ if fctx.is_static then let f = PMap.find m c.cl_statics in f.cf_type, f else match class_field c (List.map snd c.cl_params) m with | _, t,f -> t,f ] in let check_method m t req_name = if ctx.com.display.dms_error_policy = EPIgnore then () else try let overloads = find_accessor m in (* choose the correct overload if and only if there is more than one overload found *) let rec get_overload overl = match overl with | [tf] -> tf | (t2,f2) :: overl -> if type_iseq t t2 then (t2,f2) else get_overload overl | [] -> if c.cl_interface then raise Not_found else raise (Error (Custom (Printf.sprintf "No overloaded method named %s was compatible with the property %s with expected type %s" m (name) (s_type (print_context()) t) ), p)) in let t2, f2 = get_overload overloads in (* accessors must be public on As3 (issue #1872) *) if Common.defined ctx.com Define.As3 then f2.cf_meta <- (Meta.Public,[],null_pos) :: f2.cf_meta; (match f2.cf_kind with | Method MethMacro -> display_error ctx (f2.cf_name ^ ": Macro methods cannot be used as property accessor") p; display_error ctx (f2.cf_name ^ ": Accessor method is here") f2.cf_pos; | _ -> ()); unify_raise ctx t2 t f2.cf_pos; if (fctx.is_abstract_member && not (Meta.has Meta.Impl f2.cf_meta)) || (Meta.has Meta.Impl f2.cf_meta && not (fctx.is_abstract_member)) then display_error ctx "Mixing abstract implementation and static properties/accessors is not allowed" f2.cf_pos; (match req_name with None -> () | Some n -> display_error ctx ("Please use " ^ n ^ " to name your property access method") f2.cf_pos); f2.cf_meta <- List.fold_left (fun acc ((m,_,_) as meta) -> match m with | Meta.Deprecated -> meta :: acc | _ -> acc ) f2.cf_meta f.cff_meta; with | Error (Unify l,p) -> raise (Error (Stack (Custom ("In method " ^ m ^ " required by property " ^ name),Unify l),p)) | Not_found -> if req_name <> None then display_error ctx (name ^ ": Custom property accessor is no longer supported, please use get/set") p else if c.cl_interface then begin let cf = mk_field m t p null_pos in cf.cf_meta <- [Meta.CompilerGenerated,[],null_pos]; cf.cf_kind <- Method MethNormal; c.cl_fields <- PMap.add cf.cf_name cf c.cl_fields; c.cl_ordered_fields <- cf :: c.cl_ordered_fields; end else if not c.cl_extern then begin try let _, _, f2 = (if not fctx.is_static then let f = PMap.find m c.cl_statics in None, f.cf_type, f else class_field c (List.map snd c.cl_params) m) in display_error ctx (Printf.sprintf "Method %s is no valid accessor for %s because it is %sstatic" m (name) (if fctx.is_static then "not " else "")) f2.cf_pos with Not_found -> display_error ctx ("Method " ^ m ^ " required by property " ^ name ^ " is missing") p end in let display_accessor m p = try let cf = match find_accessor m with [_,cf] -> cf | _ -> raise Not_found in Display.DisplayEmitter.display_field ctx.com.display cf p with Not_found -> () in let get = (match get with | "null",_ -> AccNo | "dynamic",_ -> AccCall | "never",_ -> AccNever | "default",_ -> AccNormal | get,pget -> let get = if get = "get" then "get_" ^ name else get in if fctx.is_display_field && Display.is_display_position pget then delay ctx PTypeField (fun () -> display_accessor get pget); if not cctx.is_lib then delay ctx PTypeField (fun() -> check_method get t_get (if get <> "get" && get <> "get_" ^ name then Some ("get_" ^ name) else None)); AccCall ) in let set = (match set with | "null",_ -> (* standard flash library read-only variables can't be accessed for writing, even in subclasses *) if c.cl_extern && (match c.cl_path with "flash" :: _ , _ -> true | _ -> false) && ctx.com.platform = Flash then AccNever else AccNo | "never",_ -> AccNever | "dynamic",_ -> AccCall | "default",_ -> AccNormal | set,pset -> let set = if set = "set" then "set_" ^ name else set in if fctx.is_display_field && Display.is_display_position pset then delay ctx PTypeField (fun () -> display_accessor set pset); if not cctx.is_lib then delay ctx PTypeField (fun() -> check_method set t_set (if set <> "set" && set <> "set_" ^ name then Some ("set_" ^ name) else None)); AccCall ) in if set = AccNormal && (match get with AccCall -> true | _ -> false) then error (name ^ ": Unsupported property combination") p; let cf = { cf_name = name; cf_doc = f.cff_doc; cf_meta = f.cff_meta; cf_pos = f.cff_pos; cf_name_pos = pos f.cff_name; cf_kind = Var { v_read = get; v_write = set }; cf_expr = None; cf_expr_unoptimized = None; cf_type = ret; cf_public = is_public (ctx,cctx) f.cff_access None; cf_params = []; cf_overloads = []; } in ctx.curfield <- cf; bind_var (ctx,cctx,fctx) cf eo; cf let init_field (ctx,cctx,fctx) f = let c = cctx.tclass in let name = fst f.cff_name in check_global_metadata ctx f.cff_meta (fun m -> f.cff_meta <- m :: f.cff_meta) c.cl_module.m_path c.cl_path (Some name); let p = f.cff_pos in if name.[0] = '$' then display_error ctx "Field names starting with a dollar are not allowed" p; List.iter (fun acc -> match (acc, f.cff_kind) with | APublic, _ | APrivate, _ | AStatic, _ -> () | ADynamic, FFun _ | AOverride, FFun _ | AMacro, FFun _ | AInline, FFun _ | AInline, FVar _ -> () | _, FVar _ -> error ("Invalid accessor '" ^ Ast.s_access acc ^ "' for variable " ^ name) p | _, FProp _ -> error ("Invalid accessor '" ^ Ast.s_access acc ^ "' for property " ^ name) p ) f.cff_access; if fctx.is_override then (match c.cl_super with None -> error ("Invalid override on field '" ^ name ^ "': class has no super class") p | _ -> ()); match f.cff_kind with | FVar (t,e) -> create_variable (ctx,cctx,fctx) c f t e p | FFun fd -> create_method (ctx,cctx,fctx) c f fd p | FProp (get,set,t,eo) -> create_property (ctx,cctx,fctx) c f (get,set,t,eo) p let check_overloads ctx c = (* check if field with same signature was declared more than once *) List.iter (fun f -> if Meta.has Meta.Overload f.cf_meta then List.iter (fun f2 -> try ignore (List.find (fun f3 -> f3 != f2 && Overloads.same_overload_args f2.cf_type f3.cf_type f2 f3) (f :: f.cf_overloads)); display_error ctx ("Another overloaded field of same signature was already declared : " ^ f2.cf_name) f2.cf_pos with | Not_found -> () ) (f :: f.cf_overloads)) (c.cl_ordered_fields @ c.cl_ordered_statics) let init_class ctx c p context_init herits fields = let ctx,cctx = create_class_context ctx c context_init p in if cctx.is_class_debug then print_endline ("Created class context: " ^ dump_class_context cctx); let fields = patch_class ctx c fields in let fields = build_fields (ctx,cctx) c fields in if cctx.is_core_api && ctx.com.display.dms_check_core_api then delay ctx PForce (fun() -> init_core_api ctx c); if not cctx.is_lib then begin (match c.cl_super with None -> () | Some _ -> delay_late ctx PForce (fun() -> check_overriding ctx c)); if ctx.com.config.pf_overload then delay ctx PForce (fun() -> check_overloads ctx c) end; let rec has_field f = function | None -> false | Some (c,_) -> PMap.exists f c.cl_fields || has_field f c.cl_super || List.exists (fun i -> has_field f (Some i)) c.cl_implements in let rec check_require = function | [] -> None | (Meta.Require,conds,_) :: l -> let rec loop = function | [] -> check_require l | e :: l -> let sc = match fst e with | EConst (Ident s) -> s | EBinop ((OpEq|OpNotEq|OpGt|OpGte|OpLt|OpLte) as op,(EConst (Ident s),_),(EConst ((Int _ | Float _ | String _) as c),_)) -> s ^ s_binop op ^ s_constant c | _ -> "" in if not (Parser.is_true (Parser.eval ctx.com e)) then Some (sc,(match List.rev l with (EConst (String msg),_) :: _ -> Some msg | _ -> None)) else loop l in loop conds | _ :: l -> check_require l in let rec check_if_feature = function | [] -> [] | (Meta.IfFeature,el,_) :: _ -> List.map (fun (e,p) -> match e with EConst (String s) -> s | _ -> error "String expected" p) el | _ :: l -> check_if_feature l in let cl_if_feature = check_if_feature c.cl_meta in let cl_req = check_require c.cl_meta in List.iter (fun f -> let p = f.cff_pos in try let ctx,fctx = create_field_context (ctx,cctx) c f in if fctx.is_field_debug then print_endline ("Created field context: " ^ dump_field_context fctx); let cf = init_field (ctx,cctx,fctx) f in if fctx.is_field_debug then print_endline ("Created field: " ^ Printer.s_tclass_field "" cf); if fctx.is_static && c.cl_interface && fctx.field_kind <> FKInit && not cctx.is_lib then error "You can't declare static fields in interfaces" p; let set_feature s = ctx.m.curmod.m_extra.m_if_feature <- (s,(c,cf,fctx.is_static)) :: ctx.m.curmod.m_extra.m_if_feature in List.iter set_feature cl_if_feature; List.iter set_feature (check_if_feature cf.cf_meta); let req = check_require f.cff_meta in let req = (match req with None -> if fctx.is_static || fctx.field_kind = FKConstructor then cl_req else None | _ -> req) in (match req with | None -> () | Some r -> cf.cf_kind <- Var { v_read = AccRequire (fst r, snd r); v_write = AccRequire (fst r, snd r) }); begin match fctx.field_kind with | FKConstructor -> begin match c.cl_constructor with | None -> c.cl_constructor <- Some cf | Some ctor when ctx.com.config.pf_overload -> if Meta.has Meta.Overload cf.cf_meta && Meta.has Meta.Overload ctor.cf_meta then ctor.cf_overloads <- cf :: ctor.cf_overloads else display_error ctx ("If using overloaded constructors, all constructors must be declared with @:overload") (if Meta.has Meta.Overload cf.cf_meta then ctor.cf_pos else cf.cf_pos) | Some ctor -> display_error ctx "Duplicate constructor" p end | FKInit -> () | FKNormal -> let dup = if fctx.is_static then PMap.exists cf.cf_name c.cl_fields || has_field cf.cf_name c.cl_super else PMap.exists cf.cf_name c.cl_statics in if not cctx.is_native && not c.cl_extern && dup then error ("Same field name can't be use for both static and instance : " ^ cf.cf_name) p; if List.mem AOverride f.cff_access then c.cl_overrides <- cf :: c.cl_overrides; let is_var f = match cf.cf_kind with | Var _ -> true | _ -> false in if PMap.mem cf.cf_name (if fctx.is_static then c.cl_statics else c.cl_fields) then if ctx.com.config.pf_overload && Meta.has Meta.Overload cf.cf_meta && not (is_var f) then let mainf = PMap.find cf.cf_name (if fctx.is_static then c.cl_statics else c.cl_fields) in if is_var mainf then display_error ctx "Cannot declare a variable with same name as a method" mainf.cf_pos; (if not (Meta.has Meta.Overload mainf.cf_meta) then display_error ctx ("Overloaded methods must have @:overload metadata") mainf.cf_pos); mainf.cf_overloads <- cf :: mainf.cf_overloads else display_error ctx ("Duplicate class field declaration : " ^ cf.cf_name) p else if fctx.do_add then add_field c cf (fctx.is_static || fctx.is_macro && ctx.in_macro) end with Error (Custom str,p2) when p = p2 -> display_error ctx str p ) fields; (match cctx.abstract with | Some a -> a.a_to_field <- List.rev a.a_to_field; a.a_from_field <- List.rev a.a_from_field; a.a_ops <- List.rev a.a_ops; a.a_unops <- List.rev a.a_unops; a.a_array <- List.rev a.a_array; | None -> ()); c.cl_ordered_statics <- List.rev c.cl_ordered_statics; c.cl_ordered_fields <- List.rev c.cl_ordered_fields; (* make sure a default contructor with same access as super one will be added to the class structure at some point. *) (* add_constructor does not deal with overloads correctly *) if not ctx.com.config.pf_overload then add_constructor ctx c cctx.force_constructor p; if Meta.has Meta.StructInit c.cl_meta then check_struct_init_constructor ctx c p; (* check overloaded constructors *) (if ctx.com.config.pf_overload && not cctx.is_lib then match c.cl_constructor with | Some ctor -> delay ctx PTypeField (fun() -> List.iter (fun f -> try (* TODO: consider making a broader check, and treat some types, like TAnon and type parameters as Dynamic *) ignore(List.find (fun f2 -> f != f2 && Overloads.same_overload_args f.cf_type f2.cf_type f f2) (ctor :: ctor.cf_overloads)); display_error ctx ("Another overloaded field of same signature was already declared : " ^ f.cf_name) f.cf_pos; with Not_found -> () ) (ctor :: ctor.cf_overloads) ) | _ -> ()); (* push delays in reverse order so they will be run in correct order *) List.iter (fun (ctx,r) -> init_class_done ctx; (match r with | None -> () | Some r -> delay ctx PTypeField (fun() -> ignore((!r)()))) ) cctx.delayed_expr end let check_module_types ctx m p t = let t = t_infos t in try let m2 = Hashtbl.find ctx.g.types_module t.mt_path in if m.m_path <> m2 && String.lowercase (s_type_path m2) = String.lowercase (s_type_path m.m_path) then error ("Module " ^ s_type_path m2 ^ " is loaded with a different case than " ^ s_type_path m.m_path) p; error ("Type name " ^ s_type_path t.mt_path ^ " is redefined from module " ^ s_type_path m2) p with Not_found -> Hashtbl.add ctx.g.types_module t.mt_path m.m_path let add_module ctx m p = List.iter (check_module_types ctx m p) m.m_types; Hashtbl.add ctx.g.modules m.m_path m let handle_path_display ctx path p = let open Display.ImportHandling in match Display.ImportHandling.convert_import_to_something_usable !Parser.resume_display path,ctx.com.display.dms_kind with | (IDKPackage sl,_),_ -> raise (Parser.TypePath(sl,None,true)) | (IDKModule(sl,s),_),DMPosition -> (* We assume that we want to go to the module file, not a specific type which might not even exist anyway. *) let mt = ctx.g.do_load_module ctx (sl,s) p in let p = { pfile = mt.m_extra.m_file; pmin = 0; pmax = 0} in raise (Display.DisplayPosition [p]) | (IDKModule(sl,s),_),_ -> (* TODO: wait till nadako requests @type display for these, then implement it somehow *) raise (Parser.TypePath(sl,Some(s,false),true)) | (IDKSubType(sl,sm,st),p),DMPosition -> resolve_position_by_path ctx { tpackage = sl; tname = sm; tparams = []; tsub = Some st} p | (IDKSubType(sl,sm,st),_),_ -> raise (Parser.TypePath(sl @ [sm],Some(st,false),true)) | ((IDKSubTypeField(sl,sm,st,sf) | IDKModuleField(sl,(sm as st),sf)),p),_ -> let m = ctx.g.do_load_module ctx (sl,sm) p in List.iter (fun t -> match t with | TClassDecl c when snd c.cl_path = st -> ignore(c.cl_build()); let cf = PMap.find sf c.cl_statics in Display.DisplayEmitter.display_field ctx.com.display cf p | _ -> () ) m.m_types; | (IDK,_),_ -> () (* In this pass, we can access load and access other modules types, but we cannot follow them or access their structure since they have not been setup. We also build a context_init list that will be evaluated the first time we evaluate an expression into the context *) let init_module_type ctx context_init do_init (decl,p) = let get_type name = try List.find (fun t -> snd (t_infos t).mt_path = name) ctx.m.curmod.m_types with Not_found -> assert false in let check_path_display path p = match ctx.com.display.dms_kind with (* We cannot use ctx.is_display_file because the import could come from an import.hx file. *) | DMDiagnostics b when (b && not (ExtString.String.ends_with p.pfile "import.hx")) || Display.is_display_file p.pfile -> Display.ImportHandling.add_import_position ctx.com p path; | DMStatistics | DMUsage _ -> Display.ImportHandling.add_import_position ctx.com p path; | _ -> if Display.is_display_file p.pfile then handle_path_display ctx path p in match decl with | EImport (path,mode) -> ctx.m.module_imports <- (path,mode) :: ctx.m.module_imports; check_path_display path p; let rec loop acc = function | x :: l when is_lower_ident (fst x) -> loop (x::acc) l | rest -> List.rev acc, rest in let pack, rest = loop [] path in (match rest with | [] -> (match mode with | IAll -> ctx.m.wildcard_packages <- (List.map fst pack,p) :: ctx.m.wildcard_packages | _ -> (match List.rev path with | [] -> raise (Display.DisplayToplevel (Display.ToplevelCollector.run ctx true)); | (_,p) :: _ -> error "Module name must start with an uppercase letter" p)) | (tname,p2) :: rest -> let p1 = (match pack with [] -> p2 | (_,p1) :: _ -> p1) in let p_type = punion p1 p2 in let md = ctx.g.do_load_module ctx (List.map fst pack,tname) p_type in let types = md.m_types in let no_private (t,_) = not (t_infos t).mt_private in let chk_private t p = if (t_infos t).mt_private then error "You can't import a private type" p in let has_name name t = snd (t_infos t).mt_path = name in let get_type tname = let t = (try List.find (has_name tname) types with Not_found -> error (StringError.string_error tname (List.map (fun mt -> snd (t_infos mt).mt_path) types) ("Module " ^ s_type_path md.m_path ^ " does not define type " ^ tname)) p_type) in chk_private t p_type; t in let rebind t name = if not (name.[0] >= 'A' && name.[0] <= 'Z') then error "Type aliases must start with an uppercase letter" p; let _, _, f = ctx.g.do_build_instance ctx t p_type in (* create a temp private typedef, does not register it in module *) TTypeDecl { t_path = (fst md.m_path @ ["_" ^ snd md.m_path],name); t_module = md; t_pos = p; t_name_pos = null_pos; t_private = true; t_doc = None; t_meta = []; t_params = (t_infos t).mt_params; t_type = f (List.map snd (t_infos t).mt_params); } in let add_static_init t name s = let name = (match name with None -> s | Some n -> n) in match resolve_typedef t with | TClassDecl c -> ignore(c.cl_build()); ignore(PMap.find s c.cl_statics); ctx.m.module_globals <- PMap.add name (TClassDecl c,s,p) ctx.m.module_globals | TEnumDecl e -> ignore(PMap.find s e.e_constrs); ctx.m.module_globals <- PMap.add name (TEnumDecl e,s,p) ctx.m.module_globals | _ -> raise Not_found in (match mode with | INormal | IAsName _ -> let name = (match mode with IAsName n -> Some n | _ -> None) in (match rest with | [] -> (match name with | None -> ctx.m.module_types <- List.filter no_private (List.map (fun t -> t,p) types) @ ctx.m.module_types | Some newname -> ctx.m.module_types <- (rebind (get_type tname) newname,p) :: ctx.m.module_types); | [tsub,p2] -> let pu = punion p1 p2 in (try let tsub = List.find (has_name tsub) types in chk_private tsub pu; ctx.m.module_types <- ((match name with None -> tsub | Some n -> rebind tsub n),p) :: ctx.m.module_types with Not_found -> (* this might be a static property, wait later to check *) let tmain = get_type tname in context_init := (fun() -> try add_static_init tmain name tsub with Not_found -> error (s_type_path (t_infos tmain).mt_path ^ " has no field or subtype " ^ tsub) p ) :: !context_init) | (tsub,p2) :: (fname,p3) :: rest -> (match rest with | [] -> () | (n,p) :: _ -> error ("Unexpected " ^ n) p); let tsub = get_type tsub in context_init := (fun() -> try add_static_init tsub name fname with Not_found -> error (s_type_path (t_infos tsub).mt_path ^ " has no field " ^ fname) (punion p p3) ) :: !context_init; ) | IAll -> let t = (match rest with | [] -> get_type tname | [tsub,_] -> get_type tsub | _ :: (n,p) :: _ -> error ("Unexpected " ^ n) p ) in context_init := (fun() -> match resolve_typedef t with | TClassDecl c | TAbstractDecl {a_impl = Some c} -> ignore(c.cl_build()); PMap.iter (fun _ cf -> if not (has_meta Meta.NoImportGlobal cf.cf_meta) then ctx.m.module_globals <- PMap.add cf.cf_name (TClassDecl c,cf.cf_name,p) ctx.m.module_globals) c.cl_statics | TEnumDecl e -> PMap.iter (fun _ c -> if not (has_meta Meta.NoImportGlobal c.ef_meta) then ctx.m.module_globals <- PMap.add c.ef_name (TEnumDecl e,c.ef_name,p) ctx.m.module_globals) e.e_constrs | _ -> error "No statics to import from this type" p ) :: !context_init )) | EUsing path -> check_path_display path p; let t = match List.rev path with | (s1,_) :: (s2,_) :: sl -> if is_lower_ident s2 then { tpackage = (List.rev (s2 :: List.map fst sl)); tname = s1; tsub = None; tparams = [] } else { tpackage = List.rev (List.map fst sl); tname = s2; tsub = Some s1; tparams = [] } | (s1,_) :: sl -> { tpackage = List.rev (List.map fst sl); tname = s1; tsub = None; tparams = [] } | [] -> raise (Display.DisplayToplevel (Display.ToplevelCollector.run ctx true)); in (* do the import first *) let types = (match t.tsub with | None -> let md = ctx.g.do_load_module ctx (t.tpackage,t.tname) p in let types = List.filter (fun t -> not (t_infos t).mt_private) md.m_types in ctx.m.module_types <- (List.map (fun t -> t,p) types) @ ctx.m.module_types; types | Some _ -> let t = load_type_def ctx p t in ctx.m.module_types <- (t,p) :: ctx.m.module_types; [t] ) in (* delay the using since we need to resolve typedefs *) let filter_classes types = let rec loop acc types = match types with | td :: l -> (match resolve_typedef td with | TClassDecl c | TAbstractDecl({a_impl = Some c}) -> loop ((c,p) :: acc) l | td -> loop acc l) | [] -> acc in loop [] types in context_init := (fun() -> ctx.m.module_using <- filter_classes types @ ctx.m.module_using) :: !context_init | EClass d -> let c = (match get_type (fst d.d_name) with TClassDecl c -> c | _ -> assert false) in if ctx.is_display_file && Display.is_display_position (pos d.d_name) then Display.DisplayEmitter.display_module_type ctx.com.display (match c.cl_kind with KAbstractImpl a -> TAbstractDecl a | _ -> TClassDecl c) (pos d.d_name); check_global_metadata ctx c.cl_meta (fun m -> c.cl_meta <- m :: c.cl_meta) c.cl_module.m_path c.cl_path None; let herits = d.d_flags in c.cl_extern <- List.mem HExtern herits; c.cl_interface <- List.mem HInterface herits; let build() = let fl = Inheritance.set_heritance ctx c herits p in let rec build() = c.cl_build <- (fun()-> Building); try List.iter (fun f -> f()) fl; ClassInitializer.init_class ctx c p do_init d.d_flags d.d_data; c.cl_build <- (fun()-> Built); List.iter (fun (_,t) -> ignore(follow t)) c.cl_params; Built; with Build_canceled state -> c.cl_build <- make_pass ctx build; let rebuild() = delay_late ctx PBuildClass (fun() -> ignore(c.cl_build())); in (match state with | Built -> assert false | Building -> rebuild() | BuildMacro f -> f := rebuild :: !f); state | exn -> c.cl_build <- (fun()-> Built); raise exn in build() in ctx.pass <- PBuildClass; ctx.curclass <- c; c.cl_build <- make_pass ctx build; ctx.pass <- PBuildModule; ctx.curclass <- null_class; delay ctx PBuildClass (fun() -> ignore(c.cl_build())); if (ctx.com.platform = Java || ctx.com.platform = Cs) && not c.cl_extern then delay ctx PTypeField (fun () -> let metas = check_strict_meta ctx c.cl_meta in if metas <> [] then c.cl_meta <- metas @ c.cl_meta; let rec run_field cf = let metas = check_strict_meta ctx cf.cf_meta in if metas <> [] then cf.cf_meta <- metas @ cf.cf_meta; List.iter run_field cf.cf_overloads in List.iter run_field c.cl_ordered_statics; List.iter run_field c.cl_ordered_fields; match c.cl_constructor with | Some f -> run_field f | _ -> () ); | EEnum d -> let e = (match get_type (fst d.d_name) with TEnumDecl e -> e | _ -> assert false) in if ctx.is_display_file && Display.is_display_position (pos d.d_name) then Display.DisplayEmitter.display_module_type ctx.com.display (TEnumDecl e) (pos d.d_name); let ctx = { ctx with type_params = e.e_params } in let h = (try Some (Hashtbl.find ctx.g.type_patches e.e_path) with Not_found -> None) in check_global_metadata ctx e.e_meta (fun m -> e.e_meta <- m :: e.e_meta) e.e_module.m_path e.e_path None; (match h with | None -> () | Some (h,hcl) -> Hashtbl.iter (fun _ _ -> error "Field type patch not supported for enums" e.e_pos) h; e.e_meta <- e.e_meta @ hcl.tp_meta); let constructs = ref d.d_data in let get_constructs() = List.map (fun c -> { cff_name = c.ec_name; cff_doc = c.ec_doc; cff_meta = c.ec_meta; cff_pos = c.ec_pos; cff_access = []; cff_kind = (match c.ec_args, c.ec_params with | [], [] -> FVar (c.ec_type,None) | _ -> FFun { f_params = c.ec_params; f_type = c.ec_type; f_expr = None; f_args = List.map (fun (n,o,t) -> (n,null_pos),o,[],Some t,None) c.ec_args }); } ) (!constructs) in let init () = List.iter (fun f -> f()) !context_init in build_module_def ctx (TEnumDecl e) e.e_meta get_constructs init (fun (e,p) -> match e with | EVars [_,Some (CTAnonymous fields,p),None] -> constructs := List.map (fun f -> let args, params, t = (match f.cff_kind with | FVar (t,None) -> [], [], t | FFun { f_params = pl; f_type = t; f_expr = (None|Some (EBlock [],_)); f_args = al } -> let al = List.map (fun ((n,_),o,_,t,_) -> match t with None -> error "Missing function parameter type" f.cff_pos | Some t -> n,o,t) al in al, pl, t | _ -> error "Invalid enum constructor in @:build result" p ) in { ec_name = f.cff_name; ec_doc = f.cff_doc; ec_meta = f.cff_meta; ec_pos = f.cff_pos; ec_args = args; ec_params = params; ec_type = t; } ) fields | _ -> error "Enum build macro must return a single variable with anonymous object fields" p ); let et = TEnum (e,List.map snd e.e_params) in let names = ref [] in let index = ref 0 in let is_flat = ref true in let fields = ref PMap.empty in List.iter (fun c -> let p = c.ec_pos in let params = ref [] in params := type_type_params ~enum_constructor:true ctx ([],fst c.ec_name) (fun() -> !params) c.ec_pos c.ec_params; let params = !params in let ctx = { ctx with type_params = params @ ctx.type_params } in let rt = (match c.ec_type with | None -> et | Some t -> let t = load_complex_type ctx true p t in (match follow t with | TEnum (te,_) when te == e -> () | _ -> error "Explicit enum type must be of the same enum type" p); t ) in let t = (match c.ec_args with | [] -> rt | l -> is_flat := false; let pnames = ref PMap.empty in TFun (List.map (fun (s,opt,(t,tp)) -> (match t with CTPath({tpackage=[];tname="Void"}) -> error "Arguments of type Void are not allowed in enum constructors" c.ec_pos | _ -> ()); if PMap.mem s (!pnames) then error ("Duplicate parameter '" ^ s ^ "' in enum constructor " ^ fst c.ec_name) p; pnames := PMap.add s () (!pnames); s, opt, load_type_hint ~opt ctx p (Some (t,tp)) ) l, rt) ) in if PMap.mem (fst c.ec_name) e.e_constrs then error ("Duplicate constructor " ^ fst c.ec_name) p; let f = { ef_name = fst c.ec_name; ef_type = t; ef_pos = p; ef_name_pos = snd c.ec_name; ef_doc = c.ec_doc; ef_index = !index; ef_params = params; ef_meta = c.ec_meta; } in let cf = { cf_name = f.ef_name; cf_public = true; cf_type = f.ef_type; cf_kind = (match follow f.ef_type with | TFun _ -> Method MethNormal | _ -> Var { v_read = AccNormal; v_write = AccNo } ); cf_pos = p; cf_name_pos = f.ef_name_pos; cf_doc = f.ef_doc; cf_meta = no_meta; cf_expr = None; cf_expr_unoptimized = None; cf_params = f.ef_params; cf_overloads = []; } in if ctx.is_display_file && Display.is_display_position p then Display.DisplayEmitter.display_enum_field ctx.com.display f p; e.e_constrs <- PMap.add f.ef_name f e.e_constrs; fields := PMap.add cf.cf_name cf !fields; incr index; names := (fst c.ec_name) :: !names; ) (!constructs); e.e_names <- List.rev !names; e.e_extern <- e.e_extern; e.e_type.t_params <- e.e_params; e.e_type.t_type <- TAnon { a_fields = !fields; a_status = ref (EnumStatics e); }; if !is_flat then e.e_meta <- (Meta.FlatEnum,[],null_pos) :: e.e_meta; if (ctx.com.platform = Java || ctx.com.platform = Cs) && not e.e_extern then delay ctx PTypeField (fun () -> let metas = check_strict_meta ctx e.e_meta in e.e_meta <- metas @ e.e_meta; PMap.iter (fun _ ef -> let metas = check_strict_meta ctx ef.ef_meta in if metas <> [] then ef.ef_meta <- metas @ ef.ef_meta ) e.e_constrs ); | ETypedef d -> let t = (match get_type (fst d.d_name) with TTypeDecl t -> t | _ -> assert false) in if ctx.is_display_file && Display.is_display_position (pos d.d_name) then Display.DisplayEmitter.display_module_type ctx.com.display (TTypeDecl t) (pos d.d_name); check_global_metadata ctx t.t_meta (fun m -> t.t_meta <- m :: t.t_meta) t.t_module.m_path t.t_path None; let ctx = { ctx with type_params = t.t_params } in let tt = load_complex_type ctx true p d.d_data in let tt = (match fst d.d_data with | CTExtend _ -> tt | CTPath { tpackage = ["haxe";"macro"]; tname = "MacroType" } -> (* we need to follow MacroType immediately since it might define other module types that we will load afterwards *) if t.t_type == follow tt then error "Recursive typedef is not allowed" p; tt | _ -> if (Meta.has Meta.Eager d.d_meta) then follow tt else begin let f r = if t.t_type == follow tt then error "Recursive typedef is not allowed" p; r := (fun() -> tt); tt in let r = exc_protect ctx f "typedef_rec_check" in delay ctx PForce (fun () -> ignore(!r())); TLazy r end ) in (match t.t_type with | TMono r -> (match !r with | None -> r := Some tt; | Some _ -> assert false); | _ -> assert false); if ctx.com.platform = Cs && t.t_meta <> [] then delay ctx PTypeField (fun () -> let metas = check_strict_meta ctx t.t_meta in if metas <> [] then t.t_meta <- metas @ t.t_meta; ); | EAbstract d -> let a = (match get_type (fst d.d_name) with TAbstractDecl a -> a | _ -> assert false) in if ctx.is_display_file && Display.is_display_position (pos d.d_name) then Display.DisplayEmitter.display_module_type ctx.com.display (TAbstractDecl a) (pos d.d_name); check_global_metadata ctx a.a_meta (fun m -> a.a_meta <- m :: a.a_meta) a.a_module.m_path a.a_path None; let ctx = { ctx with type_params = a.a_params } in let is_type = ref false in let load_type t from = let t = load_complex_type ctx true p t in let t = if not (Meta.has Meta.CoreType a.a_meta) then begin if !is_type then begin let r = exc_protect ctx (fun r -> r := (fun() -> t); let at = monomorphs a.a_params a.a_this in (try (if from then Type.unify t at else Type.unify at t) with Unify_error _ -> error "You can only declare from/to with compatible types" p); t ) "constraint" in delay ctx PForce (fun () -> ignore(!r())); TLazy r end else error "Missing underlying type declaration or @:coreType declaration" p; end else begin if Meta.has Meta.Callable a.a_meta then error "@:coreType abstracts cannot be @:callable" p; t end in t in List.iter (function | AFromType t -> a.a_from <- (load_type t true) :: a.a_from | AToType t -> a.a_to <- (load_type t false) :: a.a_to | AIsType t -> if a.a_impl = None then error "Abstracts with underlying type must have an implementation" a.a_pos; if Meta.has Meta.CoreType a.a_meta then error "@:coreType abstracts cannot have an underlying type" p; let at = load_complex_type ctx true p t in delay ctx PForce (fun () -> begin match follow at with | TAbstract(a2,_) when a == a2 -> error "Abstract underlying type cannot be recursive" a.a_pos | _ -> () end; ); a.a_this <- at; is_type := true; | AExtern -> (match a.a_impl with Some c -> c.cl_extern <- true | None -> (* Hmmmm.... *) ()) | APrivAbstract -> () ) d.d_flags; if not !is_type then begin if Meta.has Meta.CoreType a.a_meta then a.a_this <- TAbstract(a,List.map snd a.a_params) else error "Abstract is missing underlying type declaration" a.a_pos end let module_pass_2 ctx m decls tdecls p = (* here is an additional PASS 1 phase, which define the type parameters for all module types. Constraints are handled lazily (no other type is loaded) because they might be recursive anyway *) List.iter (fun d -> match d with | (TClassDecl c, (EClass d, p)) -> c.cl_params <- type_type_params ctx c.cl_path (fun() -> c.cl_params) p d.d_params; if Meta.has Meta.Generic c.cl_meta && c.cl_params <> [] then c.cl_kind <- KGeneric; if Meta.has Meta.GenericBuild c.cl_meta then begin if ctx.in_macro then error "@:genericBuild cannot be used in macros" c.cl_pos; c.cl_kind <- KGenericBuild d.d_data; end; if c.cl_path = (["haxe";"macro"],"MacroType") then c.cl_kind <- KMacroType; | (TEnumDecl e, (EEnum d, p)) -> e.e_params <- type_type_params ctx e.e_path (fun() -> e.e_params) p d.d_params; | (TTypeDecl t, (ETypedef d, p)) -> t.t_params <- type_type_params ctx t.t_path (fun() -> t.t_params) p d.d_params; | (TAbstractDecl a, (EAbstract d, p)) -> a.a_params <- type_type_params ctx a.a_path (fun() -> a.a_params) p d.d_params; | _ -> assert false ) decls; (* setup module types *) let context_init = ref [] in let do_init() = match !context_init with | [] -> () | l -> context_init := []; List.iter (fun f -> f()) (List.rev l) in List.iter (init_module_type ctx context_init do_init) tdecls (* Creates a module context for [m] and types [tdecls] using it. *) let type_types_into_module ctx m tdecls p = let decls, tdecls = module_pass_1 ctx m tdecls p in let types = List.map fst decls in List.iter (check_module_types ctx m p) types; m.m_types <- m.m_types @ types; (* define the per-module context for the next pass *) let ctx = { com = ctx.com; g = ctx.g; t = ctx.t; m = { curmod = m; module_types = List.map (fun t -> t,null_pos) ctx.g.std.m_types; module_using = []; module_globals = PMap.empty; wildcard_packages = []; module_imports = []; }; is_display_file = (ctx.com.display.dms_display && Display.is_display_file m.m_extra.m_file); meta = []; this_stack = []; with_type_stack = []; call_argument_stack = []; pass = PBuildModule; on_error = (fun ctx msg p -> ctx.com.error msg p); macro_depth = ctx.macro_depth; curclass = null_class; curfield = null_field; tthis = ctx.tthis; ret = ctx.ret; locals = PMap.empty; type_params = []; curfun = FunStatic; untyped = false; in_macro = ctx.in_macro; in_display = false; in_loop = false; opened = []; in_call_args = false; vthis = None; } in if ctx.g.std != null_module then begin add_dependency m ctx.g.std; (* this will ensure both String and (indirectly) Array which are basic types which might be referenced *) ignore(load_core_type ctx "String"); end; module_pass_2 ctx m decls tdecls p; ctx let handle_import_hx ctx m decls p = let path_split = List.tl (List.rev (Path.get_path_parts m.m_extra.m_file)) in let join l = String.concat Path.path_sep (List.rev ("import.hx" :: l)) in let rec loop path pack = match path,pack with | _,[] -> [join path] | (p :: path),(_ :: pack) -> (join (p :: path)) :: (loop path pack) | _ -> [] in let candidates = loop path_split (fst m.m_path) in let make_import_module path r = Hashtbl.replace ctx.com.parser_cache path r; (* We use the file path as module name to make it unique. This may or may not be a good idea... *) let m_import = make_module ctx ([],path) path p in m_import.m_extra.m_kind <- MImport; add_module ctx m_import p; m_import in List.fold_left (fun acc path -> let decls = try let r = Hashtbl.find ctx.com.parser_cache path in let mimport = Hashtbl.find ctx.g.modules ([],path) in if mimport.m_extra.m_kind <> MFake then add_dependency m mimport; r with Not_found -> if Sys.file_exists path then begin let _,r = parse_file ctx.com path p in List.iter (fun (d,p) -> match d with EImport _ | EUsing _ -> () | _ -> error "Only import and using is allowed in import.hx files" p) r; add_dependency m (make_import_module path r); r end else begin let r = [] in (* Add empty decls so we don't check the file system all the time. *) (make_import_module path r).m_extra.m_kind <- MFake; r end in decls @ acc ) decls candidates (* Creates a new module and types [tdecls] into it. *) let type_module ctx mpath file ?(is_extern=false) tdecls p = let m = make_module ctx mpath file p in Hashtbl.add ctx.g.modules m.m_path m; let tdecls = handle_import_hx ctx m tdecls p in let ctx = type_types_into_module ctx m tdecls p in if is_extern then m.m_extra.m_kind <- MExtern; begin if ctx.is_display_file then match ctx.com.display.dms_kind with | DMResolve s -> resolve_position_by_path ctx {tname = s; tpackage = []; tsub = None; tparams = []} p | _ -> () end; m let resolve_module_file com m remap p = let forbid = ref false in let compose_path no_rename = (match m with | [] , name -> name | x :: l , name -> let x = (try match PMap.find x com.package_rules with | Forbidden -> forbid := true; x | Directory d -> if no_rename then x else d | Remap d -> remap := d :: l; d with Not_found -> x ) in String.concat "/" (x :: l) ^ "/" ^ name ) ^ ".hx" in let file = try Common.find_file com (compose_path false) with Not_found -> Common.find_file com (compose_path true) in let file = (match String.lowercase (snd m) with | "con" | "aux" | "prn" | "nul" | "com1" | "com2" | "com3" | "lpt1" | "lpt2" | "lpt3" when Sys.os_type = "Win32" -> (* these names are reserved by the OS - old DOS legacy, such files cannot be easily created but are reported as visible *) if (try (Unix.stat file).Unix.st_size with _ -> 0) > 0 then file else raise Not_found | _ -> file ) in (* if we try to load a std.xxxx class and resolve a real std file, the package name is not valid, ignore *) (match fst m with | "std" :: _ -> let file = Path.unique_full_path file in if List.exists (fun path -> ExtString.String.starts_with file (try Path.unique_full_path path with _ -> path)) com.std_path then raise Not_found; | _ -> ()); if !forbid then begin let _, decls = (!parse_hook) com file p in let rec loop decls = match decls with | ((EImport _,_) | (EUsing _,_)) :: decls -> loop decls | (EClass d,_) :: _ -> d.d_meta | (EEnum d,_) :: _ -> d.d_meta | (EAbstract d,_) :: _ -> d.d_meta | (ETypedef d,_) :: _ -> d.d_meta | [] -> [] in let meta = loop decls in if not (Meta.has Meta.NoPackageRestrict meta) then begin let x = (match fst m with [] -> assert false | x :: _ -> x) in raise (Forbid_package ((x,m,p),[],if Common.defined com Define.Macro then "macro" else platform_name com.platform)); end; end; file let parse_module ctx m p = let remap = ref (fst m) in let file = resolve_module_file ctx.com m remap p in let pack, decls = (!parse_hook) ctx.com file p in if pack <> !remap then begin let spack m = if m = [] then "" else String.concat "." m in if p == null_pos then display_error ctx ("Invalid commandline class : " ^ s_type_path m ^ " should be " ^ s_type_path (pack,snd m)) p else display_error ctx ("Invalid package : " ^ spack (fst m) ^ " should be " ^ spack pack) p end; file, if !remap <> fst m then (* build typedefs to redirect to real package *) List.rev (List.fold_left (fun acc (t,p) -> let build f d = let priv = List.mem f d.d_flags in (ETypedef { d_name = d.d_name; d_doc = None; d_meta = []; d_params = d.d_params; d_flags = if priv then [EPrivate] else []; d_data = CTPath (if priv then { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None; } else { tpackage = !remap; tname = fst d.d_name; tparams = List.map (fun tp -> TPType (CTPath { tpackage = []; tname = fst tp.tp_name; tparams = []; tsub = None; },null_pos) ) d.d_params; tsub = None; }),null_pos; },p) :: acc in match t with | EClass d -> build HPrivate d | EEnum d -> build EPrivate d | ETypedef d -> build EPrivate d | EAbstract d -> build APrivAbstract d | EImport _ | EUsing _ -> acc ) [(EImport (List.map (fun s -> s,null_pos) (!remap @ [snd m]),INormal),null_pos)] decls) else decls let load_module ctx m p = let m2 = (try Hashtbl.find ctx.g.modules m with Not_found -> match !type_module_hook ctx m p with | Some m -> m | None -> let is_extern = ref false in let file, decls = (try parse_module ctx m p with Not_found -> let rec loop = function | [] -> raise (Error (Module_not_found m,p)) | load :: l -> match load m p with | None -> loop l | Some (file,(_,a)) -> file, a in is_extern := true; loop ctx.com.load_extern_type ) in let is_extern = !is_extern in try type_module ctx m file ~is_extern decls p with Forbid_package (inf,pl,pf) when p <> null_pos -> raise (Forbid_package (inf,p::pl,pf)) ) in add_dependency ctx.m.curmod m2; if ctx.pass = PTypeField then flush_pass ctx PBuildClass "load_module"; m2 ;; type_function_params_rec := type_function_params (* former codegen.ml stuff starting here *) (* -------------------------------------------------------------------------- *) (* 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 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 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",null_pos; 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 },null_pos),None) }; { cff_name = "new",null_pos; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun { f_args = [("c",null_pos),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 fst 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 " ^ fst 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",null_pos),true,[],Some (CTFunction ([tret,null_pos],(tvoid,null_pos)),null_pos),None], eargs @ [EConst (Ident "__callb"),p] | _ -> fd.f_args, eargs @ [EConst (Ident "null"),p] else fd.f_args, eargs in let id = (EConst (String (fst 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 = f.cff_pos; 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 fst 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,pos c.d_name; d_data = fields },p) | _ -> d ) decls in let m = 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 * 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)) | TDynamic _ -> "Dynamic" | 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) v.v_pos 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 let fa = try quick_field t cf.cf_name with Not_found -> error (Printf.sprintf "Type %s has no field %s (possible typing order issue)" (s_type (print_context()) t) cf.cf_name) e.epos in build_expr {e with eexpr = TField(e1,fa)} | TTypeExpr (TClassDecl ({cl_kind = KTypeParameter _;} as c)) when Meta.has Meta.Const c.cl_meta -> let rec loop subst = match subst with | (t1,t2) :: subst -> begin match follow t1 with | TInst(c2,_) when c == c2 -> t2 | _ -> loop subst end | [] -> raise Not_found in begin try let t = loop gctx.subst in begin match follow t with | TInst({cl_kind = KExpr e},_) -> type_expr gctx.ctx e Value | _ -> error "Only Const type parameters can be used as value" e.epos end with Not_found -> e end | _ -> map_expr_type build_expr (generic_substitute_type gctx) build_var e in build_expr e 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 (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 || not (ctx.com.display.dms_full_typing) 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 load_instance ctx ({ tpackage = pack; tname = name; tparams = []; tsub = None },p) false p 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 m.m_extra.m_check_policy; } in gctx.mg <- Some mg; let cg = mk_class mg (pack,name) c.cl_pos null_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 = (* We have to clone the type parameters (issue #4672). We cannot substitute the constraints immediately because we need the full substitution list first. *) let param_subst,params = List.fold_left (fun (subst,params) (s,t) -> match follow t with | TInst(c,tl) as t -> let t2 = TInst({c with cl_pos = c.cl_pos;},tl) in (t,t2) :: subst,(s,t2) :: params | _ -> assert false ) ([],[]) cf_old.cf_params in let gctx = {gctx with subst = param_subst @ gctx.subst} in let cf_new = {cf_old with cf_pos = cf_old.cf_pos} in (* copy *) (* Type parameter constraints are substituted here. *) cf_new.cf_params <- List.rev_map (fun (s,t) -> match follow t with | TInst({cl_kind = KTypeParameter tl1} as c,_) -> let tl1 = List.map (generic_substitute_type gctx) tl1 in c.cl_kind <- KTypeParameter tl1; s,t | _ -> assert false ) params; 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 = Inheritance.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) ); add_constructor ctx cg false p; cg.cl_kind <- KGenericInstance (c,tl); cg.cl_meta <- (Meta.NoDoc,[],null_pos) :: cg.cl_meta; if has_meta Meta.Keep c.cl_meta then cg.cl_meta <- (Meta.Keep,[],null_pos) :: 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; cg.cl_overrides <- List.map (fun f -> try PMap.find f.cf_name cg.cl_fields with Not_found -> assert false ) c.cl_overrides; (* 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],null_pos) :: cg.cl_meta; end; TInst (cg,[]) end (* -------------------------------------------------------------------------- *) (* HAXE.XML.PROXY *) let extend_xml_proxy ctx c t file p = let t = load_complex_type ctx false p (t,p) 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_name_pos = null_pos; cf_doc = None; cf_meta = no_meta; cf_kind = Var { v_read = AccResolve; v_write = AccNo }; cf_params = []; cf_expr = None; cf_expr_unoptimized = 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 (* -------------------------------------------------------------------------- *) (* 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 (let path,_,_ = PMap.find i ctx.m.module_globals in path)).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); let tf = (f()) in unify_raise ctx tf t p; link_dynamic t tf; 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 (is_extends,tp) = if not is_extends then true else match fst tp with | { tpackage = ["haxe";"remoting"]; tname = "Proxy"; tparams = [TPType(CTPath t,null_pos)] } -> extend_remoting ctx c t p false true; false | { tpackage = ["haxe";"remoting"]; tname = "AsyncProxy"; tparams = [TPType(CTPath t,null_pos)] } -> extend_remoting ctx c t p true true; false | { tpackage = ["haxe";"xml"]; tname = "Proxy"; tparams = [TPExpr(EConst (String file),p);TPType (t,_)] } -> extend_xml_proxy ctx c t file p; true | _ -> true haxe_3.4.4.orig/src/typing/typer.ml0000664000175000017500000047641313166552354017231 0ustar andyandy00000000000000(* The Haxe Compiler Copyright (C) 2005-2017 Haxe Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *) open Ast open Common.DisplayMode open Common open Type open Typecore open Error open Globals (* ---------------------------------------------------------------------- *) (* TOOLS *) type switch_mode = | CMatch of (tenum_field * (string * t) option list option * pos) | CExpr of texpr type access_mode = | MGet | MSet | MCall type access_kind = | AKNo of string | AKExpr of texpr | AKSet of texpr * t * tclass_field | AKInline of texpr * tclass_field * tfield_access * t | AKMacro of texpr * tclass_field | AKUsing of texpr * tclass * tclass_field * texpr | AKAccess of tabstract * tparams * tclass * texpr * texpr type object_decl_kind = | ODKWithStructure of tanon | ODKWithClass of tclass * tparams | ODKPlain let build_call_ref : (typer -> access_kind -> expr list -> with_type -> pos -> texpr) ref = ref (fun _ _ _ _ _ -> assert false) let mk_infos ctx p params = let file = if ctx.in_macro then p.pfile else if Common.defined ctx.com Define.AbsolutePath then Path.get_full_path p.pfile else Filename.basename p.pfile in (EObjectDecl ( (("fileName",null_pos) , (EConst (String file) , p)) :: (("lineNumber",null_pos) , (EConst (Int (string_of_int (Lexer.get_error_line p))),p)) :: (("className",null_pos) , (EConst (String (s_type_path ctx.curclass.cl_path)),p)) :: if ctx.curfield.cf_name = "" then params else (("methodName",null_pos), (EConst (String ctx.curfield.cf_name),p)) :: params ) ,p) let check_assign ctx e = match e.eexpr with | TLocal {v_extra = None} | TArray _ | TField _ -> () | TConst TThis | TTypeExpr _ when ctx.untyped -> () | _ -> error "Invalid assign" e.epos type type_class = | KInt | KFloat | KString | KUnk | KDyn | KOther | KParam of t | KAbstract of tabstract * t list let rec classify t = match follow t with | TInst ({ cl_path = ([],"String") },[]) -> KString | TAbstract({a_impl = Some _} as a,tl) -> KAbstract (a,tl) | TAbstract ({ a_path = [],"Int" },[]) -> KInt | TAbstract ({ a_path = [],"Float" },[]) -> KFloat | TAbstract (a,[]) when List.exists (fun t -> match classify t with KInt | KFloat -> true | _ -> false) a.a_to -> KParam t | TInst ({ cl_kind = KTypeParameter ctl },_) when List.exists (fun t -> match classify t with KInt | KFloat -> true | _ -> false) ctl -> KParam t | TMono r when !r = None -> KUnk | TDynamic _ -> KDyn | _ -> KOther let get_iterator_param t = match follow t with | TAnon a -> if !(a.a_status) <> Closed then raise Not_found; (match follow (PMap.find "hasNext" a.a_fields).cf_type, follow (PMap.find "next" a.a_fields).cf_type with | TFun ([],tb), TFun([],t) when (match follow tb with TAbstract ({ a_path = [],"Bool" },[]) -> true | _ -> false) -> if PMap.fold (fun _ acc -> acc + 1) a.a_fields 0 <> 2 then raise Not_found; t | _ -> raise Not_found) | _ -> raise Not_found let get_iterable_param t = match follow t with | TAnon a -> if !(a.a_status) <> Closed then raise Not_found; (match follow (PMap.find "iterator" a.a_fields).cf_type with | TFun ([],it) -> let t = get_iterator_param it in if PMap.fold (fun _ acc -> acc + 1) a.a_fields 0 <> 1 then raise Not_found; t | _ -> raise Not_found) | _ -> raise Not_found let get_abstract_froms a pl = let l = List.map (apply_params a.a_params pl) a.a_from in List.fold_left (fun acc (t,f) -> match follow (field_type f) with | TFun ([_,_,v],t) -> (try ignore(type_eq EqStrict t (TAbstract(a,List.map dup pl))); (* unify fields monomorphs *) v :: acc with Unify_error _ -> acc) | _ -> acc ) l a.a_from_field (* temporally remove the constant flag from structures to allow larger unification *) let remove_constant_flag t callb = let tmp = ref [] in let rec loop t = match follow t with | TAnon a -> if !(a.a_status) = Const then begin a.a_status := Closed; tmp := a :: !tmp; end; PMap.iter (fun _ f -> loop f.cf_type) a.a_fields; | _ -> () in let restore() = List.iter (fun a -> a.a_status := Const) (!tmp) in try loop t; let ret = callb (!tmp <> []) in restore(); ret with e -> restore(); raise e let rec is_pos_infos = function | TMono r -> (match !r with | Some t -> is_pos_infos t | _ -> false) | TLazy f -> is_pos_infos (!f()) | TType ({ t_path = ["haxe"] , "PosInfos" },[]) -> true | TType (t,tl) -> is_pos_infos (apply_params t.t_params tl t.t_type) | _ -> false let check_constraints ctx tname tpl tl map delayed p = List.iter2 (fun m (name,t) -> match follow t with | TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] -> let f = (fun() -> List.iter (fun ct -> try Type.unify (map m) (map ct) with Unify_error l -> let l = Constraint_failure (tname ^ "." ^ name) :: l in raise (Unify_error l) ) constr ) in if delayed then delay ctx PCheckConstraint (fun () -> try f() with Unify_error l -> display_error ctx (error_msg (Unify l)) p) else f() | _ -> () ) tl tpl let enum_field_type ctx en ef tl_en tl_ef p = let map t = apply_params en.e_params tl_en (apply_params ef.ef_params tl_ef t) in begin try check_constraints ctx (s_type_path en.e_path) en.e_params tl_en map true p; check_constraints ctx ef.ef_name ef.ef_params tl_ef map true p; with Unify_error l -> display_error ctx (error_msg (Unify l)) p end; map ef.ef_type let add_constraint_checks ctx ctypes pl f tl p = List.iter2 (fun m (name,t) -> match follow t with | TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] -> let constr = List.map (fun t -> let t = apply_params f.cf_params tl t in (* only apply params if not static : in that case no param is passed *) let t = (if pl = [] then t else apply_params ctypes pl t) in t ) constr in delay ctx PCheckConstraint (fun() -> List.iter (fun ct -> try (* if has_mono m then raise (Unify_error [Unify_custom "Could not resolve full type for constraint checks"; Unify_custom ("Type was " ^ (s_type (print_context()) m))]); *) Type.unify m ct with Unify_error l -> display_error ctx (error_msg (Unify (Constraint_failure (f.cf_name ^ "." ^ name) :: l))) p; ) constr ); | _ -> () ) tl f.cf_params let field_type ctx c pl f p = match f.cf_params with | [] -> f.cf_type | l -> let monos = List.map (fun _ -> mk_mono()) l in if not (Meta.has Meta.Generic f.cf_meta) then add_constraint_checks ctx c.cl_params pl f monos p; apply_params l monos f.cf_type let class_field ctx c tl name p = raw_class_field (fun f -> field_type ctx c tl f p) c tl name (* checks if we can access to a given class field using current context *) let rec can_access ctx ?(in_overload=false) c cf stat = if cf.cf_public then true else if not in_overload && ctx.com.config.pf_overload && Meta.has Meta.Overload cf.cf_meta then true else (* TODO: should we add a c == ctx.curclass short check here? *) (* has metadata path *) let rec make_path c f = match c.cl_kind with | KAbstractImpl a -> fst a.a_path @ [snd a.a_path; f.cf_name] | KGenericInstance(c,_) -> make_path c f | _ when c.cl_private -> List.rev (f.cf_name :: snd c.cl_path :: (List.tl (List.rev (fst c.cl_path)))) | _ -> fst c.cl_path @ [snd c.cl_path; f.cf_name] in let rec expr_path acc e = match fst e with | EField (e,f) -> expr_path (f :: acc) e | EConst (Ident n) -> n :: acc | _ -> [] in let rec chk_path psub pfull = match psub, pfull with | [], _ -> true | a :: l1, b :: l2 when a = b -> chk_path l1 l2 | _ -> false in let has m c f path = let rec loop = function | (m2,el,_) :: l when m = m2 -> List.exists (fun e -> let p = expr_path [] e in (p <> [] && chk_path p path) ) el || loop l | _ :: l -> loop l | [] -> false in loop c.cl_meta || loop f.cf_meta in let cur_paths = ref [] in let rec loop c = cur_paths := make_path c ctx.curfield :: !cur_paths; begin match c.cl_super with | Some (csup,_) -> loop csup | None -> () end; List.iter (fun (c,_) -> loop c) c.cl_implements; in loop ctx.curclass; let is_constr = cf.cf_name = "new" in let rec loop c = (try (* if our common ancestor declare/override the field, then we can access it *) let f = if is_constr then (match c.cl_constructor with None -> raise Not_found | Some c -> c) else PMap.find cf.cf_name (if stat then c.cl_statics else c.cl_fields) in is_parent c ctx.curclass || (List.exists (has Meta.Allow c f) !cur_paths) with Not_found -> false ) || (match c.cl_super with | Some (csup,_) -> loop csup | None -> false) || has Meta.Access ctx.curclass ctx.curfield (make_path c cf) in let b = loop c (* access is also allowed of we access a type parameter which is constrained to our (base) class *) || (match c.cl_kind with | KTypeParameter tl -> List.exists (fun t -> match follow t with TInst(c,_) -> loop c | _ -> false) tl | _ -> false) || (Meta.has Meta.PrivateAccess ctx.meta) in (* TODO: find out what this does and move it to genas3 *) if b && Common.defined ctx.com Common.Define.As3 && not (Meta.has Meta.Public cf.cf_meta) then cf.cf_meta <- (Meta.Public,[],cf.cf_pos) :: cf.cf_meta; b (* removes the first argument of the class field's function type and all its overloads *) let prepare_using_field cf = match follow cf.cf_type with | TFun((_,_,tf) :: args,ret) -> let rec loop acc overloads = match overloads with | ({cf_type = TFun((_,_,tfo) :: args,ret)} as cfo) :: l -> let tfo = apply_params cfo.cf_params (List.map snd cfo.cf_params) tfo in (* ignore overloads which have a different first argument *) if Type.type_iseq tf tfo then loop ({cfo with cf_type = TFun(args,ret)} :: acc) l else loop acc l | _ :: l -> loop acc l | [] -> acc in {cf with cf_overloads = loop [] cf.cf_overloads; cf_type = TFun(args,ret)} | _ -> cf let eval ctx s = let p = { pfile = "--eval"; pmin = 0; pmax = String.length s; } in let pack,decls = Parser.parse_string ctx.com s p error false in let rec find_main current decls = match decls with | (EClass c,_) :: decls -> let path = pack,fst c.d_name in begin try let cff = List.find (fun cff -> fst cff.cff_name = "main") c.d_data in if ctx.com.main_class <> None then error "Multiple main" cff.cff_pos; ctx.com.main_class <- Some path; Some path with Not_found -> find_main (if current = None then Some path else current) decls end | ((EEnum {d_name = (s,_)} | ETypedef {d_name = (s,_)} | EAbstract {d_name = (s,_)}),_) :: decls when current = None -> find_main (Some (pack,s)) decls | _ :: decls -> find_main current decls | [] -> current in let path_module = match find_main None decls with | None -> error "Evaluated string did not define any types" p | Some path -> path in ignore(Typeload.type_module ctx path_module "eval" decls p); flush_pass ctx PBuildClass "eval" let merge_core_doc ctx c = let c_core = Typeload.load_core_class ctx c in if c.cl_doc = None then c.cl_doc <- c_core.cl_doc; let maybe_merge cf_map cf = if cf.cf_doc = None then try cf.cf_doc <- (PMap.find cf.cf_name cf_map).cf_doc with Not_found -> () in List.iter (maybe_merge c_core.cl_fields) c.cl_ordered_fields; List.iter (maybe_merge c_core.cl_statics) c.cl_ordered_statics; match c.cl_constructor,c_core.cl_constructor with | Some ({cf_doc = None} as cf),Some cf2 -> cf.cf_doc <- cf2.cf_doc | _ -> () let check_error ctx err p = match err with | Module_not_found ([],name) when Display.Diagnostics.is_diagnostics_run ctx -> Display.ToplevelCollector.handle_unresolved_identifier ctx name p true | _ -> display_error ctx (error_msg err) p (* ---------------------------------------------------------------------- *) (* PASS 3 : type expression & check structure *) let rec unify_min_raise ctx (el:texpr list) : t = let rec base_types t = let tl = ref [] in let rec loop t = (match t with | TInst(cl, params) -> (match cl.cl_kind with | KTypeParameter tl -> List.iter loop tl | _ -> ()); List.iter (fun (ic, ip) -> let t = apply_params cl.cl_params params (TInst (ic,ip)) in loop t ) cl.cl_implements; (match cl.cl_super with None -> () | Some (csup, pl) -> let t = apply_params cl.cl_params params (TInst (csup,pl)) in loop t); tl := t :: !tl; | TEnum(en,(_ :: _ as tl2)) -> tl := (TEnum(en,List.map (fun _ -> t_dynamic) tl2)) :: !tl; tl := t :: !tl; | TType (td,pl) -> loop (apply_params td.t_params pl td.t_type); (* prioritize the most generic definition *) tl := t :: !tl; | TLazy f -> loop (!f()) | TMono r -> (match !r with None -> () | Some t -> loop t) | _ -> tl := t :: !tl) in loop t; !tl in match el with | [] -> mk_mono() | [e] -> e.etype | _ -> let rec chk_null e = is_null e.etype || match e.eexpr with | TConst TNull -> true | TBlock el -> (match List.rev el with | [] -> false | e :: _ -> chk_null e) | TParenthesis e | TMeta(_,e) -> chk_null e | _ -> false in (* First pass: Try normal unification and find out if null is involved. *) let rec loop t = function | [] -> false, t | e :: el -> let t = if chk_null e then ctx.t.tnull t else t in try unify_raise ctx e.etype t e.epos; loop t el with Error (Unify _,_) -> try unify_raise ctx t e.etype e.epos; loop (if is_null t then ctx.t.tnull e.etype else e.etype) el with Error (Unify _,_) -> true, t in let has_error, t = loop (mk_mono()) el in if not has_error then t else try (* specific case for const anon : we don't want to hide fields but restrict their common type *) let fcount = ref (-1) in let field_count a = PMap.fold (fun _ acc -> acc + 1) a.a_fields 0 in let expr f = match f.cf_expr with None -> mk (TBlock []) f.cf_type f.cf_pos | Some e -> e in let fields = List.fold_left (fun acc e -> match follow e.etype with | TAnon a when !(a.a_status) = Const -> if !fcount = -1 then begin fcount := field_count a; PMap.map (fun f -> [expr f]) a.a_fields end else begin if !fcount <> field_count a then raise Not_found; PMap.mapi (fun n el -> expr (PMap.find n a.a_fields) :: el) acc end | _ -> raise Not_found ) PMap.empty el in let fields = PMap.foldi (fun n el acc -> let t = try unify_min_raise ctx el with Error (Unify _, _) -> raise Not_found in PMap.add n (mk_field n t (List.hd el).epos null_pos) acc ) fields PMap.empty in TAnon { a_fields = fields; a_status = ref Closed } with Not_found -> (* Second pass: Get all base types (interfaces, super classes and their interfaces) of most general type. Then for each additional type filter all types that do not unify. *) let common_types = base_types t in let dyn_types = List.fold_left (fun acc t -> let rec loop c = Meta.has Meta.UnifyMinDynamic c.cl_meta || (match c.cl_super with None -> false | Some (c,_) -> loop c) in match t with | TInst (c,params) when params <> [] && loop c -> TInst (c,List.map (fun _ -> t_dynamic) params) :: acc | _ -> acc ) [] common_types in let common_types = ref (match List.rev dyn_types with [] -> common_types | l -> common_types @ l) in let loop e = let first_error = ref None in let filter t = (try unify_raise ctx e.etype t e.epos; true with Error (Unify l, p) as err -> if !first_error = None then first_error := Some(err); false) in common_types := List.filter filter !common_types; match !common_types, !first_error with | [], Some err -> raise err | _ -> () in match !common_types with | [] -> error "No common base type found" (punion (List.hd el).epos (List.hd (List.rev el)).epos) | _ -> List.iter loop (List.tl el); List.hd !common_types let unify_min ctx el = try unify_min_raise ctx el with Error (Unify l,p) -> if not ctx.untyped then display_error ctx (error_msg (Unify l)) p; (List.hd el).etype let is_forced_inline c cf = match c with | Some { cl_extern = true } -> true | Some { cl_kind = KAbstractImpl _ } -> true | _ when Meta.has Meta.Extern cf.cf_meta -> true | _ -> false let rec unify_call_args' ctx el args r callp inline force_inline = let in_call_args = ctx.in_call_args in ctx.in_call_args <- true; let call_error err p = raise (Error (Call_error err,p)) in let arg_error ul name opt p = let err = Stack (ul,Custom ("For " ^ (if opt then "optional " else "") ^ "function argument '" ^ name ^ "'")) in call_error (Could_not_unify err) p in let mk_pos_infos t = let infos = mk_infos ctx callp [] in type_expr ctx infos (WithType t) in let rec default_value name t = if is_pos_infos t then mk_pos_infos t else null (ctx.t.tnull t) callp in let skipped = ref [] in let invalid_skips = ref [] in let skip name ul t p = if not ctx.com.config.pf_can_skip_non_nullable_argument && not (is_nullable t) then invalid_skips := name :: !invalid_skips; skipped := (name,ul,p) :: !skipped; default_value name t in (* let force_inline, is_extern = match cf with Some(TInst(c,_),f) -> is_forced_inline (Some c) f, c.cl_extern | _ -> false, false in *) let type_against t e = try let e = type_expr ctx e (WithType t) in AbstractCast.cast_or_unify_raise ctx t e e.epos with Error(l,p) when (match l with Call_error _ | Module_not_found _ -> false | _ -> true) -> raise (WithTypeError (l,p)) in let rec loop el args = match el,args with | [],[] -> begin match List.rev !invalid_skips with | [] -> () | name :: _ -> call_error (Cannot_skip_non_nullable name) callp; end; [] | _,[name,false,t] when (match follow t with TAbstract({a_path = ["haxe";"extern"],"Rest"},_) -> true | _ -> false) -> begin match follow t with | TAbstract({a_path=(["haxe";"extern"],"Rest")},[t]) -> (try List.map (fun e -> type_against t e,false) el with WithTypeError(ul,p) -> arg_error ul name false p) | _ -> assert false end | [],(_,false,_) :: _ -> call_error (Not_enough_arguments args) callp | [],(name,true,t) :: args -> begin match loop [] args with | [] when not (inline && (ctx.g.doinline || force_inline)) && not ctx.com.config.pf_pad_nulls -> if is_pos_infos t then [mk_pos_infos t,true] else [] | args -> let e_def = default_value name t in (e_def,true) :: args end | (_,p) :: _, [] -> begin match List.rev !skipped with | [] -> call_error Too_many_arguments p | (s,ul,p) :: _ -> arg_error ul s true p end | e :: el,(name,opt,t) :: args -> begin try let e = type_against t e in (e,opt) :: loop el args with WithTypeError (ul,p)-> if opt then let e_def = skip name ul t p in (e_def,true) :: loop (e :: el) args else arg_error ul name false p end in let el = try loop el args with exc -> ctx.in_call_args <- in_call_args; raise exc; in ctx.in_call_args <- in_call_args; el,TFun(args,r) let unify_call_args ctx el args r p inline force_inline = let el,tf = unify_call_args' ctx el args r p inline force_inline in List.map fst el,tf let unify_field_call ctx fa el args ret p inline = let map_cf cf0 map cf = let t = map (monomorphs cf.cf_params cf.cf_type) in begin match cf.cf_expr,cf.cf_kind with | None,Method MethInline when not ctx.com.config.pf_overload -> (* This is really awkward and shouldn't be here. We'll keep it for 3.2 in order to not break code that relied on the quirky behavior in 3.1.3, but it should really be reviewed afterwards. Related issue: https://github.com/HaxeFoundation/haxe/issues/3846 *) cf.cf_expr <- cf0.cf_expr; cf.cf_kind <- cf0.cf_kind; | _ -> () end; t,cf in let expand_overloads map cf = (TFun(args,ret),cf) :: (List.map (map_cf cf map) cf.cf_overloads) in let candidates,co,cf,mk_fa = match fa with | FStatic(c,cf) -> expand_overloads (fun t -> t) cf,Some c,cf,(fun cf -> FStatic(c,cf)) | FAnon cf -> expand_overloads (fun t -> t) cf,None,cf,(fun cf -> FAnon cf) | FInstance(c,tl,cf) -> let map = apply_params c.cl_params tl in let cfl = if cf.cf_name = "new" || not (Meta.has Meta.Overload cf.cf_meta && ctx.com.config.pf_overload) then List.map (map_cf cf map) cf.cf_overloads else List.map (fun (t,cf) -> map (monomorphs cf.cf_params t),cf) (Overloads.get_overloads c cf.cf_name) in (TFun(args,ret),cf) :: cfl,Some c,cf,(fun cf -> FInstance(c,tl,cf)) | FClosure(co,cf) -> let c = match co with None -> None | Some (c,_) -> Some c in expand_overloads (fun t -> t) cf,c,cf,(fun cf -> match co with None -> FAnon cf | Some (c,tl) -> FInstance(c,tl,cf)) | _ -> error "Invalid field call" p in let is_forced_inline = is_forced_inline co cf in let is_overload = Meta.has Meta.Overload cf.cf_meta in let attempt_call t cf = match follow t with | TFun(args,ret) -> let el,tf = unify_call_args' ctx el args ret p inline is_forced_inline in let mk_call ethis p_field = let ef = mk (TField(ethis,mk_fa cf)) t p_field in make_call ctx ef (List.map fst el) ret p in el,tf,mk_call | _ -> assert false in let rec loop candidates = match candidates with | [] -> [],[] | (t,cf) :: candidates -> begin try let candidate = attempt_call t cf in if ctx.com.config.pf_overload && is_overload then begin let candidates,failures = loop candidates in candidate :: candidates,failures end else [candidate],[] with Error ((Call_error _ as err),p) -> let candidates,failures = loop candidates in candidates,(cf,err,p) :: failures end in let fail_fun () = let tf = TFun(args,ret) in [],tf,(fun ethis p_field -> let e1 = mk (TField(ethis,mk_fa cf)) tf p_field in mk (TCall(e1,[])) ret p) in match candidates with | [t,cf] -> begin try let el,tf,mk_call = attempt_call t cf in List.map fst el,tf,mk_call with Error _ when ctx.com.display.dms_error_policy = EPIgnore -> fail_fun(); end | _ -> let candidates,failures = loop candidates in let fail () = let failures = List.map (fun (cf,err,p) -> cf,error_msg err,p) failures in let failures = remove_duplicates (fun (_,msg1,_) (_,msg2,_) -> msg1 <> msg2) failures in begin match failures with | [_,msg,p] -> error msg p | _ -> display_error ctx "Could not find a suitable overload, reasons follow" p; List.iter (fun (cf,msg,p2) -> display_error ctx ("Overload resolution failed for " ^ (s_type (print_context()) cf.cf_type)) p; display_error ctx msg p2; ) failures; error "End of overload failure reasons" p end in if is_overload && ctx.com.config.pf_overload then begin match Overloads.Resolution.reduce_compatible candidates with | [] -> fail() | [el,tf,mk_call] -> List.map fst el,tf,mk_call | _ -> error "Ambiguous overload" p end else begin match List.rev candidates with | [] -> fail() | (el,tf,mk_call) :: _ -> List.map fst el,tf,mk_call end let fast_enum_field e ef p = let et = mk (TTypeExpr (TEnumDecl e)) (TAnon { a_fields = PMap.empty; a_status = ref (EnumStatics e) }) p in TField (et,FEnum (e,ef)) let abstract_module_type a tl = { t_path = [],Printf.sprintf "Abstract<%s%s>" (s_type_path a.a_path) (s_type_params (ref []) tl); t_module = a.a_module; t_doc = None; t_pos = a.a_pos; t_name_pos = null_pos; t_type = TAnon { a_fields = PMap.empty; a_status = ref (AbstractStatics a); }; t_private = true; t_params = []; t_meta = no_meta; } let rec type_module_type ctx t tparams p = match t with | TClassDecl {cl_kind = KGenericBuild _} -> let _,_,f = Typeload.build_instance ctx t p in let t = f (match tparams with None -> [] | Some tl -> tl) in let mt = try module_type_of_type t with Exit -> if follow t == t_dynamic then Typeload.load_type_def ctx p { tpackage = []; tname = "Dynamic"; tparams = []; tsub = None } else error "Invalid module type" p in type_module_type ctx mt None p | TClassDecl c -> let t_tmp = { t_path = [],"Class<" ^ (s_type_path c.cl_path) ^ ">" ; t_module = c.cl_module; t_doc = None; t_pos = c.cl_pos; t_name_pos = null_pos; t_type = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c); }; t_private = true; t_params = []; t_meta = no_meta; } in mk (TTypeExpr (TClassDecl c)) (TType (t_tmp,[])) p | TEnumDecl e -> let types = (match tparams with None -> List.map (fun _ -> mk_mono()) e.e_params | Some l -> l) in mk (TTypeExpr (TEnumDecl e)) (TType (e.e_type,types)) p | TTypeDecl s -> let t = apply_params s.t_params (List.map (fun _ -> mk_mono()) s.t_params) s.t_type in if not (Common.defined ctx.com Define.NoDeprecationWarnings) then Display.DeprecationCheck.check_typedef ctx.com s p; (match follow t with | TEnum (e,params) -> type_module_type ctx (TEnumDecl e) (Some params) p | TInst (c,params) -> type_module_type ctx (TClassDecl c) (Some params) p | TAbstract (a,params) -> type_module_type ctx (TAbstractDecl a) (Some params) p | _ -> error (s_type_path s.t_path ^ " is not a value") p) | TAbstractDecl { a_impl = Some c } -> type_module_type ctx (TClassDecl c) tparams p | TAbstractDecl a -> if not (Meta.has Meta.RuntimeValue a.a_meta) then error (s_type_path a.a_path ^ " is not a value") p; let t_tmp = abstract_module_type a [] in mk (TTypeExpr (TAbstractDecl a)) (TType (t_tmp,[])) p let type_type ctx tpath p = type_module_type ctx (Typeload.load_type_def ctx p { tpackage = fst tpath; tname = snd tpath; tparams = []; tsub = None }) None p let get_constructor ctx c params p = match c.cl_kind with | KAbstractImpl a -> let f = (try PMap.find "_new" c.cl_statics with Not_found -> raise_error (No_constructor (TAbstractDecl a)) p) in let ct = field_type ctx c params f p in apply_params a.a_params params ct, f | _ -> let ct, f = (try Type.get_constructor (fun f -> field_type ctx c params f p) c with Not_found -> raise_error (No_constructor (TClassDecl c)) p) in apply_params c.cl_params params ct, f let make_call ctx e params t p = try let ethis,cl,f = match e.eexpr with | TField (ethis,fa) -> let co,cf = match fa with | FInstance(c,_,cf) | FStatic(c,cf) -> Some c,cf | FAnon cf -> None,cf | _ -> raise Exit in ethis,co,cf | _ -> raise Exit in if f.cf_kind <> Method MethInline then raise Exit; let config = match cl with | Some ({cl_kind = KAbstractImpl _}) when Meta.has Meta.Impl f.cf_meta -> let t = if f.cf_name = "_new" then t else if params = [] then error "Invalid abstract implementation function" f.cf_pos else follow (List.hd params).etype in begin match t with | TAbstract(a,pl) -> let has_params = a.a_params <> [] || f.cf_params <> [] in let monos = List.map (fun _ -> mk_mono()) f.cf_params in let map_type = fun t -> apply_params a.a_params pl (apply_params f.cf_params monos t) in Some (has_params,map_type) | _ -> None end | _ -> None in ignore(follow f.cf_type); (* force evaluation *) let params = List.map (ctx.g.do_optimize ctx) params in let force_inline = is_forced_inline cl f in (match f.cf_expr_unoptimized,f.cf_expr with | Some fd,_ | None,Some { eexpr = TFunction fd } -> (match Optimizer.type_inline ctx f fd ethis params t config p force_inline with | None -> if force_inline then error "Inline could not be done" p; raise Exit; | Some e -> e) | _ -> (* we can't inline because there is most likely a loop in the typing. this can be caused by mutually recursive vars/functions, some of them being inlined or not. In that case simply ignore inlining. *) raise Exit) with Exit -> mk (TCall (e,params)) t p let mk_array_get_call ctx (cf,tf,r,e1,e2o) c ebase p = match cf.cf_expr with | None -> if not (Meta.has Meta.NoExpr cf.cf_meta) then display_error ctx "Recursive array get method" p; mk (TArray(ebase,e1)) r p | Some _ -> let et = type_module_type ctx (TClassDecl c) None p in let ef = mk (TField(et,(FStatic(c,cf)))) tf p in make_call ctx ef [ebase;e1] r p let mk_array_set_call ctx (cf,tf,r,e1,e2o) c ebase p = let evalue = match e2o with None -> assert false | Some e -> e in match cf.cf_expr with | None -> if not (Meta.has Meta.NoExpr cf.cf_meta) then display_error ctx "Recursive array set method" p; let ea = mk (TArray(ebase,e1)) r p in mk (TBinop(OpAssign,ea,evalue)) r p | Some _ -> let et = type_module_type ctx (TClassDecl c) None p in let ef = mk (TField(et,(FStatic(c,cf)))) tf p in make_call ctx ef [ebase;e1;evalue] r p let rec acc_get ctx g p = match g with | AKNo f -> error ("Field " ^ f ^ " cannot be accessed for reading") p | AKExpr e -> e | AKSet _ | AKAccess _ -> assert false | AKUsing (et,c,cf,e) when ctx.in_display -> (* Generate a TField node so we can easily match it for position/usage completion (issue #1968) *) let ec = type_module_type ctx (TClassDecl c) None p in let t = match follow et.etype with | TFun (_ :: args,ret) -> TFun(args,ret) | _ -> et.etype in mk (TField(ec,FStatic(c,cf))) t et.epos | AKUsing (et,_,cf,e) -> (* build a closure with first parameter applied *) (match follow et.etype with | TFun (_ :: args,ret) -> let tcallb = TFun (args,ret) in let twrap = TFun ([("_e",false,e.etype)],tcallb) in (* arguments might not have names in case of variable fields of function types, so we generate one (issue #2495) *) let args = List.map (fun (n,o,t) -> let t = if o then ctx.t.tnull t else t in o,if n = "" then gen_local ctx t e.epos else alloc_var n t e.epos (* TODO: var pos *) ) args in let ve = alloc_var "_e" e.etype e.epos in let ecall = make_call ctx et (List.map (fun v -> mk (TLocal v) v.v_type p) (ve :: List.map snd args)) ret p in let ecallb = mk (TFunction { tf_args = List.map (fun (o,v) -> v,if o then Some TNull else None) args; tf_type = ret; tf_expr = (match follow ret with | TAbstract ({a_path = [],"Void"},_) -> ecall | _ -> mk (TReturn (Some ecall)) t_dynamic p); }) tcallb p in let ewrap = mk (TFunction { tf_args = [ve,None]; tf_type = tcallb; tf_expr = mk (TReturn (Some ecallb)) t_dynamic p; }) twrap p in make_call ctx ewrap [e] tcallb p | _ -> assert false) | AKInline (e,f,fmode,t) -> (* do not create a closure for static calls *) let cmode = (match fmode with FStatic _ -> fmode | FInstance (c,tl,f) -> FClosure (Some (c,tl),f) | _ -> assert false) in ignore(follow f.cf_type); (* force computing *) (match f.cf_expr with | None when ctx.com.display.dms_display -> mk (TField (e,cmode)) t p | None -> error "Recursive inline is not supported" p | Some { eexpr = TFunction _ } -> let chk_class c = (c.cl_extern || Meta.has Meta.Extern f.cf_meta) && not (Meta.has Meta.Runtime f.cf_meta) in let wrap_extern c = let c2 = let m = c.cl_module in let mpath = (fst m.m_path @ ["_" ^ snd m.m_path],(snd m.m_path) ^ "_Impl_") in try let rec loop mtl = match mtl with | (TClassDecl c) :: _ when c.cl_path = mpath -> c | _ :: mtl -> loop mtl | [] -> raise Not_found in loop c.cl_module.m_types with Not_found -> let c2 = mk_class c.cl_module mpath c.cl_pos null_pos in c.cl_module.m_types <- (TClassDecl c2) :: c.cl_module.m_types; c2 in let cf = try PMap.find f.cf_name c2.cl_statics with Not_found -> let cf = {f with cf_kind = Method MethNormal} in c2.cl_statics <- PMap.add cf.cf_name cf c2.cl_statics; c2.cl_ordered_statics <- cf :: c2.cl_ordered_statics; cf in let e_t = type_module_type ctx (TClassDecl c2) None p in mk (TField(e_t,FStatic(c2,cf))) t p in let e_def = mk (TField (e,cmode)) t p in begin match follow e.etype with | TInst (c,_) when chk_class c -> display_error ctx "Can't create closure on an extern inline member method" p; e_def | TAnon a -> begin match !(a.a_status) with | Statics {cl_extern = false} when Meta.has Meta.Extern f.cf_meta -> display_error ctx "Cannot create closure on @:extern inline method" p; e_def | Statics c when chk_class c -> wrap_extern c | _ -> e_def end | _ -> e_def end | Some e -> let rec loop e = Type.map_expr loop { e with epos = p } in loop e) | AKMacro _ -> assert false let error_require r p = if r = "" then error "This field is not available with the current compilation flags" p else let r = if r = "sys" then "a system platform (php,php7,neko,cpp,etc.)" else try if String.sub r 0 5 <> "flash" then raise Exit; let _, v = ExtString.String.replace (String.sub r 5 (String.length r - 5)) "_" "." in "flash version " ^ v ^ " (use -swf-version " ^ v ^ ")" with _ -> "'" ^ r ^ "' to be enabled" in error ("Accessing this field requires " ^ r) p let get_this ctx p = match ctx.curfun with | FunStatic -> error "Cannot access this from a static function" p | FunMemberClassLocal | FunMemberAbstractLocal -> let v = match ctx.vthis with | None -> let v = if ctx.curfun = FunMemberAbstractLocal then PMap.find "this" ctx.locals else add_local ctx "`this" ctx.tthis p in ctx.vthis <- Some v; v | Some v -> ctx.locals <- PMap.add v.v_name v ctx.locals; v in mk (TLocal v) ctx.tthis p | FunMemberAbstract -> let v = (try PMap.find "this" ctx.locals with Not_found -> assert false) in mk (TLocal v) v.v_type p | FunConstructor | FunMember -> mk (TConst TThis) ctx.tthis p let field_access ctx mode f fmode t e p = let fnormal() = AKExpr (mk (TField (e,fmode)) t p) in let normal() = match follow e.etype with | TAnon a -> (match !(a.a_status) with | EnumStatics en -> let c = (try PMap.find f.cf_name en.e_constrs with Not_found -> assert false) in let fmode = FEnum (en,c) in AKExpr (mk (TField (e,fmode)) t p) | _ -> fnormal()) | _ -> fnormal() in match f.cf_kind with | Method m -> if mode = MSet && m <> MethDynamic && not ctx.untyped then error "Cannot rebind this method : please use 'dynamic' before method declaration" p; begin match ctx.curfun,e.eexpr with | (FunMemberAbstract | FunMemberAbstractLocal),TTypeExpr(TClassDecl ({cl_kind = KAbstractImpl a} as c)) when c == ctx.curclass && Meta.has Meta.Impl f.cf_meta -> let e = mk (TField(e,fmode)) t p in let ethis = get_this ctx p in let ethis = {ethis with etype = TAbstract(a,List.map snd a.a_params)} in AKUsing(e,ctx.curclass,f,ethis) | _ -> (match m, mode with | MethInline, _ -> AKInline (e,f,fmode,t) | MethMacro, MGet -> display_error ctx "Macro functions must be called immediately" p; normal() | MethMacro, MCall -> AKMacro (e,f) | _ , MGet -> let cmode = (match fmode with | FInstance(_, _, cf) | FStatic(_, cf) when Meta.has Meta.Generic cf.cf_meta -> display_error ctx "Cannot create closure on generic function" p; fmode | FInstance (c,tl,cf) -> FClosure (Some (c,tl),cf) | FStatic _ | FEnum _ -> fmode | FAnon f -> FClosure (None, f) | FDynamic _ | FClosure _ -> assert false ) in AKExpr (mk (TField (e,cmode)) t p) | _ -> normal()) end | Var v -> match (match mode with MGet | MCall -> v.v_read | MSet -> v.v_write) with | AccNo when not (Meta.has Meta.PrivateAccess ctx.meta) -> (match follow e.etype with | TInst (c,_) when is_parent c ctx.curclass || can_access ctx c { f with cf_public = false } false -> normal() | TAnon a -> (match !(a.a_status) with | Opened when mode = MSet -> f.cf_kind <- Var { v with v_write = AccNormal }; normal() | Statics c2 when ctx.curclass == c2 || can_access ctx c2 { f with cf_public = false } true -> normal() | _ -> if ctx.untyped then normal() else AKNo f.cf_name) | _ -> if ctx.untyped then normal() else AKNo f.cf_name) | AccNormal | AccNo -> (* if we are reading from a read-only variable on an anonymous object, it might actually be a method, so make sure to create a closure *) let is_maybe_method() = match v.v_write, follow t, follow e.etype with | (AccNo | AccNever), TFun _, TAnon a -> (match !(a.a_status) with | Statics _ | EnumStatics _ -> false | _ -> true) | _ -> false in if mode = MGet && is_maybe_method() then AKExpr (mk (TField (e,FClosure (None,f))) t p) else normal() | AccCall -> let m = (match mode with MSet -> "set_" | _ -> "get_") ^ f.cf_name in let is_abstract_this_access () = match e.eexpr,ctx.curfun with | TTypeExpr (TClassDecl ({cl_kind = KAbstractImpl _} as c)),(FunMemberAbstract | FunMemberAbstractLocal) -> c == ctx.curclass | _ -> false in if m = ctx.curfield.cf_name && (match e.eexpr with TConst TThis -> true | TLocal v -> Option.map_default (fun vthis -> v == vthis) false ctx.vthis | TTypeExpr (TClassDecl c) when c == ctx.curclass -> true | _ -> false) then let prefix = (match ctx.com.platform with Flash when Common.defined ctx.com Define.As3 -> "$" | _ -> "") in if is_extern_field f then begin display_error ctx "This field cannot be accessed because it is not a real variable" p; display_error ctx "Add @:isVar here to enable it" f.cf_pos; end; AKExpr (mk (TField (e,if prefix = "" then fmode else FDynamic (prefix ^ f.cf_name))) t p) else if is_abstract_this_access() then begin let this = get_this ctx p in if mode = MSet then begin let c,a = match ctx.curclass with {cl_kind = KAbstractImpl a} as c -> c,a | _ -> assert false in let f = PMap.find m c.cl_statics in (* we don't have access to the type parameters here, right? *) (* let t = apply_params a.a_params pl (field_type ctx c [] f p) in *) let t = (field_type ctx c [] f p) in let ef = mk (TField (e,FStatic (c,f))) t p in AKUsing (ef,c,f,this) end else AKExpr (make_call ctx (mk (TField (e,quick_field_dynamic e.etype m)) (tfun [this.etype] t) p) [this] t p) end else if mode = MSet then AKSet (e,t,f) else AKExpr (make_call ctx (mk (TField (e,quick_field_dynamic e.etype m)) (tfun [] t) p) [] t p) | AccResolve -> let fstring = mk (TConst (TString f.cf_name)) ctx.t.tstring p in let tresolve = tfun [ctx.t.tstring] t in AKExpr (make_call ctx (mk (TField (e,FDynamic "resolve")) tresolve p) [fstring] t p) | AccNever -> if ctx.untyped then normal() else AKNo f.cf_name | AccInline -> AKInline (e,f,fmode,t) | AccRequire (r,msg) -> match msg with | None -> error_require r p | Some msg -> error msg p let rec using_field ctx mode e i p = if mode = MSet then raise Not_found; (* do not try to find using fields if the type is a monomorph, which could lead to side-effects *) let is_dynamic = match follow e.etype with | TMono _ -> raise Not_found | t -> t == t_dynamic in let check_constant_struct = ref false in let rec loop = function | [] -> raise Not_found | (c,pc) :: l -> try let cf = PMap.find i c.cl_statics in if Meta.has Meta.NoUsing cf.cf_meta || not (can_access ctx c cf true) || (Meta.has Meta.Impl cf.cf_meta) then raise Not_found; let monos = List.map (fun _ -> mk_mono()) cf.cf_params in let map = apply_params cf.cf_params monos in let t = map cf.cf_type in begin match follow t with | TFun((_,_,(TType({t_path = ["haxe";"macro"],"ExprOf"},[t0]) | t0)) :: args,r) -> if is_dynamic && follow t0 != t_dynamic then raise Not_found; let e = AbstractCast.cast_or_unify_raise ctx t0 e p in (* early constraints check is possible because e.etype has no monomorphs *) List.iter2 (fun m (name,t) -> match follow t with | TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] && not (has_mono m) -> List.iter (fun tc -> Type.unify m (map tc)) constr | _ -> () ) monos cf.cf_params; let et = type_module_type ctx (TClassDecl c) None p in Display.ImportHandling.maybe_mark_import_position ctx pc; AKUsing (mk (TField (et,FStatic (c,cf))) t p,c,cf,e) | _ -> raise Not_found end with Not_found -> loop l | Unify_error el | Error (Unify el,_) -> if List.exists (function Has_extra_field _ -> true | _ -> false) el then check_constant_struct := true; loop l in try loop ctx.m.module_using with Not_found -> try let acc = loop ctx.g.global_using in (match acc with | AKUsing (_,c,_,_) -> add_dependency ctx.m.curmod c.cl_module | _ -> assert false); acc with Not_found -> if not !check_constant_struct then raise Not_found; remove_constant_flag e.etype (fun ok -> if ok then using_field ctx mode e i p else raise Not_found) let rec type_ident_raise ctx i p mode = match i with | "true" -> if mode = MGet then AKExpr (mk (TConst (TBool true)) ctx.t.tbool p) else AKNo i | "false" -> if mode = MGet then AKExpr (mk (TConst (TBool false)) ctx.t.tbool p) else AKNo i | "this" -> (match mode, ctx.curclass.cl_kind with | MSet, KAbstractImpl _ -> (match ctx.curfield.cf_kind with | Method MethInline -> () | Method _ when ctx.curfield.cf_name = "_new" -> () | _ -> error "You can only modify 'this' inside an inline function" p); AKExpr (get_this ctx p) | (MCall, KAbstractImpl _) | (MGet, _)-> AKExpr(get_this ctx p) | _ -> AKNo i) | "super" -> let t = (match ctx.curclass.cl_super with | None -> error "Current class does not have a superclass" p | Some (c,params) -> TInst(c,params) ) in (match ctx.curfun with | FunMember | FunConstructor -> () | FunMemberAbstract -> error "Cannot access super inside an abstract function" p | FunStatic -> error "Cannot access super inside a static function" p; | FunMemberClassLocal | FunMemberAbstractLocal -> error "Cannot access super inside a local function" p); AKExpr (mk (TConst TSuper) t p) | "null" -> if mode = MGet then AKExpr (null (mk_mono()) p) else AKNo i | _ -> try let v = PMap.find i ctx.locals in (match v.v_extra with | Some (params,e) -> let t = monomorphs params v.v_type in (match e with | Some ({ eexpr = TFunction f } as e) when ctx.com.display.dms_full_typing -> begin match mode with | MSet -> error "Cannot set inline closure" p | MGet -> error "Cannot create closure on inline closure" p | MCall -> (* create a fake class with a fake field to emulate inlining *) let c = mk_class ctx.m.curmod (["local"],v.v_name) e.epos null_pos in let cf = { (mk_field v.v_name v.v_type e.epos null_pos) with cf_params = params; cf_expr = Some e; cf_kind = Method MethInline } in c.cl_extern <- true; c.cl_fields <- PMap.add cf.cf_name cf PMap.empty; AKInline (mk (TConst TNull) (TInst (c,[])) p, cf, FInstance(c,[],cf), t) end | _ -> AKExpr (mk (TLocal v) t p)) | _ -> AKExpr (mk (TLocal v) v.v_type p)) with Not_found -> try (* member variable lookup *) if ctx.curfun = FunStatic then raise Not_found; let c , t , f = class_field ctx ctx.curclass (List.map snd ctx.curclass.cl_params) i p in field_access ctx mode f (match c with None -> FAnon f | Some (c,tl) -> FInstance (c,tl,f)) t (get_this ctx p) p with Not_found -> try (* lookup using on 'this' *) if ctx.curfun = FunStatic then raise Not_found; (match using_field ctx mode (mk (TConst TThis) ctx.tthis p) i p with | AKUsing (et,c,f,_) -> AKUsing (et,c,f,get_this ctx p) | _ -> assert false) with Not_found -> try (* static variable lookup *) let f = PMap.find i ctx.curclass.cl_statics in if Meta.has Meta.Impl f.cf_meta && not (Meta.has Meta.Impl ctx.curfield.cf_meta) && not (Meta.has Meta.Enum f.cf_meta) then error (Printf.sprintf "Cannot access non-static field %s from static method" f.cf_name) p; let e = type_type ctx ctx.curclass.cl_path p in (* check_locals_masking already done in type_type *) field_access ctx mode f (FStatic (ctx.curclass,f)) (field_type ctx ctx.curclass [] f p) e p with Not_found -> try let wrap e = if mode = MSet then AKNo i else AKExpr e in (* lookup imported enums *) let rec loop l = match l with | [] -> raise Not_found | (t,pt) :: l -> match t with | TAbstractDecl ({a_impl = Some c} as a) when Meta.has Meta.Enum a.a_meta -> begin try let cf = PMap.find i c.cl_statics in if not (Meta.has Meta.Enum cf.cf_meta) then loop l else begin let et = type_module_type ctx (TClassDecl c) None p in let fa = FStatic(c,cf) in let t = monomorphs cf.cf_params cf.cf_type in Display.ImportHandling.maybe_mark_import_position ctx pt; begin match cf.cf_kind with | Var {v_read = AccInline} -> AKInline(et,cf,fa,t) | _ -> AKExpr (mk (TField(et,fa)) t p) end end with Not_found -> loop l end | TClassDecl _ | TAbstractDecl _ -> loop l | TTypeDecl t -> (match follow t.t_type with | TEnum (e,_) -> loop ((TEnumDecl e,pt) :: l) | _ -> loop l) | TEnumDecl e -> try let ef = PMap.find i e.e_constrs in let et = type_module_type ctx t None p in let monos = List.map (fun _ -> mk_mono()) e.e_params in let monos2 = List.map (fun _ -> mk_mono()) ef.ef_params in Display.ImportHandling.maybe_mark_import_position ctx pt; wrap (mk (TField (et,FEnum (e,ef))) (enum_field_type ctx e ef monos monos2 p) p) with Not_found -> loop l in (try loop (List.rev_map (fun t -> t,null_pos) ctx.m.curmod.m_types) with Not_found -> loop ctx.m.module_types) with Not_found -> (* lookup imported globals *) let t, name, pi = PMap.find i ctx.m.module_globals in Display.ImportHandling.maybe_mark_import_position ctx pi; let e = type_module_type ctx t None p in type_field ctx e name p mode and type_field ?(resume=false) ctx e i p mode = let no_field() = if resume then raise Not_found; let t = match follow e.etype with | TAnon a -> (match !(a.a_status) with | Statics {cl_kind = KAbstractImpl a} -> TAbstract(a,[]) | _ -> e.etype) | TInst({cl_kind = KAbstractImpl a},_) -> TAbstract(a,[]) | _ -> e.etype in let has_special_field a = List.exists (fun (_,cf) -> cf.cf_name = i) a.a_ops || List.exists (fun (_,_,cf) -> cf.cf_name = i) a.a_unops || List.exists (fun cf -> cf.cf_name = i) a.a_array in if not ctx.untyped then begin match t with | TAbstract(a,_) when has_special_field a -> (* the abstract field is not part of the field list, which is only true when it has no expression (issue #2344) *) display_error ctx ("Field " ^ i ^ " cannot be called directly because it has no expression") p; | _ -> display_error ctx (StringError.string_error i (string_source t) (s_type (print_context()) t ^ " has no field " ^ i)) p; end; AKExpr (mk (TField (e,FDynamic i)) (mk_mono()) p) in let does_forward a stat = try let _,el,_ = Meta.get (if stat then Meta.ForwardStatics else Meta.Forward) a.a_meta in match el with | [] -> true | _ -> List.exists (fun e -> match fst e with | EConst(Ident s | String s) -> s = i | _ -> error "Identifier or string expected as argument to @:forward" (pos e) ) el with Not_found -> false in match follow e.etype with | TInst (c,params) -> let rec loop_dyn c params = match c.cl_dynamic with | Some t -> let t = apply_params c.cl_params params t in if (mode = MGet || mode = MCall) && PMap.mem "resolve" c.cl_fields then begin let f = PMap.find "resolve" c.cl_fields in begin match f.cf_kind with | Method MethMacro -> display_error ctx "The macro accessor is not allowed for field resolve" f.cf_pos | _ -> () end; let texpect = tfun [ctx.t.tstring] t in let tfield = apply_params c.cl_params params (monomorphs f.cf_params f.cf_type) in (try Type.unify tfield texpect with Unify_error l -> display_error ctx "Field resolve has an invalid type" f.cf_pos; display_error ctx (error_msg (Unify [Cannot_unify(tfield,texpect)])) f.cf_pos); AKExpr (make_call ctx (mk (TField (e,FInstance (c,params,f))) tfield p) [Codegen.type_constant ctx.com (String i) p] t p) end else AKExpr (mk (TField (e,FDynamic i)) t p) | None -> match c.cl_super with | None -> raise Not_found | Some (c,params) -> loop_dyn c params in (try let c2, t , f = class_field ctx c params i p in if e.eexpr = TConst TSuper then (match mode,f.cf_kind with | MGet,Var {v_read = AccCall } | MSet,Var {v_write = AccCall } | MCall,Var {v_read = AccCall } -> () | MCall, Var _ -> display_error ctx "Cannot access superclass variable for calling: needs to be a proper method" p | MCall, _ -> () | MGet,Var _ | MSet,Var _ when (match c2 with Some ({ cl_extern = true; cl_path = ("flash" :: _,_) }, _) -> true | _ -> false) -> () | _, Method _ -> display_error ctx "Cannot create closure on super method" p | _ -> display_error ctx "Normal variables cannot be accessed with 'super', use 'this' instead" p); if not (can_access ctx c f false) && not ctx.untyped then display_error ctx ("Cannot access private field " ^ i) p; field_access ctx mode f (match c2 with None -> FAnon f | Some (c,tl) -> FInstance (c,tl,f)) (apply_params c.cl_params params t) e p with Not_found -> try using_field ctx mode e i p with Not_found -> try loop_dyn c params with Not_found -> try (* if we have an abstract constraint we have to check its static fields and recurse (issue #2343) *) begin match c.cl_kind with | KTypeParameter tl -> let rec loop tl = match tl with | t :: tl -> begin match follow t with | TAbstract({a_impl = Some c},tl) when PMap.mem i c.cl_statics -> let e = mk_cast e t p in type_field ctx e i p mode; | _ -> loop tl end | [] -> raise Not_found in loop tl | _ -> raise Not_found end with Not_found -> if PMap.mem i c.cl_statics then error ("Cannot access static field " ^ i ^ " from a class instance") p; no_field()) | TDynamic t -> (try using_field ctx mode e i p with Not_found -> AKExpr (mk (TField (e,FDynamic i)) t p)) | TAnon a -> (try let f = PMap.find i a.a_fields in if not f.cf_public && not ctx.untyped then begin match !(a.a_status) with | Closed | Extend _ -> () (* always allow anon private fields access *) | Statics c when can_access ctx c f true -> () | _ -> display_error ctx ("Cannot access private field " ^ i) p end; let fmode, ft = (match !(a.a_status) with | Statics c -> FStatic (c,f), field_type ctx c [] f p | EnumStatics e -> FEnum (e,try PMap.find f.cf_name e.e_constrs with Not_found -> assert false), Type.field_type f | _ -> match f.cf_params with | [] -> FAnon f, Type.field_type f | l -> (* handle possible constraints *) let monos = List.map (fun _ -> mk_mono()) l in let t = apply_params f.cf_params monos f.cf_type in add_constraint_checks ctx [] [] f monos p; FAnon f, t ) in field_access ctx mode f fmode ft e p with Not_found -> try match !(a.a_status) with | Statics {cl_kind = KAbstractImpl a} when does_forward a true -> let mt = try module_type_of_type a.a_this with Exit -> raise Not_found in let et = type_module_type ctx mt None p in type_field ctx et i p mode; | _ -> raise Not_found with Not_found -> if is_closed a then try using_field ctx mode e i p with Not_found -> no_field() else let f = { cf_name = i; cf_type = mk_mono(); cf_doc = None; cf_meta = no_meta; cf_public = true; cf_pos = p; cf_name_pos = null_pos; cf_kind = Var { v_read = AccNormal; v_write = (match mode with MSet -> AccNormal | MGet | MCall -> AccNo) }; cf_expr = None; cf_expr_unoptimized = None; cf_params = []; cf_overloads = []; } in a.a_fields <- PMap.add i f a.a_fields; field_access ctx mode f (FAnon f) (Type.field_type f) e p ) | TMono r -> let f = { cf_name = i; cf_type = mk_mono(); cf_doc = None; cf_meta = no_meta; cf_public = true; cf_pos = p; cf_name_pos = null_pos; cf_kind = Var { v_read = AccNormal; v_write = (match mode with MSet -> AccNormal | MGet | MCall -> AccNo) }; cf_expr = None; cf_expr_unoptimized = None; cf_params = []; cf_overloads = []; } in let x = ref Opened in let t = TAnon { a_fields = PMap.add i f PMap.empty; a_status = x } in ctx.opened <- x :: ctx.opened; r := Some t; field_access ctx mode f (FAnon f) (Type.field_type f) e p | TAbstract (a,pl) -> let static_abstract_access_through_instance = ref false in (try let c = (match a.a_impl with None -> raise Not_found | Some c -> c) in let f = PMap.find i c.cl_statics in if not (can_access ctx c f true) && not ctx.untyped then display_error ctx ("Cannot access private field " ^ i) p; let field_type f = if not (Meta.has Meta.Impl f.cf_meta) then begin static_abstract_access_through_instance := true; raise Not_found; end; let t = field_type ctx c [] f p in apply_params a.a_params pl t in let et = type_module_type ctx (TClassDecl c) None p in let field_expr f t = mk (TField (et,FStatic (c,f))) t p in (match mode, f.cf_kind with | (MGet | MCall), Var {v_read = AccCall } -> (* getter call *) let f = PMap.find ("get_" ^ f.cf_name) c.cl_statics in let t = field_type f in let r = match follow t with TFun(_,r) -> r | _ -> raise Not_found in let ef = field_expr f t in AKExpr(make_call ctx ef [e] r p) | MSet, Var {v_write = AccCall } -> let f = PMap.find ("set_" ^ f.cf_name) c.cl_statics in let t = field_type f in let ef = field_expr f t in AKUsing (ef,c,f,e) | (MGet | MCall), Var {v_read = AccNever} -> AKNo f.cf_name | (MGet | MCall), _ -> let rec loop cfl = match cfl with | [] -> error (Printf.sprintf "Field %s cannot be called on %s" f.cf_name (s_type (print_context()) e.etype)) p | cf :: cfl -> match follow (apply_params a.a_params pl (monomorphs cf.cf_params cf.cf_type)) with | TFun((_,_,t1) :: _,_) when type_iseq t1 (Abstract.get_underlying_type a pl) -> cf | _ -> loop cfl in let f = match f.cf_overloads with | [] -> f | cfl -> loop (f :: cfl) in let t = field_type f in begin match follow t with | TFun((_,_,t1) :: _,_) -> () | _ -> error ("Invalid call to static function " ^ i ^ " through abstract instance") p end; let ef = field_expr f t in AKUsing (ef,c,f,e) | MSet, _ -> error "This operation is unsupported" p) with Not_found -> try if does_forward a false then type_field ~resume:true ctx {e with etype = apply_params a.a_params pl a.a_this} i p mode else raise Not_found with Not_found -> try using_field ctx mode e i p with Not_found -> try (match ctx.curfun, e.eexpr with | FunMemberAbstract, TConst (TThis) -> type_field ctx {e with etype = apply_params a.a_params pl a.a_this} i p mode; | _ -> raise Not_found) with Not_found -> try let c,cf = match a.a_impl,a.a_resolve with | Some c,Some cf -> c,cf | _ -> raise Not_found in let et = type_module_type ctx (TClassDecl c) None p in let t = apply_params a.a_params pl (field_type ctx c [] cf p) in let ef = mk (TField (et,FStatic (c,cf))) t p in AKExpr ((!build_call_ref) ctx (AKUsing(ef,c,cf,e)) [EConst (String i),p] NoValue p) with Not_found -> if !static_abstract_access_through_instance then error ("Invalid call to static function " ^ i ^ " through abstract instance") p else no_field()) | _ -> try using_field ctx mode e i p with Not_found -> no_field() let type_bind ctx (e : texpr) params p = let args,ret = match follow e.etype with TFun(args, ret) -> args, ret | _ -> error "First parameter of callback is not a function" p in let vexpr v = mk (TLocal v) v.v_type p in let acount = ref 0 in let alloc_name n = if n = "" || String.length n > 2 && not ctx.is_display_file then begin incr acount; "a" ^ string_of_int !acount; end else n in let rec loop args params given_args missing_args ordered_args = match args, params with | [], [] -> given_args,missing_args,ordered_args | [], _ -> error "Too many callback arguments" p | (n,o,t) :: args , [] when o -> let a = if is_pos_infos t then let infos = mk_infos ctx p [] in ordered_args @ [type_expr ctx infos (WithType t)] else if ctx.com.config.pf_pad_nulls then (ordered_args @ [(mk (TConst TNull) t_dynamic p)]) else ordered_args in loop args [] given_args missing_args a | (n,o,t) :: _ , (EConst(Ident "_"),p) :: _ when not ctx.com.config.pf_can_skip_non_nullable_argument && o && not (is_nullable t) -> error "Usage of _ is not supported for optional non-nullable arguments" p | (n,o,t) :: args , ([] as params) | (n,o,t) :: args , (EConst(Ident "_"),_) :: params -> let v = alloc_var (alloc_name n) (if o then ctx.t.tnull t else t) p in loop args params given_args (missing_args @ [v,o]) (ordered_args @ [vexpr v]) | (n,o,t) :: args , param :: params -> let e = type_expr ctx param (WithType t) in let e = AbstractCast.cast_or_unify ctx t e p in let v = alloc_var (alloc_name n) t (pos param) in loop args params (given_args @ [v,o,Some e]) missing_args (ordered_args @ [vexpr v]) in let given_args,missing_args,ordered_args = loop args params [] [] [] in let rec gen_loc_name n = let name = if n = 0 then "f" else "f" ^ (string_of_int n) in if List.exists (fun (n,_,_) -> name = n) args then gen_loc_name (n + 1) else name in let loc = alloc_var (gen_loc_name 0) e.etype e.epos in let given_args = (loc,false,Some e) :: given_args in let inner_fun_args l = List.map (fun (v,o) -> v.v_name, o, v.v_type) l in let t_inner = TFun(inner_fun_args missing_args, ret) in let call = make_call ctx (vexpr loc) ordered_args ret p in let e_ret = match follow ret with | TAbstract ({a_path = [],"Void"},_) -> call | TMono _ -> mk (TReturn (Some call)) t_dynamic p; | _ -> mk (TReturn (Some call)) t_dynamic p; in let func = mk (TFunction { tf_args = List.map (fun (v,o) -> v, if o then Some TNull else None) missing_args; tf_type = ret; tf_expr = e_ret; }) t_inner p in let outer_fun_args l = List.map (fun (v,o,_) -> v.v_name, o, v.v_type) l in let func = mk (TFunction { tf_args = List.map (fun (v,_,_) -> v,None) given_args; tf_type = t_inner; tf_expr = mk (TReturn (Some func)) t_inner p; }) (TFun(outer_fun_args given_args, t_inner)) p in make_call ctx func (List.map (fun (_,_,e) -> (match e with Some e -> e | None -> assert false)) given_args) t_inner p (* We want to try unifying as an integer and apply side effects. However, in case the value is not a normal Monomorph but one issued from a Dynamic relaxation, we will instead unify with float since we don't want to accidentaly truncate the value *) let unify_int ctx e k = let is_dynamic t = match follow t with | TDynamic _ -> true | _ -> false in let is_dynamic_array t = match follow t with | TInst (_,[p]) -> is_dynamic p | _ -> true in let is_dynamic_field t f = match follow t with | TAnon a -> (try is_dynamic (PMap.find f a.a_fields).cf_type with Not_found -> false) | TInst (c,tl) -> (try is_dynamic (apply_params c.cl_params tl ((let _,t,_ = Type.class_field c tl f in t))) with Not_found -> false) | _ -> true in let is_dynamic_return t = match follow t with | TFun (_,r) -> is_dynamic r | _ -> true in (* This is some quick analysis that matches the most common cases of dynamic-to-mono convertions *) let rec maybe_dynamic_mono e = match e.eexpr with | TLocal _ -> is_dynamic e.etype | TArray({ etype = t } as e,_) -> is_dynamic_array t || maybe_dynamic_rec e t | TField({ etype = t } as e,f) -> is_dynamic_field t (field_name f) || maybe_dynamic_rec e t | TCall({ etype = t } as e,_) -> is_dynamic_return t || maybe_dynamic_rec e t | TParenthesis e | TMeta(_,e) -> maybe_dynamic_mono e | TIf (_,a,Some b) -> maybe_dynamic_mono a || maybe_dynamic_mono b | _ -> false and maybe_dynamic_rec e t = match follow t with | TMono _ | TDynamic _ -> maybe_dynamic_mono e (* we might have inferenced a tmono into a single field *) | TAnon a when !(a.a_status) = Opened -> maybe_dynamic_mono e | _ -> false in match k with | KUnk | KDyn when maybe_dynamic_mono e -> unify ctx e.etype ctx.t.tfloat e.epos; false | _ -> unify ctx e.etype ctx.t.tint e.epos; true let type_generic_function ctx (e,fa) el ?(using_param=None) with_type p = let c,tl,cf,stat = match fa with | FInstance(c,tl,cf) -> c,tl,cf,false | FStatic(c,cf) -> c,[],cf,true | _ -> assert false in if cf.cf_params = [] then error "Function has no type parameters and cannot be generic" p; let monos = List.map (fun _ -> mk_mono()) cf.cf_params in let map_monos t = apply_params cf.cf_params monos t in let map t = if stat then map_monos t else apply_params c.cl_params tl (map_monos t) in let t = map cf.cf_type in let args,ret = match t,using_param with | TFun((_,_,ta) :: args,ret),Some e -> let ta = if not (Meta.has Meta.Impl cf.cf_meta) then ta else match follow ta with TAbstract(a,tl) -> Abstract.get_underlying_type a tl | _ -> assert false in (* manually unify first argument *) unify ctx e.etype ta p; args,ret | TFun(args,ret),None -> args,ret | _ -> error "Invalid field type for generic call" p in begin match with_type with | WithType t -> unify ctx ret t p | _ -> () end; let el,_ = unify_call_args ctx el args ret p false false in begin try check_constraints ctx cf.cf_name cf.cf_params monos map false p with Unify_error l -> display_error ctx (error_msg (Unify l)) p end; let el = match using_param with None -> el | Some e -> e :: el in (try let gctx = Typeload.make_generic ctx cf.cf_params monos p in let name = cf.cf_name ^ "_" ^ gctx.Typeload.name in let unify_existing_field tcf pcf = try unify_raise ctx tcf t p with Error(Unify _,_) as err -> display_error ctx ("Cannot create field " ^ name ^ " due to type mismatch") p; display_error ctx "Conflicting field was defined here" pcf; raise err in let cf2 = try let cf2 = if stat then let cf2 = PMap.find name c.cl_statics in unify_existing_field cf2.cf_type cf2.cf_pos; cf2 else let cf2 = PMap.find name c.cl_fields in unify_existing_field cf2.cf_type cf2.cf_pos; cf2 in cf2 with Not_found -> let cf2 = mk_field name (map_monos cf.cf_type) cf.cf_pos cf.cf_name_pos in if stat then begin c.cl_statics <- PMap.add name cf2 c.cl_statics; c.cl_ordered_statics <- cf2 :: c.cl_ordered_statics end else begin if List.memq cf c.cl_overrides then c.cl_overrides <- cf2 :: c.cl_overrides; c.cl_fields <- PMap.add name cf2 c.cl_fields; c.cl_ordered_fields <- cf2 :: c.cl_ordered_fields end; ignore(follow cf.cf_type); let rec check e = match e.eexpr with | TNew({cl_kind = KTypeParameter _} as c,_,_) when not (Typeload.is_generic_parameter ctx c) -> display_error ctx "Only generic type parameters can be constructed" e.epos; display_error ctx "While specializing this call" p; | _ -> Type.iter check e in cf2.cf_expr <- (match cf.cf_expr with | None -> display_error ctx "Recursive @:generic function" p; None; | Some e -> let e = Typeload.generic_substitute_expr gctx e in check e; Some e ); cf2.cf_kind <- cf.cf_kind; cf2.cf_public <- cf.cf_public; let metadata = List.filter (fun (m,_,_) -> match m with | Meta.Generic -> false | _ -> true ) cf.cf_meta in cf2.cf_meta <- (Meta.NoCompletion,[],p) :: (Meta.NoUsing,[],p) :: (Meta.GenericInstance,[],p) :: metadata; cf2 in let path = match c.cl_kind with | KAbstractImpl(a) -> a.a_path | _ -> c.cl_path in let e = if stat then type_type ctx path p else e in let fa = if stat then FStatic (c,cf2) else FInstance (c,tl,cf2) in let e = mk (TField(e,fa)) cf2.cf_type p in make_call ctx e el ret p with Typeload.Generic_Exception (msg,p) -> error msg p) let call_to_string ctx ?(resume=false) e = (* Ignore visibility of the toString field. *) ctx.meta <- (Meta.PrivateAccess,[],e.epos) :: ctx.meta; let acc = type_field ~resume ctx e "toString" e.epos MCall in ctx.meta <- List.tl ctx.meta; !build_call_ref ctx acc [] (WithType ctx.t.tstring) e.epos let rec type_binop ctx op e1 e2 is_assign_op with_type p = match op with | OpAssign -> let e1 = type_access ctx (fst e1) (snd e1) MSet in let tt = (match e1 with AKNo _ | AKInline _ | AKUsing _ | AKMacro _ | AKAccess _ -> Value | AKSet(_,t,_) -> WithType t | AKExpr e -> WithType e.etype) in let e2 = type_expr ctx e2 tt in (match e1 with | AKNo s -> error ("Cannot access field or identifier " ^ s ^ " for writing") p | AKExpr e1 -> let e2 = AbstractCast.cast_or_unify ctx e1.etype e2 p in check_assign ctx e1; (match e1.eexpr , e2.eexpr with | TLocal i1 , TLocal i2 when i1 == i2 -> error "Assigning a value to itself" p | TField ({ eexpr = TConst TThis },FInstance (_,_,f1)) , TField ({ eexpr = TConst TThis },FInstance (_,_,f2)) when f1 == f2 -> error "Assigning a value to itself" p | _ , _ -> ()); mk (TBinop (op,e1,e2)) e1.etype p | AKSet (e,t,cf) -> let e2 = AbstractCast.cast_or_unify ctx t e2 p in make_call ctx (mk (TField (e,quick_field_dynamic e.etype ("set_" ^ cf.cf_name))) (tfun [t] t) p) [e2] t p | AKAccess(a,tl,c,ebase,ekey) -> mk_array_set_call ctx (AbstractCast.find_array_access ctx a tl ekey (Some e2) p) c ebase p | AKUsing(ef,_,_,et) -> (* this must be an abstract setter *) let e2,ret = match follow ef.etype with | TFun([_;(_,_,t)],ret) -> AbstractCast.cast_or_unify ctx t e2 p,ret | _ -> error "Invalid field type for abstract setter" p in make_call ctx ef [et;e2] ret p | AKInline _ | AKMacro _ -> assert false) | OpAssignOp (OpBoolAnd | OpBoolOr) -> error "The operators ||= and &&= are not supported" p | OpAssignOp op -> (match type_access ctx (fst e1) (snd e1) MSet with | AKNo s -> error ("Cannot access field or identifier " ^ s ^ " for writing") p | AKExpr e -> let save = save_locals ctx in let v = gen_local ctx e.etype e.epos in let has_side_effect = OptimizerTexpr.has_side_effect e in let e1 = if has_side_effect then (EConst(Ident v.v_name),e.epos) else e1 in let eop = type_binop ctx op e1 e2 true with_type p in save(); (match eop.eexpr with | TBinop (_,_,e2) -> unify ctx eop.etype e.etype p; check_assign ctx e; mk (TBinop (OpAssignOp op,e,e2)) e.etype p; | TMeta((Meta.RequiresAssign,_,_),e2) -> unify ctx e2.etype e.etype p; check_assign ctx e; begin match e.eexpr with | TArray(ea1,ea2) when has_side_effect -> let v1 = gen_local ctx ea1.etype ea1.epos in let ev1 = mk (TLocal v1) v1.v_type p in let v2 = gen_local ctx ea2.etype ea2.epos in let ev2 = mk (TLocal v2) v2.v_type p in let e = {e with eexpr = TArray(ev1,ev2)} in mk (TBlock [ mk (TVar(v1,Some ea1)) ctx.t.tvoid p; mk (TVar(v2,Some ea2)) ctx.t.tvoid p; mk (TVar(v,Some e)) ctx.t.tvoid p; mk (TBinop (OpAssign,e,e2)) e.etype p; ]) e.etype p | TField(ea1,fa) when has_side_effect -> let v1 = gen_local ctx ea1.etype ea1.epos in let ev1 = mk (TLocal v1) v1.v_type p in let e = {e with eexpr = TField(ev1,fa)} in mk (TBlock [ mk (TVar(v1,Some ea1)) ctx.t.tvoid p; mk (TVar(v,Some e)) ctx.t.tvoid p; mk (TBinop (OpAssign,e,e2)) e.etype p; ]) e.etype p | _ -> mk (TBinop (OpAssign,e,e2)) e.etype p; end | _ -> (* this must be an abstract cast *) check_assign ctx e; if has_side_effect then mk (TBlock [ mk (TVar(v,Some e)) ctx.t.tvoid eop.epos; eop ]) eop.etype eop.epos else eop) | AKSet (e,t,cf) -> let l = save_locals ctx in let v = gen_local ctx e.etype e.epos in let ev = mk (TLocal v) e.etype p in let get = type_binop ctx op (EField ((EConst (Ident v.v_name),p),cf.cf_name),p) e2 true with_type p in let e' = match get.eexpr with | TBinop _ | TMeta((Meta.RequiresAssign,_,_),_) -> unify ctx get.etype t p; make_call ctx (mk (TField (ev,quick_field_dynamic ev.etype ("set_" ^ cf.cf_name))) (tfun [t] t) p) [get] t p | _ -> (* abstract setter *) get in l(); mk (TBlock [ mk (TVar (v,Some e)) ctx.t.tvoid p; e' ]) t p | AKUsing(ef,c,cf,et) -> (* abstract setter + getter *) let ta = match c.cl_kind with KAbstractImpl a -> TAbstract(a, List.map (fun _ -> mk_mono()) a.a_params) | _ -> assert false in let ret = match follow ef.etype with | TFun([_;_],ret) -> ret | _ -> error "Invalid field type for abstract setter" p in let l = save_locals ctx in let v,is_temp = match et.eexpr with | TLocal v when not (v.v_name = "this") -> v,false | _ -> gen_local ctx ta ef.epos,true in let ev = mk (TLocal v) ta p in (* this relies on the fact that cf_name is set_name *) let getter_name = String.sub cf.cf_name 4 (String.length cf.cf_name - 4) in let get = type_binop ctx op (EField ((EConst (Ident v.v_name),p),getter_name),p) e2 true with_type p in unify ctx get.etype ret p; l(); let e_call = make_call ctx ef [ev;get] ret p in if is_temp then mk (TBlock [ mk (TVar (v,Some et)) ctx.t.tvoid p; e_call ]) ret p else e_call | AKAccess(a,tl,c,ebase,ekey) -> let cf_get,tf_get,r_get,ekey,_ = AbstractCast.find_array_access ctx a tl ekey None p in (* bind complex keys to a variable so they do not make it into the output twice *) let save = save_locals ctx in let maybe_bind_to_temp e = match Optimizer.make_constant_expression ctx e with | Some e -> e,None | None -> let v = gen_local ctx e.etype p in let e' = mk (TLocal v) e.etype p in e', Some (mk (TVar (v,Some e)) ctx.t.tvoid p) in let ekey,ekey' = maybe_bind_to_temp ekey in let ebase,ebase' = maybe_bind_to_temp ebase in let eget = mk_array_get_call ctx (cf_get,tf_get,r_get,ekey,None) c ebase p in let eget = type_binop2 ctx op eget e2 true (WithType eget.etype) p in unify ctx eget.etype r_get p; let cf_set,tf_set,r_set,ekey,eget = AbstractCast.find_array_access ctx a tl ekey (Some eget) p in let eget = match eget with None -> assert false | Some e -> e in let et = type_module_type ctx (TClassDecl c) None p in let e = match cf_set.cf_expr,cf_get.cf_expr with | None,None -> let ea = mk (TArray(ebase,ekey)) r_get p in mk (TBinop(OpAssignOp op,ea,type_expr ctx e2 (WithType r_get))) r_set p | Some _,Some _ -> let ef_set = mk (TField(et,(FStatic(c,cf_set)))) tf_set p in let el = [make_call ctx ef_set [ebase;ekey;eget] r_set p] in let el = match ebase' with None -> el | Some ebase -> ebase :: el in let el = match ekey' with None -> el | Some ekey -> ekey :: el in begin match el with | [e] -> e | el -> mk (TBlock el) r_set p end | _ -> error "Invalid array access getter/setter combination" p in save(); e | AKInline _ | AKMacro _ -> assert false) | _ -> (* If the with_type is an abstract which has exactly one applicable @:op method, we can promote it to the individual arguments (issue #2786). *) let wt = match with_type with | WithType t -> begin match follow t with | TAbstract(a,_) -> begin match List.filter (fun (o,_) -> o = OpAssignOp(op) || o == op) a.a_ops with | [_] -> with_type | _ -> Value end | _ -> Value end | _ -> Value in let e1 = type_expr ctx e1 wt in type_binop2 ctx op e1 e2 is_assign_op wt p and type_binop2 ctx op (e1 : texpr) (e2 : Ast.expr) is_assign_op wt p = let e2 = type_expr ctx e2 (if op == OpEq || op == OpNotEq then WithType e1.etype else wt) in let tint = ctx.t.tint in let tfloat = ctx.t.tfloat in let tstring = ctx.t.tstring in let to_string e = let rec loop t = match classify t with | KAbstract ({a_impl = Some c},_) when PMap.mem "toString" c.cl_statics -> call_to_string ctx e | KInt | KFloat | KString -> e | KUnk | KDyn | KParam _ | KOther -> let std = type_type ctx ([],"Std") e.epos in let acc = acc_get ctx (type_field ctx std "string" e.epos MCall) e.epos in ignore(follow acc.etype); let acc = (match acc.eexpr with TField (e,FClosure (Some (c,tl),f)) -> { acc with eexpr = TField (e,FInstance (c,tl,f)) } | _ -> acc) in make_call ctx acc [e] ctx.t.tstring e.epos | KAbstract (a,tl) -> try AbstractCast.cast_or_unify_raise ctx tstring e p with Error (Unify _,_) -> loop (Abstract.get_underlying_type a tl) in loop e.etype in let mk_op e1 e2 t = if op = OpAdd && (classify t) = KString then let e1 = to_string e1 in let e2 = to_string e2 in mk (TBinop (op,e1,e2)) t p else mk (TBinop (op,e1,e2)) t p in let make e1 e2 = match op with | OpAdd -> mk_op e1 e2 (match classify e1.etype, classify e2.etype with | KInt , KInt -> tint | KFloat , KInt | KInt, KFloat | KFloat, KFloat -> tfloat | KUnk , KInt -> if unify_int ctx e1 KUnk then tint else tfloat | KUnk , KFloat | KUnk , KString -> unify ctx e1.etype e2.etype e1.epos; e1.etype | KInt , KUnk -> if unify_int ctx e2 KUnk then tint else tfloat | KFloat , KUnk | KString , KUnk -> unify ctx e2.etype e1.etype e2.epos; e2.etype | _ , KString | KString , _ -> tstring | _ , KDyn -> e2.etype | KDyn , _ -> e1.etype | KUnk , KUnk -> let ok1 = unify_int ctx e1 KUnk in let ok2 = unify_int ctx e2 KUnk in if ok1 && ok2 then tint else tfloat | KParam t1, KParam t2 when Type.type_iseq t1 t2 -> t1 | KParam t, KInt | KInt, KParam t -> t | KParam _, KFloat | KFloat, KParam _ | KParam _, KParam _ -> tfloat | KParam t, KUnk -> unify ctx e2.etype tfloat e2.epos; tfloat | KUnk, KParam t -> unify ctx e1.etype tfloat e1.epos; tfloat | KAbstract _,KFloat -> unify ctx e1.etype tfloat e1.epos; tfloat | KFloat, KAbstract _ -> unify ctx e2.etype tfloat e2.epos; tfloat | KAbstract _,KInt -> unify ctx e1.etype ctx.t.tint e1.epos; ctx.t.tint | KInt, KAbstract _ -> unify ctx e2.etype ctx.t.tint e2.epos; ctx.t.tint | KAbstract _,_ | _,KAbstract _ | KParam _, _ | _, KParam _ | KOther, _ | _ , KOther -> let pr = print_context() in error ("Cannot add " ^ s_type pr e1.etype ^ " and " ^ s_type pr e2.etype) p ) | OpAnd | OpOr | OpXor | OpShl | OpShr | OpUShr -> let i = tint in unify ctx e1.etype i e1.epos; unify ctx e2.etype i e2.epos; mk_op e1 e2 i | OpMod | OpMult | OpDiv | OpSub -> let result = ref (if op = OpDiv then tfloat else tint) in (match classify e1.etype, classify e2.etype with | KFloat, KFloat -> result := tfloat | KParam t1, KParam t2 when Type.type_iseq t1 t2 -> if op <> OpDiv then result := t1 | KParam _, KParam _ -> result := tfloat | KParam t, KInt | KInt, KParam t -> if op <> OpDiv then result := t | KParam _, KFloat | KFloat, KParam _ -> result := tfloat | KFloat, k -> ignore(unify_int ctx e2 k); result := tfloat | k, KFloat -> ignore(unify_int ctx e1 k); result := tfloat | k1 , k2 -> let ok1 = unify_int ctx e1 k1 in let ok2 = unify_int ctx e2 k2 in if not ok1 || not ok2 then result := tfloat; ); mk_op e1 e2 !result | OpEq | OpNotEq -> let e1,e2 = try (* we only have to check one type here, because unification fails if one is Void and the other is not *) (match follow e2.etype with TAbstract({a_path=[],"Void"},_) -> error "Cannot compare Void" p | _ -> ()); AbstractCast.cast_or_unify_raise ctx e2.etype e1 p,e2 with Error (Unify _,_) -> e1,AbstractCast.cast_or_unify ctx e1.etype e2 p in mk_op e1 e2 ctx.t.tbool | OpGt | OpGte | OpLt | OpLte -> (match classify e1.etype, classify e2.etype with | KInt , KInt | KInt , KFloat | KFloat , KInt | KFloat , KFloat | KString , KString -> () | KInt , KUnk -> ignore(unify_int ctx e2 KUnk) | KFloat , KUnk | KString , KUnk -> unify ctx e2.etype e1.etype e2.epos | KUnk , KInt -> ignore(unify_int ctx e1 KUnk) | KUnk , KFloat | KUnk , KString -> unify ctx e1.etype e2.etype e1.epos | KUnk , KUnk -> ignore(unify_int ctx e1 KUnk); ignore(unify_int ctx e2 KUnk); | KDyn , KInt | KDyn , KFloat | KDyn , KString -> () | KInt , KDyn | KFloat , KDyn | KString , KDyn -> () | KDyn , KDyn -> () | KParam _ , x | x , KParam _ when x <> KString && x <> KOther -> () | KAbstract _,_ | _,KAbstract _ | KDyn , KUnk | KUnk , KDyn | KString , KInt | KString , KFloat | KInt , KString | KFloat , KString | KParam _ , _ | _ , KParam _ | KOther , _ | _ , KOther -> let pr = print_context() in error ("Cannot compare " ^ s_type pr e1.etype ^ " and " ^ s_type pr e2.etype) p ); mk_op e1 e2 ctx.t.tbool | OpBoolAnd | OpBoolOr -> let b = ctx.t.tbool in unify ctx e1.etype b p; unify ctx e2.etype b p; mk_op e1 e2 b | OpInterval -> let t = Typeload.load_core_type ctx "IntIterator" in unify ctx e1.etype tint e1.epos; unify ctx e2.etype tint e2.epos; mk (TNew ((match t with TInst (c,[]) -> c | _ -> assert false),[],[e1;e2])) t p | OpArrow -> error "Unexpected =>" p | OpAssign | OpAssignOp _ -> assert false in let find_overload a c tl left = let map = apply_params a.a_params tl in let make op_cf cf e1 e2 tret = if cf.cf_expr = None then begin if not (Meta.has Meta.NoExpr cf.cf_meta) then display_error ctx "Recursive operator method" p; if not (Meta.has Meta.CoreType a.a_meta) then begin (* for non core-types we require that the return type is compatible to the native result type *) let e' = make {e1 with etype = Abstract.follow_with_abstracts e1.etype} {e1 with etype = Abstract.follow_with_abstracts e2.etype} in let t_expected = e'.etype in begin try unify_raise ctx tret t_expected p with Error (Unify _,_) -> match follow tret with | TAbstract(a,tl) when type_iseq (Abstract.get_underlying_type a tl) t_expected -> () | _ -> let st = s_type (print_context()) in error (Printf.sprintf "The result of this operation (%s) is not compatible with declared return type %s" (st t_expected) (st tret)) p end; end; let e = Codegen.binop op e1 e2 tret p in mk_cast e tret p (* Codegen.maybe_cast e tret *) end else begin let e = make_static_call ctx c cf map [e1;e2] tret p in e end in (* special case for == and !=: if the second type is a monomorph, assume that we want to unify it with the first type to preserve comparison semantics. *) let is_eq_op = match op with OpEq | OpNotEq -> true | _ -> false in if is_eq_op then begin match follow e1.etype,follow e2.etype with | TMono _,_ | _,TMono _ -> Type.unify e1.etype e2.etype | _ -> () end; let rec loop ol = match ol with | (op_cf,cf) :: ol when op_cf <> op && (not is_assign_op || op_cf <> OpAssignOp(op)) -> loop ol | (op_cf,cf) :: ol -> let is_impl = Meta.has Meta.Impl cf.cf_meta in begin match follow cf.cf_type with | TFun([(_,_,t1);(_,_,t2)],tret) -> let check e1 e2 swapped = let map_arguments () = let monos = List.map (fun _ -> mk_mono()) cf.cf_params in let map t = map (apply_params cf.cf_params monos t) in let t1 = map t1 in let t2 = map t2 in let tret = map tret in monos,t1,t2,tret in let monos,t1,t2,tret = map_arguments() in let make e1 e2 = make op_cf cf e1 e2 tret in let t1 = if is_impl then Abstract.follow_with_abstracts t1 else t1 in let e1,e2 = if left || not left && swapped then begin Type.type_eq EqStrict (if is_impl then Abstract.follow_with_abstracts e1.etype else e1.etype) t1; e1,AbstractCast.cast_or_unify_raise ctx t2 e2 p end else begin Type.type_eq EqStrict e2.etype t2; AbstractCast.cast_or_unify_raise ctx t1 e1 p,e2 end in check_constraints ctx "" cf.cf_params monos (apply_params a.a_params tl) false cf.cf_pos; let check_null e t = if is_eq_op then match e.eexpr with | TConst TNull when not (is_explicit_null t) -> raise (Unify_error []) | _ -> () in (* If either expression is `null` we only allow operator resolving if the argument type is explicitly Null (issue #3376) *) if is_eq_op then begin check_null e2 t2; check_null e1 t1; end; let e = if not swapped then make e1 e2 else if not (OptimizerTexpr.has_side_effect e1) && not (OptimizerTexpr.has_side_effect e2) then make e1 e2 else let v1,v2 = gen_local ctx t1 e1.epos, gen_local ctx t2 e2.epos in let ev1,ev2 = mk (TVar(v1,Some e1)) ctx.t.tvoid p,mk (TVar(v2,Some e2)) ctx.t.tvoid p in let eloc1,eloc2 = mk (TLocal v1) v1.v_type p,mk (TLocal v2) v2.v_type p in let e = make eloc1 eloc2 in let e = mk (TBlock [ ev2; ev1; e ]) e.etype e.epos in e in if is_assign_op && op_cf = op then (mk (TMeta((Meta.RequiresAssign,[],p),e)) e.etype e.epos) else e in begin try check e1 e2 false with Error (Unify _,_) | Unify_error _ -> try if not (Meta.has Meta.Commutative cf.cf_meta) then raise Not_found; check e2 e1 true with Not_found | Error (Unify _,_) | Unify_error _ -> loop ol end | _ -> assert false end | [] -> raise Not_found in loop (if left then a.a_ops else List.filter (fun (_,cf) -> not (Meta.has Meta.Impl cf.cf_meta)) a.a_ops) in try begin match follow e1.etype with | TAbstract({a_impl = Some c} as a,tl) -> find_overload a c tl true | _ -> raise Not_found end with Not_found -> try begin match follow e2.etype with | TAbstract({a_impl = Some c} as a,tl) -> find_overload a c tl false | _ -> raise Not_found end with Not_found -> make e1 e2 and type_unop ctx op flag e p = let set = (op = Increment || op = Decrement) in let acc = type_access ctx (fst e) (snd e) (if set then MSet else MGet) in let access e = let make e = let t = (match op with | Not -> if flag = Postfix then error "Postfix ! is not supported" p; unify ctx e.etype ctx.t.tbool e.epos; ctx.t.tbool | NegBits -> unify ctx e.etype ctx.t.tint e.epos; ctx.t.tint | Increment | Decrement | Neg -> if set then check_assign ctx e; (match classify e.etype with | KFloat -> ctx.t.tfloat | KParam t -> unify ctx e.etype ctx.t.tfloat e.epos; t | k -> if unify_int ctx e k then ctx.t.tint else ctx.t.tfloat) ) in mk (TUnop (op,flag,e)) t p in try (match follow e.etype with | TAbstract ({a_impl = Some c} as a,pl) -> let rec loop opl = match opl with | [] -> raise Not_found | (op2,flag2,cf) :: opl when op == op2 && flag == flag2 -> let m = mk_mono() in let tcf = apply_params a.a_params pl (monomorphs cf.cf_params cf.cf_type) in if Meta.has Meta.Impl cf.cf_meta then begin if type_iseq (tfun [apply_params a.a_params pl a.a_this] m) tcf then cf,tcf,m else loop opl end else if type_iseq (tfun [e.etype] m) tcf then cf,tcf,m else loop opl | _ :: opl -> loop opl in let cf,t,r = try loop a.a_unops with Not_found -> raise Not_found in (match cf.cf_expr with | None -> let e = {e with etype = apply_params a.a_params pl a.a_this} in let e = mk (TUnop(op,flag,e)) r p in (* unify ctx r e.etype p; *) (* TODO: I'm not sure why this was here (related to #2295) *) e | Some _ -> let et = type_module_type ctx (TClassDecl c) None p in let ef = mk (TField (et,FStatic (c,cf))) t p in make_call ctx ef [e] r p) | _ -> raise Not_found ) with Not_found -> make e in let rec loop acc = match acc with | AKExpr e -> access e | AKInline _ | AKUsing _ when not set -> access (acc_get ctx acc p) | AKNo s -> error ("The field or identifier " ^ s ^ " is not accessible for " ^ (if set then "writing" else "reading")) p | AKAccess(a,tl,c,ebase,ekey) -> begin try (match op with Increment | Decrement -> () | _ -> raise Not_found); let v_key = alloc_var "tmp" ekey.etype ekey.epos in let evar_key = mk (TVar(v_key,Some ekey)) ctx.com.basic.tvoid ekey.epos in let ekey = mk (TLocal v_key) ekey.etype ekey.epos in (* get *) let e_get = mk_array_get_call ctx (AbstractCast.find_array_access_raise ctx a tl ekey None p) c ebase p in let v_get = alloc_var "tmp" e_get.etype e_get.epos in let ev_get = mk (TLocal v_get) v_get.v_type p in let evar_get = mk (TVar(v_get,Some e_get)) ctx.com.basic.tvoid p in (* op *) let e_one = mk (TConst (TInt (Int32.of_int 1))) ctx.com.basic.tint p in let e_op = mk (TBinop((if op = Increment then OpAdd else OpSub),ev_get,e_one)) ev_get.etype p in (* set *) let e_set = mk_array_set_call ctx (AbstractCast.find_array_access_raise ctx a tl ekey (Some e_op) p) c ebase p in let el = evar_key :: evar_get :: e_set :: (if flag = Postfix then [ev_get] else []) in mk (TBlock el) e_set.etype p with Not_found -> let e = mk_array_get_call ctx (AbstractCast.find_array_access ctx a tl ekey None p) c ebase p in loop (AKExpr e) end | AKInline _ | AKUsing _ | AKMacro _ -> error "This kind of operation is not supported" p | AKSet (e,t,cf) -> let l = save_locals ctx in let v = gen_local ctx e.etype p in let ev = mk (TLocal v) e.etype p in let op = (match op with Increment -> OpAdd | Decrement -> OpSub | _ -> assert false) in let one = (EConst (Int "1"),p) in let eget = (EField ((EConst (Ident v.v_name),p),cf.cf_name),p) in match flag with | Prefix -> let get = type_binop ctx op eget one false Value p in unify ctx get.etype t p; l(); mk (TBlock [ mk (TVar (v,Some e)) ctx.t.tvoid p; make_call ctx (mk (TField (ev,quick_field_dynamic ev.etype ("set_" ^ cf.cf_name))) (tfun [t] t) p) [get] t p ]) t p | Postfix -> let v2 = gen_local ctx t p in let ev2 = mk (TLocal v2) t p in let get = type_expr ctx eget Value in let plusone = type_binop ctx op (EConst (Ident v2.v_name),p) one false Value p in unify ctx get.etype t p; l(); mk (TBlock [ mk (TVar (v,Some e)) ctx.t.tvoid p; mk (TVar (v2,Some get)) ctx.t.tvoid p; make_call ctx (mk (TField (ev,quick_field_dynamic ev.etype ("set_" ^ cf.cf_name))) (tfun [plusone.etype] t) p) [plusone] t p; ev2 ]) t p in loop acc and type_ident ctx i p mode = try type_ident_raise ctx i p mode with Not_found -> try (* lookup type *) if is_lower_ident i then raise Not_found; let e = (try type_type ctx ([],i) p with Error (Module_not_found ([],name),_) when name = i -> raise Not_found) in AKExpr e with Not_found -> if ctx.untyped then begin if i = "__this__" then AKExpr (mk (TConst TThis) ctx.tthis p) else let t = mk_mono() in let v = alloc_unbound_var i t p in AKExpr (mk (TLocal v) t p) end else begin if ctx.curfun = FunStatic && PMap.mem i ctx.curclass.cl_fields then error ("Cannot access " ^ i ^ " in static function") p; begin try let t = List.find (fun (i2,_) -> i2 = i) ctx.type_params in let c = match follow (snd t) with TInst(c,_) -> c | _ -> assert false in if Typeload.is_generic_parameter ctx c && Meta.has Meta.Const c.cl_meta then AKExpr (type_module_type ctx (TClassDecl c) None p) else begin display_error ctx ("Type parameter " ^ i ^ " is only available at compilation and is not a runtime value") p; AKExpr (mk (TConst TNull) t_dynamic p) end with Not_found -> let err = Unknown_ident i in if ctx.in_display then begin raise (Error (err,p)) end; match ctx.com.display.dms_kind with | DMNone -> raise (Error(err,p)) | DMDiagnostics b when b || ctx.is_display_file -> Display.ToplevelCollector.handle_unresolved_identifier ctx i p false; let t = mk_mono() in AKExpr (mk (TLocal (add_unbound_local ctx i t p)) t p) | _ -> display_error ctx (error_msg err) p; let t = mk_mono() in AKExpr (mk (TLocal (add_unbound_local ctx i t p)) t p) end end (* MORDOR *) and handle_efield ctx e p mode = let fields ?(resume=false) path e = let resume = ref resume in let force = ref false in let e = List.fold_left (fun e (f,_,p) -> let e = acc_get ctx (e MGet) p in let f = type_field ~resume:(!resume) ctx e f p in force := !resume; resume := false; f ) e path in if !force then ignore(e MCall); (* not necessarily a call, but prevent #2602 among others *) e in let type_path path = let rec loop acc path = match path with | [] -> (match List.rev acc with | [] -> assert false | (name,flag,p) :: path -> try fields path (type_ident ctx name p) with Error (Unknown_ident _,p2) as e when p = p2 -> try let path = ref [] in let name , _ , _ = List.find (fun (name,flag,p) -> if flag then true else begin path := name :: !path; false end ) (List.rev acc) in raise (Error (Module_not_found (List.rev !path,name),p)) with Not_found -> if ctx.in_display then raise (Parser.TypePath (List.map (fun (n,_,_) -> n) (List.rev acc),None,false)); raise e) | (_,false,_) as x :: path -> loop (x :: acc) path | (name,true,p) as x :: path -> let pack = List.rev_map (fun (x,_,_) -> x) acc in let def() = try let e = type_type ctx (pack,name) p in fields path (fun _ -> AKExpr e) with Error (Module_not_found m,_) when m = (pack,name) -> loop ((List.rev path) @ x :: acc) [] in match path with | (sname,true,p) :: path -> let get_static resume t = fields ~resume ((sname,true,p) :: path) (fun _ -> AKExpr (type_module_type ctx t None p)) in let check_module m v = try let md = Typeload.load_module ctx m p in (* first look for existing subtype *) (try let t = List.find (fun t -> not (t_infos t).mt_private && t_path t = (fst m,sname)) md.m_types in Some (fields path (fun _ -> AKExpr (type_module_type ctx t None p))) with Not_found -> try (* then look for main type statics *) if fst m = [] then raise Not_found; (* ensure that we use def() to resolve local types first *) let t = List.find (fun t -> not (t_infos t).mt_private && t_path t = m) md.m_types in Some (get_static false t) with Not_found -> None) with Error (Module_not_found m2,_) when m = m2 -> None in let rec loop pack = match check_module (pack,name) sname with | Some r -> r | None -> match List.rev pack with | [] -> def() | _ :: l -> loop (List.rev l) in (match pack with | [] -> (try let path_match t = snd (t_infos t).mt_path = name in let t = try List.find path_match ctx.m.curmod.m_types with Not_found -> let t,p = List.find (fun (t,_) -> path_match t) ctx.m.module_types in Display.ImportHandling.maybe_mark_import_position ctx p; t in (* if the static is not found, look for a subtype instead - #1916 *) get_static true t with Not_found -> loop (fst ctx.m.curmod.m_path)) | _ -> match check_module (pack,name) sname with | Some r -> r | None -> def()); | _ -> def() in match path with | [] -> assert false | (name,_,p) :: pnext -> try fields pnext (fun _ -> type_ident_raise ctx name p MGet) with Not_found -> loop [] path in let rec loop acc e = let p = pos e in match fst e with | EField (e,s) -> loop ((s,not (is_lower_ident s),p) :: acc) e | EConst (Ident i) -> type_path ((i,not (is_lower_ident i),p) :: acc) | _ -> fields acc (type_access ctx (fst e) (snd e)) in loop [] (e,p) mode and type_access ctx e p mode = match e with | EConst (Ident s) -> type_ident ctx s p mode | EField (e1,"new") -> let e1 = type_expr ctx e1 Value in begin match e1.eexpr with | TTypeExpr (TClassDecl c) -> if mode = MSet then error "Cannot set constructor" p; if mode = MCall then error ("Cannot call constructor like this, use 'new " ^ (s_type_path c.cl_path) ^ "()' instead") p; let monos = List.map (fun _ -> mk_mono()) c.cl_params in let ct, cf = get_constructor ctx c monos p in let args = match follow ct with TFun(args,ret) -> args | _ -> assert false in let vl = List.map (fun (n,_,t) -> alloc_var n t c.cl_pos) args in let vexpr v = mk (TLocal v) v.v_type p in let el = List.map vexpr vl in let ec,t = match c.cl_kind with | KAbstractImpl a -> let e = type_module_type ctx (TClassDecl c) None p in let e = mk (TField (e,(FStatic (c,cf)))) ct p in let t = TAbstract(a,monos) in make_call ctx e el t p,t | _ -> let t = TInst(c,monos) in mk (TNew(c,monos,el)) t p,t in AKExpr(mk (TFunction { tf_args = List.map (fun v -> v,None) vl; tf_type = t; tf_expr = mk (TReturn (Some ec)) t p; }) (TFun ((List.map (fun v -> v.v_name,false,v.v_type) vl),t)) p) | _ -> error "Binding new is only allowed on class types" p end; | EField _ -> handle_efield ctx e p mode | EArray (e1,e2) -> let e1 = type_expr ctx e1 Value in let e2 = type_expr ctx e2 Value in let has_abstract_array_access = ref false in (try (match follow e1.etype with | TAbstract ({a_impl = Some c} as a,pl) when a.a_array <> [] -> begin match mode with | MSet -> (* resolve later *) AKAccess (a,pl,c,e1,e2) | _ -> has_abstract_array_access := true; let e = mk_array_get_call ctx (AbstractCast.find_array_access ctx a pl e2 None p) c e1 p in AKExpr e end | _ -> raise Not_found) with Not_found -> unify ctx e2.etype ctx.t.tint e2.epos; let rec loop et = match follow et with | TInst ({ cl_array_access = Some t; cl_params = pl },tl) -> apply_params pl tl t | TInst ({ cl_super = Some (c,stl); cl_params = pl },tl) -> apply_params pl tl (loop (TInst (c,stl))) | TInst ({ cl_path = [],"ArrayAccess" },[t]) -> t | TInst ({ cl_path = [],"Array"},[t]) when t == t_dynamic -> t_dynamic | TAbstract(a,tl) when Meta.has Meta.ArrayAccess a.a_meta -> loop (apply_params a.a_params tl a.a_this) | _ -> let pt = mk_mono() in let t = ctx.t.tarray pt in (try unify_raise ctx et t p with Error(Unify _,_) -> if not ctx.untyped then begin if !has_abstract_array_access then error ("No @:arrayAccess function accepts an argument of " ^ (s_type (print_context()) e2.etype)) e1.epos else error ("Array access is not allowed on " ^ (s_type (print_context()) e1.etype)) e1.epos end); pt in let pt = loop e1.etype in AKExpr (mk (TArray (e1,e2)) pt p)) | _ -> AKExpr (type_expr ctx (e,p) Value) and type_vars ctx vl p = let vl = List.map (fun ((v,pv),t,e) -> try let t = Typeload.load_type_hint ctx p t in let e = (match e with | None -> None | Some e -> let e = type_expr ctx e (WithType t) in let e = AbstractCast.cast_or_unify ctx t e p in Some e ) in if v.[0] = '$' then display_error ctx "Variables names starting with a dollar are not allowed" p; let v = add_local ctx v t pv in v.v_meta <- (Meta.UserVariable,[],pv) :: v.v_meta; if ctx.in_display && Display.is_display_position pv then Display.DisplayEmitter.display_variable ctx.com.display v pv; v,e with Error (e,p) -> check_error ctx e p; add_unbound_local ctx v t_dynamic pv, None ) vl in match vl with | [v,eo] -> mk (TVar (v,eo)) ctx.t.tvoid p | _ -> let e = mk (TBlock (List.map (fun (v,e) -> (mk (TVar (v,e)) ctx.t.tvoid p)) vl)) ctx.t.tvoid p in mk (TMeta((Meta.MergeBlock,[],p), e)) e.etype e.epos and format_string ctx s p = let e = ref None in let pmin = ref p.pmin in let min = ref (p.pmin + 1) in let add_expr (enext,p) len = min := !min + len; let enext = if ctx.in_display && Display.is_display_position p then Display.ExprPreprocessing.process_expr ctx.com (enext,p) else enext,p in match !e with | None -> e := Some enext | Some prev -> e := Some (EBinop (OpAdd,prev,enext),punion (pos prev) p) in let add enext len = let p = { p with pmin = !min; pmax = !min + len } in add_expr (enext,p) len in let add_sub start pos = let len = pos - start in if len > 0 || !e = None then add (EConst (String (String.sub s start len))) len in let warn_escape = Common.defined ctx.com Define.FormatWarning in let warn pos len = ctx.com.warning "This string is formated" { p with pmin = !pmin + 1 + pos; pmax = !pmin + 1 + pos + len } in let len = String.length s in let rec parse start pos = if pos = len then add_sub start pos else let c = String.unsafe_get s pos in let pos = pos + 1 in if c = '\'' then begin incr pmin; incr min; end; if c <> '$' || pos = len then parse start pos else match String.unsafe_get s pos with | '$' -> if warn_escape then warn pos 1; (* double $ *) add_sub start pos; parse (pos + 1) (pos + 1) | '{' -> parse_group start pos '{' '}' "brace" | 'a'..'z' | 'A'..'Z' | '_' -> add_sub start (pos - 1); incr min; let rec loop i = if i = len then i else let c = String.unsafe_get s i in match c with | 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' -> loop (i+1) | _ -> i in let iend = loop (pos + 1) in let len = iend - pos in if warn_escape then warn pos len; add (EConst (Ident (String.sub s pos len))) len; parse (pos + len) (pos + len) | _ -> (* keep as-it *) parse start pos and parse_group start pos gopen gclose gname = add_sub start (pos - 1); let rec loop groups i = if i = len then match groups with | [] -> assert false | g :: _ -> error ("Unclosed " ^ gname) { p with pmin = !pmin + g + 1; pmax = !pmin + g + 2 } else let c = String.unsafe_get s i in if c = gopen then loop (i :: groups) (i + 1) else if c = gclose then begin let groups = List.tl groups in if groups = [] then i else loop groups (i + 1) end else loop groups (i + 1) in let send = loop [pos] (pos + 1) in let slen = send - pos - 1 in let scode = String.sub s (pos + 1) slen in if warn_escape then warn (pos + 1) slen; min := !min + 2; if slen > 0 then add_expr (Parser.parse_expr_string ctx.com scode { p with pmin = !pmin + pos + 2; pmax = !pmin + send + 1 } error true) slen; min := !min + 1; parse (send + 1) (send + 1) in parse 0 0; match !e with | None -> assert false | Some e -> e and type_block ctx el with_type p = let merge e = match e.eexpr with | TMeta((Meta.MergeBlock,_,_), {eexpr = TBlock el}) -> el | _ -> [e] in let rec loop = function | [] -> [] | [e] -> (try merge (type_expr ctx e with_type) with Error (e,p) -> check_error ctx e p; []) | e :: l -> try let e = type_expr ctx e NoValue in merge e @ loop l with Error (e,p) -> check_error ctx e p; loop l in let l = loop el in let rec loop = function | [] -> ctx.t.tvoid | [e] -> e.etype | _ :: l -> loop l in mk (TBlock l) (loop l) p and type_object_decl ctx fl with_type p = let dynamic_parameter = ref None in let a = (match with_type with | WithType t -> let rec loop in_abstract_from t = match follow t with | TAnon a when not (PMap.is_empty a.a_fields) && not in_abstract_from -> ODKWithStructure a | TAbstract (a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> (match List.fold_left (fun acc t -> match loop true t with ODKPlain -> acc | t -> t :: acc) [] (get_abstract_froms a pl) with | [t] -> t | _ -> ODKPlain) | TDynamic t when (follow t != t_dynamic) -> dynamic_parameter := Some t; ODKWithStructure { a_status = ref Closed; a_fields = PMap.empty; } | TInst(c,tl) when Meta.has Meta.StructInit c.cl_meta -> ODKWithClass(c,tl) | _ -> ODKPlain in loop false t | _ -> ODKPlain ) in let wrap_quoted_meta e = mk (TMeta((Meta.QuotedField,[],e.epos),e)) e.etype e.epos in let type_fields field_map = let fields = ref PMap.empty in let extra_fields = ref [] in let fl = List.map (fun ((n,pn),e) -> let n,is_quoted,is_valid = Parser.unquote_ident n in if PMap.mem n !fields then error ("Duplicate field in object declaration : " ^ n) p; let e = try let t = match !dynamic_parameter with | Some t -> t | None -> let cf = PMap.find n field_map in if ctx.in_display && Display.is_display_position pn then Display.DisplayEmitter.display_field ctx.com.display cf pn; cf.cf_type in let e = type_expr ctx e (WithType t) in let e = AbstractCast.cast_or_unify ctx t e p in (try type_eq EqStrict e.etype t; e with Unify_error _ -> mk (TCast (e,None)) t e.epos) with Not_found -> if is_valid then extra_fields := n :: !extra_fields; type_expr ctx e Value in if is_valid then begin if String.length n > 0 && n.[0] = '$' then error "Field names starting with a dollar are not allowed" p; let cf = mk_field n e.etype (punion pn e.epos) pn in fields := PMap.add n cf !fields; end; let e = if is_quoted then wrap_quoted_meta e else e in (n,e) ) fl in let t = (TAnon { a_fields = !fields; a_status = ref Const }) in if not ctx.untyped then begin (match PMap.foldi (fun n cf acc -> if not (Meta.has Meta.Optional cf.cf_meta) && not (PMap.mem n !fields) then n :: acc else acc) field_map [] with | [] -> () | [n] -> raise_or_display ctx [Unify_custom ("Object requires field " ^ n)] p | nl -> raise_or_display ctx [Unify_custom ("Object requires fields: " ^ (String.concat ", " nl))] p); (match !extra_fields with | [] -> () | _ -> raise_or_display ctx (List.map (fun n -> has_extra_field t n) !extra_fields) p); end; t, fl in (match a with | ODKPlain -> let rec loop (l,acc) ((f,pf),e) = let f,is_quoted,is_valid = Parser.unquote_ident f in if PMap.mem f acc then error ("Duplicate field in object declaration : " ^ f) p; let e = type_expr ctx e Value in (match follow e.etype with TAbstract({a_path=[],"Void"},_) -> error "Fields of type Void are not allowed in structures" e.epos | _ -> ()); let cf = mk_field f e.etype (punion pf e.epos) pf in if ctx.in_display && Display.is_display_position pf then Display.DisplayEmitter.display_field ctx.com.display cf pf; let e = if is_quoted then wrap_quoted_meta e else e in ((f,e) :: l, if is_valid then begin if String.length f > 0 && f.[0] = '$' then error "Field names starting with a dollar are not allowed" p; PMap.add f cf acc end else acc) in let fields , types = List.fold_left loop ([],PMap.empty) fl in let x = ref Const in ctx.opened <- x :: ctx.opened; mk (TObjectDecl (List.rev fields)) (TAnon { a_fields = types; a_status = x }) p | ODKWithStructure a -> let t, fl = type_fields a.a_fields in if !(a.a_status) <> Const then a.a_status := Closed; mk (TObjectDecl fl) t p | ODKWithClass (c,tl) -> let t,ctor = get_constructor ctx c tl p in let args = match follow t with | TFun(args,_) -> args | _ -> assert false in let fields = List.fold_left (fun acc (n,opt,t) -> let f = mk_field n t ctor.cf_pos ctor.cf_name_pos in if opt then f.cf_meta <- [(Meta.Optional,[],ctor.cf_pos)]; PMap.add n f acc ) PMap.empty args in let t,fl = type_fields fields in let evars,fl,_ = List.fold_left (fun (evars,elocs,had_side_effect) (s,e) -> begin match e.eexpr with | TConst _ | TTypeExpr _ | TFunction _ -> evars,(s,e) :: elocs,had_side_effect | _ -> if had_side_effect then begin let v = gen_local ctx e.etype e.epos in let ev = mk (TVar(v,Some e)) e.etype e.epos in let eloc = mk (TLocal v) v.v_type e.epos in (ev :: evars),((s,eloc) :: elocs),had_side_effect end else evars,(s,e) :: elocs,OptimizerTexpr.has_side_effect e end ) ([],[],false) (List.rev fl) in let el = List.map (fun (n,_,t) -> try List.assoc n fl with Not_found -> mk (TConst TNull) t p ) args in let e = mk (TNew(c,tl,el)) (TInst(c,tl)) p in mk (TBlock (List.rev (e :: (List.rev evars)))) e.etype e.epos ) and type_new ctx path el with_type p = let unify_constructor_call c params f ct = match follow ct with | TFun (args,r) -> (try let el,_,_ = unify_field_call ctx (FInstance(c,params,f)) el args r p false in el with Error (e,p) -> display_error ctx (error_msg e) p; []) | _ -> error "Constructor is not a function" p in let t = if (fst path).tparams <> [] then follow (Typeload.load_instance ctx path false p) else try ctx.call_argument_stack <- el :: ctx.call_argument_stack; let t = follow (Typeload.load_instance ctx path true p) in ctx.call_argument_stack <- List.tl ctx.call_argument_stack; (* Try to properly build @:generic classes here (issue #2016) *) begin match t with | TInst({cl_kind = KGeneric } as c,tl) -> follow (Typeload.build_generic ctx c p tl) | _ -> t end with Typeload.Generic_Exception _ -> (* Try to infer generic parameters from the argument list (issue #2044) *) match resolve_typedef (Typeload.load_type_def ctx p (fst path)) with | TClassDecl ({cl_constructor = Some cf} as c) -> let monos = List.map (fun _ -> mk_mono()) c.cl_params in let ct, f = get_constructor ctx c monos p in ignore (unify_constructor_call c monos f ct); begin try let t = Typeload.build_generic ctx c p monos in let map = apply_params c.cl_params monos in check_constraints ctx (s_type_path c.cl_path) c.cl_params monos map true p; t with Typeload.Generic_Exception _ as exc -> (* If we have an expected type, just use that (issue #3804) *) begin match with_type with | WithType t -> begin match follow t with | TMono _ -> raise exc | t -> t end | _ -> raise exc end end | mt -> error ((s_type_path (t_infos mt).mt_path) ^ " cannot be constructed") p in Display.DisplayEmitter.check_display_type ctx t (pos path); let build_constructor_call c tl = let ct, f = get_constructor ctx c tl p in if (Meta.has Meta.CompilerGenerated f.cf_meta) then display_error ctx (error_msg (No_constructor (TClassDecl c))) p; if not (can_access ctx c f true || is_parent c ctx.curclass) && not ctx.untyped then display_error ctx "Cannot access private constructor" p; (match f.cf_kind with | Var { v_read = AccRequire (r,msg) } -> (match msg with Some msg -> error msg p | None -> error_require r p) | _ -> ()); let el = unify_constructor_call c tl f ct in el,f,ct in try begin match t with | TInst ({cl_kind = KTypeParameter tl} as c,params) -> if not (Typeload.is_generic_parameter ctx c) then error "Only generic type parameters can be constructed" p; let el = List.map (fun e -> type_expr ctx e Value) el in let ct = (tfun (List.map (fun e -> e.etype) el) ctx.t.tvoid) in let rec loop t = match follow t with | TAnon a -> (try unify ctx (PMap.find "new" a.a_fields).cf_type ct p; true with Not_found -> false) | TAbstract({a_path = ["haxe"],"Constructible"},_) -> true | TInst({cl_kind = KTypeParameter tl},_) -> List.exists loop tl | _ -> false in if not (List.exists loop tl) then raise_error (No_constructor (TClassDecl c)) p; mk (TNew (c,params,el)) t p | TAbstract({a_impl = Some c} as a,tl) when not (Meta.has Meta.MultiType a.a_meta) -> let el,cf,ct = build_constructor_call c tl in let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in let e = mk (TTypeExpr (TClassDecl c)) ta p in let e = mk (TField (e,(FStatic (c,cf)))) ct p in make_call ctx e el t p | TInst (c,params) | TAbstract({a_impl = Some c},params) -> let el,_,_ = build_constructor_call c params in mk (TNew (c,params,el)) t p | _ -> error (s_type (print_context()) t ^ " cannot be constructed") p end with Error(No_constructor _ as err,p) when ctx.com.display.dms_display -> display_error ctx (error_msg err) p; Display.Diagnostics.secure_generated_code ctx (mk (TConst TNull) t p) and type_try ctx e1 catches with_type p = let e1 = type_expr ctx (Expr.ensure_block e1) with_type in let rec check_unreachable cases t p = match cases with | (v,e) :: cases -> let unreachable () = display_error ctx "This block is unreachable" p; let st = s_type (print_context()) in display_error ctx (Printf.sprintf "%s can be assigned to %s, which is handled here" (st t) (st v.v_type)) e.epos in begin try begin match follow t,follow v.v_type with | TDynamic _, TDynamic _ -> unreachable() | TDynamic _,_ -> () | _ -> Type.unify t v.v_type; unreachable() end with Unify_error _ -> check_unreachable cases t p end | [] -> () in let check_catch_type path params = List.iter (fun pt -> if pt != t_dynamic then error "Catch class parameter must be Dynamic" p; ) params; (match path with | x :: _ , _ -> x | [] , name -> name) in let catches = List.fold_left (fun acc ((v,pv),t,e_ast,pc) -> let t = Typeload.load_complex_type ctx true p t in let rec loop t = match follow t with | TInst ({ cl_kind = KTypeParameter _} as c,_) when not (Typeload.is_generic_parameter ctx c) -> error "Cannot catch non-generic type parameter" p | TInst ({ cl_path = path },params) | TEnum ({ e_path = path },params) -> check_catch_type path params,t | TAbstract(a,params) when Meta.has Meta.RuntimeValue a.a_meta -> check_catch_type a.a_path params,t | TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) -> loop (Abstract.get_underlying_type a tl) | TDynamic _ -> "",t | _ -> error "Catch type must be a class, an enum or Dynamic" (pos e_ast) in let name,t2 = loop t in if v.[0] = '$' then display_error ctx "Catch variable names starting with a dollar are not allowed" p; check_unreachable acc t2 (pos e_ast); let locals = save_locals ctx in let v = add_local ctx v t pv in if ctx.is_display_file && Display.is_display_position pv then Display.DisplayEmitter.display_variable ctx.com.display v pv; let e = type_expr ctx e_ast with_type in (* If the catch position is the display position it means we get completion on the catch keyword or some punctuation. Otherwise we wouldn't reach this point. *) if ctx.is_display_file && Display.is_display_position pc then ignore(display_expr ctx e_ast e with_type pc); v.v_type <- t2; locals(); if with_type <> NoValue then unify ctx e.etype e1.etype e.epos; if PMap.mem name ctx.locals then error ("Local variable " ^ name ^ " is preventing usage of this type here") e.epos; (v , e) :: acc ) [] catches in mk (TTry (e1,List.rev catches)) (if with_type = NoValue then ctx.t.tvoid else e1.etype) p and type_map_declaration ctx e1 el with_type p = let (tkey,tval,has_type) = let get_map_params t = match follow t with | TAbstract({a_path=[],"Map"},[tk;tv]) -> tk,tv,true | TInst({cl_path=["haxe";"ds"],"IntMap"},[tv]) -> ctx.t.tint,tv,true | TInst({cl_path=["haxe";"ds"],"StringMap"},[tv]) -> ctx.t.tstring,tv,true | TInst({cl_path=["haxe";"ds"],("ObjectMap" | "EnumValueMap")},[tk;tv]) -> tk,tv,true | _ -> mk_mono(),mk_mono(),false in match with_type with | WithType t -> get_map_params t | _ -> (mk_mono(),mk_mono(),false) in let keys = Hashtbl.create 0 in let check_key e_key = try let p = Hashtbl.find keys e_key.eexpr in display_error ctx "Duplicate key" e_key.epos; error "Previously defined here" p with Not_found -> Hashtbl.add keys e_key.eexpr e_key.epos; in let el = e1 :: el in let el_kv = List.map (fun e -> match fst e with | EBinop(OpArrow,e1,e2) -> e1,e2 | _ -> error "Expected a => b" (pos e) ) el in let el_k,el_v,tkey,tval = if has_type then begin let el_k,el_v = List.fold_left (fun (el_k,el_v) (e1,e2) -> let e1 = type_expr ctx e1 (WithType tkey) in check_key e1; let e1 = AbstractCast.cast_or_unify ctx tkey e1 e1.epos in let e2 = type_expr ctx e2 (WithType tval) in let e2 = AbstractCast.cast_or_unify ctx tval e2 e2.epos in (e1 :: el_k,e2 :: el_v) ) ([],[]) el_kv in el_k,el_v,tkey,tval end else begin let el_k,el_v = List.fold_left (fun (el_k,el_v) (e1,e2) -> let e1 = type_expr ctx e1 Value in check_key e1; let e2 = type_expr ctx e2 Value in (e1 :: el_k,e2 :: el_v) ) ([],[]) el_kv in let unify_min_resume el = try unify_min_raise ctx el with Error (Unify l,p) when ctx.in_call_args -> raise (WithTypeError(Unify l,p)) in let tkey = unify_min_resume el_k in let tval = unify_min_resume el_v in el_k,el_v,tkey,tval end in let m = Typeload.load_module ctx ([],"Map") null_pos in let a,c = match m.m_types with | (TAbstractDecl ({a_impl = Some c} as a)) :: _ -> a,c | _ -> assert false in let tmap = TAbstract(a,[tkey;tval]) in let cf = PMap.find "set" c.cl_statics in let v = gen_local ctx tmap p in let ev = mk (TLocal v) tmap p in let ec = type_module_type ctx (TClassDecl c) None p in let ef = mk (TField(ec,FStatic(c,cf))) (tfun [tkey;tval] ctx.t.tvoid) p in let el = ev :: List.map2 (fun e1 e2 -> (make_call ctx ef [ev;e1;e2] ctx.com.basic.tvoid p)) el_k el_v in let enew = mk (TNew(c,[tkey;tval],[])) tmap p in let el = (mk (TVar (v,Some enew)) t_dynamic p) :: (List.rev el) in mk (TBlock el) tmap p and type_local_function ctx name f with_type p = let params = Typeload.type_function_params ctx f (match name with None -> "localfun" | Some n -> n) p in if params <> [] then begin if name = None then display_error ctx "Type parameters not supported in unnamed local functions" p; if with_type <> NoValue then error "Type parameters are not supported for rvalue functions" p end; List.iter (fun tp -> if tp.tp_constraints <> [] then display_error ctx "Type parameter constraints are not supported for local functions" p) f.f_params; let inline, v = (match name with | None -> false, None | Some v when ExtString.String.starts_with v "inline_" -> true, Some (String.sub v 7 (String.length v - 7)) | Some v -> false, Some v ) in let old_tp,old_in_loop = ctx.type_params,ctx.in_loop in ctx.type_params <- params @ ctx.type_params; if not inline then ctx.in_loop <- false; let rt = Typeload.load_type_hint ctx p f.f_type in let args = List.map (fun ((s,_),opt,_,t,c) -> let t = Typeload.load_type_hint ctx p t in let t, c = Typeload.type_function_arg ctx t c opt p in s, c, t ) f.f_args in (match with_type with | WithType t -> let rec loop t = (match follow t with | TFun (args2,tr) when List.length args2 = List.length args -> List.iter2 (fun (_,_,t1) (_,_,t2) -> match follow t1 with | TMono _ -> unify ctx t2 t1 p | _ -> () ) args args2; (* unify for top-down inference unless we are expecting Void *) begin match follow tr,follow rt with | TAbstract({a_path = [],"Void"},_),_ -> () | _,TMono _ -> unify ctx rt tr p | _ -> () end | TAbstract(a,tl) -> loop (Abstract.get_underlying_type a tl) | _ -> ()) in loop t | NoValue -> if name = None then display_error ctx "Unnamed lvalue functions are not supported" p | _ -> ()); let ft = TFun (fun_args args,rt) in let v = (match v with | None -> None | Some v -> if v.[0] = '$' then display_error ctx "Variable names starting with a dollar are not allowed" p; Some (add_local ctx v ft p) (* TODO: var pos *) ) in let curfun = match ctx.curfun with | FunStatic -> FunStatic | FunMemberAbstract -> FunMemberAbstractLocal | _ -> FunMemberClassLocal in let e , fargs = Typeload.type_function ctx args rt curfun f ctx.in_display p in ctx.type_params <- old_tp; ctx.in_loop <- old_in_loop; let f = { tf_args = fargs; tf_type = rt; tf_expr = e; } in let e = mk (TFunction f) ft p in (match v with | None -> e | Some v -> if params <> [] || inline then v.v_extra <- Some (params,if inline then Some e else None); let rec loop = function | Filters.Block f | Filters.Loop f | Filters.Function f -> f loop | Filters.Use v2 | Filters.Assign v2 when v == v2 -> raise Exit | Filters.Use _ | Filters.Assign _ | Filters.Declare _ -> () in let is_rec = (try Filters.local_usage loop e; false with Exit -> true) in let decl = (if is_rec then begin if inline then display_error ctx "Inline function cannot be recursive" e.epos; let vnew = add_local ctx v.v_name ft v.v_pos in mk (TVar (vnew,Some (mk (TBlock [ mk (TVar (v,Some (mk (TConst TNull) ft p))) ctx.t.tvoid p; mk (TBinop (OpAssign,mk (TLocal v) ft p,e)) ft p; mk (TLocal v) ft p ]) ft p))) ctx.t.tvoid p end else if inline then mk (TBlock []) ctx.t.tvoid p (* do not add variable since it will be inlined *) else mk (TVar (v,Some e)) ctx.t.tvoid p ) in if with_type <> NoValue && not inline then mk (TBlock [decl;mk (TLocal v) v.v_type p]) v.v_type p else decl) and type_array_decl ctx el with_type p = let tp = (match with_type with | WithType t -> let rec loop t = (match follow t with | TInst ({ cl_path = [],"Array" },[tp]) -> (match follow tp with | TMono _ -> None | _ -> Some tp) | TAnon _ -> (try Some (get_iterable_param t) with Not_found -> None) | TAbstract (a,pl) -> (match List.fold_left (fun acc t -> match loop t with None -> acc | Some t -> t :: acc) [] (get_abstract_froms a pl) with | [t] -> Some t | _ -> None) | t -> if t == t_dynamic then Some t else None) in loop t | _ -> None ) in (match tp with | None -> let el = List.map (fun e -> type_expr ctx e Value) el in let t = try unify_min_raise ctx el with Error (Unify l,p) -> if ctx.untyped || ctx.com.display.dms_error_policy = EPIgnore then t_dynamic else begin display_error ctx "Arrays of mixed types are only allowed if the type is forced to Array" p; raise (Error (Unify l, p)) end in mk (TArrayDecl el) (ctx.t.tarray t) p | Some t -> let el = List.map (fun e -> let e = type_expr ctx e (WithType t) in AbstractCast.cast_or_unify ctx t e p; ) el in mk (TArrayDecl el) (ctx.t.tarray t) p) and type_expr ctx (e,p) (with_type:with_type) = match e with | EField ((EConst (String s),ps),"code") -> if UTF8.length s <> 1 then error "String must be a single UTF8 char" ps; mk (TConst (TInt (Int32.of_int (UChar.code (UTF8.get s 0))))) ctx.t.tint p | EField(_,n) when n.[0] = '$' -> error "Field names starting with $ are not allowed" p | EConst (Ident s) -> if s = "super" && with_type <> NoValue && not ctx.in_display then error "Cannot use super as value" p; let e = maybe_type_against_enum ctx (fun () -> type_ident ctx s p MGet) with_type p in acc_get ctx e p | EField _ | EArray _ -> acc_get ctx (type_access ctx e p MGet) p | EConst (Regexp (r,opt)) -> let str = mk (TConst (TString r)) ctx.t.tstring p in let opt = mk (TConst (TString opt)) ctx.t.tstring p in let t = Typeload.load_core_type ctx "EReg" in mk (TNew ((match t with TInst (c,[]) -> c | _ -> assert false),[],[str;opt])) t p | EConst (String s) when s <> "" && Lexer.is_fmt_string p -> type_expr ctx (format_string ctx s p) with_type | EConst c -> Codegen.type_constant ctx.com c p | EBinop (op,e1,e2) -> type_binop ctx op e1 e2 false with_type p | EBlock [] when with_type <> NoValue -> type_expr ctx (EObjectDecl [],p) with_type | EBlock l -> let locals = save_locals ctx in let e = type_block ctx l with_type p in locals(); e | EParenthesis e -> let e = type_expr ctx e with_type in mk (TParenthesis e) e.etype p | EObjectDecl fl -> type_object_decl ctx fl with_type p | EArrayDecl [(EFor _,_) | (EWhile _,_) as e] -> let v = gen_local ctx (mk_mono()) p in let et = ref (EConst(Ident "null"),p) in let rec map_compr (e,p) = match e with | EFor(it,e2) -> (EFor (it, map_compr e2),p) | EWhile(cond,e2,flag) -> (EWhile (cond,map_compr e2,flag),p) | EIf (cond,e2,None) -> (EIf (cond,map_compr e2,None),p) | EBlock [e] -> (EBlock [map_compr e],p) | EParenthesis e2 -> (EParenthesis (map_compr e2),p) | EBinop(OpArrow,a,b) -> et := (ENew(({tpackage=[];tname="Map";tparams=[];tsub=None},null_pos),[]),p); (ECall ((EField ((EConst (Ident v.v_name),p),"set"),p),[a;b]),p) | _ -> et := (EArrayDecl [],p); (ECall ((EField ((EConst (Ident v.v_name),p),"push"),p),[(e,p)]),p) in let e = map_compr e in let ea = type_expr ctx !et with_type in unify ctx v.v_type ea.etype p; let efor = type_expr ctx e NoValue in mk (TBlock [ mk (TVar (v,Some ea)) ctx.t.tvoid p; efor; mk (TLocal v) v.v_type p; ]) v.v_type p | EArrayDecl ((EBinop(OpArrow,_,_),_) as e1 :: el) -> type_map_declaration ctx e1 el with_type p | EArrayDecl el -> type_array_decl ctx el with_type p | EVars vl -> type_vars ctx vl p | EFor (it,e2) -> let rec loop_ident display e1 = match e1 with | EConst(Ident i),p -> i,p,display | EDisplay(e1,_),_ -> loop_ident true e1 | _ -> error "Identifier expected" (pos e1) in let rec loop display e1 = match fst e1 with | EIn(e1,e2) -> loop_ident display e1,e2 | EDisplay(e1,_) -> loop true e1 | _ -> error "For expression should be 'v in expr'" (snd it) in let (i, pi, display), e1 = loop false it in let e1 = type_expr ctx e1 Value in let old_loop = ctx.in_loop in let old_locals = save_locals ctx in ctx.in_loop <- true; let e2 = Expr.ensure_block e2 in let default() = let t, pt = Typeload.t_iterator ctx in let i = add_local ctx i pt pi in let e1 = (match follow e1.etype with | TMono _ | TDynamic _ -> display_error ctx "You can't iterate on a Dynamic value, please specify Iterator or Iterable" e1.epos; e1 | TLazy _ -> assert false | _ -> (try AbstractCast.cast_or_unify_raise ctx t e1 p with Error (Unify _,_) -> let acc = build_call ctx (type_field ctx e1 "iterator" e1.epos MCall) [] Value e1.epos in try unify_raise ctx acc.etype t acc.epos; acc with Error (Unify(l),p) -> display_error ctx "Field iterator has an invalid type" acc.epos; display_error ctx (error_msg (Unify l)) p; mk (TConst TNull) t_dynamic p ) ) in if display then ignore(handle_display ctx (EConst(Ident i.v_name),i.v_pos) (WithType i.v_type)); let e2 = type_expr ctx e2 NoValue in (try Optimizer.optimize_for_loop_iterator ctx i e1 e2 p with Exit -> mk (TFor (i,e1,e2)) ctx.t.tvoid p) in let e = match Optimizer.optimize_for_loop ctx (i,pi) e1 e2 p with | Some e -> if display then ignore(handle_display ctx (EConst(Ident i),pi) Value); e | None -> default() in ctx.in_loop <- old_loop; old_locals(); e | EIn _ -> error "This expression is not allowed outside a for loop" p | ETernary (e1,e2,e3) -> type_expr ctx (EIf (e1,e2,Some e3),p) with_type | EIf (e,e1,e2) -> let e = type_expr ctx e Value in let e = AbstractCast.cast_or_unify ctx ctx.t.tbool e p in let e1 = type_expr ctx (Expr.ensure_block e1) with_type in (match e2 with | None -> mk (TIf (e,e1,None)) ctx.t.tvoid p | Some e2 -> let e2 = type_expr ctx (Expr.ensure_block e2) with_type in let e1,e2,t = match with_type with | NoValue -> e1,e2,ctx.t.tvoid | Value -> e1,e2,unify_min ctx [e1; e2] | WithType t when (match follow t with TMono _ -> true | _ -> false) -> e1,e2,unify_min ctx [e1; e2] | WithType t -> let e1 = AbstractCast.cast_or_unify ctx t e1 e1.epos in let e2 = AbstractCast.cast_or_unify ctx t e2 e2.epos in e1,e2,t in mk (TIf (e,e1,Some e2)) t p) | EWhile (cond,e,NormalWhile) -> let old_loop = ctx.in_loop in let cond = type_expr ctx cond Value in let cond = AbstractCast.cast_or_unify ctx ctx.t.tbool cond p in ctx.in_loop <- true; let e = type_expr ctx (Expr.ensure_block e) NoValue in ctx.in_loop <- old_loop; mk (TWhile (cond,e,NormalWhile)) ctx.t.tvoid p | EWhile (cond,e,DoWhile) -> let old_loop = ctx.in_loop in ctx.in_loop <- true; let e = type_expr ctx (Expr.ensure_block e) NoValue in ctx.in_loop <- old_loop; let cond = type_expr ctx cond Value in let cond = AbstractCast.cast_or_unify ctx ctx.t.tbool cond cond.epos in mk (TWhile (cond,e,DoWhile)) ctx.t.tvoid p | ESwitch (e1,cases,def) -> let wrap e1 = mk (TMeta((Meta.Ast,[e,p],p),e1)) e1.etype e1.epos in let e = match_expr ctx e1 cases def with_type p in wrap e | EReturn e -> begin match e with | None -> let v = ctx.t.tvoid in unify ctx v ctx.ret p; mk (TReturn None) t_dynamic p | Some e -> let e = type_expr ctx e (WithType ctx.ret) in let e = AbstractCast.cast_or_unify ctx ctx.ret e p in begin match follow e.etype with | TAbstract({a_path=[],"Void"},_) -> (* if we get a Void expression (e.g. from inlining) we don't want to return it (issue #4323) *) mk (TBlock [ e; mk (TReturn None) t_dynamic p ]) t_dynamic e.epos; | _ -> mk (TReturn (Some e)) t_dynamic p end end | EBreak -> if not ctx.in_loop then display_error ctx "Break outside loop" p; mk TBreak t_dynamic p | EContinue -> if not ctx.in_loop then display_error ctx "Continue outside loop" p; mk TContinue t_dynamic p | ETry (e1,[]) -> type_expr ctx e1 with_type | ETry (e1,catches) -> type_try ctx e1 catches with_type p | EThrow e -> let e = type_expr ctx e Value in mk (TThrow e) (mk_mono()) p | ECall (e,el) -> type_call ctx e el with_type p | ENew (t,el) -> type_new ctx t el with_type p | EUnop (op,flag,e) -> type_unop ctx op flag e p | EFunction (name,f) -> type_local_function ctx name f with_type p | EUntyped e -> let old = ctx.untyped in ctx.untyped <- true; if not (Meta.has Meta.HasUntyped ctx.curfield.cf_meta) then ctx.curfield.cf_meta <- (Meta.HasUntyped,[],p) :: ctx.curfield.cf_meta; let e = type_expr ctx e with_type in ctx.untyped <- old; { eexpr = e.eexpr; etype = mk_mono(); epos = e.epos; } | ECast (e,None) -> let e = type_expr ctx e Value in mk (TCast (e,None)) (mk_mono()) p | ECast (e, Some t) -> let t = Typeload.load_complex_type ctx true p t in let check_param pt = match follow pt with | TMono _ -> () (* This probably means that Dynamic wasn't bound (issue #4675). *) | t when t == t_dynamic -> () | _ ->error "Cast type parameters must be Dynamic" p in let rec loop t = match follow t with | TInst (_,params) | TEnum (_,params) -> List.iter check_param params; (match follow t with | TInst (c,_) -> (match c.cl_kind with KTypeParameter _ -> error "Can't cast to a type parameter" p | _ -> ()); TClassDecl c | TEnum (e,_) -> TEnumDecl e | _ -> assert false); | TAbstract (a,params) when Meta.has Meta.RuntimeValue a.a_meta -> List.iter check_param params; TAbstractDecl a | TAbstract (a,params) -> loop (Abstract.get_underlying_type a params) | _ -> error "Cast type must be a class or an enum" p in let texpr = loop t in mk (TCast (type_expr ctx e Value,Some texpr)) t p | EDisplay (e,iscall) -> begin match ctx.com.display.dms_kind with | DMField | DMSignature when iscall -> handle_signature_display ctx e with_type | _ -> handle_display ctx e with_type end | EDisplayNew t -> assert false (*let t = Typeload.load_instance ctx t true p in (match follow t with | TInst (c,params) | TAbstract({a_impl = Some c},params) -> let ct, f = get_constructor ctx c params p in raise (Display.DisplaySignatures ((ct,f.cf_doc) :: List.map (fun f -> (f.cf_type,f.cf_doc)) f.cf_overloads)) | _ -> error "Not a class" p)*) | ECheckType (e,t) -> let t = Typeload.load_complex_type ctx true p t in let e = type_expr ctx e (WithType t) in let e = AbstractCast.cast_or_unify ctx t e p in if e.etype == t then e else mk (TCast (e,None)) t p | EMeta (m,e1) -> if ctx.is_display_file then Display.DisplayEmitter.check_display_metadata ctx [m]; let old = ctx.meta in ctx.meta <- m :: ctx.meta; let e () = type_expr ctx e1 with_type in let e = match m with | (Meta.ToString,_,_) -> let e = e() in (match follow e.etype with | TAbstract({a_impl = Some c},_) when PMap.mem "toString" c.cl_statics -> call_to_string ctx e | _ -> e) | (Meta.This,_,_) -> let e = match ctx.this_stack with | [] -> error "Cannot type @:this this here" p | e :: _ -> e in let rec loop e = match e.eexpr with | TConst TThis -> get_this ctx e.epos | _ -> Type.map_expr loop e in loop e | (Meta.Analyzer,_,_) -> let e = e() in {e with eexpr = TMeta(m,e)} | (Meta.MergeBlock,_,_) -> begin match fst e1 with | EBlock el -> let e = type_block ctx el with_type p in {e with eexpr = TMeta(m,e)} | _ -> e() end | (Meta.StoredTypedExpr,_,_) -> let id = match e1 with (EConst (Int s),_) -> int_of_string s | _ -> assert false in MacroContext.get_stored_typed_expr ctx.com id | (Meta.NoPrivateAccess,_,_) -> ctx.meta <- List.filter (fun(m,_,_) -> m <> Meta.PrivateAccess) ctx.meta; e() | (Meta.Fixed,_,_) when ctx.com.platform=Cpp -> let e = e() in {e with eexpr = TMeta(m,e)} | _ -> e() in ctx.meta <- old; e and get_submodule_fields ctx path = let m = Hashtbl.find ctx.g.modules path in let tl = List.filter (fun t -> path <> (t_infos t).mt_path && not (t_infos t).mt_private) m.m_types in let tl = List.map (fun mt -> let infos = t_infos mt in (snd infos.mt_path),Display.FKType (type_of_module_type mt),infos.mt_doc ) tl in tl and handle_display ctx e_ast with_type = let old = ctx.in_display,ctx.in_call_args in ctx.in_display <- true; ctx.in_call_args <- false; let e = match e_ast,with_type with | (EConst (Ident "$type"),_),_ -> let mono = mk_mono() in raise (Display.DisplaySignatures ([((["expression",false,mono],mono),Some "Outputs type of argument as a warning and uses argument as value")],0)) | (EConst (Ident "trace"),_),_ -> raise (Display.DisplaySignatures ([((["value",false,t_dynamic],ctx.com.basic.tvoid),Some "Print given arguments")],0)) | (EConst (Ident "_"),p),WithType t -> mk (TConst TNull) t p (* This is "probably" a bind skip, let's just use the expected type *) | _ -> try type_expr ctx e_ast with_type with Error (Unknown_ident n,_) -> raise (Parser.TypePath ([n],None,false)) | Error (Type_not_found (path,_),_) as err -> begin try raise (Display.DisplayFields (get_submodule_fields ctx path)) with Not_found -> raise err end in let p = e.epos in let e = match with_type with | WithType t -> (try AbstractCast.cast_or_unify_raise ctx t e e.epos with Error (Unify l,p) -> e) | _ -> e in ctx.in_display <- fst old; ctx.in_call_args <- snd old; display_expr ctx e_ast e with_type p and handle_signature_display ctx e_ast with_type = ctx.in_display <- true; let p = pos e_ast in let find_constructor_types t = match follow t with | TInst (c,tl) | TAbstract({a_impl = Some c},tl) -> let ct,cf = get_constructor ctx c tl p in let tl = (ct,cf.cf_doc) :: List.rev_map (fun cf' -> cf'.cf_type,cf.cf_doc) cf.cf_overloads in tl | _ -> [] in let tl,el,p0 = match fst e_ast with | ECall(e1,el) -> let e1 = try type_expr ctx e1 Value with Error (Unknown_ident "trace",_) -> let e = expr_of_type_path (["haxe";"Log"],"trace") p in type_expr ctx e Value in let tl = match e1.eexpr with | TField(_,fa) -> begin match extract_field fa with | Some cf -> (e1.etype,cf.cf_doc) :: List.rev_map (fun cf' -> cf'.cf_type,cf.cf_doc) cf.cf_overloads | None -> [e1.etype,None] end | TConst TSuper -> find_constructor_types e1.etype | _ -> [e1.etype,None] in tl,el,e1.epos | ENew(tpath,el) -> let t = Typeload.load_instance ctx tpath true p in find_constructor_types t,el,pos tpath | _ -> error "Call expected" p in let rec follow_with_callable (t,doc) = match follow t with | TAbstract(a,tl) when Meta.has Meta.Callable a.a_meta -> follow_with_callable (Abstract.get_underlying_type a tl,doc) | TFun(args,ret) -> ((args,ret),doc) | _ -> error ("Not a callable type: " ^ (s_type (print_context()) t)) p in let tl = List.map follow_with_callable tl in let rec loop i p1 el = match el with | (e,p2) :: el -> if Display.is_display_position (punion p1 p2) then i else loop (i + 1) p2 el | [] -> i in let display_arg = loop 0 p0 el in (* If our display position exceeds the argument number we add a null expression in order to make unify_call_args error out. *) let el = if display_arg >= List.length el then el @ [EConst (Ident "null"),null_pos] else el in let rec loop acc tl = match tl with | (t,doc) :: tl -> let keep (args,r) = begin try let _ = unify_call_args' ctx el args r p false false in true with | Error(Call_error (Not_enough_arguments _),_) -> true | _ -> false end in loop (if keep t then (t,doc) :: acc else acc) tl | [] -> acc in let overloads = match loop [] tl with [] -> tl | tl -> tl in raise (Display.DisplaySignatures(overloads,display_arg)) and display_expr ctx e_ast e with_type p = let get_super_constructor () = match ctx.curclass.cl_super with | None -> error "Current class does not have a super" p | Some (c,params) -> let _, f = get_constructor ctx c params p in f in match ctx.com.display.dms_kind with | DMResolve _ | DMPackage | DMSignature -> assert false | DMType -> let rec loop e = match e.eexpr with | TVar(v,_) -> v.v_type,None | TCall({eexpr = TConst TSuper; etype = t},_) -> t,None | TNew({cl_kind = KAbstractImpl a},tl,_) -> TType(abstract_module_type a tl,[]),None | TNew(c,tl,_) -> TInst(c,tl),None | TTypeExpr (TClassDecl {cl_kind = KAbstractImpl a}) -> TType(abstract_module_type a (List.map snd a.a_params),[]),None | TField(e1,FDynamic "bind") when (match follow e1.etype with TFun _ -> true | _ -> false) -> e1.etype,None | TReturn (Some e1) -> loop e1 (* No point in letting the internal Dynamic surface (issue #5655) *) | TField(_,(FStatic(c,cf) | FInstance(c,_,cf) | FClosure(Some(c,_),cf))) -> if Meta.has Meta.CoreApi c.cl_meta then merge_core_doc ctx c; e.etype,cf.cf_doc | TField(_,FEnum(_,ef)) -> e.etype,ef.ef_doc | _ -> e.etype,None in let t,doc = loop e in raise (Display.DisplayType (t,p,doc)) | DMUsage _ -> let rec loop e = match e.eexpr with | TField(_,FEnum(_,ef)) -> ef.ef_meta <- (Meta.Usage,[],p) :: ef.ef_meta; | TField(_,(FAnon cf | FInstance (_,_,cf) | FStatic (_,cf) | FClosure (_,cf))) -> cf.cf_meta <- (Meta.Usage,[],p) :: cf.cf_meta; | TLocal v | TVar(v,_) -> v.v_meta <- (Meta.Usage,[],p) :: v.v_meta; | TTypeExpr mt -> let ti = t_infos mt in ti.mt_meta <- (Meta.Usage,[],p) :: ti.mt_meta; | TNew(c,tl,_) -> begin try let _,cf = get_constructor ctx c tl p in cf.cf_meta <- (Meta.Usage,[],p) :: cf.cf_meta; with Not_found -> () end | TCall({eexpr = TConst TSuper},_) -> begin try let cf = get_super_constructor() in cf.cf_meta <- (Meta.Usage,[],p) :: cf.cf_meta; with Not_found -> () end | TConst TSuper -> begin match ctx.curclass.cl_super with | None -> () | Some (c,_) -> c.cl_meta <- (Meta.Usage,[],p) :: c.cl_meta; end | TCall(e1,_) -> loop e1 | _ -> () in loop e; e | DMPosition -> let rec loop e = match e.eexpr with | TField(_,FEnum(_,ef)) -> [ef.ef_pos] | TField(_,(FAnon cf | FInstance (_,_,cf) | FStatic (_,cf) | FClosure (_,cf))) -> [cf.cf_pos] | TLocal v | TVar(v,_) -> [v.v_pos] | TTypeExpr mt -> [(t_infos mt).mt_pos] | TNew(c,tl,_) -> begin try let _,cf = get_constructor ctx c tl p in [cf.cf_pos] with Not_found -> [] end | TCall({eexpr = TConst TSuper},_) -> begin try let cf = get_super_constructor() in [cf.cf_pos] with Not_found -> [] end | TConst TSuper -> begin match ctx.curclass.cl_super with | None -> [] | Some (c,_) -> [c.cl_pos] end | TCall(e1,_) -> loop e1 | _ -> [] in let pl = loop e in raise (Display.DisplayPosition pl); | DMToplevel -> raise (Display.DisplayToplevel (Display.ToplevelCollector.run ctx false)) | DMField | DMNone | DMModuleSymbols _ | DMDiagnostics _ | DMStatistics -> let opt_args args ret = TFun(List.map(fun (n,o,t) -> n,true,t) args,ret) in let e = match e.eexpr with | TField (e1,fa) -> if field_name fa = "bind" then (match follow e1.etype with | TFun(args,ret) -> {e1 with etype = opt_args args ret} | _ -> e) else e | _ -> e in let opt_type t = match t with | TLazy f -> Typeload.return_partial_type := true; let t = (!f)() in Typeload.return_partial_type := false; t | _ -> t in let should_access c cf stat = if c != ctx.curclass && not cf.cf_public && String.length cf.cf_name > 4 then begin match String.sub cf.cf_name 0 4 with | "get_" | "set_" -> false | _ -> can_access ctx c cf stat end else can_access ctx c cf stat in let rec get_fields t = match follow t with | TInst (c,params) -> if Meta.has Meta.CoreApi c.cl_meta then merge_core_doc ctx c; let merge ?(cond=(fun _ -> true)) a b = PMap.foldi (fun k f m -> if cond f then PMap.add k f m else m) a b in let rec loop c params = let m = List.fold_left (fun m (i,params) -> merge m (loop i params) ) PMap.empty c.cl_implements in let m = (match c.cl_super with | None -> m | Some (csup,cparams) -> merge m (loop csup cparams) ) in let m = merge ~cond:(fun f -> should_access c f false) c.cl_fields m in let m = (match c.cl_kind with | KTypeParameter pl -> List.fold_left (fun acc t -> merge acc (get_fields t)) m pl | _ -> m ) in PMap.map (fun f -> { f with cf_type = apply_params c.cl_params params (opt_type f.cf_type); cf_public = true; }) m in loop c params | TAbstract({a_impl = Some c} as a,pl) -> if Meta.has Meta.CoreApi c.cl_meta then merge_core_doc ctx c; let fields = try let _,el,_ = Meta.get Meta.Forward a.a_meta in let sl = ExtList.List.filter_map (fun e -> match fst e with | EConst(Ident s) -> Some s | _ -> None ) el in let fields = get_fields (apply_params a.a_params pl a.a_this) in if sl = [] then fields else PMap.fold (fun cf acc -> if List.mem cf.cf_name sl then PMap.add cf.cf_name cf acc else acc ) fields PMap.empty with Not_found -> PMap.empty in PMap.fold (fun f acc -> if f.cf_name <> "_new" && should_access c f true && Meta.has Meta.Impl f.cf_meta && not (Meta.has Meta.Enum f.cf_meta) then begin let f = prepare_using_field f in let t = apply_params a.a_params pl (follow f.cf_type) in PMap.add f.cf_name { f with cf_public = true; cf_type = opt_type t } acc end else acc ) c.cl_statics fields | TAnon a when PMap.is_empty a.a_fields -> begin match with_type with | WithType t -> get_fields t | _ -> a.a_fields end | TAnon a -> (match !(a.a_status) with | Statics c -> if Meta.has Meta.CoreApi c.cl_meta then merge_core_doc ctx c; let is_abstract_impl = match c.cl_kind with KAbstractImpl _ -> true | _ -> false in let pm = match c.cl_constructor with None -> PMap.empty | Some cf -> PMap.add "new" cf PMap.empty in PMap.fold (fun f acc -> if should_access c f true && (not is_abstract_impl || not (Meta.has Meta.Impl f.cf_meta) || Meta.has Meta.Enum f.cf_meta) then PMap.add f.cf_name { f with cf_public = true; cf_type = opt_type f.cf_type } acc else acc ) a.a_fields pm | _ -> a.a_fields) | TFun (args,ret) -> let t = opt_args args ret in let cf = mk_field "bind" (tfun [t] t) p null_pos in PMap.add "bind" cf PMap.empty | _ -> PMap.empty in let fields = get_fields e.etype in (* add 'using' methods compatible with this type *) let rec loop acc = function | [] -> acc | (c,_) :: l -> let acc = ref (loop acc l) in let rec dup t = Type.map dup t in List.iter (fun f -> if not (Meta.has Meta.NoUsing f.cf_meta) then let f = { f with cf_type = opt_type f.cf_type } in let monos = List.map (fun _ -> mk_mono()) f.cf_params in let map = apply_params f.cf_params monos in match follow (map f.cf_type) with | TFun((_,_,TType({t_path=["haxe";"macro"], "ExprOf"}, [t])) :: args, ret) | TFun((_,_,t) :: args, ret) -> (try unify_raise ctx (dup e.etype) t e.epos; List.iter2 (fun m (name,t) -> match follow t with | TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] -> List.iter (fun tc -> unify_raise ctx m (map tc) e.epos) constr | _ -> () ) monos f.cf_params; if not (can_access ctx c f true) || follow e.etype == t_dynamic && follow t != t_dynamic then () else begin let f = prepare_using_field f in let f = { f with cf_params = []; cf_public = true; cf_type = TFun(args,ret) } in acc := PMap.add f.cf_name f (!acc) end with Error (Unify _,_) -> ()) | _ -> () ) c.cl_ordered_statics; !acc in let use_methods = match follow e.etype with TMono _ -> PMap.empty | _ -> loop (loop PMap.empty ctx.g.global_using) ctx.m.module_using in let fields = PMap.fold (fun f acc -> PMap.add f.cf_name f acc) fields use_methods in let fields = match fst e_ast with | EConst(String s) when String.length s = 1 -> let cf = mk_field "code" ctx.t.tint e.epos null_pos in cf.cf_doc <- Some "The character code of this character (inlined at compile-time)."; cf.cf_kind <- Var { v_read = AccNormal; v_write = AccNever }; PMap.add cf.cf_name cf fields | _ -> fields in let fields = PMap.fold (fun f acc -> if Meta.has Meta.NoCompletion f.cf_meta then acc else f :: acc) fields [] in let get_field acc f = List.fold_left (fun acc f -> let kind = match f.cf_kind with Method _ -> Display.FKMethod f.cf_type | Var _ -> Display.FKVar f.cf_type in if f.cf_public then (f.cf_name,kind,f.cf_doc) :: acc else acc ) acc (f :: f.cf_overloads) in let fields = List.fold_left get_field [] fields in let fields = try let sl = string_list_of_expr_path_raise e_ast in fields @ get_submodule_fields ctx (List.tl sl,List.hd sl) with Exit | Not_found -> fields in raise (Display.DisplayFields fields) and maybe_type_against_enum ctx f with_type p = try begin match with_type with | WithType t -> let rec loop stack t = match follow t with | TEnum (en,_) -> en.e_path,en.e_names,TEnumDecl en | TAbstract ({a_impl = Some c} as a,_) when has_meta Meta.Enum a.a_meta -> let fields = ExtList.List.filter_map (fun cf -> if Meta.has Meta.Enum cf.cf_meta then Some cf.cf_name else None ) c.cl_ordered_statics in a.a_path,fields,TAbstractDecl a | TAbstract (a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> begin match get_abstract_froms a pl with | [t2] -> if (List.exists (fast_eq t) stack) then raise Exit; loop (t :: stack) t2 | _ -> raise Exit end (* We might type against an enum constructor. *) | TFun(_,tr) -> loop stack tr | _ -> raise Exit in let path,fields,mt = loop [] t in let old = ctx.m.curmod.m_types in let restore () = ctx.m.curmod.m_types <- old in ctx.m.curmod.m_types <- ctx.m.curmod.m_types @ [mt]; let e = try f() with | Error (Unknown_ident n,_) -> restore(); raise_or_display_message ctx (StringError.string_error n fields ("Identifier '" ^ n ^ "' is not part of " ^ s_type_path path)) p; AKExpr (mk (TConst TNull) (mk_mono()) p) | exc -> restore(); raise exc; in restore(); e | _ -> raise Exit end with Exit -> f() and type_call ctx e el (with_type:with_type) p = let def () = let e = maybe_type_against_enum ctx (fun () -> type_access ctx (fst e) (snd e) MCall) with_type p in let e = build_call ctx e el with_type p in e in match e, el with | (EConst (Ident "trace"),p) , e :: el -> if Common.defined ctx.com Define.NoTraces then null ctx.t.tvoid p else let mk_to_string_meta e = EMeta((Meta.ToString,[],null_pos),e),pos e in let params = (match el with [] -> [] | _ -> [("customParams",null_pos),(EArrayDecl (List.map mk_to_string_meta el) , p)]) in let infos = mk_infos ctx p params in if (platform ctx.com Js || platform ctx.com Python) && el = [] && has_dce ctx.com then let e = type_expr ctx e Value in let infos = type_expr ctx infos Value in let e = match follow e.etype with | TAbstract({a_impl = Some c},_) when PMap.mem "toString" c.cl_statics -> call_to_string ctx e | _ -> e in let v_trace = alloc_unbound_var "`trace" t_dynamic p in mk (TCall (mk (TLocal v_trace) t_dynamic p,[e;infos])) ctx.t.tvoid p else type_expr ctx (ECall ((EField ((EField ((EConst (Ident "haxe"),p),"Log"),p),"trace"),p),[mk_to_string_meta e;infos]),p) NoValue | (EConst(Ident "callback"),p1),args -> let ecb = try Some (type_ident_raise ctx "callback" p1 MCall) with Not_found -> None in (match ecb with | Some ecb -> build_call ctx ecb args with_type p | None -> display_error ctx "callback syntax has changed to func.bind(args)" p; let e = type_expr ctx e Value in type_bind ctx e args p) | (EField ((EConst (Ident "super"),_),_),_), _ -> def() | (EField (e,"bind"),p), args -> let e = type_expr ctx e Value in (match follow e.etype with | TFun _ -> type_bind ctx e args p | _ -> def ()) | (EConst (Ident "$type"),_) , [e] -> let e = type_expr ctx e Value in ctx.com.warning (s_type (print_context()) e.etype) e.epos; let e = Display.Diagnostics.secure_generated_code ctx e in e | (EField(e,"match"),p), [epat] -> let et = type_expr ctx e Value in (match follow et.etype with | TEnum _ -> let e = match_expr ctx e [[epat],None,Some (EConst(Ident "true"),p),p] (Some (Some (EConst(Ident "false"),p),p)) (WithType ctx.t.tbool) p in (* TODO: add that back *) (* let locals = !get_pattern_locals_ref ctx epat t in PMap.iter (fun _ (_,p) -> display_error ctx "Capture variables are not allowed" p) locals; *) e | _ -> def ()) | (EConst (Ident "__unprotect__"),_) , [(EConst (String _),_) as e] -> let e = type_expr ctx e Value in if Common.platform ctx.com Flash then let t = tfun [e.etype] e.etype in let v_unprotect = alloc_unbound_var "__unprotect__" t p in mk (TCall (mk (TLocal v_unprotect) t p,[e])) e.etype e.epos else e | (EDisplay((EConst (Ident "super"),_ as e1),false),_),_ -> handle_display ctx (ECall(e1,el),p) with_type | (EConst (Ident "super"),sp) , el -> if ctx.curfun <> FunConstructor then error "Cannot call super constructor outside class constructor" p; let el, t = (match ctx.curclass.cl_super with | None -> error "Current class does not have a super" p | Some (c,params) -> let ct, f = get_constructor ctx c params p in if (Meta.has Meta.CompilerGenerated f.cf_meta) then display_error ctx (error_msg (No_constructor (TClassDecl c))) p; let el = (match follow ct with | TFun (args,r) -> let el,_,_ = unify_field_call ctx (FInstance(c,params,f)) el args r p false in el | _ -> error "Constructor is not a function" p ) in el , TInst (c,params) ) in mk (TCall (mk (TConst TSuper) t sp,el)) ctx.t.tvoid p | _ -> def () and build_call ctx acc el (with_type:with_type) p = match acc with | AKInline (ethis,f,fmode,t) when Meta.has Meta.Generic f.cf_meta -> type_generic_function ctx (ethis,fmode) el with_type p | AKInline (ethis,f,fmode,t) -> (match follow t with | TFun (args,r) -> let _,_,mk_call = unify_field_call ctx fmode el args r p true in mk_call ethis p | _ -> error (s_type (print_context()) t ^ " cannot be called") p ) | AKUsing (et,cl,ef,eparam) when Meta.has Meta.Generic ef.cf_meta -> (match et.eexpr with | TField(ec,fa) -> type_generic_function ctx (ec,fa) el ~using_param:(Some eparam) with_type p | _ -> assert false) | AKUsing (et,cl,ef,eparam) -> begin match ef.cf_kind with | Method MethMacro -> let ethis = type_module_type ctx (TClassDecl cl) None p in let eparam,f = push_this ctx eparam in let e = build_call ctx (AKMacro (ethis,ef)) (eparam :: el) with_type p in f(); e | _ -> let t = follow (field_type ctx cl [] ef p) in (* for abstracts we have to apply their parameters to the static function *) let t,tthis = match follow eparam.etype with | TAbstract(a,tl) when Meta.has Meta.Impl ef.cf_meta -> apply_params a.a_params tl t,apply_params a.a_params tl a.a_this | te -> t,te in let params,args,r,eparam = match t with | TFun ((_,_,t1) :: args,r) -> unify ctx tthis t1 eparam.epos; let ef = prepare_using_field ef in begin match unify_call_args ctx el args r p (ef.cf_kind = Method MethInline) (is_forced_inline (Some cl) ef) with | el,TFun(args,r) -> el,args,r,eparam | _ -> assert false end | _ -> assert false in make_call ctx et (eparam :: params) r p end | AKMacro (ethis,cf) -> if ctx.macro_depth > 300 then error "Stack overflow" p; ctx.macro_depth <- ctx.macro_depth + 1; ctx.with_type_stack <- with_type :: ctx.with_type_stack; let ethis_f = ref (fun () -> ()) in let f = (match ethis.eexpr with | TTypeExpr (TClassDecl c) -> (match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name el p with | None -> (fun() -> type_expr ctx (EConst (Ident "null"),p) Value) | Some (EMeta((Meta.MergeBlock,_,_),(EBlock el,_)),_) -> (fun () -> let e = type_block ctx el with_type p in mk (TMeta((Meta.MergeBlock,[],p), e)) e.etype e.epos) | Some e -> (fun() -> type_expr ctx e with_type)) | _ -> (* member-macro call : since we will make a static call, let's found the actual class and not its subclass *) (match follow ethis.etype with | TInst (c,_) -> let rec loop c = if PMap.mem cf.cf_name c.cl_fields then let eparam,f = push_this ctx ethis in ethis_f := f; let e = match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name (eparam :: el) p with | None -> (fun() -> type_expr ctx (EConst (Ident "null"),p) Value) | Some e -> (fun() -> type_expr ctx e Value) in e else match c.cl_super with | None -> assert false | Some (csup,_) -> loop csup in loop c | _ -> assert false)) in ctx.macro_depth <- ctx.macro_depth - 1; ctx.with_type_stack <- List.tl ctx.with_type_stack; let old = ctx.on_error in ctx.on_error <- (fun ctx msg ep -> (* display additional info in the case the error is not part of our original call *) if ep.pfile <> p.pfile || ep.pmax < p.pmin || ep.pmin > p.pmax then begin Typeload.locate_macro_error := false; old ctx msg ep; Typeload.locate_macro_error := true; ctx.com.error "Called from macro here" p; end else old ctx msg ep; ); let e = try f() with Error (m,p) -> ctx.on_error <- old; !ethis_f(); raise (Fatal_error ((error_msg m),p)) in let e = Display.Diagnostics.secure_generated_code ctx e in ctx.on_error <- old; !ethis_f(); e | AKNo _ | AKSet _ | AKAccess _ -> ignore(acc_get ctx acc p); assert false | AKExpr e -> let rec loop t = match follow t with | TFun (args,r) -> begin match e.eexpr with | TField(e1,fa) when not (match fa with FEnum _ -> true | _ -> false) -> begin match fa with | FInstance(_,_,cf) | FStatic(_,cf) when Meta.has Meta.Generic cf.cf_meta -> type_generic_function ctx (e1,fa) el with_type p | _ -> let _,_,mk_call = unify_field_call ctx fa el args r p false in mk_call e1 e.epos end | _ -> let el, tfunc = unify_call_args ctx el args r p false false in let r = match tfunc with TFun(_,r) -> r | _ -> assert false in mk (TCall (e,el)) r p end | TAbstract(a,tl) when Meta.has Meta.Callable a.a_meta -> loop (Abstract.get_underlying_type a tl) | TMono _ -> let t = mk_mono() in let el = List.map (fun e -> type_expr ctx e Value) el in unify ctx (tfun (List.map (fun e -> e.etype) el) t) e.etype e.epos; mk (TCall (e,el)) t p | t -> let el = List.map (fun e -> type_expr ctx e Value) el in let t = if t == t_dynamic then t_dynamic else if ctx.untyped then mk_mono() else error (s_type (print_context()) e.etype ^ " cannot be called") e.epos in mk (TCall (e,el)) t p in loop e.etype (* ---------------------------------------------------------------------- *) (* FINALIZATION *) let get_main ctx types = match ctx.com.main_class with | None -> None | Some cl -> let t = Typeload.load_type_def ctx null_pos { tpackage = fst cl; tname = snd cl; tparams = []; tsub = None } in let fmode, ft, r = (match t with | TEnumDecl _ | TTypeDecl _ | TAbstractDecl _ -> error ("Invalid -main : " ^ s_type_path cl ^ " is not a class") null_pos | TClassDecl c -> try let f = PMap.find "main" c.cl_statics in let t = Type.field_type f in (match follow t with | TFun ([],r) -> FStatic (c,f), t, r | _ -> error ("Invalid -main : " ^ s_type_path cl ^ " has invalid main function") c.cl_pos); with Not_found -> error ("Invalid -main : " ^ s_type_path cl ^ " does not have static function main") c.cl_pos ) in let emain = type_type ctx cl null_pos in let main = mk (TCall (mk (TField (emain,fmode)) ft null_pos,[])) r null_pos in (* add haxe.EntryPoint.run() call *) let main = (try let et = List.find (fun t -> t_path t = (["haxe"],"EntryPoint")) types in let ec = (match et with TClassDecl c -> c | _ -> assert false) in let ef = PMap.find "run" ec.cl_statics in let p = null_pos in let et = mk (TTypeExpr et) (TAnon { a_fields = PMap.empty; a_status = ref (Statics ec) }) p in let call = mk (TCall (mk (TField (et,FStatic (ec,ef))) ef.cf_type p,[])) ctx.t.tvoid p in mk (TBlock [main;call]) ctx.t.tvoid p with Not_found -> main ) in Some main let finalize ctx = flush_pass ctx PFinal "final"; match ctx.com.callbacks.after_typing with | [] -> () | fl -> let rec loop handled_types = let all_types = Hashtbl.fold (fun _ m acc -> m.m_types @ acc) ctx.g.modules [] in match (List.filter (fun mt -> not (List.memq mt handled_types)) all_types) with | [] -> () | new_types -> List.iter (fun f -> f new_types) fl; flush_pass ctx PFinal "final"; loop all_types in loop [] type state = | Generating | Done | NotYet let generate ctx = let types = ref [] in let states = Hashtbl.create 0 in let state p = try Hashtbl.find states p with Not_found -> NotYet in let statics = ref PMap.empty in let rec loop t = let p = t_path t in match state p with | Done -> () | Generating -> ctx.com.warning ("Warning : maybe loop in static generation of " ^ s_type_path p) (t_infos t).mt_pos; | NotYet -> Hashtbl.add states p Generating; let t = (match t with | TClassDecl c -> walk_class p c; t | TEnumDecl _ | TTypeDecl _ | TAbstractDecl _ -> t ) in Hashtbl.replace states p Done; types := t :: !types and loop_class p c = if c.cl_path <> p then loop (TClassDecl c) and loop_enum p e = if e.e_path <> p then loop (TEnumDecl e) and loop_abstract p a = if a.a_path <> p then loop (TAbstractDecl a) and walk_static_field p c cf = match cf.cf_expr with | None -> () | Some e -> if PMap.mem (c.cl_path,cf.cf_name) (!statics) then () else begin statics := PMap.add (c.cl_path,cf.cf_name) () (!statics); walk_expr p e; end and walk_expr p e = match e.eexpr with | TTypeExpr t -> (match t with | TClassDecl c -> loop_class p c | TEnumDecl e -> loop_enum p e | TAbstractDecl a -> loop_abstract p a | TTypeDecl _ -> assert false) | TNew (c,_,_) -> iter (walk_expr p) e; loop_class p c; let rec loop c = if PMap.mem (c.cl_path,"new") (!statics) then () else begin statics := PMap.add (c.cl_path,"new") () !statics; (match c.cl_constructor with | Some { cf_expr = Some e } -> walk_expr p e | _ -> ()); match c.cl_super with | None -> () | Some (csup,_) -> loop csup end in loop c | TField(e1,FStatic(c,cf)) -> walk_expr p e1; walk_static_field p c cf; | _ -> iter (walk_expr p) e and walk_class p c = (match c.cl_super with None -> () | Some (c,_) -> loop_class p c); List.iter (fun (c,_) -> loop_class p c) c.cl_implements; (match c.cl_init with | None -> () | Some e -> walk_expr p e); PMap.iter (fun _ f -> match f.cf_expr with | None -> () | Some e -> match e.eexpr with | TFunction _ -> () | _ -> walk_expr p e ) c.cl_statics in let sorted_modules = List.sort (fun m1 m2 -> compare m1.m_path m2.m_path) (Hashtbl.fold (fun _ m acc -> m :: acc) ctx.g.modules []) in List.iter (fun m -> List.iter loop m.m_types) sorted_modules; get_main ctx !types, List.rev !types, sorted_modules (* ---------------------------------------------------------------------- *) (* TYPER INITIALIZATION *) let rec create com = let ctx = { com = com; t = com.basic; g = { core_api = None; macros = None; modules = Hashtbl.create 0; types_module = Hashtbl.create 0; type_patches = Hashtbl.create 0; global_metadata = []; module_check_policies = []; delayed = []; debug_delayed = []; delayed_macros = DynArray.create(); doinline = com.display.dms_inline && not (Common.defined com Define.NoInline); hook_generate = []; get_build_infos = (fun() -> None); std = null_module; global_using = []; do_inherit = Typeload.on_inherit; do_create = create; do_macro = MacroContext.type_macro; do_load_module = Typeload.load_module; do_optimize = Optimizer.reduce_expression; do_build_instance = Typeload.build_instance; do_format_string = format_string; do_finalize = finalize; do_generate = generate; }; m = { curmod = null_module; module_types = []; module_using = []; module_globals = PMap.empty; wildcard_packages = []; module_imports = []; }; is_display_file = false; meta = []; this_stack = []; with_type_stack = []; call_argument_stack = []; pass = PBuildModule; macro_depth = 0; untyped = false; curfun = FunStatic; in_loop = false; in_display = false; in_macro = Common.defined com Define.Macro; ret = mk_mono(); locals = PMap.empty; type_params = []; curclass = null_class; curfield = null_field; tthis = mk_mono(); opened = []; vthis = None; in_call_args = false; on_error = (fun ctx msg p -> ctx.com.error msg p); } in ctx.g.std <- (try Typeload.load_module ctx ([],"StdTypes") null_pos with Error (Module_not_found ([],"StdTypes"),_) -> error "Standard library not found" null_pos ); (* We always want core types to be available so we add them as default imports (issue #1904 and #3131). *) ctx.m.module_types <- List.map (fun t -> t,null_pos) ctx.g.std.m_types; List.iter (fun t -> match t with | TAbstractDecl a -> (match snd a.a_path with | "Void" -> ctx.t.tvoid <- TAbstract (a,[]); | "Float" -> ctx.t.tfloat <- TAbstract (a,[]); | "Int" -> ctx.t.tint <- TAbstract (a,[]) | "Bool" -> ctx.t.tbool <- TAbstract (a,[]) | "Dynamic" -> t_dynamic_def := TAbstract(a,List.map snd a.a_params); | _ -> ()); | TEnumDecl e -> () | TClassDecl c -> () | TTypeDecl td -> (match snd td.t_path with | "Null" -> let mk_null t = try if not (is_null ~no_lazy:true t) then TType (td,[t]) else t with Exit -> (* don't force lazy evaluation *) let r = ref (fun() -> assert false) in r := (fun() -> let t = (if not (is_null t) then TType (td,[t]) else t) in r := (fun() -> t); t ); TLazy r in ctx.t.tnull <- mk_null; | _ -> ()); ) ctx.g.std.m_types; let m = Typeload.load_module ctx ([],"String") null_pos in (match m.m_types with | [TClassDecl c] -> ctx.t.tstring <- TInst (c,[]) | _ -> assert false); let m = Typeload.load_module ctx ([],"Array") null_pos in (try List.iter (fun t -> ( match t with | TClassDecl ({cl_path = ([],"Array")} as c) -> ctx.t.tarray <- (fun t -> TInst (c,[t])); raise Exit | _ -> () )) m.m_types; assert false with Exit -> ()); let m = Typeload.load_module ctx (["haxe"],"EnumTools") null_pos in (match m.m_types with | [TClassDecl c1;TClassDecl c2] -> ctx.g.global_using <- (c1,c1.cl_pos) :: (c2,c2.cl_pos) :: ctx.g.global_using | [TClassDecl c1] -> let m = Typeload.load_module ctx (["haxe"],"EnumValueTools") null_pos in (match m.m_types with | [TClassDecl c2 ] -> ctx.g.global_using <- (c1,c1.cl_pos) :: (c2,c2.cl_pos) :: ctx.g.global_using | _ -> assert false); | _ -> assert false); ctx ;; unify_min_ref := unify_min; make_call_ref := make_call; get_constructor_ref := get_constructor; cast_or_unify_ref := AbstractCast.cast_or_unify_raise; type_module_type_ref := type_module_type; find_array_access_raise_ref := AbstractCast.find_array_access_raise; build_call_ref := build_call; merge_core_doc_ref := merge_core_doc; MacroContext.unify_call_args_ref := unify_call_argshaxe_3.4.4.orig/std/Any.hx0000664000175000017500000000346213166552354015303 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** `Any` is a type that is compatible with any other in both ways. This means that a value of any type can be assigned to `Any`, and vice-versa, a value of `Any` type can be assigned to any other type. It's a more type-safe alternative to `Dynamic`, because it doesn't support field access or operators and it's bound to monomorphs. So, to work with the actual value, it needs to be explicitly promoted to another type. **/ abstract Any(Dynamic) { @:noCompletion @:extern @:to inline function __promote():T return this; @:noCompletion @:extern @:from inline static function __cast(value:T):Any return cast value; @:noCompletion @:extern inline function toString():String return Std.string(this); } haxe_3.4.4.orig/std/Array.hx0000664000175000017500000002223713166552354015633 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** An Array is a storage for values. You can access it using indexes or with its API. @see https://haxe.org/manual/std-Array.html @see https://haxe.org/manual/lf-array-comprehension.html **/ extern class Array { /** The length of `this` Array. **/ var length(default,null) : Int; /** Creates a new Array. **/ function new() : Void; /** Returns a new Array by appending the elements of `a` to the elements of `this` Array. This operation does not modify `this` Array. If `a` is the empty Array `[]`, a copy of `this` Array is returned. The length of the returned Array is equal to the sum of `this.length` and `a.length`. If `a` is `null`, the result is unspecified. **/ function concat( a : Array ) : Array; /** Returns a string representation of `this` Array, with `sep` separating each element. The result of this operation is equal to `Std.string(this[0]) + sep + Std.string(this[1]) + sep + ... + sep + Std.string(this[this.length-1])` If `this` is the empty Array `[]`, the result is the empty String `""`. If `this` has exactly one element, the result is equal to a call to `Std.string(this[0])`. If `sep` is null, the result is unspecified. **/ function join( sep : String ) : String; /** Removes the last element of `this` Array and returns it. This operation modifies `this` Array in place. If `this` has at least one element, `this.length` will decrease by 1. If `this` is the empty Array `[]`, null is returned and the length remains 0. **/ function pop() : Null; /** Adds the element `x` at the end of `this` Array and returns the new length of `this` Array. This operation modifies `this` Array in place. `this.length` increases by 1. **/ function push(x : T) : Int; /** Reverse the order of elements of `this` Array. This operation modifies `this` Array in place. If `this.length < 2`, `this` remains unchanged. **/ function reverse() : Void; /** Removes the first element of `this` Array and returns it. This operation modifies `this` Array in place. If `this` has at least one element, `this`.length and the index of each remaining element is decreased by 1. If `this` is the empty Array `[]`, `null` is returned and the length remains 0. **/ function shift() : Null; /** Creates a shallow copy of the range of `this` Array, starting at and including `pos`, up to but not including `end`. This operation does not modify `this` Array. The elements are not copied and retain their identity. If `end` is omitted or exceeds `this.length`, it defaults to the end of `this` Array. If `pos` or `end` are negative, their offsets are calculated from the end of `this` Array by `this.length + pos` and `this.length + end` respectively. If this yields a negative value, 0 is used instead. If `pos` exceeds `this.length` or if `end` is less than or equals `pos`, the result is `[]`. **/ function slice( pos : Int, ?end : Int ) : Array; /** Sorts `this` Array according to the comparison function `f`, where `f(x,y)` returns 0 if x == y, a positive Int if x > y and a negative Int if x < y. This operation modifies `this` Array in place. The sort operation is not guaranteed to be stable, which means that the order of equal elements may not be retained. For a stable Array sorting algorithm, `haxe.ds.ArraySort.sort()` can be used instead. If `f` is null, the result is unspecified. **/ function sort( f : T -> T -> Int ) : Void; /** Removes `len` elements from `this` Array, starting at and including `pos`, an returns them. This operation modifies `this` Array in place. If `len` is < 0 or `pos` exceeds `this`.length, an empty Array [] is returned and `this` Array is unchanged. If `pos` is negative, its value is calculated from the end of `this` Array by `this.length + pos`. If this yields a negative value, 0 is used instead. If the sum of the resulting values for `len` and `pos` exceed `this.length`, this operation will affect the elements from `pos` to the end of `this` Array. The length of the returned Array is equal to the new length of `this` Array subtracted from the original length of `this` Array. In other words, each element of the original `this` Array either remains in `this` Array or becomes an element of the returned Array. **/ function splice( pos : Int, len : Int ) : Array; /** Returns a string representation of `this` Array. The result will include the individual elements' String representations separated by comma. The enclosing [ ] may be missing on some platforms, use `Std.string()` to get a String representation that is consistent across platforms. **/ function toString() : String; /** Adds the element `x` at the start of `this` Array. This operation modifies `this` Array in place. `this.length` and the index of each Array element increases by 1. **/ function unshift( x : T ) : Void; /** Inserts the element `x` at the position `pos`. This operation modifies `this` Array in place. The offset is calculated like so: - If `pos` exceeds `this.length`, the offset is `this.length`. - If `pos` is negative, the offset is calculated from the end of `this` Array, i.e. `this.length + pos`. If this yields a negative value, the offset is 0. - Otherwise, the offset is `pos`. If the resulting offset does not exceed `this.length`, all elements from and including that offset to the end of `this` Array are moved one index ahead. **/ function insert( pos : Int, x : T ) : Void; /** Removes the first occurrence of `x` in `this` Array. This operation modifies `this` Array in place. If `x` is found by checking standard equality, it is removed from `this` Array and all following elements are reindexed accordingly. The function then returns true. If `x` is not found, `this` Array is not changed and the function returns false. **/ function remove( x : T ) : Bool; /** Returns position of the first occurrence of `x` in `this` Array, searching front to back. If `x` is found by checking standard equality, the function returns its index. If `x` is not found, the function returns -1. If `fromIndex` is specified, it will be used as the starting index to search from, otherwise search starts with zero index. If it is negative, it will be taken as the offset from the end of `this` Array to compute the starting index. If given or computed starting index is less than 0, the whole array will be searched, if it is greater than or equal to the length of `this` Array, the function returns -1. **/ function indexOf( x : T, ?fromIndex:Int ) : Int; /** Returns position of the last occurrence of `x` in `this` Array, searching back to front. If `x` is found by checking standard equality, the function returns its index. If `x` is not found, the function returns -1. If `fromIndex` is specified, it will be used as the starting index to search from, otherwise search starts with the last element index. If it is negative, it will be taken as the offset from the end of `this` Array to compute the starting index. If given or computed starting index is greater than or equal to the length of `this` Array, the whole array will be searched, if it is less than 0, the function returns -1. **/ function lastIndexOf( x : T, ?fromIndex:Int ) : Int; /** Returns a shallow copy of `this` Array. The elements are not copied and retain their identity, so `a[i] == a.copy()[i]` is true for any valid `i`. However, `a == a.copy()` is always false. **/ function copy() : Array; /** Returns an iterator of the Array values. **/ function iterator() : Iterator; /** Creates a new Array by applying function `f` to all elements of `this`. The order of elements is preserved. If `f` is null, the result is unspecified. **/ function map( f : T -> S ) : Array; /** Returns an Array containing those elements of `this` for which `f` returned true. The individual elements are not duplicated and retain their identity. If `f` is null, the result is unspecified. **/ function filter( f : T -> Bool ) : Array; } haxe_3.4.4.orig/std/Class.hx0000664000175000017500000000245213166552354015617 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** An abstract type that represents a Class. See `Type` for the Haxe Reflection API. @see https://haxe.org/manual/types-class-instance.html **/ @:coreType @:runtimeValue abstract Class { } haxe_3.4.4.orig/std/Date.hx0000664000175000017500000001146413166552354015432 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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 Date class provides a basic structure for date and time related information. Date instances can be created by - `new Date()` for a specific date, - `Date.now()` to obtain information about the current time, - `Date.fromTime()` with a given timestamp or - `Date.fromString()` by parsing from a String. There are some extra functions available in the `DateTools` class. In the context of Haxe dates, a timestamp is defined as the number of milliseconds elapsed since 1st January 1970. **/ extern class Date { /** Creates a new date object from the given arguments. The behaviour of a Date instance is only consistent across platforms if the the arguments describe a valid date. - month: 0 to 11 - day: 1 to 31 - hour: 0 to 23 - min: 0 to 59 - sec: 0 to 59 **/ function new(year : Int, month : Int, day : Int, hour : Int, min : Int, sec : Int ) : Void; /** Returns the timestamp (in milliseconds) of the date. It might only have a per-second precision depending on the platforms. **/ function getTime() : Float; /** Returns the hours of `this` Date (0-23 range). **/ function getHours() : Int; /** Returns the minutes of `this` Date (0-59 range). **/ function getMinutes() : Int; /** Returns the seconds of `this` Date (0-59 range). **/ function getSeconds() : Int; /** Returns the full year of `this` Date (4-digits). **/ function getFullYear() : Int; /** Returns the month of `this` Date (0-11 range). **/ function getMonth() : Int; /** Returns the day of `this` Date (1-31 range). **/ function getDate() : Int; /** Returns the day of the week of `this` Date (0-6 range) where `0` is Sunday. **/ function getDay() : Int; /** Returns a string representation of `this` Date, by using the standard format [YYYY-MM-DD HH:MM:SS]. See `DateTools.format` for other formating rules. **/ function toString():String; /** Returns a Date representing the current local time. **/ static function now() : Date; /** Returns a Date from timestamp `t`. **/ static function fromTime( t : Float ) : Date; /** Returns a Date from a formated string `s`, with the following accepted formats: - `"YYYY-MM-DD hh:mm:ss"` - `"YYYY-MM-DD"` - `"hh:mm:ss"` The first two formats are expressed in local time, the third in UTC Epoch. **/ static function fromString( s : String ) : Date; #if flash private static function __init__() : Void untyped { var d : Dynamic = Date; d.now = function() { return __new__(Date); }; d.fromTime = function(t){ var d : Date = __new__(Date); d.setTime(t); return d; }; d.fromString = function(s : String) { switch( s.length ) { case 8: // hh:mm:ss var k = s.split(":"); var d : Date = __new__(Date); d.setTime(0); d.setUTCHours(k[0]); d.setUTCMinutes(k[1]); d.setUTCSeconds(k[2]); return d; case 10: // YYYY-MM-DD var k = s.split("-"); return new Date(cast k[0],cast k[1] - 1,cast k[2],0,0,0); case 19: // YYYY-MM-DD hh:mm:ss var k = s.split(" "); var y = k[0].split("-"); var t = k[1].split(":"); return new Date(cast y[0],cast y[1] - 1,cast y[2],cast t[0],cast t[1],cast t[2]); default: throw "Invalid date format : " + s; } }; d.prototype[#if (as3 || no_flash_override) "toStringHX" #else "toString" #end] = function() { var date : Date = __this__; var m = date.getMonth() + 1; var d = date.getDate(); var h = date.getHours(); var mi = date.getMinutes(); var s = date.getSeconds(); return date.getFullYear() +"-"+(if( m < 10 ) "0"+m else ""+m) +"-"+(if( d < 10 ) "0"+d else ""+d) +" "+(if( h < 10 ) "0"+h else ""+h) +":"+(if( mi < 10 ) "0"+mi else ""+mi) +":"+(if( s < 10 ) "0"+s else ""+s); }; } #end } haxe_3.4.4.orig/std/DateTools.hx0000664000175000017500000001643113166552354016452 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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 DateTools class contains some extra functionalities for handling `Date` instances and timestamps. In the context of Haxe dates, a timestamp is defined as the number of milliseconds elapsed since 1st January 1970. **/ class DateTools { #if php #elseif (neko && !(macro || interp)) static var date_format = neko.Lib.load("std","date_format",2); #else static var DAY_SHORT_NAMES = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; static var DAY_NAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; static var MONTH_SHORT_NAMES = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; static var MONTH_NAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; private static function __format_get( d : Date, e : String ) : String { return switch( e ){ case "%": "%"; case "a": DAY_SHORT_NAMES[d.getDay()]; case "A": DAY_NAMES[d.getDay()]; case "b","h": MONTH_SHORT_NAMES[d.getMonth()]; case "B": MONTH_NAMES[d.getMonth()]; case "C": untyped StringTools.lpad(Std.string(Std.int(d.getFullYear()/100)),"0",2); case "d": untyped StringTools.lpad(Std.string(d.getDate()),"0",2); case "D": __format(d,"%m/%d/%y"); case "e": untyped Std.string(d.getDate()); case "F": __format(d,"%Y-%m-%d"); case "H","k": untyped StringTools.lpad(Std.string(d.getHours()),if( e == "H" ) "0" else " ",2); case "I","l": var hour = d.getHours()%12; untyped StringTools.lpad(Std.string(hour == 0 ? 12 : hour),if( e == "I" ) "0" else " ",2); case "m": untyped StringTools.lpad(Std.string(d.getMonth()+1),"0",2); case "M": untyped StringTools.lpad(Std.string(d.getMinutes()),"0",2); case "n": "\n"; case "p": untyped if( d.getHours() > 11 ) "PM"; else "AM"; case "r": __format(d,"%I:%M:%S %p"); case "R": __format(d,"%H:%M"); case "s": Std.string(Std.int(d.getTime()/1000)); case "S": untyped StringTools.lpad(Std.string(d.getSeconds()),"0",2); case "t": "\t"; case "T": __format(d,"%H:%M:%S"); case "u": untyped{ var t = d.getDay(); if( t == 0 ) "7"; else Std.string(t); } case "w": untyped Std.string(d.getDay()); case "y": untyped StringTools.lpad(Std.string(d.getFullYear()%100),"0",2); case "Y": untyped Std.string(d.getFullYear()); default: throw "Date.format %"+e+"- not implemented yet."; } } private static function __format( d : Date, f : String ) : String { var r = new StringBuf(); var p = 0; while( true ){ var np = f.indexOf("%", p); if( np < 0 ) break; r.addSub(f,p,np-p); r.add( __format_get(d, f.substr(np+1,1) ) ); p = np+2; } r.addSub(f,p,f.length-p); return r.toString(); } #end /** Format the date `d` according to the format `f`. The format is compatible with the `strftime` standard format, except that there is no support in Flash and JS for day and months names (due to lack of proper internationalization API). On Haxe/Neko/Windows, some formats are not supported. ```haxe var t = DateTools.format(Date.now(), "%Y-%m-%d_%H:%M:%S"); // 2016-07-08_14:44:05 var t = DateTools.format(Date.now(), "%r"); // 02:44:05 PM var t = DateTools.format(Date.now(), "%T"); // 14:44:05 var t = DateTools.format(Date.now(), "%F"); // 2016-07-08 ``` **/ public static function format( d : Date, f : String ) : String { #if (neko && !(macro || interp)) return new String(untyped date_format(d.__t, f.__s)); #elseif php return untyped __call__("strftime",f,d.__t); #else return __format(d,f); #end } /** Returns the result of adding timestamp `t` to Date `d`. This is a convenience function for calling `Date.fromTime(d.getTime() + t)`. **/ public static inline function delta( d : Date, t : Float ) : Date { return Date.fromTime( d.getTime() + t ); } static var DAYS_OF_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; /** Returns the number of days in the month of Date `d`. This method handles leap years. **/ public static function getMonthDays( d : Date ) : Int { var month = d.getMonth(); var year = d.getFullYear(); if (month != 1) return DAYS_OF_MONTH[month]; var isB = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); return if (isB) 29 else 28; } /** Converts a number of seconds to a timestamp. **/ public static inline function seconds( n : Float ) : Float { return n * 1000.0; } /** Converts a number of minutes to a timestamp. **/ #if as3 @:extern #end public static inline function minutes( n : Float ) : Float { return n * 60.0 * 1000.0; } /** Converts a number of hours to a timestamp. **/ public static inline function hours( n : Float ) : Float { return n * 60.0 * 60.0 * 1000.0; } /** Converts a number of days to a timestamp. **/ public static inline function days( n : Float ) : Float { return n * 24.0 * 60.0 * 60.0 * 1000.0; } /** Separate a date-time into several components **/ public static function parse( t : Float ) { var s = t / 1000; var m = s / 60; var h = m / 60; return { ms : t % 1000, seconds : Std.int(s % 60), minutes : Std.int(m % 60), hours : Std.int(h % 24), days : Std.int(h / 24), }; } /** Build a date-time from several components **/ public static function make( o : { ms : Float, seconds : Int, minutes : Int, hours : Int, days : Int } ) { return o.ms + 1000.0 * (o.seconds + 60.0 * (o.minutes + 60.0 * (o.hours + 24.0 * o.days))); } #if (js || flash || php || cpp || python) /** Retrieve Unix timestamp value from Date components. Takes same argument sequence as the Date constructor. **/ public static #if (js || flash || php) inline #end function makeUtc(year : Int, month : Int, day : Int, hour : Int, min : Int, sec : Int ):Float { #if (js || flash || python) return untyped Date.UTC(year, month, day, hour, min, sec); #elseif php return untyped __call__("gmmktime", hour, min, sec, month + 1, day, year) * 1000; #elseif cpp return untyped __global__.__hxcpp_utc_date(year,month,day,hour,min,sec)*1000.0 ; #else //TODO return 0.; #end } #end } haxe_3.4.4.orig/std/EReg.hx0000664000175000017500000001450213166552354015373 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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 EReg class represents regular expressions. While basic usage and patterns consistently work across platforms, some more complex operations may yield different results. This is a necessary trade- off to retain a certain level of performance. EReg instances can be created by calling the constructor, or with the special syntax `~/pattern/modifier` EReg instances maintain an internal state, which is affected by several of its methods. A detailed explanation of the supported operations is available at **/ class EReg { /** Creates a new regular expression with pattern `r` and modifiers `opt`. This is equivalent to the shorthand syntax `~/r/opt` If `r` or `opt` are null, the result is unspecified. **/ public function new( r : String, opt : String ) { throw "Regular expressions are not implemented for this platform"; } /** Tells if `this` regular expression matches String `s`. This method modifies the internal state. If `s` is `null`, the result is unspecified. **/ public function match( s : String ) : Bool { return false; } /** Returns the matched sub-group `n` of `this` EReg. This method should only be called after `this.match` or `this.matchSub`, and then operates on the String of that operation. The index `n` corresponds to the n-th set of parentheses in the pattern of `this` EReg. If no such sub-group exists, an exception is thrown. If `n` equals 0, the whole matched substring is returned. **/ public function matched( n : Int ) : String { return null; } /** Returns the part to the left of the last matched substring. If the most recent call to `this.match` or `this.matchSub` did not match anything, the result is unspecified. If the global g modifier was in place for the matching, only the substring to the left of the leftmost match is returned. The result does not include the matched part. **/ public function matchedLeft() : String { return null; } /** Returns the part to the right of the last matched substring. If the most recent call to `this.match` or `this.matchSub` did not match anything, the result is unspecified. If the global g modifier was in place for the matching, only the substring to the right of the leftmost match is returned. The result does not include the matched part. **/ public function matchedRight() : String { return null; } /** Returns the position and length of the last matched substring, within the String which was last used as argument to `this.match` or `this.matchSub`. If the most recent call to `this.match` or `this.matchSub` did not match anything, the result is unspecified. If the global g modifier was in place for the matching, the position and length of the leftmost substring is returned. **/ public function matchedPos() : { pos : Int, len : Int } { return null; } /** Tells if `this` regular expression matches a substring of String `s`. This function expects `pos` and `len` to describe a valid substring of `s`, or else the result is unspecified. To get more robust behavior, `this.match(s.substr(pos,len))` can be used instead. This method modifies the internal state. If `s` is null, the result is unspecified. **/ public function matchSub( s : String, pos : Int, len : Int = -1):Bool { return false; } /** Splits String `s` at all substrings `this` EReg matches. If a match is found at the start of `s`, the result contains a leading empty String "" entry. If a match is found at the end of `s`, the result contains a trailing empty String "" entry. If two matching substrings appear next to each other, the result contains the empty String `""` between them. By default, this method splits `s` into two parts at the first matched substring. If the global g modifier is in place, `s` is split at each matched substring. If `s` is null, the result is unspecified. **/ public function split( s : String ) : Array { return null; } /** Replaces the first substring of `s` which `this` EReg matches with `by`. If `this` EReg does not match any substring, the result is `s`. By default, this method replaces only the first matched substring. If the global g modifier is in place, all matched substrings are replaced. If `by` contains `$1` to `$9`, the digit corresponds to number of a matched sub-group and its value is used instead. If no such sub-group exists, the replacement is unspecified. The string `$$` becomes `$`. If `s` or `by` are null, the result is unspecified. **/ public function replace( s : String, by : String ) : String { return null; } /** Calls the function `f` for the substring of `s` which `this` EReg matches and replaces that substring with the result of `f` call. The `f` function takes `this` EReg object as its first argument and should return a replacement string for the substring matched. If `this` EReg does not match any substring, the result is `s`. By default, this method replaces only the first matched substring. If the global g modifier is in place, all matched substrings are replaced. If `s` or `f` are null, the result is unspecified. **/ public function map( s : String, f : EReg -> String ) : String { return null; } } haxe_3.4.4.orig/std/Enum.hx0000664000175000017500000000254513166552354015461 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** An abstract type that represents an Enum type. The corresponding enum instance type is `EnumValue`. See `Type` for the Haxe Reflection API. @see https://haxe.org/manual/types-enum-instance.html **/ @:coreType @:runtimeValue abstract Enum { } haxe_3.4.4.orig/std/EnumValue.hx0000664000175000017500000000244213166552354016452 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** An abstract type that represents any enum value. See `Type` for the Haxe Reflection API. @see https://haxe.org/manual/types-enum-instance.html **/ @:coreType abstract EnumValue { } haxe_3.4.4.orig/std/IntIterator.hx0000664000175000017500000000414513166552354017017 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** IntIterator is used for implementing interval iterations. It is usually not used explicitly, but through its special syntax: `min...max` While it is possible to assign an instance of IntIterator to a variable or field, it is worth noting that IntIterator does not reset after being used in a for-loop. Subsequent uses of the same instance will then have no effect. @see https://haxe.org/manual/lf-iterators.html **/ class IntIterator { var min : Int; var max : Int; /** Iterates from `min` (inclusive) to `max` (exclusive). If `max <= min`, the iterator will not act as a countdown. **/ public inline function new( min : Int, max : Int ) { this.min = min; this.max = max; } /** Returns true if the iterator has other items, false otherwise. **/ public inline function hasNext() { return min < max; } /** Moves to the next item of the iterator. If this is called while hasNext() is false, the result is unspecified. **/ public inline function next() { return min++; } } haxe_3.4.4.orig/std/Lambda.hx0000664000175000017500000001615513166552354015737 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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 `Lambda` class is a collection of methods to support functional programming. It is ideally used with `using Lambda` and then acts as an extension to Iterable types. On static platforms, working with the Iterable structure might be slower than performing the operations directly on known types, such as Array and List. If the first argument to any of the methods is null, the result is unspecified. @see https://haxe.org/manual/std-Lambda.html **/ class Lambda { /** Creates an Array from Iterable `it`. If `it` is an Array, this function returns a copy of it. **/ public static function array
( it : Iterable ) : Array { var a = new Array(); for(i in it) a.push(i); return a; } /** Creates a List form Iterable `it`. If `it` is a List, this function returns a copy of it. **/ public static function list( it : Iterable ) : List { var l = new List(); for(i in it) l.add(i); return l; } /** Creates a new List by applying function `f` to all elements of `it`. The order of elements is preserved. If `f` is null, the result is unspecified. **/ public static function map( it : Iterable, f : A -> B ) : List { var l = new List(); for( x in it ) l.add(f(x)); return l; } /** Similar to map, but also passes the index of each element to `f`. The order of elements is preserved. If `f` is null, the result is unspecified. **/ public static function mapi( it : Iterable, f : Int -> A -> B ) : List { var l = new List(); var i = 0; for( x in it ) l.add(f(i++,x)); return l; } /** Concatenate a list of lists. The order of elements is preserved. **/ public static function flatten( it : Iterable> ) : List { var l = new List(); for (e in it) for (x in e) l.add(x); return l; } /** A composition of map and flatten. The order of elements is preserved. If `f` is null, the result is unspecified. **/ public static function flatMap( it : Iterable, f: A -> Iterable ) : List { return Lambda.flatten(Lambda.map(it, f)); } /** Tells if `it` contains `elt`. This function returns true as soon as an element is found which is equal to `elt` according to the `==` operator. If no such element is found, the result is false. **/ public static function has( it : Iterable, elt : A ) : Bool { for( x in it ) if( x == elt ) return true; return false; } /** Tells if `it` contains an element for which `f` is true. This function returns true as soon as an element is found for which a call to `f` returns true. If no such element is found, the result is false. If `f` is null, the result is unspecified. **/ public static function exists( it : Iterable, f : A -> Bool ) { for( x in it ) if( f(x) ) return true; return false; } /** Tells if `f` is true for all elements of `it`. This function returns false as soon as an element is found for which a call to `f` returns false. If no such element is found, the result is true. In particular, this function always returns true if `it` is empty. If `f` is null, the result is unspecified. **/ public static function foreach( it : Iterable, f : A -> Bool ) { for( x in it ) if( !f(x) ) return false; return true; } /** Calls `f` on all elements of `it`, in order. If `f` is null, the result is unspecified. **/ public static function iter( it : Iterable, f : A -> Void ) { for( x in it ) f(x); } /** Returns a List containing those elements of `it` for which `f` returned true. If `it` is empty, the result is the empty List even if `f` is null. Otherwise if `f` is null, the result is unspecified. **/ public static function filter( it : Iterable, f : A -> Bool ) { var l = new List(); for( x in it ) if( f(x) ) l.add(x); return l; } /** Functional fold on Iterable `it`, using function `f` with start argument `first`. If `it` has no elements, the result is `first`. Otherwise the first element of `it` is passed to `f` alongside `first`. The result of that call is then passed to `f` with the next element of `it`, and so on until `it` has no more elements. If `it` or `f` are null, the result is unspecified. **/ public static function fold( it : Iterable, f : A -> B -> B, first : B ) : B { for( x in it ) first = f(x,first); return first; } /** Returns the number of elements in `it` for which `pred` is true, or the total number of elements in `it` if `pred` is null. This function traverses all elements. **/ public static function count( it : Iterable, ?pred : A -> Bool ) { var n = 0; if( pred == null ) for( _ in it ) n++; else for( x in it ) if( pred(x) ) n++; return n; } /** Tells if Iterable `it` does not contain any element. **/ public static function empty( it : Iterable ) : Bool { return !it.iterator().hasNext(); } /** Returns the index of the first element `v` within Iterable `it`. This function uses operator `==` to check for equality. If `v` does not exist in `it`, the result is -1. **/ public static function indexOf( it : Iterable, v : T ) : Int { var i = 0; for( v2 in it ) { if( v == v2 ) return i; i++; } return -1; } /** Returns the first element of `it` for which `f` is true. This function returns as soon as an element is found for which a call to `f` returns true. If no such element is found, the result is null. If `f` is null, the result is unspecified. **/ public static function find( it : Iterable, f : T -> Bool ) : Null { for( v in it ) { if(f(v)) return v; } return null; } /** Returns a new List containing all elements of Iterable `a` followed by all elements of Iterable `b`. If `a` or `b` are null, the result is unspecified. **/ public static function concat( a : Iterable, b : Iterable ) : List { var l = new List(); for( x in a ) l.add(x); for( x in b ) l.add(x); return l; } } haxe_3.4.4.orig/std/List.hx0000664000175000017500000001424513166552354015470 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** A linked-list of elements. The list is composed of element container objects that are chained together. It is optimized so that adding or removing an element does not imply copying the whole list content every time. @see https://haxe.org/manual/std-List.html **/ class List { private var h : ListNode; private var q : ListNode; /** The length of `this` List. **/ public var length(default,null) : Int; /** Creates a new empty list. **/ public function new() { length = 0; } /** Adds element `item` at the end of `this` List. `this.length` increases by 1. **/ public function add( item : T ) { var x = ListNode.create(item, null); if( h == null ) h = x; else q.next = x; q = x; length++; } /** Adds element `item` at the beginning of `this` List. `this.length` increases by 1. **/ public function push( item : T ) { var x = ListNode.create(item, h); h = x; if( q == null ) q = x; length++; } /** Returns the first element of `this` List, or null if no elements exist. This function does not modify `this` List. **/ public function first() : Null { return if( h == null ) null else h.item; } /** Returns the last element of `this` List, or null if no elements exist. This function does not modify `this` List. **/ public function last() : Null { return if( q == null ) null else q.item; } /** Returns the first element of `this` List, or null if no elements exist. The element is removed from `this` List. **/ public function pop() : Null { if( h == null ) return null; var x = h.item; h = h.next; if( h == null ) q = null; length--; return x; } /** Tells if `this` List is empty. **/ public function isEmpty() : Bool { return (h == null); } /** Empties `this` List. This function does not traverse the elements, but simply sets the internal references to null and `this.length` to 0. **/ public function clear() : Void { h = null; q = null; length = 0; } /** Removes the first occurrence of `v` in `this` List. If `v` is found by checking standard equality, it is removed from `this` List and the function returns true. Otherwise, false is returned. **/ public function remove( v : T ) : Bool { var prev:ListNode = null; var l = h; while( l != null ) { if( l.item == v ) { if( prev == null ) h = l.next; else prev.next = l.next; if( q == l ) q = prev; length--; return true; } prev = l; l = l.next; } return false; } /** Returns an iterator on the elements of the list. **/ public inline function iterator() : ListIterator { return new ListIterator(h); } /** Returns a string representation of `this` List. The result is enclosed in { } with the individual elements being separated by a comma. **/ public function toString() { var s = new StringBuf(); var first = true; var l = h; s.add("{"); while( l != null ) { if( first ) first = false; else s.add(", "); s.add(Std.string(l.item)); l = l.next; } s.add("}"); return s.toString(); } /** Returns a string representation of `this` List, with `sep` separating each element. **/ public function join(sep : String) { var s = new StringBuf(); var first = true; var l = h; while( l != null ) { if( first ) first = false; else s.add(sep); s.add(l.item); l = l.next; } return s.toString(); } /** Returns a list filtered with `f`. The returned list will contain all elements for which `f(x) == true`. **/ public function filter( f : T -> Bool ) { var l2 = new List(); var l = h; while( l != null ) { var v = l.item; l = l.next; if( f(v) ) l2.add(v); } return l2; } /** Returns a new list where all elements have been converted by the function `f`. **/ public function map(f : T -> X) : List { var b = new List(); var l = h; while( l != null ) { var v = l.item; l = l.next; b.add(f(v)); } return b; } } #if neko private extern class ListNode extends neko.NativeArray { var item(get,set):T; var next(get,set):ListNode; private inline function get_item():T return this[0]; private inline function set_item(v:T):T return this[0] = v; private inline function get_next():ListNode return this[1]; private inline function set_next(v:ListNode):ListNode return this[1] = v; inline static function create(item:T, next:ListNode):ListNode { return untyped __dollar__array(item, next); } } #else private class ListNode { public var item:T; public var next:ListNode; public function new(item:T, next:ListNode) { this.item = item; this.next = next; } @:extern public inline static function create(item:T, next:ListNode):ListNode { return new ListNode(item, next); } } #end private class ListIterator { var head:ListNode; public inline function new(head:ListNode) { this.head = head; } public inline function hasNext():Bool { return head != null; } public inline function next():T { var val = head.item; head = head.next; return val; } } haxe_3.4.4.orig/std/Map.hx0000664000175000017500000001163213166552354015267 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import haxe.ds.StringMap; import haxe.ds.IntMap; import haxe.ds.HashMap; import haxe.ds.ObjectMap; import haxe.ds.WeakMap; import haxe.ds.EnumValueMap; import haxe.Constraints.IMap; /** Map allows key to value mapping for arbitrary value types, and many key types. This is a multi-type abstract, it is instantiated as one of its specialization types depending on its type parameters. A Map can be instantiated without explicit type parameters. Type inference will then determine the type parameters from the usage. Maps can also be created with `key1 => value1, key2 => value2` syntax. Map is an abstract type, it is not available at runtime. @see https://haxe.org/manual/std-Map.html **/ @:multiType(@:followWithAbstracts K) abstract Map(IMap ) { /** Creates a new Map. This becomes a constructor call to one of the specialization types in the output. The rules for that are as follows: 1. if K is a `String`, `haxe.ds.StringMap` is used 2. if K is an `Int`, `haxe.ds.IntMap` is used 3. if K is an `EnumValue`, `haxe.ds.EnumValueMap` is used 4. if K is any other class or structure, `haxe.ds.ObjectMap` is used 5. if K is any other type, it causes a compile-time error (Cpp) Map does not use weak keys on ObjectMap by default. **/ public function new(); /** Maps `key` to `value`. If `key` already has a mapping, the previous value disappears. If `key` is null, the result is unspecified. **/ public inline function set(key:K, value:V) this.set(key, value); /** Returns the current mapping of `key`. If no such mapping exists, null is returned. Note that a check like `map.get(key) == null` can hold for two reasons: 1. the map has no mapping for `key` 2. the map has a mapping with a value of `null` If it is important to distinguish these cases, `exists()` should be used. If `key` is null, the result is unspecified. **/ @:arrayAccess public inline function get(key:K) return this.get(key); /** Returns true if `key` has a mapping, false otherwise. If `key` is null, the result is unspecified. **/ public inline function exists(key:K) return this.exists(key); /** Removes the mapping of `key` and returns true if such a mapping existed, false otherwise. If `key` is null, the result is unspecified. **/ public inline function remove(key:K) return this.remove(key); /** Returns an Iterator over the keys of `this` Map. The order of keys is undefined. **/ public inline function keys():Iterator { return this.keys(); } /** Returns an Iterator over the values of `this` Map. The order of values is undefined. **/ public inline function iterator():Iterator { return this.iterator(); } /** Returns a String representation of `this` Map. The exact representation depends on the platform and key-type. **/ public inline function toString():String { return this.toString(); } @:arrayAccess @:noCompletion public inline function arrayWrite(k:K, v:V):V { this.set(k, v); return v; } @:to static inline function toStringMap(t:IMap):StringMap { return new StringMap(); } @:to static inline function toIntMap(t:IMap):IntMap { return new IntMap(); } @:to static inline function toEnumValueMapMap(t:IMap):EnumValueMap { return new EnumValueMap(); } @:to static inline function toObjectMap(t:IMap):ObjectMap { return new ObjectMap(); } @:from static inline function fromStringMap(map:StringMap):Map< String, V > { return cast map; } @:from static inline function fromIntMap(map:IntMap):Map< Int, V > { return cast map; } @:from static inline function fromObjectMap(map:ObjectMap):Map { return cast map; } } @:dox(hide) @:deprecated typedef IMap = haxe.Constraints.IMap;haxe_3.4.4.orig/std/Math.hx0000664000175000017500000002234213166552354015443 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** This class defines mathematical functions and constants. @see https://haxe.org/manual/std-math.html **/ #if cpp @:include("hxMath.h") #end @:pure extern class Math { /** Represents the ratio of the circumference of a circle to its diameter, specified by the constant, π. `PI` is approximately 3.141592653589793. **/ static var PI(default,null) : Float; /** A special `Float` constant which denotes negative infinity. For example, this is the result of -1.0 / 0.0. Operations with `NEGATIVE_INFINITY` as an operand may result in `NEGATIVE_INFINITY`, `POSITIVE_INFINITY` or `NaN`. If this constant is converted to an `Int`, e.g. through `Std.int()`, the result is unspecified. **/ static var NEGATIVE_INFINITY(default, null) : Float; /** A special `Float` constant which denotes positive infinity. For example, this is the result of 1.0 / 0.0. Operations with `POSITIVE_INFINITY` as an operand may result in `NEGATIVE_INFINITY`, `POSITIVE_INFINITY` or `NaN`. If this constant is converted to an `Int`, e.g. through `Std.int()`, the result is unspecified. **/ static var POSITIVE_INFINITY(default,null) : Float; /** A special `Float` constant which denotes an invalid number. NaN stands for "Not a Number". It occurs when a mathematically incorrect operation is executed, such as taking the square root of a negative number: Math.sqrt(-1). All further operations with `NaN` as an operand will result in `NaN`. If this constant is converted to an `Int`, e.g. through `Std.int()`, the result is unspecified. In order to test if a value is `NaN`, you should use `Math.isNaN()` function. @php In PHP versions prior to 5.3.1 VC 9 there may be unexpected results when performing arithmetic operations with `NaN` on Windows, see **/ static var NaN(default, null) : Float; /** Returns the absolute value of `v`. If `v` is positive or 0, the result is unchanged. Otherwise the result is -`v`. If `v` is `NEGATIVE_INFINITY` or `POSITIVE_INFINITY`, the result is `POSITIVE_INFINITY`. If `v` is `NaN`, the result is `NaN`. **/ static function abs(v:Float):Float; /** Returns the smaller of values `a` and `b`. If `a` or `b` are `NaN`, the result is `NaN`. If `a` or `b` are `NEGATIVE_INFINITY`, the result is `NEGATIVE_INFINITY`. If `a` and `b` are `POSITIVE_INFINITY`, the result is `POSITIVE_INFINITY`. **/ static function min(a:Float, b:Float):Float; /** Returns the greater of values `a` and `b`. If `a` or `b` are `NaN`, the result is `NaN`. If `a` or `b` are `POSITIVE_INFINITY`, the result is `POSITIVE_INFINITY`. If `a` and `b` are `NEGATIVE_INFINITY`, the result is `NEGATIVE_INFINITY`. **/ static function max(a:Float, b:Float):Float; /** Returns the trigonometric sine of the specified angle `v`, in radians. If `v` is `NaN` or infinite, the result is `NaN`. **/ static function sin(v:Float):Float; /** Returns the trigonometric cosine of the specified angle `v`, in radians. If `v` is `NaN` or infinite, the result is `NaN`. **/ static function cos(v:Float):Float; /** Returns the trigonometric tangent of the specified angle `v`, in radians. If `v` is `NaN` or infinite, the result is `NaN`. **/ static function tan(v:Float):Float; /** Returns the trigonometric arc of the specified angle `v`, in radians. If `v` is `NaN` or infinite, the result is `NaN`. **/ static function asin(v:Float):Float; /** Returns the trigonometric arc cosine of the specified angle `v`, in radians. If `v` is `NaN` or infinite, the result is `NaN`. **/ static function acos(v:Float):Float; /** Returns the trigonometric arc tangent of the specified angle `v`, in radians. If `v` is `NaN` or infinite, the result is `NaN`. **/ static function atan(v:Float):Float; /** Returns the trigonometric arc tangent whose tangent is the quotient of two specified numbers, in radians. If parameter `x` or `y` is `NaN`, `NEGATIVE_INFINITY` or `POSITIVE_INFINITY`, the result is `NaN`. **/ static function atan2(y:Float, x:Float):Float; /** Returns Euler's number, raised to the power of `v`. exp(1.0) is approximately 2.718281828459. If `v` is `POSITIVE_INFINITY`, the result is `POSITIVE_INFINITY`. If `v` is `NEGATIVE_INFINITY`, the result is `0.0`. If `v` is `NaN`, the result is `NaN`. **/ static function exp(v:Float):Float; /** Returns the natural logarithm of `v`. This is the mathematical inverse operation of exp, i.e. `log(exp(v)) == v` always holds. If `v` is negative (including `NEGATIVE_INFINITY`) or `NaN`, the result is `NaN`. If `v` is `POSITIVE_INFINITY`, the result is `POSITIVE_INFINITY`. If `v` is `0.0`, the result is `NEGATIVE_INFINITY`. **/ static function log(v:Float):Float; /** Returns a specified base `v` raised to the specified power `exp`. **/ static function pow(v:Float, exp:Float):Float; /** Returns the square root of `v`. If `v` is negative (including `NEGATIVE_INFINITY`) or `NaN`, the result is `NaN`. If `v` is `POSITIVE_INFINITY`, the result is `POSITIVE_INFINITY`. If `v` is `0.0`, the result is `0.0`. **/ static function sqrt(v:Float):Float; /** Rounds `v` to the nearest integer value. Ties are rounded up, so that `0.5` becomes `1` and `-0.5` becomes `0`. If `v` is outside of the signed `Int32` range, or is `NaN`, `NEGATIVE_INFINITY` or `POSITIVE_INFINITY`, the result is unspecified. **/ static function round(v:Float):Int; /** Returns the largest integer value that is not greater than `v`. If `v` is outside of the signed `Int32` range, or is `NaN`, `NEGATIVE_INFINITY` or `POSITIVE_INFINITY`, the result is unspecified. **/ static function floor(v:Float):Int; /** Returns the smallest integer value that is not less than `v`. If `v` is outside of the signed `Int32` range, or is `NaN`, `NEGATIVE_INFINITY` or `POSITIVE_INFINITY`, the result is unspecified. **/ static function ceil(v:Float):Int; /** Returns a pseudo-random number which is greater than or equal to 0.0, and less than 1.0. **/ static function random() : Float; #if ((flash && !as3) || cpp) /** Returns the largest integer value that is not greater than `v`, as a `Float`. If `v` is is `NaN`, `NEGATIVE_INFINITY` or `POSITIVE_INFINITY`, the result is unspecified. **/ static function ffloor( v : Float ) : Float; /** Returns the smallest integer value that is not less than `v`, as a `Float`. If `v` is is `NaN`, `NEGATIVE_INFINITY` or `POSITIVE_INFINITY`, the result is unspecified. **/ static function fceil( v : Float ) : Float; /** Rounds `v` to the nearest integer value, as a Float. Ties are rounded up, so that `0.5` becomes `1` and `-0.5` becomes `0`. If `v` is is `NaN`, `NEGATIVE_INFINITY` or `POSITIVE_INFINITY`, the result is unspecified. **/ static function fround( v : Float ) : Float; #else static inline function ffloor( v : Float ) : Float { return floor(v); } static inline function fceil( v : Float ) : Float { return ceil(v); } static inline function fround( v : Float ) : Float { return round(v); } #end /** Tells if `f` is a finite number. If `f` is `POSITIVE_INFINITY`, `NEGATIVE_INFINITY` or `NaN`, the result is `false`, otherwise the result is `true`. **/ static function isFinite( f : Float ) : Bool; /** Tells if `f` is not a valid number. If `f` is `NaN`, the result is `true`, otherwise the result is `false`. In particular, both `POSITIVE_INFINITY` and `NEGATIVE_INFINITY` are not considered `NaN`. **/ static function isNaN( f : Float ) : Bool; private static function __init__() : Void untyped { #if flash NaN = __global__["Number"].NaN; NEGATIVE_INFINITY = __global__["Number"].NEGATIVE_INFINITY; POSITIVE_INFINITY = __global__["Number"].POSITIVE_INFINITY; #else Math.__name__ = ["Math"]; Math.NaN = Number["NaN"]; Math.NEGATIVE_INFINITY = Number["NEGATIVE_INFINITY"]; Math.POSITIVE_INFINITY = Number["POSITIVE_INFINITY"]; #end Math.isFinite = function(i) { return #if flash __global__["isFinite"](i); #else false; #end }; Math.isNaN = function(i) { return #if flash __global__["isNaN"](i); #else false; #end }; } } haxe_3.4.4.orig/std/Reflect.hx0000664000175000017500000001431513166552354016137 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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 Reflect API is a way to manipulate values dynamically through an abstract interface in an untyped manner. Use with care. @see https://haxe.org/manual/std-reflection.html **/ extern class Reflect { /** Tells if structure `o` has a field named `field`. This is only guaranteed to work for anonymous structures. Refer to `Type.getInstanceFields` for a function supporting class instances. If `o` or `field` are null, the result is unspecified. **/ public static function hasField( o : Dynamic, field : String ) : Bool; /** Returns the value of the field named `field` on object `o`. If `o` is not an object or has no field named `field`, the result is null. If the field is defined as a property, its accessors are ignored. Refer to `Reflect.getProperty` for a function supporting property accessors. If `field` is null, the result is unspecified. (As3) If used on a property field, the getter will be invoked. It is not possible to obtain the value directly. **/ public static function field( o : Dynamic, field : String ) : Dynamic; /** Sets the field named `field` of object `o` to value `value`. If `o` has no field named `field`, this function is only guaranteed to work for anonymous structures. If `o` or `field` are null, the result is unspecified. (As3) If used on a property field, the setter will be invoked. It is not possible to set the value directly. **/ public static function setField( o : Dynamic, field : String, value : Dynamic ) : Void; /** Returns the value of the field named `field` on object `o`, taking property getter functions into account. If the field is not a property, this function behaves like `Reflect.field`, but might be slower. If `o` or `field` are null, the result is unspecified. **/ public static function getProperty( o : Dynamic, field : String ) : Dynamic; /** Sets the field named `field` of object `o` to value `value`, taking property setter functions into account. If the field is not a property, this function behaves like `Reflect.setField`, but might be slower. If `field` is null, the result is unspecified. **/ public static function setProperty( o : Dynamic, field : String, value : Dynamic ) : Void; /** Call a method with the given object and arguments. **/ public static function callMethod( o : Dynamic, func : haxe.Constraints.Function, args : Array ) : Dynamic; /** Returns the fields of structure `o`. This method is only guaranteed to work on anonymous structures. Refer to `Type.getInstanceFields` for a function supporting class instances. If `o` is null, the result is unspecified. **/ public static function fields( o : Dynamic ) : Array; /** Returns true if `f` is a function, false otherwise. If `f` is null, the result is false. **/ public static function isFunction( f : Dynamic ) : Bool; /** Compares `a` and `b`. If `a` is less than `b`, the result is negative. If `b` is less than `a`, the result is positive. If `a` and `b` are equal, the result is 0. This function is only defined if `a` and `b` are of the same type. If that type is a function, the result is unspecified and `Reflect.compareMethods` should be used instead. For all other types, the result is 0 if `a` and `b` are equal. If they are not equal, the result depends on the type and is negative if: - Numeric types: a is less than b - String: a is lexicographically less than b - Other: unspecified If `a` and `b` are null, the result is 0. If only one of them is null, the result is unspecified. **/ public static function compare( a : T, b : T ) : Int; /** Compares the functions `f1` and `f2`. If `f1` or `f2` are not functions, the result is unspecified. Otherwise the result is true if `f1` and the `f2` are physically equal, false otherwise. **/ public static function compareMethods( f1 : Dynamic, f2 : Dynamic ) : Bool; /** Tells if `v` is an object. The result is true if `v` is one of the following: - class instance - structure - `Class` - `Enum` Otherwise, including if `v` is null, the result is false. **/ public static function isObject( v : Dynamic ) : Bool; /** Tells if `v` is an enum value. The result is true if `v` is of type EnumValue, i.e. an enum constructor. Otherwise, including if `v` is null, the result is false. **/ public static function isEnumValue( v : Dynamic ) : Bool; /** Removes the field named `field` from structure `o`. This method is only guaranteed to work on anonymous structures. If `o` or `field` are null, the result is unspecified. **/ public static function deleteField( o : Dynamic, field : String ) : Bool; /** Copies the fields of structure `o`. This is only guaranteed to work on anonymous structures. If `o` is null, the result is unspecified. **/ public static function copy( o : T ) : T; /** Transform a function taking an array of arguments into a function that can be called with any number of arguments. **/ @:overload(function( f : Array -> Void ) : Dynamic {}) public static function makeVarArgs( f : Array -> Dynamic ) : Dynamic; } haxe_3.4.4.orig/std/Std.hx0000664000175000017500000001052113166552354015300 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ #if !(core_api || cross) #error "Please don't add haxe/std to your classpath, instead set HAXE_STD_PATH env var" #end /** The Std class provides standard methods for manipulating basic types. **/ extern class Std { /** Tells if a value `v` is of the type `t`. Returns `false` if `v` or `t` are null. **/ public static function is( v : Dynamic, t : Dynamic ) : Bool; /** Checks if object `value` is an instance of class `c`. Compiles only if the class specified by `c` can be assigned to the type of `value`. This method checks if a downcast is possible. That is, if the runtime type of `value` is assignable to the class specified by `c`, `value` is returned. Otherwise null is returned. This method is not guaranteed to work with interfaces or core types such as `String`, `Array` and `Date`. If `value` is null, the result is null. If `c` is null, the result is unspecified. **/ public static function instance( value : T, c : Class ) : S; /** Converts any value to a String. If `s` is of `String`, `Int`, `Float` or `Bool`, its value is returned. If `s` is an instance of a class and that class or one of its parent classes has a `toString` method, that method is called. If no such method is present, the result is unspecified. If `s` is an enum constructor without argument, the constructor's name is returned. If arguments exists, the constructor's name followed by the String representations of the arguments is returned. If `s` is a structure, the field names along with their values are returned. The field order and the operator separating field names and values are unspecified. If s is null, "null" is returned. **/ public static function string( s : Dynamic ) : String; /** Converts a `Float` to an `Int`, rounded towards 0. If `x` is outside of the signed Int32 range, or is `NaN`, `NEGATIVE_INFINITY` or `POSITIVE_INFINITY`, the result is unspecified. **/ public static function int( x : Float ) : Int; /** Converts a `String` to an `Int`. Leading whitespaces are ignored. If `x` starts with 0x or 0X, hexadecimal notation is recognized where the following digits may contain 0-9 and A-F. Otherwise `x` is read as decimal number with 0-9 being allowed characters. `x` may also start with a - to denote a negative value. In decimal mode, parsing continues until an invalid character is detected, in which case the result up to that point is returned. For hexadecimal notation, the effect of invalid characters is unspecified. Leading 0s that are not part of the 0x/0X hexadecimal notation are ignored, which means octal notation is not supported. If the input cannot be recognized, the result is `null`. **/ public static function parseInt( x : String ) : Null; /** Converts a `String` to a `Float`. The parsing rules for `parseInt` apply here as well, with the exception of invalid input resulting in a `NaN` value instead of null. Additionally, decimal notation may contain a single `.` to denote the start of the fractions. **/ public static function parseFloat( x : String ) : Float; /** Return a random integer between 0 included and `x` excluded. If `x <= 1`, the result is always 0. **/ public static function random( x : Int ) : Int; } haxe_3.4.4.orig/std/StdTypes.hx0000664000175000017500000001214013166552354016324 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // standard Haxe types /** The standard `Void` type. Only `null` values can be of the type `Void`. @see https://haxe.org/manual/types-void.html **/ @:coreType abstract Void { } /** The standard `Float` type, this is a double-precision IEEE 64bit float. On static targets, `null` cannot be assigned to Float. If this is necessary, `Null` can be used instead. `Std.int` converts a `Float` to an `Int`, rounded towards 0. `Std.parseFloat` converts a `String` to a `Float`. @see https://haxe.org/manual/types-basic-types.html @see https://haxe.org/manual/types-nullability.html **/ @:coreType @:notNull @:runtimeValue abstract Float { } /** The standard `Int` type. Its precision depends on the platform. On static targets, `null` cannot be assigned to `Int`. If this is necessary, `Null` can be used instead. `Std.int` converts a `Float` to an `Int`, rounded towards 0. `Std.parseInt` converts a `String` to an `Int`. @see https://haxe.org/manual/types-basic-types.html @see https://haxe.org/manual/std-math-integer-math.html @see https://haxe.org/manual/types-nullability.html **/ @:coreType @:notNull @:runtimeValue abstract Int to Float { } #if (java || cs || hl) /** Single-precision IEEE 32bit float (4-byte). **/ @:coreType @:notNull @:runtimeValue abstract Single to Float from Float {} #end /** `Null` can be useful in two cases. In order to document some methods that accept or can return a `null` value, or for the Flash compiler and AS3 generator to distinguish between base values that can be `null` and others that can't. @see https://haxe.org/manual/types-nullability.html **/ typedef Null = T /** The standard Boolean type, which can either be `true` or `false`. On static targets, `null` cannot be assigned to `Bool`. If this is necessary, `Null` can be used instead. @see https://haxe.org/manual/types-bool.html @see https://haxe.org/manual/types-nullability.html **/ @:coreType @:notNull @:runtimeValue abstract Bool { } /** `Dynamic` is a special type which is compatible with all other types. Use of `Dynamic` should be minimized as it prevents several compiler checks and optimizations. See `Any` type for a safer alternative for representing values of any type. @see https://haxe.org/manual/types-dynamic.html **/ @:coreType @:runtimeValue abstract Dynamic { } /** An `Iterator` is a structure that permits iteration over elements of type `T`. Any class with matching `hasNext()` and `next()` fields is considered an `Iterator` and can then be used e.g. in `for`-loops. This makes it easy to implement custom iterators. @see https://haxe.org/manual/lf-iterators.html **/ typedef Iterator = { /** Returns `false` if the iteration is complete, `true` otherwise. Usually iteration is considered to be complete if all elements of the underlying data structure were handled through calls to `next()`. However, in custom iterators any logic may be used to determine the completion state. **/ function hasNext() : Bool; /** Returns the current item of the `Iterator` and advances to the next one. This method is not required to check `hasNext()` first. A call to this method while `hasNext()` is `false` yields unspecified behavior. On the other hand, iterators should not require a call to `hasNext()` before the first call to `next()` if an element is available. **/ function next() : T; } /** An `Iterable` is a data structure which has an `iterator()` method. See `Lambda` for generic functions on iterable structures. @see https://haxe.org/manual/lf-iterators.html **/ typedef Iterable = { function iterator() : Iterator; } /** `ArrayAccess` is used to indicate a class that can be accessed using brackets. The type parameter represents the type of the elements stored. This interface should be used for externs only. Haxe does not support custom array access on classes. However, array access can be implemented for abstract types. @see https://haxe.org/manual/types-abstract-array-access.html **/ extern interface ArrayAccess { } haxe_3.4.4.orig/std/String.hx0000664000175000017500000001347113166552354016023 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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 basic String class. A Haxe String is immutable, it is not possible to modify individual characters. No method of this class changes the state of `this` String. Strings can be constructed using the String literal syntax `"string value"`. String can be concatenated by using the `+` operator. If an operand is not a String, it is passed through `Std.string()` first. @see https://haxe.org/manual/std-String.html **/ extern class String { /** The number of characters in `this` String. **/ var length(default,null) : Int; /** Creates a copy from a given String. **/ function new(string:String) : Void; /** Returns a String where all characters of `this` String are upper case. Affects the characters `a-z`. Other characters remain unchanged. **/ function toUpperCase() : String; /** Returns a String where all characters of `this` String are lower case. Affects the characters `A-Z`. Other characters remain unchanged. **/ function toLowerCase() : String; /** Returns the character at position `index` of `this` String. If `index` is negative or exceeds `this.length`, the empty String `""` is returned. **/ function charAt(index : Int) : String; /** Returns the character code at position `index` of `this` String. If `index` is negative or exceeds `this.length`, `null` is returned. To obtain the character code of a single character, `"x".code` can be used instead to inline the character code at compile time. Note that this only works on String literals of length 1. **/ function charCodeAt( index : Int) : Null; /** Returns the position of the leftmost occurrence of `str` within `this` String. If `startIndex` is given, the search is performed within the substring of `this` String starting from `startIndex`. Otherwise the search is performed within `this` String. In either case, the returned position is relative to the beginning of `this` String. If `str` cannot be found, -1 is returned. **/ function indexOf( str : String, ?startIndex : Int ) : Int; /** Returns the position of the rightmost occurrence of `str` within `this` String. If `startIndex` is given, the search is performed within the substring of `this` String from 0 to `startIndex`. Otherwise the search is performed within `this` String. In either case, the returned position is relative to the beginning of `this` String. If `str` cannot be found, -1 is returned. **/ function lastIndexOf( str : String, ?startIndex : Int ) : Int; /** Splits `this` String at each occurrence of `delimiter`. If `this` String is the empty String `""`, the result is not consistent across targets and may either be `[]` (on Js, Cpp) or `[""]`. If `delimiter` is the empty String `""`, `this` String is split into an Array of `this.length` elements, where the elements correspond to the characters of `this` String. If `delimiter` is not found within `this` String, the result is an Array with one element, which equals `this` String. If `delimiter` is null, the result is unspecified. Otherwise, `this` String is split into parts at each occurrence of `delimiter`. If `this` String starts (or ends) with `delimiter`, the result `Array` contains a leading (or trailing) empty String `""` element. Two subsequent delimiters also result in an empty String `""` element. **/ function split( delimiter : String ) : Array; /** Returns `len` characters of `this` String, starting at position `pos`. If `len` is omitted, all characters from position `pos` to the end of `this` String are included. If `pos` is negative, its value is calculated from the end of `this` String by `this.length + pos`. If this yields a negative value, 0 is used instead. If the calculated position + `len` exceeds `this.length`, the characters from that position to the end of `this` String are returned. If `len` is negative, the result is unspecified. **/ function substr( pos : Int, ?len : Int ) : String; /** Returns the part of `this` String from `startIndex` to but not including `endIndex`. If `startIndex` or `endIndex` are negative, 0 is used instead. If `startIndex` exceeds `endIndex`, they are swapped. If the (possibly swapped) `endIndex` is omitted or exceeds `this.length`, `this.length` is used instead. If the (possibly swapped) `startIndex` exceeds `this.length`, the empty String `""` is returned. **/ function substring( startIndex : Int, ?endIndex : Int ) : String; /** Returns the String itself. **/ function toString() : String; /** Returns the String corresponding to the character code `code`. If `code` is negative or has another invalid value, the result is unspecified. **/ @:pure static function fromCharCode( code : Int ) : String; } haxe_3.4.4.orig/std/StringBuf.hx0000664000175000017500000000617213166552354016460 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** A String buffer is an efficient way to build a big string by appending small elements together. Its cross-platform implementation uses String concatenation internally, but StringBuf may be optimized for different targets. Unlike String, an instance of StringBuf is not immutable in the sense that it can be passed as argument to functions which modify it by appending more values. However, the internal buffer cannot be modified. **/ class StringBuf { var b:String; /** The length of `this` StringBuf in characters. **/ public var length(get,never) : Int; /** Creates a new StringBuf instance. This may involve initialization of the internal buffer. **/ public inline function new() { b = ""; } inline function get_length() : Int { return b.length; } /** Appends the representation of `x` to `this` StringBuf. The exact representation of `x` may vary per platform. To get more consistent behavior, this function should be called with Std.string(x). If `x` is null, the String "null" is appended. **/ public inline function add( x : T ) : Void { b += x; } /** Appends the character identified by `c` to `this` StringBuf. If `c` is negative or has another invalid value, the result is unspecified. **/ public inline function addChar( c : Int ) : Void { b += String.fromCharCode(c); } /** Appends a substring of `s` to `this` StringBuf. This function expects `pos` and `len` to describe a valid substring of `s`, or else the result is unspecified. To get more robust behavior, `this.add(s.substr(pos,len))` can be used instead. If `s` or `pos` are null, the result is unspecified. If `len` is omitted or null, the substring ranges from `pos` to the end of `s`. **/ public inline function addSub( s : String, pos : Int, ?len : Int) : Void { b += (len == null ? s.substr(pos) : s.substr(pos, len)); } /** Returns the content of `this` StringBuf as String. The buffer is not emptied by this operation. **/ public inline function toString() : String { return b; } } haxe_3.4.4.orig/std/StringTools.hx0000664000175000017500000003776413166552354017057 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** This class provides advanced methods on Strings. It is ideally used with `using StringTools` and then acts as an [extension](https://haxe.org/manual/lf-static-extension.html) to the `String` class. If the first argument to any of the methods is null, the result is unspecified. **/ #if cpp using cpp.NativeString; #end class StringTools { /** Encode an URL by using the standard format. **/ #if (!java && !cpp && !lua) inline #end public static function urlEncode( s : String ) : String { #if flash return untyped __global__["encodeURIComponent"](s); #elseif neko return untyped new String(_urlEncode(s.__s)); #elseif js return untyped encodeURIComponent(s); #elseif cpp return untyped s.__URLEncode(); #elseif java return postProcessUrlEncode(java.net.URLEncoder.encode(s, "UTF-8")); #elseif cs return untyped cs.system.Uri.EscapeDataString(s); #elseif python return python.lib.urllib.Parse.quote(s, ""); #elseif hl var len = 0; var b = @:privateAccess s.bytes.urlEncode(len); return @:privateAccess String.__alloc__(b,len); #elseif lua s = lua.NativeStringTools.gsub(s, "\n", "\r\n"); s = lua.NativeStringTools.gsub(s, "([^%w %-%_%.%~])", function (c) { return lua.NativeStringTools.format("%%%02X", lua.NativeStringTools.byte(c) + ''); }); s = lua.NativeStringTools.gsub(s, " ", "+"); return s; #else return null; #end } #if java private static function postProcessUrlEncode( s : String ) : String { var ret = new StringBuf(); var i = 0, len = s.length; while (i < len) { switch(_charAt(s, i++)) { case '+'.code: ret.add('%20'); case '%'.code if (i <= len - 2): var c1 = _charAt(s, i++), c2 = _charAt(s, i++); switch[c1, c2] { case ['2'.code, '1'.code]: ret.addChar('!'.code); case ['2'.code, '7'.code]: ret.addChar('\''.code); case ['2'.code, '8'.code]: ret.addChar('('.code); case ['2'.code, '9'.code]: ret.addChar(')'.code); case ['7'.code, 'E'.code] | ['7'.code, 'e'.code]: ret.addChar('~'.code); case _: ret.addChar('%'.code); ret.addChar(cast c1); ret.addChar(cast c2); } case chr: ret.addChar(cast chr); } } return ret.toString(); } #end /** Decode an URL using the standard format. **/ #if (!java && !cpp && !lua) inline #end public static function urlDecode( s : String ) : String { #if flash return untyped __global__["decodeURIComponent"](s.split("+").join(" ")); #elseif neko return untyped new String(_urlDecode(s.__s)); #elseif js return untyped decodeURIComponent(s.split("+").join(" ")); #elseif cpp return untyped s.__URLDecode(); #elseif java try return untyped __java__("java.net.URLDecoder.decode(s, \"UTF-8\")") catch (e:Dynamic) throw e; #elseif cs return untyped cs.system.Uri.UnescapeDataString(s); #elseif python return python.lib.urllib.Parse.unquote(s); #elseif hl var len = 0; var b = @:privateAccess s.bytes.urlDecode(len); return @:privateAccess String.__alloc__(b,len); #elseif lua s = lua.NativeStringTools.gsub (s, "+", " "); s = lua.NativeStringTools.gsub (s, "%%(%x%x)", function(h) {return lua.NativeStringTools.char(lua.Lua.tonumber(h,16));}); s = lua.NativeStringTools.gsub (s, "\r\n", "\n"); return s; #else return null; #end } /** Escapes HTML special characters of the string `s`. The following replacements are made: - `&` becomes `&`; - `<` becomes `<`; - `>` becomes `>`; If `quotes` is true, the following characters are also replaced: - `"` becomes `"`; - `'` becomes `'`; **/ public static function htmlEscape( s : String, ?quotes : Bool ) : String { s = s.split("&").join("&").split("<").join("<").split(">").join(">"); return quotes ? s.split('"').join(""").split("'").join("'") : s; } /** Unescapes HTML special characters of the string `s`. This is the inverse operation to htmlEscape, i.e. the following always holds: `htmlUnescape(htmlEscape(s)) == s` The replacements follow: - `&` becomes `&` - `<` becomes `<` - `>` becomes `>` - `"` becomes `"` - `'` becomes `'` **/ public static function htmlUnescape( s : String ) : String { return s.split(">").join(">").split("<").join("<").split(""").join('"').split("'").join("'").split("&").join("&"); } /** Tells if the string `s` starts with the string `start`. If `start` is `null`, the result is unspecified. If `start` is the empty String `""`, the result is true. **/ public static #if (cs || java) inline #end function startsWith( s : String, start : String ) : Bool { #if java return untyped s.startsWith(start); #elseif cs return untyped s.StartsWith(start); #elseif cpp if (s.length= start.length && s.bytes.compare(0,start.bytes,0,start.length<<1) == 0); #else return( s.length >= start.length && s.substr(0, start.length) == start ); #end } /** Tells if the string `s` ends with the string `end`. If `end` is `null`, the result is unspecified. If `end` is the empty String `""`, the result is true. **/ public static #if (cs || java) inline #end function endsWith( s : String, end : String ) : Bool { #if java return untyped s.endsWith(end); #elseif cs return untyped s.EndsWith(end); #elseif cpp if (s.length= elen && s.bytes.compare((slen - elen) << 1, end.bytes, 0, elen << 1) == 0); #else var elen = end.length; var slen = s.length; return( slen >= elen && s.substr(slen - elen, elen) == end ); #end } /** Tells if the character in the string `s` at position `pos` is a space. A character is considered to be a space character if its character code is 9,10,11,12,13 or 32. If `s` is the empty String `""`, or if pos is not a valid position within `s`, the result is false. **/ public static function isSpace( s : String, pos : Int ) : Bool { #if (python || lua) if (s.length == 0 || pos < 0 || pos >= s.length) return false; #end var c = s.charCodeAt( pos ); return (c > 8 && c < 14) || c == 32; } /** Removes leading space characters of `s`. This function internally calls `isSpace()` to decide which characters to remove. If `s` is the empty String `""` or consists only of space characters, the result is the empty String `""`. **/ public #if cs inline #end static function ltrim( s : String ) : String { #if cs return untyped s.TrimStart(); #else var l = s.length; var r = 0; while( r < l && isSpace(s,r) ){ r++; } if( r > 0 ) return s.substr(r, l-r); else return s; #end } /** Removes trailing space characters of `s`. This function internally calls `isSpace()` to decide which characters to remove. If `s` is the empty String `""` or consists only of space characters, the result is the empty String `""`. **/ public #if cs inline #end static function rtrim( s : String ) : String { #if cs return untyped s.TrimEnd(); #else var l = s.length; var r = 0; while( r < l && isSpace(s,l-r-1) ){ r++; } if( r > 0 ){ return s.substr(0, l-r); }else{ return s; } #end } /** Removes leading and trailing space characters of `s`. This is a convenience function for `ltrim(rtrim(s))`. **/ public #if (cs || java) inline #end static function trim( s : String ) : String { #if cs return untyped s.Trim(); #elseif java return untyped s.trim(); #else return ltrim(rtrim(s)); #end } /** Concatenates `c` to `s` until `s.length` is at least `l`. If `c` is the empty String `""` or if `l` does not exceed `s.length`, `s` is returned unchanged. If `c.length` is 1, the resulting String length is exactly `l`. Otherwise the length may exceed `l`. If `c` is null, the result is unspecified. **/ public static function lpad( s : String, c : String, l : Int ) : String { if (c.length <= 0) return s; while (s.length < l) { s = c + s; } return s; } /** Appends `c` to `s` until `s.length` is at least `l`. If `c` is the empty String `""` or if `l` does not exceed `s.length`, `s` is returned unchanged. If `c.length` is 1, the resulting String length is exactly `l`. Otherwise the length may exceed `l`. If `c` is null, the result is unspecified. **/ public static function rpad( s : String, c : String, l : Int ) : String { if (c.length <= 0) return s; while (s.length < l) { s = s + c; } return s; } /** Replace all occurrences of the String `sub` in the String `s` by the String `by`. If `sub` is the empty String `""`, `by` is inserted after each character of `s`. If `by` is also the empty String `""`, `s` remains unchanged. This is a convenience function for `s.split(sub).join(by)`. If `sub` or `by` are null, the result is unspecified. **/ public static function replace( s : String, sub : String, by : String ) : String { #if java if (sub.length == 0) return s.split(sub).join(by); else return untyped s.replace(sub, by); #elseif cs if (sub.length == 0) return s.split(sub).join(by); else return untyped s.Replace(sub, by); #else return s.split(sub).join(by); #end } /** Encodes `n` into a hexadecimal representation. If `digits` is specified, the resulting String is padded with "0" until its `length` equals `digits`. **/ public static function hex( n : Int, ?digits : Int ) { #if flash var n : UInt = n; var s : String = untyped n.toString(16); s = s.toUpperCase(); #else var s = ""; var hexChars = "0123456789ABCDEF"; do { s = hexChars.charAt(n&15) + s; n >>>= 4; } while( n > 0 ); #end #if python if (digits != null && s.length < digits) { var diff = digits - s.length; for (_ in 0...diff) { s = "0" + s; } } #else if( digits != null ) while( s.length < digits ) s = "0"+s; #end return s; } /** Returns the character code at position `index` of String `s`, or an end-of-file indicator at if `position` equals `s.length`. This method is faster than `String.charCodeAt()` on some platforms, but the result is unspecified if `index` is negative or greater than `s.length`. End of file status can be checked by calling `StringTools.isEof()` with the returned value as argument. This operation is not guaranteed to work if `s` contains the `\0` character. **/ public static inline function fastCodeAt( s : String, index : Int ) : Int { #if neko return untyped __dollar__sget(s.__s, index); #elseif cpp return untyped s.cca(index); #elseif flash return untyped s.cca(index); #elseif java return ( index < s.length ) ? cast(_charAt(s, index), Int) : -1; #elseif cs return ( cast(index, UInt) < s.length ) ? cast(s[index], Int) : -1; #elseif js return (untyped s).charCodeAt(index); #elseif python return if (index >= s.length) -1 else python.internal.UBuiltins.ord(python.Syntax.arrayAccess(s, index)); #elseif hl return @:privateAccess s.bytes.getUI16(index << 1); #elseif lua return lua.NativeStringTools.byte(s,index+1); #else return untyped s.cca(index); #end } /* Tells if `c` represents the end-of-file (EOF) character. */ @:noUsing public static inline function isEof( c : Int ) : Bool { #if (flash || cpp || hl) return c == 0; #elseif js return c != c; // fast NaN #elseif (neko || lua) return c == null; #elseif cs return c == -1; #elseif java return c == -1; #elseif python return c == -1; #else return false; #end } /** Returns a String that can be used as a single command line argument on Unix. The input will be quoted, or escaped if necessary. */ public static function quoteUnixArg(argument:String):String { // Based on cpython's shlex.quote(). // https://hg.python.org/cpython/file/a3f076d4f54f/Lib/shlex.py#l278 if (argument == "") return "''"; if (!~/[^a-zA-Z0-9_@%+=:,.\/-]/.match(argument)) return argument; // use single quotes, and put single quotes into double quotes // the string $'b is then quoted as '$'"'"'b' return "'" + replace(argument, "'", "'\"'\"'") + "'"; } /** Character codes of the characters that will be escaped by `quoteWinArg(_, true)`. */ public static var winMetaCharacters = [" ".code, "(".code, ")".code, "%".code, "!".code, "^".code, "\"".code, "<".code, ">".code, "&".code, "|".code, "\n".code, "\r".code, ",".code, ";".code]; /** Returns a String that can be used as a single command line argument on Windows. The input will be quoted, or escaped if necessary, such that the output will be parsed as a single argument using the rule specified in http://msdn.microsoft.com/en-us/library/ms880421 Examples: ``` quoteWinArg("abc") == "abc"; quoteWinArg("ab c") == '"ab c"'; ``` */ public static function quoteWinArg(argument:String, escapeMetaCharacters:Bool):String { // If there is no space, tab, back-slash, or double-quotes, and it is not an empty string. if (!~/^[^ \t\\"]+$/.match(argument)) { // Based on cpython's subprocess.list2cmdline(). // https://hg.python.org/cpython/file/50741316dd3a/Lib/subprocess.py#l620 var result = new StringBuf(); var needquote = argument.indexOf(" ") != -1 || argument.indexOf("\t") != -1 || argument == ""; if (needquote) result.add('"'); var bs_buf = new StringBuf(); for (i in 0...argument.length) { switch (argument.charCodeAt(i)) { case "\\".code: // Don't know if we need to double yet. bs_buf.add("\\"); case '"'.code: // Double backslashes. var bs = bs_buf.toString(); result.add(bs); result.add(bs); bs_buf = new StringBuf(); result.add('\\"'); case c: // Normal char if (bs_buf.length > 0) { result.add(bs_buf.toString()); bs_buf = new StringBuf(); } result.addChar(c); } } // Add remaining backslashes, if any. result.add(bs_buf.toString()); if (needquote) { result.add(bs_buf.toString()); result.add('"'); } argument = result.toString(); } if (escapeMetaCharacters) { var result = new StringBuf(); for (i in 0...argument.length) { var c = argument.charCodeAt(i); if (winMetaCharacters.indexOf(c) >= 0) { result.addChar("^".code); } result.addChar(c); } return result.toString(); } else { return argument; } } #if java private static inline function _charAt(str:String, idx:Int):java.StdTypes.Char16 return untyped str._charAt(idx); #end #if neko private static var _urlEncode = neko.Lib.load("std","url_encode",1); private static var _urlDecode = neko.Lib.load("std","url_decode",1); #end } haxe_3.4.4.orig/std/Sys.hx0000664000175000017500000001236013166552354015327 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** This class gives you access to many base functionalities of system platforms. Looks in `sys` sub packages for more system APIs. **/ @:require(sys) extern class Sys { /** Print any value on the standard output. **/ static function print( v : Dynamic ) : Void; /** Print any value on the standard output, followed by a newline. **/ static function println( v : Dynamic ) : Void; /** Returns all the arguments that were passed by the command line. **/ static function args() : Array; /** Returns the value of the given environment variable. **/ static function getEnv( s : String ) : String; /** Set the value of the given environment variable. **/ static function putEnv( s : String, v : String ) : Void; /** Returns all environment variables. **/ static function environment() : Map; /** Suspend the current execution for the given time (in seconds). **/ static function sleep( seconds : Float ) : Void; /** Change the current time locale, which will affect `DateTools.format` date formating. Returns true if the locale was successfully changed **/ static function setTimeLocale( loc : String ) : Bool; /** Get the current working directory (usually the one in which the program was started) **/ static function getCwd() : String; /** Change the current working directory. **/ static function setCwd( s : String ) : Void; /** Returns the name of the system you are running on. For instance : "Windows", "Linux", "BSD" and "Mac" depending on your desktop OS. **/ static function systemName() : String; /** Run the given command. The command output will be printed on the same output as the current process. The current process will block until the command terminates and it will return the command result (0 if there was no error). Command arguments can be passed in two ways: 1. using `args`, 2. appending to `cmd` and leaving `args` as `null`. 1. When using `args` to pass command arguments, each argument will be automatically quoted, and shell meta-characters will be escaped if needed. `cmd` should be an executable name that can be located in the `PATH` environment variable, or a path to an executable. 2. When `args` is not given or is `null`, command arguments can be appended to `cmd`. No automatic quoting/escaping will be performed. `cmd` should be formatted exactly as it would be when typed at the command line. It can run executables, as well as shell commands that are not executables (e.g. on Windows: `dir`, `cd`, `echo` etc). Read the `sys.io.Process` api for a more complete way to start background processes. **/ static function command( cmd : String, ?args : Array ) : Int; /** Exit the current process with the given error code. **/ static function exit( code : Int ) : Void; /** Gives the most precise timestamp value (in seconds). **/ static function time() : Float; /** Gives the most precise timestamp value (in seconds) but only account for the actual time spent running on the CPU for the current thread/process. **/ static function cpuTime() : Float; /** Returns the path to the current executable that we are running. **/ @:deprecated("Use programPath instead") static function executablePath() : String; /** Returns the absolute path to the current program file that we are running. Concretely, for an executable binary, it returns the path to the binary. For a script (e.g. a PHP file), it returns the path to the script. **/ static function programPath() : String; /** Read a single input character from the standard input (without blocking) and returns it. Setting `echo` to true will also display it on the output. **/ static function getChar( echo : Bool ) : Int; /** Returns the process standard input, from which you can read what user enters. Usually it will block until the user send a full input line. See `getChar` for an alternative. **/ static function stdin() : haxe.io.Input; /** Returns the process standard output on which you can write. **/ static function stdout() : haxe.io.Output; /** Returns the process standard error on which you can write. **/ static function stderr() : haxe.io.Output; } haxe_3.4.4.orig/std/Type.hx0000664000175000017500000002233513166552354015475 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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 Reflection API allows retrieval of type information at runtime. This class complements the more lightweight Reflect class, with a focus on class and enum instances. @see https://haxe.org/manual/types.html @see https://haxe.org/manual/std-reflection.html **/ extern class Type { /** Returns the class of `o`, if `o` is a class instance. If `o` is null or of a different type, null is returned. In general, type parameter information cannot be obtained at runtime. **/ public static function getClass( o : T ) : Class; /** Returns the enum of enum instance `o`. An enum instance is the result of using an enum constructor. Given an `enum Color { Red; }`, `getEnum(Red)` returns `Enum`. If `o` is null, null is returned. In general, type parameter information cannot be obtained at runtime. **/ public static function getEnum( o : EnumValue ) : Enum; /** Returns the super-class of class `c`. If `c` has no super class, null is returned. If `c` is null, the result is unspecified. In general, type parameter information cannot be obtained at runtime. **/ public static function getSuperClass( c : Class ) : Class; /** Returns the name of class `c`, including its path. If `c` is inside a package, the package structure is returned dot- separated, with another dot separating the class name: `pack1.pack2.(...).packN.ClassName` If `c` is a sub-type of a Haxe module, that module is not part of the package structure. If `c` has no package, the class name is returned. If `c` is null, the result is unspecified. The class name does not include any type parameters. **/ public static function getClassName( c : Class ) : String; /** Returns the name of enum `e`, including its path. If `e` is inside a package, the package structure is returned dot- separated, with another dot separating the enum name: `pack1.pack2.(...).packN.EnumName` If `e` is a sub-type of a Haxe module, that module is not part of the package structure. If `e` has no package, the enum name is returned. If `e` is null, the result is unspecified. The enum name does not include any type parameters. **/ public static function getEnumName( e : Enum ) : String; /** Resolves a class by name. If `name` is the path of an existing class, that class is returned. Otherwise null is returned. If `name` is null or the path to a different type, the result is unspecified. The class name must not include any type parameters. **/ public static function resolveClass( name : String ) : Class; /** Resolves an enum by name. If `name` is the path of an existing enum, that enum is returned. Otherwise null is returned. If `name` is null the result is unspecified. If `name` is the path to a different type, null is returned. The enum name must not include any type parameters. **/ public static function resolveEnum( name : String ) : Enum; /** Creates an instance of class `cl`, using `args` as arguments to the class constructor. This function guarantees that the class constructor is called. Default values of constructors arguments are not guaranteed to be taken into account. If `cl` or `args` are null, or if the number of elements in `args` does not match the expected number of constructor arguments, or if any argument has an invalid type, or if `cl` has no own constructor, the result is unspecified. In particular, default values of constructor arguments are not guaranteed to be taken into account. **/ public static function createInstance( cl : Class, args : Array ) : T; /** Creates an instance of class `cl`. This function guarantees that the class constructor is not called. If `cl` is null, the result is unspecified. **/ public static function createEmptyInstance( cl : Class ) : T; /** Creates an instance of enum `e` by calling its constructor `constr` with arguments `params`. If `e` or `constr` is null, or if enum `e` has no constructor named `constr`, or if the number of elements in `params` does not match the expected number of constructor arguments, or if any argument has an invalid type, the result is unspecified. **/ public static function createEnum( e : Enum, constr : String, ?params : Array ) : T; /** Creates an instance of enum `e` by calling its constructor number `index` with arguments `params`. The constructor indices are preserved from Haxe syntax, so the first declared is index 0, the next index 1 etc. If `e` or `constr` is null, or if enum `e` has no constructor named `constr`, or if the number of elements in `params` does not match the expected number of constructor arguments, or if any argument has an invalid type, the result is unspecified. **/ public static function createEnumIndex( e : Enum, index : Int, ?params : Array ) : T; /** Returns a list of the instance fields of class `c`. This only includes fields which are known at compile-time. In particular, using getInstanceFields(getClass(obj)) will not include any fields which were added to obj at runtime. The order of the fields in the returned Array is unspecified. If `c` is null, the result is unspecified. (As3) This method only returns instance fields that are public. **/ public static function getInstanceFields( c : Class ) : Array; /** Returns a list of static fields of class `c`. This does not include static fields of parent classes. The order of the fields in the returned Array is unspecified. If `c` is null, the result is unspecified. (As3) This method only returns class fields that are public. **/ public static function getClassFields( c : Class ) : Array; /** Returns a list of the names of all constructors of enum `e`. The order of the constructor names in the returned Array is preserved from the original syntax. If `c` is null, the result is unspecified. **/ public static function getEnumConstructs( e : Enum ) : Array; /** Returns the runtime type of value `v`. The result corresponds to the type `v` has at runtime, which may vary per platform. Assumptions regarding this should be minimized to avoid surprises. **/ public static function typeof( v : Dynamic ) : ValueType; /** Recursively compares two enum instances `a` and `b` by value. Unlike `a == b`, this function performs a deep equality check on the arguments of the constructors, if exists. If `a` or `b` are null, the result is unspecified. **/ public static function enumEq( a : T, b : T ) : Bool; /** Returns the constructor name of enum instance `e`. The result String does not contain any constructor arguments. If `e` is null, the result is unspecified. **/ public static function enumConstructor( e : EnumValue ) : String; /** Returns a list of the constructor arguments of enum instance `e`. If `e` has no arguments, the result is []. Otherwise the result are the values that were used as arguments to `e`, in the order of their declaration. If `e` is null, the result is unspecified. **/ public static function enumParameters( e : EnumValue ) : Array; /** Returns the index of enum instance `e`. This corresponds to the original syntactic position of `e`. The index of the first declared constructor is 0, the next one is 1 etc. If `e` is null, the result is unspecified. **/ public static function enumIndex( e : EnumValue ) : Int; /** Returns a list of all constructors of enum `e` that require no arguments. This may return the empty Array `[]` if all constructors of `e` require arguments. Otherwise an instance of `e` constructed through each of its non- argument constructors is returned, in the order of the constructor declaration. If `e` is null, the result is unspecified. **/ public static function allEnums( e : Enum ) : Array; } /** The different possible runtime types of a value. **/ enum ValueType { TNull; TInt; TFloat; TBool; TObject; TFunction; TClass( c : Class ); TEnum( e : Enum ); TUnknown; } haxe_3.4.4.orig/std/UInt.hx0000664000175000017500000002312013166552354015424 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ #if ((flash || flash9doc || cs || hl) && !doc_gen) /** The unsigned `Int` type is only defined for Flash and C#. It's currently handled the same as a normal Int. @see https://haxe.org/manual/types-basic-types.html **/ @:coreType @:notNull @:runtimeValue @:analyzer(no_const_propagation) abstract UInt to Int from Int { @:commutative @:op(A+B) private static function addI(lhs:UInt, rhs:Int):UInt; @:commutative @:op(A+B) private static function addF(lhs:UInt, rhs:Float):Float; @:op(A+B) private static function add(lhs:UInt, rhs:UInt):UInt; @:commutative @:op(A*B) private static function mulI(lhs:UInt, rhs:Int):UInt; @:commutative @:op(A*B) private static function mulF(lhs:UInt, rhs:Float):Float; @:op(A*B) private static function mul(lhs:UInt, rhs:UInt):UInt; @:op(A%B) private static function modI(lhs:UInt, rhs:Int):UInt; @:op(A%B) private static function modF(lhs:UInt, rhs:Float):Float; @:op(A%B) private static function mod(lhs:UInt, rhs:UInt):UInt; @:op(A-B) private static function subI(lhs:UInt, rhs:Int):UInt; @:op(A-B) private static function subF(lhs:UInt, rhs:Float):Float; @:op(A-B) private static function sub(lhs:UInt, rhs:UInt):UInt; @:op(A/B) private static function divI(lhs:UInt, rhs:Int):Float; @:op(A/B) private static function divF(lhs:UInt, rhs:Float):Float; @:op(A/B) private static function div(lhs:UInt, rhs:UInt):Float; @:commutative @:op(A|B) private static function orI(lhs:UInt, rhs:Int):UInt; @:op(A|B) private static function or(lhs:UInt, rhs:UInt):UInt; @:commutative @:op(A^B) private static function xorI(lhs:UInt, rhs:Int):UInt; @:op(A^B) private static function xor(lhs:UInt, rhs:UInt):UInt; @:commutative @:op(A&B) private static function andI(lhs:UInt, rhs:Int):UInt; @:op(A&B) private static function and(lhs:UInt, rhs:UInt):UInt; @:op(A<>B) private static inline function shr(lhs:UInt, rhs:Int):UInt return lhs >>> rhs; @:op(A>>>B) private static function ushr(lhs:UInt, rhs:Int):UInt; @:op(A>B) private static function gt(lhs:UInt, rhs:UInt):Bool; @:op(A>=B) private static function gte(lhs:UInt, rhs:UInt):Bool; @:op(AB) private static function gtf(lhs:UInt, rhs:Float):Bool; @:op(A>B) private static function gtf2(lhs:Float, rhs:UInt):Bool; @:op(A>=B) private static function gtef(lhs:UInt, rhs:Float):Bool; @:op(A>=B) private static function gtef2(lhs:Float, rhs:UInt):Bool; @:op(A(a:UInt, b:T):Bool; @:commutative @:op(A != B) private static function notEqualsInt(a:UInt, b:T):Bool; @:commutative @:op(A == B) private static function equalsFloat(a:UInt, b:T):Bool; @:commutative @:op(A != B) private static function notEqualsFloat(a:UInt, b:T):Bool; @:op(++A) private function prefixIncrement():UInt; @:op(A++) private function postfixIncrement():UInt; @:op(--A) private function prefixDecrement():UInt; @:op(A--) private function postfixDecrement():UInt; } #else /** The unsigned `Int` type is only defined for Flash and C#. Simulate it for other platforms. @see https://haxe.org/manual/types-basic-types.html **/ abstract UInt(Int) from Int to Int { @:op(A + B) private static inline function add(a:UInt, b:UInt):UInt { return a.toInt() + b.toInt(); } @:op(A / B) private static inline function div(a:UInt, b:UInt):Float { return a.toFloat() / b.toFloat(); } @:op(A * B) private static inline function mul(a:UInt, b:UInt):UInt { return a.toInt() * b.toInt(); } @:op(A - B) private static inline function sub(a:UInt, b:UInt):UInt { return a.toInt() - b.toInt(); } @:op(A > B) private static #if !js inline #end function gt(a:UInt, b:UInt):Bool { var aNeg = a.toInt() < 0; var bNeg = b.toInt() < 0; return if( aNeg != bNeg ) aNeg; else a.toInt() > b.toInt(); } @:op(A >= B) private static #if !js inline #end function gte(a:UInt, b:UInt):Bool { var aNeg = a.toInt() < 0; var bNeg = b.toInt() < 0; return if( aNeg != bNeg ) aNeg; else a.toInt() >= b.toInt(); } @:op(A < B) private static inline function lt(a:UInt, b:UInt):Bool { return gt(b, a); } @:op(A <= B) private static inline function lte(a:UInt, b:UInt):Bool { return gte(b, a); } @:op(A & B) private static inline function and(a:UInt, b:UInt):UInt { return a.toInt() & b.toInt(); } @:op(A | B) private static inline function or(a:UInt, b:UInt):UInt { return a.toInt() | b.toInt(); } @:op(A ^ B) private static inline function xor(a:UInt, b:UInt):UInt { return a.toInt() ^ b.toInt(); } @:op(A << B) private static inline function shl(a:UInt, b:Int):UInt { return a.toInt() << b; } @:op(A >> B) private static inline function shr(a:UInt, b:Int):UInt { return a.toInt() >>> b; } @:op(A >>> B) private static inline function ushr(a:UInt, b:Int):UInt { return a.toInt() >>> b; } @:op(A % B) private static inline function mod(a:UInt, b:UInt):UInt { return Std.int( a.toFloat() % b.toFloat() ); } @:commutative @:op(A + B) private static inline function addWithFloat(a:UInt, b:Float):Float { return a.toFloat() + b; } @:commutative @:op(A * B) private static inline function mulWithFloat(a:UInt, b:Float):Float { return a.toFloat() * b; } @:op(A / B) private static inline function divFloat(a:UInt, b:Float):Float { return a.toFloat() / b; } @:op(A / B) private static inline function floatDiv(a:Float, b:UInt):Float { return a / b.toFloat(); } @:op(A - B) private static inline function subFloat(a:UInt, b:Float):Float { return a.toFloat() - b; } @:op(A - B) private static inline function floatSub(a:Float, b:UInt):Float { return a - b.toFloat(); } @:op(A > B) private static inline function gtFloat(a:UInt, b:Float):Bool { return a.toFloat() > b; } @:commutative @:op(A == B) private static inline function equalsInt(a:UInt, b:T):Bool { return a.toInt() == b; } @:commutative @:op(A != B) private static inline function notEqualsInt(a:UInt, b:T):Bool { return a.toInt() != b; } @:commutative @:op(A == B) private static inline function equalsFloat(a:UInt, b:T):Bool { return a.toFloat() == b; } @:commutative @:op(A != B) private static inline function notEqualsFloat(a:UInt, b:T):Bool { return a.toFloat() != b; } @:op(A >= B) private static inline function gteFloat(a:UInt, b:Float):Bool { return a.toFloat() >= b; } @:op(A > B) private static inline function floatGt(a:Float, b:UInt):Bool { return a > b.toFloat(); } @:op(A >= B) private static inline function floatGte(a:Float, b:UInt):Bool { return a >= b.toFloat(); } @:op(A < B) private static inline function ltFloat(a:UInt, b:Float):Bool { return a.toFloat() < b; } @:op(A <= B) private static inline function lteFloat(a:UInt, b:Float):Bool { return a.toFloat() <= b; } @:op(A < B) private static inline function floatLt(a:Float, b:UInt):Bool { return a < b.toFloat(); } @:op(A <= B) private static inline function floatLte(a:Float, b:UInt):Bool { return a <= b.toFloat(); } @:op(A % B) private static inline function modFloat(a:UInt, b:Float):Float { return a.toFloat() % b; } @:op(A % B) private static inline function floatMod(a:Float, b:UInt):Float { return a % b.toFloat(); } @:op(~A) private inline function negBits():UInt { return ~this; } @:op(++A) private inline function prefixIncrement():UInt { return ++this; } @:op(A++) private inline function postfixIncrement():UInt { return this++; } @:op(--A) private inline function prefixDecrement():UInt { return --this; } @:op(A--) private inline function postfixDecrement():UInt { return this--; } // TODO: radix is just defined to deal with doc_gen issues private inline function toString(?radix:Int):String { return Std.string(toFloat()); } private inline function toInt():Int { return this; } @:to private #if (!js || analyzer) inline #end function toFloat():Float { var int = toInt(); if (int < 0) { return 4294967296.0 + int; } else { // + 0.0 here to make sure we promote to Float on some platforms // In particular, PHP was having issues when comparing to Int in the == op. return int + 0.0; } } } #end haxe_3.4.4.orig/std/Xml.hx0000664000175000017500000002325413166552354015315 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ /** Xml node types. @see https://haxe.org/manual/std-Xml.html **/ @:enum abstract XmlType(Int) { /** Represents an XML element type. **/ var Element = 0; /** Represents XML parsed character data type. **/ var PCData = 1; /** Represents XML character data type. **/ var CData = 2; /** Represents an XML comment type. **/ var Comment = 3; /** Represents an XML doctype element type. **/ var DocType = 4; /** Represents an XML processing instruction type. **/ var ProcessingInstruction = 5; /** Represents an XML document type. **/ var Document = 6; } /** Cross-platform Xml API. @see https://haxe.org/manual/std-Xml.html **/ class Xml { /** XML element type. **/ static public var Element(default,never) = XmlType.Element; /** XML parsed character data type. **/ static public var PCData(default,never) = XmlType.PCData; /** XML character data type. **/ static public var CData(default,never) = XmlType.CData; /** XML comment type. **/ static public var Comment(default,never) = XmlType.Comment; /** XML doctype element type. **/ static public var DocType(default,never) = XmlType.DocType; /** XML processing instruction type. **/ static public var ProcessingInstruction(default,never) = XmlType.ProcessingInstruction; /** XML document type. **/ static public var Document(default,never) = XmlType.Document; /** Parses the String into an Xml document. **/ static public function parse( str : String ) : Xml { return haxe.xml.Parser.parse(str); } /** Returns the type of the Xml Node. This should be used before accessing other functions since some might raise an exception if the node type is not correct. **/ public var nodeType(default, null) : XmlType; /** Returns the node name of an Element. **/ @:isVar public var nodeName(get, set) : String; /** Returns the node value. Only works if the Xml node is not an Element or a Document. **/ @:isVar public var nodeValue(get, set) : String; /** Returns the parent object in the Xml hierarchy. The parent can be `null`, an Element or a Document. **/ public var parent(default, null) : Xml; var children:Array; var attributeMap:Map; #if !cppia inline #end function get_nodeName() { if (nodeType != Element) { throw 'Bad node type, expected Element but found $nodeType'; } return nodeName; } #if !cppia inline #end function set_nodeName(v) { if (nodeType != Element) { throw 'Bad node type, expected Element but found $nodeType'; } return this.nodeName = v; } #if !cppia inline #end function get_nodeValue() { if (nodeType == Document || nodeType == Element) { throw 'Bad node type, unexpected $nodeType'; } return nodeValue; } #if !cppia inline #end function set_nodeValue(v) { if (nodeType == Document || nodeType == Element) { throw 'Bad node type, unexpected $nodeType'; } return this.nodeValue = v; } /** Creates a node of the given type. **/ static public function createElement( name : String ) : Xml { var xml = new Xml(Element); xml.nodeName = name; return xml; } /** Creates a node of the given type. **/ static public function createPCData( data : String ) : Xml { var xml = new Xml(PCData); xml.nodeValue = data; return xml; } /** Creates a node of the given type. **/ static public function createCData( data : String ) : Xml { var xml = new Xml(CData); xml.nodeValue = data; return xml; } /** Creates a node of the given type. **/ static public function createComment( data : String ) : Xml { var xml = new Xml(Comment); xml.nodeValue = data; return xml; } /** Creates a node of the given type. **/ static public function createDocType( data : String ) : Xml { var xml = new Xml(DocType); xml.nodeValue = data; return xml; } /** Creates a node of the given type. **/ static public function createProcessingInstruction( data : String ) : Xml { var xml = new Xml(ProcessingInstruction); xml.nodeValue = data; return xml; } /** Creates a node of the given type. **/ static public function createDocument() : Xml { return new Xml(Document); } /** Get the given attribute of an Element node. Returns `null` if not found. Attributes are case-sensitive. **/ public function get( att : String ) : String { if (nodeType != Element) { throw 'Bad node type, expected Element but found $nodeType'; } return attributeMap[att]; } /** Set the given attribute value for an Element node. Attributes are case-sensitive. **/ public function set( att : String, value : String ) : Void { if (nodeType != Element) { throw 'Bad node type, expected Element but found $nodeType'; } attributeMap.set(att, value); } /** Removes an attribute for an Element node. Attributes are case-sensitive. **/ public function remove( att : String ) : Void { if (nodeType != Element) { throw 'Bad node type, expected Element but found $nodeType'; } attributeMap.remove(att); } /** Tells if the Element node has a given attribute. Attributes are case-sensitive. **/ public function exists( att : String ) : Bool { if (nodeType != Element) { throw 'Bad node type, expected Element but found $nodeType'; } return attributeMap.exists(att); } /** Returns an `Iterator` on all the attribute names. **/ public function attributes() : Iterator { if (nodeType != Element) { throw 'Bad node type, expected Element but found $nodeType'; } return attributeMap.keys(); } /** Returns an iterator of all child nodes. Only works if the current node is an Element or a Document. **/ public #if !cppia inline #end function iterator() : Iterator { ensureElementType(); return children.iterator(); } /** Returns an iterator of all child nodes which are Elements. Only works if the current node is an Element or a Document. **/ public function elements() : Iterator { ensureElementType(); var ret = [for (child in children) if (child.nodeType == Element) child]; return ret.iterator(); } /** Returns an iterator of all child nodes which are Elements with the given nodeName. Only works if the current node is an Element or a Document. **/ public function elementsNamed( name : String ) : Iterator { ensureElementType(); var ret = [for (child in children) if (child.nodeType == Element && child.nodeName == name) child]; return ret.iterator(); } /** Returns the first child node. **/ public #if !cppia inline #end function firstChild() : Xml { ensureElementType(); return children[0]; } /** Returns the first child node which is an Element. **/ public function firstElement() : Xml { ensureElementType(); for (child in children) { if (child.nodeType == Element) { return child; } } return null; } /** Adds a child node to the Document or Element. A child node can only be inside one given parent node, which is indicated by the `parent` property. If the child is already inside this Document or Element, it will be moved to the last position among the Document or Element's children. If the child node was previously inside a different node, it will be moved to this Document or Element. **/ public function addChild( x : Xml ) : Void { ensureElementType(); if (x.parent != null) { x.parent.removeChild(x); } children.push(x); x.parent = this; } /** Removes a child from the Document or Element. Returns true if the child was successfuly removed. **/ public function removeChild( x : Xml ) : Bool { ensureElementType(); if (children.remove(x)) { x.parent = null; return true; } return false; } /** Inserts a child at the given position among the other childs. A child node can only be inside one given parent node, which is indicated by the [parent] property. If the child is already inside this Document or Element, it will be moved to the new position among the Document or Element's children. If the child node was previously inside a different node, it will be moved to this Document or Element. **/ public function insertChild( x : Xml, pos : Int ) : Void { ensureElementType(); if (x.parent != null) { x.parent.children.remove(x); } children.insert(pos, x); x.parent = this; } /** Returns a String representation of the Xml node. **/ public #if !cppia inline #end function toString() : String { return haxe.xml.Printer.print(this); } function new(nodeType:XmlType) { this.nodeType = nodeType; children = []; attributeMap = new Map(); } inline function ensureElementType() { if (nodeType != Document && nodeType != Element) { throw 'Bad node type, expected Element or Document but found $nodeType'; } } } haxe_3.4.4.orig/std/cpp/ArrayBase.hx0000664000175000017500000000253113166552354017203 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; extern class ArrayBase { // Length is number of elements public var length(default,null):Int; public function getElementSize():Int; public function getByteCount():Int; public function getBase():RawPointer; } haxe_3.4.4.orig/std/cpp/AtomicInt.hx0000664000175000017500000000103013166552354017212 0ustar andyandy00000000000000package cpp; @:scalar @:coreType extern abstract AtomicInt from(Int) to(Int) { // returns true if exchange took place @:native("_hx_atomic_exchange_if") public static function exchangeIf(ioValue:Pointer, test:Int, newVal:Int) : Bool; // returns value before increment @:native("_hx_atomic_inc") public static function atomicInc(ioValue:Pointer) : Int; // returns value before decrement @:native("_hx_atomic_dec") public static function atomicDec(ioValue:Pointer) : Int; } haxe_3.4.4.orig/std/cpp/AutoCast.hx0000664000175000017500000000221413166552354017053 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; extern class AutoCast { } haxe_3.4.4.orig/std/cpp/Callable.hx0000664000175000017500000000475613166552354017044 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:noPackageRestrict @:callable typedef CallableData = T; // The generator intercepts this type and converts it to a cpp.Function on cpp @:noPackageRestrict @:callable #if cpp extern #end abstract Callable( CallableData ) { inline public function new(inValue:T) this = inValue; public var call(get,never):CallableData; inline function get_call():CallableData return this; #if cpp @:from inline static public function fromFunction( func:Function ) : Callable return new Callable(cast func); @:to inline public function toFunction() : Function return cast this; inline public static function getProcAddress(inModule:String, inFunction:String) : Function return Function.getProcAddress(inModule, inFunction); inline public static function fromStaticFunction(inStaticFunction:T) : Callable return Function.fromStaticFunction(inStaticFunction); inline public function lt(inOther:Callable):Bool return toFunction().lt(inOther.toFunction()); inline public function leq(inOther:Callable):Bool return toFunction().leq(inOther.toFunction()); inline public function gt(inOther:Callable):Bool return toFunction().gt(inOther.toFunction()); inline public function geq(inOther:Callable):Bool return toFunction().geq(inOther.toFunction()); #end } haxe_3.4.4.orig/std/cpp/CastCharStar.hx0000664000175000017500000000261613166552354017660 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; abstract CastCharStar( RawPointer ) to(RawPointer) { inline function new(s:String) this = cast untyped s.__s; @:from static public inline function fromString(s:String) return new CastCharStar(s); @:to public inline function toPointer() return this; } haxe_3.4.4.orig/std/cpp/Char.hx0000664000175000017500000000227013166552354016207 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:notNull @:runtimeValue abstract Char from Int to Int {} haxe_3.4.4.orig/std/cpp/ConstCharStar.hx0000664000175000017500000000300613166552354020046 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:extern abstract ConstCharStar( RawConstPointer ) to(RawConstPointer) { inline function new(s:String) this = untyped s.__s; @:from static public inline function fromString(s:String) return new ConstCharStar(s); @:to @:extern public inline function toString():String return new String(untyped this); @:to @:extern public inline function toPointer() return this; } haxe_3.4.4.orig/std/cpp/ConstPointer.hx0000664000175000017500000000504113166552354017760 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:include("cpp/Pointer.h") @:native("cpp.Pointer") @:analyzer(as_var) extern class ConstPointer { // ptr actually returns the pointer - not strictly a 'T' - for pointers to smart pointers // Use value or ref to get dereferenced value public var ptr:Star; public var value(get,never):T; // Typecast to non-const public var raw(get,never):RawPointer; // const version public var constRaw(get,never):RawConstPointer; public function get_value() : Reference; public function get_constRaw() : RawConstPointer; public function get_raw() : RawPointer; public function lt(inOther:ConstPointer):Bool; public function leq(inOther:ConstPointer):Bool; public function gt(inOther:ConstPointer):Bool; public function geq(inOther:ConstPointer):Bool; public function setRaw(ptr:RawPointer) : Void; public static function fromRaw(ptr:RawConstPointer) : ConstPointer; public static function fromPointer(inNativePointer:Dynamic) : ConstPointer; public function reinterpret():Pointer; public function rawCast():RawPointer; public function at(inIndex:Int):Reference; public function inc():ConstPointer; public function dec():ConstPointer; public function postIncVal():Reference; public function incBy(inT:Int):ConstPointer; public function add(inT:Int):ConstPointer; } haxe_3.4.4.orig/std/cpp/ConstStar.hx0000664000175000017500000000235113166552354017252 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; // Allows haxe to type result correctly, and hxcpp can recognise this use the correct type typedef ConstStar = T; haxe_3.4.4.orig/std/cpp/EnumBase.hx0000664000175000017500000000244213166552354017032 0ustar andyandy00000000000000package cpp; @:native("hx.EnumBase") extern class EnumBase { #if (hxcpp_api_level >= 330) public function _hx_getIndex():Int; public function _hx_getTag():String; public function _hx_getParamCount():Int; public function _hx_getParamI(inIndex:Int):Dynamic; public function _hx_getParameters():Array; inline public function getIndex():Int return _hx_getIndex(); inline public function getTag():String return _hx_getTag(); inline public function getParamCount():Int return _hx_getParamCount(); inline public function getParamI(inIndex:Int):Dynamic return _hx_getParamI(inIndex); inline public function getParameters():Array return _hx_getParameters(); #else public function __EnumParams():Array; public function __Tag():String; public function __Index():Int; inline public function _hx_getIndex():Int return untyped __Index(); inline public function _hx_getTag():String return untyped __Tag(); inline public function _hx_getParamCount():Int return untyped __EnumParams()==null ? 0 : __EnumParams().length; inline public function _hx_getParamI(inIndex:Int):Dynamic return untyped __EnumParams()[inIndex]; inline public function _hx_getParameters():Array return __EnumParams()==null ? [] : __EnumParams(); #end } haxe_3.4.4.orig/std/cpp/FILE.hx0000664000175000017500000000230113166552354016044 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:include("stdio.h") @:native(" ::cpp::Pointer") extern class FILE { } haxe_3.4.4.orig/std/cpp/FastIterator.hx0000664000175000017500000000232013166552354017735 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; extern class FastIterator { public function hasNext():Bool; public function next():T; } haxe_3.4.4.orig/std/cpp/Finalizable.hx0000664000175000017500000000052213166552354017550 0ustar andyandy00000000000000package cpp; // This is just a helper class. You do not actually need to inherit from this to use // NativeGc.addFinalizable(this,inPin), you just need a function called "finalize" class Finalizable { public function new(inPin = false) { NativeGc.addFinalizable(this,inPin); } public function finalize():Void { } } haxe_3.4.4.orig/std/cpp/Float32.hx0000664000175000017500000000227713166552354016553 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:notNull @:runtimeValue abstract Float32 from Float to Float {} haxe_3.4.4.orig/std/cpp/Float64.hx0000664000175000017500000000227713166552354016560 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:notNull @:runtimeValue abstract Float64 from Float to Float {} haxe_3.4.4.orig/std/cpp/Function.hx0000664000175000017500000000465013166552354017123 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:callable typedef FunctionData = T; @:include("cpp/Pointer.h") @:callable extern abstract Function( FunctionData ) { inline public function new(inValue:T) this = inValue; // Legacy Api public var call(get,never):FunctionData; inline function get_call():FunctionData return this; @:native("::cpp::Function_obj::getProcAddress") @:extern static function nativeGetProcAddress(inModule:String, inFunction:String) : AutoCast return null; inline public static function getProcAddress(inModule:String, inFunction:String) : Function { return cast nativeGetProcAddress(inModule, inFunction); } @:native("::cpp::Function_obj::fromStaticFunction") @:extern static function nativeFromStaticFunction(inStaticFunction:T) : AutoCast return null; inline public static function fromStaticFunction(inStaticFunction:T) : Callable { return cast nativeFromStaticFunction(inStaticFunction); } @:extern public function lt(inOther:Function):Bool return false; @:extern public function leq(inOther:Function):Bool return false; @:extern public function gt(inOther:Function):Bool return false; @:extern public function geq(inOther:Function):Bool return false; } haxe_3.4.4.orig/std/cpp/Int16.hx0000664000175000017500000000227113166552354016234 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:notNull @:runtimeValue abstract Int16 from Int to Int {} haxe_3.4.4.orig/std/cpp/Int32.hx0000664000175000017500000000227113166552354016232 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:notNull @:runtimeValue abstract Int32 from Int to Int {} haxe_3.4.4.orig/std/cpp/Int64.hx0000664000175000017500000000227113166552354016237 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:notNull @:runtimeValue abstract Int64 from Int to Int {} haxe_3.4.4.orig/std/cpp/Int8.hx0000664000175000017500000000227013166552354016154 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:notNull @:runtimeValue abstract Int8 from Int to Int {} haxe_3.4.4.orig/std/cpp/Lib.hx0000664000175000017500000001173113166552354016042 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; /** Platform-specific Cpp Library. Provides some platform-specific functions for the C++ target, such as conversion from Haxe types to native types and vice-versa. **/ class Lib { /** Load and return a Cpp primitive from a DLL library. **/ public static function load( lib : String, prim : String, nargs : Int ) : Dynamic { #if (iphone || emscripten) return loadLazy(lib,prim,nargs); #else return untyped __global__.__loadprim(lib,prim,nargs); #end } /** Unloaded all dynamic libraries in reverse order of loading. Returns the number of libraries unloaded. **/ public static function unloadAllLibraries() : Int { return untyped __global__.__hxcpp_unload_all_libraries(); } public static function _loadPrime( lib : String, prim : String, signature : String, quietFail = false ) : Dynamic { var factory:Callable< ConstCharStar -> Object > = untyped __global__.__hxcpp_cast_get_proc_address(lib, prim + "__prime", quietFail); if (factory!=null) { var func:Dynamic = factory.call(signature); if (func==null && !quietFail) throw '$prim does not have signature $signature'; return func; } return null; } /** Tries to load, and always returns a valid function, but the function may throw if called. **/ public static function loadLazy(lib,prim,nargs) : Dynamic { try { return untyped __global__.__loadprim(lib,prim,nargs); } catch( e : Dynamic ) { switch(nargs) { case 0 : return function() { throw e; }; case 2 : return function(_1,_2) { throw e; }; case 3 : return function(_1,_2,_3) { throw e; }; case 4 : return function(_1,_2,_3,_4) { throw e; }; case 5 : return function(_1,_2,_3,_4,_5) { throw e; }; default : return function(_1) { throw e; }; } } return null; } @:extern @:noDebug @:native("HX_STACK_DO_RETHROW") static function do_rethrow(inExp:Dynamic) { throw inExp; } @:noDebug #if(!cppia) inline #end public static function rethrow(inExp:Dynamic) { do_rethrow(inExp); } public static function stringReference(inBytes:haxe.io.Bytes) : String { var result:String = ""; untyped __global__.__hxcpp_string_of_bytes(inBytes.b, result, 0, 0, true); return result; } public static function pushDllSearchPath(inPath:String) : Void untyped __global__.__hxcpp_push_dll_path(inPath); public static function getDllExtension() : String return untyped __global__.__hxcpp_get_dll_extension(); public static function getBinDirectory() : String return untyped __global__.__hxcpp_get_bin_dir(); /** Returns bytes referencing the content of a string. Use with extreme caution - changing constant strings will crash. Changing one string can cause others to change unexpectedly. Only really safe if you are using it read-only or if it comes from stringReference above **/ public inline static function bytesReference( s : String ) : haxe.io.Bytes { var bytes = new haxe.io.BytesData(); untyped bytes.__unsafeStringReference(s); return haxe.io.Bytes.ofData(bytes); } /** Print the specified value on the default output. **/ public static function print( v : Dynamic ) : Void { untyped __global__.__hxcpp_print(v); } /** This function is used to make porting from neko to cpp easy. It does not need to do anything because the c-code can work with any Dynamic **/ public static function haxeToNeko( v : Dynamic ) : Dynamic { return v; } /** This function is used to make porting from neko to cpp easy. It does not need to do anything because the c-code can work with any Dynamic **/ public static function nekoToHaxe( v : Dynamic ) : Dynamic { return v; } /** Print the specified value on the default output followed by a newline character. **/ public static function println( v : Dynamic ) : Void { untyped __global__.__hxcpp_println(v); } public static function setFloatFormat(inFormat:String):Void { untyped __global__.__hxcpp_set_float_format(inFormat); } } haxe_3.4.4.orig/std/cpp/NativeArc.hx0000664000175000017500000000045013166552354017204 0ustar andyandy00000000000000package cpp; extern class NativeArc { @:native("(__bridge_transfer id)") public static function _bridgeTransfer(ptr:cpp.RawPointer ):cpp.RawPointer; public static inline function bridgeTransfer(ptr:cpp.RawPointer ):T return cast _bridgeTransfer(ptr); } haxe_3.4.4.orig/std/cpp/NativeArray.hx0000664000175000017500000000743713166552354017571 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; extern class NativeArray { #if cppia public static inline function create(length:Int):Array { var result = new Array(); NativeArray.setSize(result,length); return result; } #else @:native("_hx_create_array_length") public static function create(length:Int):Array; #end public static inline function blit( ioDestArray:Array, inDestElement:Int, inSourceArray:Array, inSourceElement:Int, inElementCount:Int ): Void { untyped ioDestArray.blit(inDestElement, inSourceArray, inSourceElement, inElementCount); }; public static inline function getBase( inArray:Array ) : ArrayBase { return untyped inArray; } @:nativeStaticExtension public static function reserve( inArray:Array,inElements:Int ) : Void { } @:nativeStaticExtension public static function capacity( inArray:Array ) : Int { } @:nativeStaticExtension public static function getElementSize( inArray:Array ) : Int { } public static inline function address( inArray:Array,inIndex:Int ) : Pointer { return Pointer.arrayElem(inArray,inIndex); } @:nativeStaticExtension public static function setData( inArray:Array,inData:Pointer,inElementCount:Int ) : Void { } @:nativeStaticExtension public static function setUnmanagedData( inArray:Array,inData:ConstPointer,inElementCount:Int ) : Void { } @:nativeStaticExtension public static function zero( ioDestArray:Array, ?inFirst:Int, ?inElements:Int ) : Void { }; @:nativeStaticExtension public static function memcmp( inArrayA:Array, inArrayB:Array) : Int { } @:native("_hx_reslove_virtual_array") public static function resolveVirtualArray( inArray:Array) : Dynamic { } #if cppia public static inline function unsafeGet( inDestArray:Array, inIndex:Int) : T { return untyped inDestArray.__unsafe_get(inIndex); } public static inline function unsafeSet( ioDestArray:Array, inIndex:Int, inValue:T) : T { return untyped ioDestArray.__unsafe_set(inIndex,inValue); } public static inline function setSize( ioArray:Array, inSize:Int) : Array { return untyped ioArray.__SetSizeExact(inSize); } #else @:native("_hx_array_unsafe_get") public static function unsafeGet( inDestArray:Array, inIndex:Int) : T { return untyped null; } @:native("_hx_array_unsafe_set") public static inline function unsafeSet( ioDestArray:Array, inIndex:Int, inValue:T) : T { return untyped ioDestArray.__unsafe_set(inIndex,inValue); } @:native("_hx_array_set_size_exact") public static function setSize( ioArray:Array, inSize:Int) : Array return null; #end } haxe_3.4.4.orig/std/cpp/NativeFile.hx0000664000175000017500000000364413166552354017366 0ustar andyandy00000000000000package cpp; @:buildXml('') extern class NativeFile { @:extern @:native("_hx_std_file_open") public static function file_open(fname:String,r:String) : Dynamic return null; @:extern @:native("_hx_std_file_close") public static function file_close(handle:Dynamic) : Void { } @:extern @:native("_hx_std_file_write") public static function file_write(handle:Dynamic,s:haxe.io.BytesData,p:Int,n:Int) : Int return 0; @:extern @:native("_hx_std_file_write_char") public static function file_write_char(handle:Dynamic,c:Int) : Void { } @:extern @:native("_hx_std_file_read") public static function file_read(handle:Dynamic,s:haxe.io.BytesData,p:Int,n:Int) : Int return 0; @:extern @:native("_hx_std_file_read_char") public static function file_read_char(handle:Dynamic) : Int return 0; @:extern @:native("_hx_std_file_seek") public static function file_seek(handle:Dynamic,pos:Int,kind:Int) : Void { } @:extern @:native("_hx_std_file_tell") public static function file_tell(handle:Dynamic) : Int return 0; @:extern @:native("_hx_std_file_eof") public static function file_eof(handle:Dynamic) : Bool return false; @:extern @:native("_hx_std_file_flush") public static function file_flush(handle:Dynamic) : Void return null; @:extern @:native("_hx_std_file_contents_string") public static function file_contents_string(name:String) : String return null; @:extern @:native("_hx_std_file_contents_bytes") public static function file_contents_bytes(name:String) : haxe.io.BytesData return null; @:extern @:native("_hx_std_file_stdin") public static function file_stdin() : Dynamic return null; @:extern @:native("_hx_std_file_stdout") public static function file_stdout() : Dynamic return null; @:extern @:native("_hx_std_file_stderr") public static function file_stderr() : Dynamic return null; } haxe_3.4.4.orig/std/cpp/NativeGc.hx0000664000175000017500000000406213166552354017033 0ustar andyandy00000000000000package cpp; extern class NativeGc { @:native("__hxcpp_gc_mem_info") static public function memInfo(inWhatInfo:Int) : Float return 0.0; @:native("_hx_allocate_extended") @:templatedCall static public function allocateExtended(cls:Class, size:Int) : T return null; @:native("_hx_add_finalizable") public static function addFinalizable( instance:{ function finalize():Void; }, inPin:Bool ): Void {} @:native("hx::InternalNew") public static function allocGcBytesRaw( inBytes : Int, isContainer:Bool ): RawPointer return null; inline public static function allocGcBytes( inBytes : Int ): Pointer { return Pointer.fromRaw( allocGcBytesRaw(inBytes, false) ); } @:native("__hxcpp_enable") @:extern static public function enable(inEnable:Bool) : Void { } @:native("__hxcpp_collect") @:extern static public function run(major:Bool) : Void { } @:native("__hxcpp_gc_compact") @:extern static public function compact() : Void { } @:native("__hxcpp_gc_trace") @:extern static public function nativeTrace(sought:Class,printInstances:Bool) : Int return 0; @:native("__hxcpp_gc_do_not_kill") @:extern static public function doNotKill(inObject:Dynamic) : Void { } @:native("__hxcpp_get_next_zombie") @:extern static public function getNextZombie() : Dynamic return null; @:native("__hxcpp_gc_safe_point") @:extern static public function safePoint() : Void { } @:native("__hxcpp_enter_gc_free_zone") @:extern static public function enterGCFreeZone() : Void { } @:native("__hxcpp_exit_gc_free_zone") @:extern static public function exitGCFreeZone() : Void { } @:native("__hxcpp_set_minimum_free_space") @:extern static public function setMinimumFreeSpace(inBytes:Int) : Void { } @:native("__hxcpp_set_target_free_space_percentage") @:extern static public function setTargetFreeSpacePercentage(inPercentage:Int) : Void { } @:native("__hxcpp_set_minimum_working_memory") @:extern static public function setMinimumWorkingMemory(inBytes:Int) : Void { } } haxe_3.4.4.orig/std/cpp/NativeMath.hx0000664000175000017500000000142013166552354017366 0ustar andyandy00000000000000package cpp; @:noPackageRestrict extern class NativeMath { #if (cpp && !cppia) @:native("_hx_idiv") public static function idiv(num:Int,denom:Int):Int return 0; @:native("_hx_imod") public static function imod(num:Int,denom:Int):Int return 0; @:native("_hx_cast_int") public static function castInt(f:Float):Int return 0; @:native("_hx_fast_floor") public static function fastInt(f:Float):Int return 0; #else public static inline function imod(num:Int,denom:Int):Int return num%denom; public static inline function idiv(num:Int,denom:Int):Int return Std.int(num/denom); public static inline function castInt(f:Float):Int return Std.int(f); public static inline function fastInt(f:Float):Int return Std.int(f); #end } haxe_3.4.4.orig/std/cpp/NativeProcess.hx0000664000175000017500000000256413166552354020125 0ustar andyandy00000000000000package cpp; @:buildXml('') extern class NativeProcess { @:extern @:native("_hx_std_process_run") public static function process_run(cmd:String,vargs:Array) : Dynamic return null; @:extern @:native("_hx_std_process_run") public static function process_run_with_show(cmd:String,vargs:Array,inShow:Int) : Dynamic return null; @:extern @:native("_hx_std_process_stdout_read") public static function process_stdout_read(handle:Dynamic,buf:haxe.io.BytesData,pos:Int,len:Int) : Int return 0; @:extern @:native("_hx_std_process_stderr_read") public static function process_stderr_read(handle:Dynamic,buf:haxe.io.BytesData,pos:Int,len:Int) : Int return 0; @:extern @:native("_hx_std_process_stdin_write") public static function process_stdin_write(handle:Dynamic,buf:haxe.io.BytesData,pos:Int,len:Int) : Int return 0; @:extern @:native("_hx_std_process_stdin_close") public static function process_stdin_close(handle:Dynamic) : Void { } @:extern @:native("_hx_std_process_exit") public static function process_exit(handle:Dynamic) : Int return 0; @:extern @:native("_hx_std_process_pid") public static function process_pid(handle:Dynamic) : Int return 0; @:extern @:native("_hx_std_process_close") public static function process_close(handle:Dynamic) : Void { }; } haxe_3.4.4.orig/std/cpp/NativeRandom.hx0000664000175000017500000000111413166552354017715 0ustar andyandy00000000000000package cpp; @:buildXml('') extern class NativeRandom { @:extern @:native("_hx_std_random_new") public static function random_new() : Dynamic return null; @:extern @:native("_hx_std_random_set_seed") public static function random_set_seed(handle:Dynamic,v:Int) : Void { } @:extern @:native("_hx_std_random_int") public static function random_int(handle:Dynamic,max:Int) : Int return 0; @:extern @:native("_hx_std_random_float") public static function random_float(handle:Dynamic) : Float return 0.0; } haxe_3.4.4.orig/std/cpp/NativeSocket.hx0000664000175000017500000001214713166552354017735 0ustar andyandy00000000000000package cpp; import sys.net.Socket; @:buildXml('') extern class NativeSocket { @:extern @:native("_hx_std_socket_init") public static function socket_init() : Void { } @:extern @:native("_hx_std_socket_new") public static function socket_new(udp:Bool) : Dynamic return null; @:extern @:native("_hx_std_socket_new") public static function socket_new_ip(udp:Bool,ipv6:Bool) : Dynamic return null; @:extern @:native("_hx_std_socket_close") public static function socket_close(handle:Dynamic) : Void { } @:extern @:native("_hx_std_socket_bind") public static function socket_bind(o:Dynamic,host:Int,port:Int) : Void { } @:extern @:native("_hx_std_socket_bind_ipv6") public static function socket_bind_ipv6(o:Dynamic,host:haxe.io.BytesData,port:Int) : Void { } @:extern @:native("_hx_std_socket_send_char") public static function socket_send_char(o:Dynamic,c:Int) : Void { } @:extern @:native("_hx_std_socket_send") public static function socket_send(o:Dynamic,buf:haxe.io.BytesData,p:Int,l:Int) : Int return 0; @:extern @:native("_hx_std_socket_recv") public static function socket_recv(o:Dynamic,buf:haxe.io.BytesData,p:Int,l:Int) : Int return 0; @:extern @:native("_hx_std_socket_recv_char") public static function socket_recv_char(o:Dynamic) : Int return 0; @:extern @:native("_hx_std_socket_write") public static function socket_write(o:Dynamic,buf:haxe.io.BytesData) : Void { } @:extern @:native("_hx_std_socket_read") public static function socket_read(o:Dynamic) : haxe.io.BytesData return null; @:extern @:native("_hx_std_host_resolve_ipv6") public static function host_resolve_ipv6(host:String) : haxe.io.BytesData return null; @:extern @:native("_hx_std_host_resolve") public static function host_resolve(host:String) : Int return 0; @:extern @:native("_hx_std_host_to_string") public static function host_to_string(ip:Int) : String return null; @:extern @:native("_hx_std_host_to_string_ipv6") public static function host_to_string_ipv6(ipv6:haxe.io.BytesData) : String return null; @:extern @:native("_hx_std_host_reverse") public static function host_reverse(host:Int) : String return null; @:extern @:native("_hx_std_host_reverse_ipv6") public static function host_reverse_ipv6(ipv6:haxe.io.BytesData) : String return null; @:extern @:native("_hx_std_host_local") public static function host_local() : String return null; inline public static function host_local_ipv6() : String return "::1"; @:extern @:native("_hx_std_socket_connect") public static function socket_connect(o:Dynamic,host:Int,port:Int) : Void { } @:extern @:native("_hx_std_socket_connect_ipv6") public static function socket_connect_ipv6(o:Dynamic,host:haxe.io.BytesData,port:Int) : Void { } @:extern @:native("_hx_std_socket_listen") public static function socket_listen(o:Dynamic,n:Int) : Void { } @:extern @:native("_hx_std_socket_select") public static function socket_select(rs:Array,ws:Array,es:Array,timeout:Dynamic) : Array return null; @:extern @:native("_hx_std_socket_fast_select") public static function socket_fast_select(rs:Array,ws:Array,es:Array,timeout:Dynamic) : Void { } @:extern @:native("_hx_std_socket_accept") public static function socket_accept(o:Dynamic) : Dynamic return null; @:extern @:native("_hx_std_socket_peer") public static function socket_peer(o:Dynamic) : Array return null; @:extern @:native("_hx_std_socket_host") public static function socket_host(o:Dynamic) : Array return null; @:extern @:native("_hx_std_socket_set_timeout") public static function socket_set_timeout(o:Dynamic,t:Dynamic) : Void { } @:extern @:native("_hx_std_socket_shutdown") public static function socket_shutdown(o:Dynamic,r:Bool,w:Bool) : Void { } @:extern @:native("_hx_std_socket_set_blocking") public static function socket_set_blocking(o:Dynamic,b:Bool) : Void { } @:extern @:native("_hx_std_socket_set_fast_send") public static function socket_set_fast_send(o:Dynamic,b:Bool) : Void { } @:extern @:native("_hx_std_socket_poll_alloc") public static function socket_poll_alloc(nsocks:Int) : Dynamic return null; @:extern @:native("_hx_std_socket_poll_prepare") public static function socket_poll_prepare(pdata:Dynamic,rsocks:Array,wsocks:Array) : Array< Array > return null; @:extern @:native("_hx_std_socket_poll_events") public static function socket_poll_events(pdata:Dynamic,timeout:Float) : Void { } @:extern @:native("_hx_std_socket_poll") public static function socket_poll(socks:Array,pdata:Dynamic,timeout:Float) : Array return null; @:extern @:native("_hx_std_socket_send_to") public static function socket_send_to(o:Dynamic,buf:haxe.io.BytesData,p:Int,l:Int,inAddr:Dynamic) : Int return 0; @:extern @:native("_hx_std_socket_recv_from") public static function socket_recv_from(o:Dynamic,buf:haxe.io.BytesData,p:Int,l:Int,outAddr:Dynamic) : Int return 0; } haxe_3.4.4.orig/std/cpp/NativeSsl.hx0000664000175000017500000001124113166552354017240 0ustar andyandy00000000000000package cpp; @:buildXml('') extern class NativeSsl { @:extern @:native("_hx_ssl_new") public static function ssl_new( conf : Dynamic ) : Dynamic { } @:extern @:native("_hx_ssl_close") public static function ssl_close( ctx : Dynamic ) : Void { } @:extern @:native("_hx_ssl_handshake") public static function ssl_handshake( ctx : Dynamic ) : Void { } @:extern @:native("_hx_ssl_set_socket") public static function ssl_set_socket( ctx : Dynamic, socket : Dynamic ) : Void { } @:extern @:native("_hx_ssl_set_hostname") public static function ssl_set_hostname( ctx : Dynamic, hostname : String ) : Void { } @:extern @:native("_hx_ssl_get_peer_certificate") public static function ssl_get_peer_certificate( ctx : Dynamic ) : Dynamic { } @:extern @:native("_hx_ssl_get_verify_result") public static function ssl_get_verify_result( ctx : Dynamic ) : Bool { } @:extern @:native("_hx_ssl_send_char") public static function ssl_send_char( ctx : Dynamic, char : Int ) : Void { } @:extern @:native("_hx_ssl_send") public static function ssl_send( ctx : Dynamic, buf : haxe.io.BytesData, p : Int, l : Int ) : Int { } @:extern @:native("_hx_ssl_write") public static function ssl_write( ctx : Dynamic, data : haxe.io.BytesData ) : Void { } @:extern @:native("_hx_ssl_recv_char") public static function ssl_recv_char( ctx : Dynamic ) : Int { } @:extern @:native("_hx_ssl_recv") public static function ssl_recv( ctx : Dynamic, buf : haxe.io.BytesData, p : Int, l : Int ) : Int { } @:extern @:native("_hx_ssl_read") public static function ssl_read( ctx : Dynamic ) : haxe.io.BytesData { } @:extern @:native("_hx_ssl_conf_new") public static function conf_new( server : Bool ) : Dynamic { } @:extern @:native("_hx_ssl_conf_close") public static function conf_close( conf : Dynamic ) : Void { } @:extern @:native("_hx_ssl_conf_set_ca") public static function conf_set_ca( conf : Dynamic, cert : Dynamic ) : Void { } @:extern @:native("_hx_ssl_conf_set_verify") public static function conf_set_verify( conf : Dynamic, mode : Int ) : Void { } @:extern @:native("_hx_ssl_conf_set_cert") public static function conf_set_cert( conf : Dynamic, cert : Dynamic, pkey : Dynamic ) : Void { } @:extern @:native("_hx_ssl_conf_set_servername_callback") public static function conf_set_servername_callback( conf : Dynamic, cb : Dynamic ) : Void { } @:extern @:native("_hx_ssl_cert_load_defaults") public static function cert_load_defaults() : Dynamic { } @:extern @:native("_hx_ssl_cert_load_file") public static function cert_load_file( file : String ) : Dynamic { } @:extern @:native("_hx_ssl_cert_load_path") public static function cert_load_path( path : String ) : Dynamic { } @:extern @:native("_hx_ssl_cert_get_subject") public static function cert_get_subject( cert : Dynamic, field : String ) : String { } @:extern @:native("_hx_ssl_cert_get_issuer") public static function cert_get_issuer( cert : Dynamic, field : String ) : String { } @:extern @:native("_hx_ssl_cert_get_altnames") public static function cert_get_altnames( cert : Dynamic ) : Array { } @:extern @:native("_hx_ssl_cert_get_notbefore") public static function cert_get_notbefore( cert : Dynamic ) : Array { } @:extern @:native("_hx_ssl_cert_get_notafter") public static function cert_get_notafter( cert : Dynamic ) : Array { } @:extern @:native("_hx_ssl_cert_get_next") public static function cert_get_next( cert : Dynamic ) : Dynamic { } @:extern @:native("_hx_ssl_cert_add_pem") public static function cert_add_pem( cert : Dynamic, data : String ) : Dynamic { } @:extern @:native("_hx_ssl_cert_add_der") public static function cert_add_der( cert : Dynamic, data : haxe.io.BytesData ) : Dynamic { } @:extern @:native("_hx_ssl_key_from_der") public static function key_from_der( data : haxe.io.BytesData, pub : Bool ) : Dynamic { } @:extern @:native("_hx_ssl_key_from_pem") public static function key_from_pem( data : String, pub : Bool, pass : String ) : Dynamic { } @:extern @:native("_hx_ssl_dgst_make") public static function dgst_make( data : haxe.io.BytesData, alg : String ) : haxe.io.BytesData { } @:extern @:native("_hx_ssl_dgst_sign") public static function dgst_sign( data : haxe.io.BytesData, key : Dynamic, alg : String ) : haxe.io.BytesData { } @:extern @:native("_hx_ssl_dgst_verify") public static function dgst_verify( data : haxe.io.BytesData, sign : haxe.io.BytesData, key : Dynamic, alg : String ) : Bool { } @:extern @:native("_hx_ssl_init") public static function init() : Void { } } haxe_3.4.4.orig/std/cpp/NativeString.hx0000664000175000017500000000477213166552354017760 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; extern class NativeString { public static inline function raw( inString:String ) : RawConstPointer { return untyped inString.__s; } public static inline function c_str( inString:String ) : ConstPointer { return cpp.ConstPointer.fromPointer(untyped inString.__s); } public static inline function fromPointer(inPtr:ConstPointer ) : String { return untyped __global__.String(inPtr.ptr); } public static inline function fromGcPointer(inPtr:ConstPointer, inLen:Int ) : String { return untyped __global__.String(inPtr.ptr,inLen); } @:native("_hx_string_compare") public static function compare(inString0:String, inString1:String) : Int return 0; @:native("_hx_utf8_char_code_at") public static function utf8CharCodeAt(inString:String, inIndex:Int) : Int return 0; @:native("_hx_utf8_length") public static function utf8Length(inString:String) : Int return 1; @:native("_hx_utf8_is_valid") public static function utf8IsValid(inString:String) : Bool return false; @:native("_hx_utf8_sub") public static function utf8Sub(inString:String,charStart:Int, inLen:Int) : String return null; @:native("_hx_string_create") public static function fromPointerLen(inPtr:ConstPointer, len:Int ) : String; @:native("_hx_utf8_decode_advance") public static function utf8DecodeAdvance(reference:Char) : Int return 0; } haxe_3.4.4.orig/std/cpp/NativeSys.hx0000664000175000017500000000576113166552354017267 0ustar andyandy00000000000000package cpp; @:buildXml('') extern class NativeSys { @:native("__hxcpp_print") public static function print( v : Dynamic ) : Void { } @:native("__hxcpp_println") public static function println( v : Dynamic ) : Void { } @:extern @:native("_hx_std_get_env") public static function get_env(v:String) : String return null; @:extern @:native("_hx_std_put_env") public static function put_env(e:String,v:String) : Void { } @:extern @:native("_hx_std_sys_sleep") public static function sys_sleep(f:Float) : Void { } @:extern @:native("_hx_std_set_time_locale") public static function set_time_locale(l:String) : Bool return false; @:extern @:native("_hx_std_get_cwd") public static function get_cwd() : String return null; @:extern @:native("_hx_std_set_cwd") public static function set_cwd(d:String) : Void { } @:extern @:native("_hx_std_sys_string") public static function sys_string() : String return null; @:extern @:native("_hx_std_sys_is64") public static function sys_is64() : Bool return false; @:extern @:native("_hx_std_sys_command") public static function sys_command(cmd:String) : Int return 0; @:extern @:native("_hx_std_sys_exit") public static function sys_exit(code:Int) : Void { } @:extern @:native("_hx_std_sys_exists") public static function sys_exists(path:String) : Bool return false; @:extern @:native("_hx_std_file_delete") public static function file_delete(path:String) : Void { } @:extern @:native("_hx_std_sys_rename") public static function sys_rename(path:String,newname:String) : Bool return false; @:extern @:native("_hx_std_sys_stat") public static function sys_stat(path:String) : Dynamic return null; @:extern @:native("_hx_std_sys_file_type") public static function sys_file_type(path:String) : String return null; @:extern @:native("_hx_std_sys_create_dir") public static function sys_create_dir(path:String,mode:Int) : Bool return false; @:extern @:native("_hx_std_sys_remove_dir") public static function sys_remove_dir(path:String) : Void { } @:extern @:native("_hx_std_sys_time") public static function sys_time() : Float return 0; @:extern @:native("_hx_std_sys_cpu_time") public static function sys_cpu_time() : Float return 0; @:extern @:native("_hx_std_sys_read_dir") public static function sys_read_dir(p:String) : Array return null; @:extern @:native("_hx_std_file_full_path") public static function file_full_path(path:String) : String return null; @:extern @:native("_hx_std_sys_exe_path") public static function sys_exe_path() : String return null; @:extern @:native("_hx_std_sys_env") public static function sys_env() : Array return null; @:extern @:native("_hx_std_sys_getch") public static function sys_getch(b:Bool) : Int return 0; @:extern @:native("_hx_std_sys_get_pid") public static function sys_get_pid() : Int return 0; } haxe_3.4.4.orig/std/cpp/NativeXml.hx0000664000175000017500000002754213166552354017252 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:enum abstract XmlType(Int) { /** Represents an XML element type. **/ var Element = 0; /** Represents XML parsed character data type. **/ var PCData = 1; /** Represents XML character data type. **/ var CData = 2; /** Represents an XML comment type. **/ var Comment = 3; /** Represents an XML doctype element type. **/ var DocType = 4; /** Represents an XML processing instruction type. **/ var ProcessingInstruction = 5; /** Represents an XML document type. **/ var Document = 6; } class NativeXmlState { var cur : Xml; public function new(x:Xml) { x._children = new Array(); cur = x; } @:keep public function xml(name:String, att:Dynamic) { var x = new Xml(); x._parent = cur; x.nodeType = Xml.Element; x._nodeName = name; x._attributes = att; x._children = new Array(); cur.addChild(x); cur = x; } @:keep public function cdata(text:String) { var x = new Xml(); x._parent = cur; x.nodeType = Xml.CData; x._nodeValue = text; cur.addChild(x); } @:keep public function pcdata(text:String) { var x = new Xml(); x._parent = cur; x.nodeType = Xml.PCData; x._nodeValue = text; cur.addChild(x); } @:keep public function comment(text:String) { var x = new Xml(); x._parent = cur; if( text.length>1 && StringTools.fastCodeAt(text,0) == 63 ) { x.nodeType = Xml.ProcessingInstruction; text = text.substr(1, text.length - 2); } else { x.nodeType = Xml.Comment; } x._nodeValue = text; cur.addChild(x); } @:keep public function doctype(text:String) { var x = new Xml(); x._parent = cur; x.nodeType = Xml.DocType; x._nodeValue = text.substr(1); cur.addChild(x); } @:keep public function done() { cur = cur._parent; } } private class NativeXmlIterator { var cur = 0; var children:Array; public function new(inChildren:Array) { children = inChildren; cur = 0; } public function hasNext() : Bool { var k = cur; var l = children.length; while( k < l ) { if (children[k].nodeType == Xml.Element) break; k += 1; } cur = k; return k < l; } public function next():Xml { var k = cur; var l = children.length; while( k < l ) { var n = children[k]; k += 1; if( n.nodeType == Xml.Element ) { cur = k; return n; } } return null; } } private class NativeXmlNamedIterator { var cur = 0; var children:Array; var name:String; public function new(inChildren:Array, inName:String) { children = inChildren; name = inName; cur = 0; } public function hasNext() : Bool { var k = cur; var l = children.length; while( k < l ) { var n = children[k]; if( n.nodeType == Xml.Element && n._nodeName == name ) break; k++; } cur = k; return k < l; } public function next():Xml { var k = cur; var l = children.length; while( k < l ) { var n = children[k]; k++; if( n.nodeType == Xml.Element && n._nodeName == name ) { cur = k; return n; } } return null; } } @:cppInclude("./NativeXmlImport.cpp") @:allow(cpp.NativeXmlState) @:allow(cpp.NativeXmlIterator) @:allow(cpp.NativeXmlNamedIterator) class Xml { static inline var Element = XmlType.Element; static inline var PCData = XmlType.PCData; static inline var CData = XmlType.CData; static inline var Comment = XmlType.Comment; static inline var DocType = XmlType.DocType; static inline var ProcessingInstruction = XmlType.ProcessingInstruction; static inline var Document = XmlType.Document; private var _nodeName : String; private var _nodeValue : String; private var _attributes : Dynamic; private var _children : Array; private var _parent : Xml; function new() : Void { } @:extern @:native("parse_xml") static function parse_xml(str:String, state:NativeXmlState) { } public static function parse( str : String ) : Xml { var x = new Xml(); var state = new NativeXmlState(x); parse_xml(str,state); x.nodeType = Xml.Document; return x; } public static function createElement( name : String ) : Xml { var r = new Xml(); r.nodeType = Xml.Element; r._nodeName = name; r._attributes = null; r._children = new Array(); return r; } public static function createPCData( data : String ) : Xml { var r = new Xml(); r.nodeType = Xml.PCData; r._nodeValue = data; return r; } public static function createCData( data : String ) : Xml { var r = new Xml(); r.nodeType = Xml.CData; r._nodeValue = data; return r; } public static function createComment( data : String ) : Xml { var r = new Xml(); r.nodeType = Xml.Comment; r._nodeValue = data; return r; } public static function createDocType( data : String ) : Xml { var r = new Xml(); r.nodeType = Xml.DocType; r._nodeValue = data; return r; } public static function createProcessingInstruction( data : String ) : Xml { var r = new Xml(); r.nodeType = Xml.ProcessingInstruction; r._nodeValue = data; return r; } public static function createDocument() : Xml { var r = new Xml(); r.nodeType = Xml.Document; r._children = new Array(); return r; } public var nodeType(default,null) : XmlType; public var nodeName(get,set) : String; public var nodeValue(get,set) : String; private function get_nodeName() : String { if( nodeType != Xml.Element ) throw "bad nodeType"; return _nodeName; } private function set_nodeName( n : String ) : String { if( nodeType != Xml.Element ) throw "bad nodeType"; return _nodeName = n; } private function get_nodeValue() : String { if( nodeType == Xml.Element || nodeType == Xml.Document ) throw "bad nodeType"; return _nodeValue; } private function set_nodeValue( v : String ) : String { if( nodeType == Xml.Element || nodeType == Xml.Document ) throw "bad nodeType"; return _nodeValue = v; } public var parent(get,null) : Xml; private function get_parent() : Xml { return _parent; } public function get( att : String ) : String { if( nodeType != Xml.Element ) throw "bad nodeType"; return Reflect.field( _attributes, att ); } public function set( att : String, value : String ) : Void { if( nodeType != Xml.Element ) throw "bad nodeType"; if (_attributes==null) _attributes = {}; Reflect.setField (_attributes, att, value ); return null; } public function remove( att : String ) : Void{ if( nodeType != Xml.Element ) throw "bad nodeType"; Reflect.deleteField( _attributes, att ); return null; } public function exists( att : String ) : Bool { if( nodeType != Xml.Element ) throw "bad nodeType"; return Reflect.hasField( _attributes, att ); } public function attributes() : Iterator { if( nodeType != Xml.Element ) throw "bad nodeType"; return Reflect.fields( _attributes ).iterator(); } public function iterator() : Iterator { if( _children == null ) throw "bad nodetype"; return untyped _children.iterator(); } public function elements(): Iterator { if( _children == null ) throw "bad nodetype"; return new NativeXmlIterator(_children); } public function elementsNamed( name : String ) : Iterator { if( _children == null ) throw "bad nodetype"; return new NativeXmlNamedIterator(_children,name); } public function firstChild() : Xml { if( _children == null ) throw "bad nodetype"; return _children[0]; } public function firstElement() : Xml { if( _children == null ) throw "bad nodetype"; for( cur in 0..._children.length ) { var n:Xml = _children[cur]; if( n.nodeType == Xml.Element ) return n; } return null; } public function addChild( x : Xml ) : Void { if( _children == null ) throw "bad nodetype"; if( x._parent != null ) x._parent._children.remove(x); x._parent = this; _children.push( x ); return null; } public function removeChild( x : Xml ) : Bool { if( _children == null ) throw "bad nodetype"; var b = _children.remove( x ); if( b ) x._parent = null; return b; } public function insertChild( x : Xml, pos : Int ) : Void { if( _children == null ) throw "bad nodetype"; if( x._parent != null ) x._parent._children.remove(x); x._parent = this; _children.insert( pos, x ); return null; } public function toString() : String { var s = new StringBuf(); toStringRec(s); return s.toString(); } private function toStringRec(s: StringBuf) : Void { switch( nodeType ) { case Xml.Document: for( x in _children ) x.toStringRec(s); case Xml.Element: s.addChar("<".code); s.add(_nodeName); for( k in Reflect.fields(_attributes) ) { s.addChar(" ".code); s.add(k); s.addChar("=".code); s.addChar("\"".code); s.add(Reflect.field(_attributes,k)); s.addChar("\"".code); } if( _children.length == 0 ) { s.addChar("/".code); s.addChar(">".code); return; } s.addChar(">".code); for( x in _children ) x.toStringRec(s); s.addChar("<".code); s.addChar("/".code); s.add(_nodeName); s.addChar(">".code); case Xml.PCData: s.add(StringTools.htmlEscape(_nodeValue)); case Xml.CData: s.add(""); case Xml.Comment: s.add(""); case Xml.DocType: s.add(""); case Xml.ProcessingInstruction: s.add(""); } } } haxe_3.4.4.orig/std/cpp/NativeXmlImport.cpp0000664000175000017500000002222313166552354020577 0ustar andyandy00000000000000 #ifdef EPPC #include #else #include #endif #ifndef HX_WINDOWS # include # undef strcmpi # define strcmpi(a,b) strcasecmp(a,b) #else # include #endif // -------------- parsing -------------------------- enum STATE { IGNORE_SPACES, BEGIN, BEGIN_NODE, TAG_NAME, BODY, ATTRIB_NAME, EQUALS, ATTVAL_BEGIN, ATTRIB_VAL, CHILDS, CLOSE, WAIT_END, WAIT_END_RET, PCDATA, HEADER, COMMENT, DOCTYPE, CDATA, }; static void xml_error( const char *xml, const char *inWhere, int *line, String msg ) { String b = HX_CSTRING("Xml parse error : ") + msg + HX_CSTRING(" at line ") + String(*line) + HX_CSTRING(" : "); String where(inWhere); int l = where.length; int nchars = 30; if( inWhere != xml ) b += HX_CSTRING("..."); if (where.length==0) b+= HX_CSTRING(""); else if (where.length= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || ( c >= '0' && c <= '9' ) || c == ':' || c == '.' || c == '_' || c == '-'; } static void do_parse_xml( const char *xml, const char **lp, int *line, cpp::NativeXmlState callb, String parentname ) { STATE state = BEGIN; STATE next = BEGIN; String aname; hx::Anon attribs; String nodename; const char *start = NULL; const char *p = *lp; char c = *p; int nsubs = 0, nbrackets = 0; while( c ) { switch( state ) { case IGNORE_SPACES: switch( c ) { case '\n': case '\r': case '\t': case ' ': break; default: state = next; continue; } break; case BEGIN: switch( c ) { case '<': state = IGNORE_SPACES; next = BEGIN_NODE; break; default: start = p; state = PCDATA; continue; } break; case PCDATA: if( c == '<' ) { callb->pcdata(String(start,p-start).dup()); nsubs++; state = IGNORE_SPACES; next = BEGIN_NODE; } break; case CDATA: if( c == ']' && p[1] == ']' && p[2] == '>' ) { callb->cdata(String(start,p-start).dup()); nsubs++; p += 2; state = BEGIN; } break; case BEGIN_NODE: switch( c ) { case '!': if( p[1] == '[' ) { p += 2; if( (p[0] != 'C' && p[0] != 'c') || (p[1] != 'D' && p[1] != 'd') || (p[2] != 'A' && p[2] != 'a') || (p[3] != 'T' && p[3] != 't') || (p[4] != 'A' && p[4] != 'a') || (p[5] != '[') ) ERROR("Expected xml(nodename,attribs); break; case '>': state = CHILDS; nsubs++; callb->xml(nodename,attribs); break; default: state = ATTRIB_NAME; start = p; continue; } break; case ATTRIB_NAME: if( !is_valid_char(c) ) { if( start == p ) ERROR("Expected attribute name"); aname = String(start,p-start).dup(); if( attribs->__Field(aname,hx::paccDynamic) != null() ) ERROR("Duplicate attribute"); state = IGNORE_SPACES; next = EQUALS; continue; } break; case EQUALS: switch( c ) { case '=': state = IGNORE_SPACES; next = ATTVAL_BEGIN; break; default: ERROR("Expected ="); } break; case ATTVAL_BEGIN: switch( c ) { case '"': case '\'': state = ATTRIB_VAL; start = p; break; default: ERROR("Expected \""); } break; case ATTRIB_VAL: if( c == *start ) { attribs->Add( aname, String(start+1,p-start-1).dup() ); state = IGNORE_SPACES; next = BODY; } break; case CHILDS: *lp = p; do_parse_xml(xml,lp,line,callb,nodename); p = *lp; start = p; state = BEGIN; break; case WAIT_END: switch( c ) { case '>': callb->done(); state = BEGIN; break; default : ERROR("Expected >"); } break; case WAIT_END_RET: switch( c ) { case '>': if( nsubs == 0 ) callb->pcdata(HX_CSTRING("")); *lp = p; return; default : ERROR("Expected >"); } break; case CLOSE: if( !is_valid_char(c) ) { if( start == p ) ERROR("Expected node name"); { String v = String(start,p - start).dup(); if( strcmpi(parentname.__s,v.__s) != 0 ) { ERRORSTR(HX_CSTRING("Expected ")); } } state = IGNORE_SPACES; next = WAIT_END_RET; continue; } break; case COMMENT: if( c == '-' && p[1] == '-' && p[2] == '>' ) { callb->comment(String(start,p-start).dup()); p += 2; state = BEGIN; } break; case DOCTYPE: if( c == '[' ) nbrackets++; else if( c == ']' ) nbrackets--; else if( c == '>' && nbrackets == 0 ) { callb->doctype(String(start,p-start).dup()); state = BEGIN; } break; case HEADER: if( c == '?' && p[1] == '>' ) { p++; callb->comment(String(start,p-start).dup()); state = BEGIN; } break; } c = *++p; if( c == '\n' ) (*line)++; } if( state == BEGIN ) { start = p; state = PCDATA; } if( parentname.__s == 0 && state == PCDATA ) { if( p != start || nsubs == 0 ) callb->pcdata(String(start,p-start).dup()); return; } ERROR("Unexpected end"); } // ---------------------------------------------- /**

Xml

The standard event-driven XML parser.

**/ /** parse_xml : xml:string -> events:object -> void The [parse_xml] parse a string and for each parsed element call the corresponding object method in [events] :
  • [void xml( name : string, attribs : object)] when an XML node is found
  • [void done()] when an XML node is closed
  • [void pcdata(string)] when PCData chars found
  • [void cdata(string)] when a CData session is found
  • [void comment(string)] when some comment or special header is found
You can then implement the events so they build the appropriate XML data structure needed by your language.
**/ static void parse_xml( String str, cpp::NativeXmlState state ) { int line = 0; const char *p = str.__s; // skip BOM if( p[0] == (char)0xEF && p[1] == (char)0xBB && p[2] == (char)0xBF ) p += 3; do_parse_xml(p,&p,&line,state,String()); } haxe_3.4.4.orig/std/cpp/Object.hx0000664000175000017500000000224213166552354016537 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:noPackageRestrict typedef Object = Dynamic; haxe_3.4.4.orig/std/cpp/ObjectType.hx0000664000175000017500000000112113166552354017374 0ustar andyandy00000000000000package cpp; extern class ObjectType { public inline static var vtUnknown = -1; public inline static var vtInt = 0xff; public inline static var vtNull = 0; public inline static var vtFloat = 1; public inline static var vtBool = 2; public inline static var vtString = 3; public inline static var vtObject = 4; public inline static var vtArray = 5; public inline static var vtFunction = 6; public inline static var vtEnum = 7; public inline static var vtClass = 8; public inline static var vtInt64 = 9; public inline static var vtAbstractBase = 0x100; } haxe_3.4.4.orig/std/cpp/Pointer.hx0000664000175000017500000000620113166552354016750 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; import haxe.extern.AsVar; @:coreType @:analyzer(as_var) extern class Pointer extends ConstPointer implements ArrayAccess { public var ref(get,set):Reference; public function get_ref() : Reference; public function set_ref(t:T) : Reference; public function setAt(inIndex:Int, value:T):Void; public static function fromRaw(ptr:RawPointer) : Pointer; @:native("::cpp::Pointer_obj::fromHandle") static function nativeFromHandle(inHandle:Dynamic,?inKind:String):AutoCast; inline public static function fromHandle(inHandle:Dynamic,?inKind:String) : Pointer { return cast nativeFromHandle(inHandle,inKind); } public static function fromPointer(inNativePointer:Dynamic) : Pointer; public static function addressOf(inVariable:cpp.Reference) : Pointer; public static function endOf(inVariable:T) : Pointer; @:native("::cpp::Pointer_obj::arrayElem") static function nativeArrayElem(array:Array, inElem:Int):AutoCast; inline static function arrayElem(array:Array, inElem:Int):Pointer { return cast nativeArrayElem(array,inElem); } @:native("::cpp::Pointer_obj::ofArray") static function nativeOfArray(array:Array):AutoCast; inline public static function ofArray(array:Array):Pointer { return cast nativeOfArray(array); } inline public function toUnmanagedArray(elementCount:Int) : Array { var result = new Array(); NativeArray.setUnmanagedData(result,this,elementCount); return result; } inline public function toUnmanagedVector(elementCount:Int) : haxe.ds.Vector return cast toUnmanagedArray(elementCount); override public function inc():Pointer; override public function dec():Pointer; override public function incBy(inT:Int):Pointer; override public function add(inT:Int):Pointer; public function postIncRef():Reference; public function destroy():Void; public function destroyArray():Void; } haxe_3.4.4.orig/std/cpp/Prime.hx0000664000175000017500000000766613166552354016424 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; #if macro import haxe.macro.Context; import haxe.macro.Type; import haxe.macro.Expr; #end @:noPackageRestrict class Prime { #if (!macro && cpp) public static function _loadPrime( lib : String, prim : String, signature : String, quietFail = false ) : Dynamic { var factory:Callable< ConstCharStar -> Object > = untyped __global__.__hxcpp_cast_get_proc_address(lib, prim + "__prime", quietFail); if (factory!=null) { var func:Dynamic = factory.call(signature); if (func==null && !quietFail) throw '$prim does not have signature $signature'; return func; } return null; } #end #if (macro) static function codeToType(code:String,forCpp:Bool) : String { var isCpp = Context.defined("cpp"); switch(code) { case "b" : return "Bool"; case "i" : return "Int"; case "d" : return "Float"; case "s" : return "String"; case "f" : return forCpp ? "cpp.Float32" : "Float"; case "o" : return forCpp ? "cpp.Object" : "Dynamic"; case "v" : return forCpp ? "cpp.Void" : "Dynamic"; case "c" : if (forCpp) return "cpp.ConstCharStar"; throw "const char * type only supported in cpp mode"; default: throw "Unknown signature type :" + code; } } #end public static function nekoInit(inModuleName:String) : Bool { #if neko var init = neko.Lib.load(inModuleName, "neko_init", 5); if (init != null) { init( function(s) return new String(s), function(len:Int) { var r = []; if (len > 0) r[len - 1] = null; return r; }, null, true, false); return true; } #end return false; } public static macro function load(inModule:String, inName:String, inSig:String,inAllowFail:Bool = false) { var parts = inSig.split(""); if (parts.length<1) throw "Invalid function signature " + inSig; var argCount = parts.length-1; var cppMode = Context.defined("cpp"); var typeString = parts.length==1 ? "Void" : codeToType(parts.shift(),cppMode); for(p in parts) typeString += "->" + codeToType(p,cppMode); if (cppMode) { typeString = "cpp.Callable<" + typeString + ">"; var expr = 'new $typeString(cpp.Prime._loadPrime("$inModule","$inName","$inSig",$inAllowFail))'; return Context.parse( expr, Context.currentPos() ); } else { if (argCount>5) argCount = -1; var lazy = inAllowFail ? "loadLazy" : "load"; var expr = 'new cpp.Callable<$typeString>(neko.Lib.$lazy("$inModule","$inName",$argCount))'; return Context.parse( expr, Context.currentPos() ); } } } haxe_3.4.4.orig/std/cpp/Random.hx0000664000175000017500000000273113166552354016554 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; class Random { var r : Dynamic; public function new() { r = cpp.NativeRandom.random_new(); } public function setSeed( s : Int ) { cpp.NativeRandom.random_set_seed(r,s); } public function int( max : Int ) : Int { return cpp.NativeRandom.random_int(r,max); } public function float() : Float { return cpp.NativeRandom.random_float(r); } } haxe_3.4.4.orig/std/cpp/RawConstPointer.hx0000664000175000017500000000243713166552354020440 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:unreflective extern class RawConstPointer implements ArrayAccess { @:native("hx::AddressOf") public static function addressOf(t:T) : RawConstPointer; } haxe_3.4.4.orig/std/cpp/RawPointer.hx0000664000175000017500000000242613166552354017427 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:unreflective extern class RawPointer extends RawConstPointer { @:native("hx::AddressOf") public static function addressOf(t:T) : RawPointer; } haxe_3.4.4.orig/std/cpp/Reference.hx0000664000175000017500000000236513166552354017235 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; // Allows haxe to type result correctly, and hxcpp can recognise this and prevent // unwanted casting typedef Reference = T; haxe_3.4.4.orig/std/cpp/SizeT.hx0000664000175000017500000000232013166552354016364 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:native("size_t") @:scalar @:coreType @:notNull extern abstract SizeT from(Int) to(Int) { } haxe_3.4.4.orig/std/cpp/Star.hx0000664000175000017500000000234413166552354016245 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; // Allows haxe to type result correctly, and hxcpp can recognise this use the correct type typedef Star = T; haxe_3.4.4.orig/std/cpp/StdString.hx0000664000175000017500000000102313166552354017246 0ustar andyandy00000000000000package cpp; using cpp.NativeString; @:native("hx::StdString") @:include("hx/StdString.h") @:stackOnly @:structAccess extern class StdString extends StdStringRef { @:extern @:native("std::string::npos") public static var npos(default,null):Int; //public function new(inData:StdStringData); @:native("hx::StdString") static public function ofString(s:String) : StdString; //public function toString():String; //public function find(s:String):Int; //public function substr(pos:Int, len:Int):StdString; } haxe_3.4.4.orig/std/cpp/StdStringRef.hx0000664000175000017500000000062513166552354017712 0ustar andyandy00000000000000package cpp; using cpp.NativeString; @:native("hx::StdString const &") @:include("hx/StdString.h") @:structAccess extern class StdStringRef { public function c_str() : ConstPointer; public function size() : Int; public function find(s:String):Int; public function substr(pos:Int, len:Int):StdString; public function toString():String; public function toStdString():StdString; } haxe_3.4.4.orig/std/cpp/Stdio.hx0000664000175000017500000000331413166552354016414 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; import haxe.extern.Rest; @:include("stdio.h") extern class Stdio { @:native("printf") public static function printf(format:ConstCharStar, rest:Rest):Void; @:native("fopen") public static function fopen(filename:ConstCharStar, mode:ConstCharStar) : FILE; @:native("fwrite") public static function fwrite(data:RawPointer, elemSize:SizeT, elemCount:SizeT, file:FILE ) : SizeT; @:native("fclose") public static function fclose(file:FILE) : Int; @:native("fprintf") public static function fprintf(file:FILE,format:ConstCharStar, rest:Rest):Void; } haxe_3.4.4.orig/std/cpp/Stdlib.hx0000664000175000017500000000507313166552354016557 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:include("stdlib.h") extern class Stdlib { @:native("malloc") public static function nativeMalloc(bytes:Int) : cpp.RawPointer return null; @:native("calloc") public static function nativeCalloc(bytes:Int) : cpp.RawPointer return null; @:native("realloc") public static function nativeRealloc(inPtr:cpp.RawPointer,bytes:Int) : cpp.RawPointer return null; @:native("free") public static function nativeFree(ptr:cpp.RawPointer) : Void { } @:native("memcpy") public static function nativeMemcpy(dest:cpp.RawPointer, src:cpp.RawConstPointer, bytes:Int) : Void { } @:native("hx::ClassSizeOf") @:templatedCall public static function sizeof(t:T) : Int { } inline public static function memcpy(dest:cpp.Pointer, src:cpp.ConstPointer, bytes:Int) : Void nativeMemcpy(cast dest.ptr, cast src.ptr, bytes); inline public static function malloc(bytes:Int) : cpp.Pointer return cast nativeMalloc(bytes); inline public static function calloc(bytes:Int) : cpp.Pointer return cast nativeCalloc(bytes); inline public static function realloc(ioPtr:cpp.Pointer, bytes:Int) : Void ioPtr.setRaw( nativeRealloc(cast ioPtr.ptr, bytes) ); inline public static function free(ptr:cpp.Pointer) : Void { if (ptr!=null) { nativeFree(cast ptr.ptr); ptr.ptr = null; } } } haxe_3.4.4.orig/std/cpp/Struct.hx0000664000175000017500000000231513166552354016616 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; // Wrap external types with a class that integrates with Dynamic typedef Struct = T; haxe_3.4.4.orig/std/cpp/UInt16.hx0000664000175000017500000000227213166552354016362 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:notNull @:runtimeValue abstract UInt16 from Int to Int {} haxe_3.4.4.orig/std/cpp/UInt32.hx0000664000175000017500000000227213166552354016360 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:notNull @:runtimeValue abstract UInt32 from Int to Int {} haxe_3.4.4.orig/std/cpp/UInt64.hx0000664000175000017500000000227213166552354016365 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:notNull @:runtimeValue abstract UInt64 from Int to Int {} haxe_3.4.4.orig/std/cpp/UInt8.hx0000664000175000017500000000227113166552354016302 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:coreType @:notNull @:runtimeValue abstract UInt8 from Int to Int {} haxe_3.4.4.orig/std/cpp/VarArg.hx0000664000175000017500000000235213166552354016515 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; // Allows haxe to type params correctly, and hxcpp can recognise this use the correct type typedef VarArg = Dynamic; haxe_3.4.4.orig/std/cpp/VirtualArray.hx0000664000175000017500000000713113166552354017760 0ustar andyandy00000000000000package cpp; @:native("cpp::VirtualArray") @:coreType extern class NativeVirtualArray implements ArrayAccess { public function new() : Void; public var length(get,null) : Int; // concat( a:Array ) : Array ? public function concat( a : VirtualArray ) : VirtualArray; public function join( sep : String ) : String; public function pop() : Dynamic; public function push(x : Dynamic) : Int; public function reverse() : Void; public function shift() : Dynamic; public function slice( pos : Int, ?end : Int ) : VirtualArray; public function sort( f : Dynamic -> Dynamic -> Int ) : Void; public function splice( pos : Int, len : Int ) : VirtualArray; public function toString() : String; public function unshift( x : Dynamic ) : Void; public function insert( pos : Int, x : Dynamic ) : Void; public function remove( x : Dynamic ) : Bool; public function indexOf( x : Dynamic, ?fromIndex:Int ) : Int; public function lastIndexOf( x : Dynamic, ?fromIndex:Int ) : Int; public function copy() : VirtualArray; public function iterator() : Iterator; public function map( f : Dynamic -> S ) : VirtualArray; public function filter( f : Dynamic -> Bool ) : VirtualArray; } abstract VirtualArray(NativeVirtualArray) { // Add these two functions... @:from @:extern inline static public function fromArray(a:Array) : VirtualArray return untyped a; @:to @:extern inline public function toArray() : Array return untyped this; // The rest is just boiler-plate inline public function new() this=new NativeVirtualArray(); @:extern @:arrayAccess inline function get(idx:Int) : Dynamic return untyped this[idx]; @:extern @:arrayAccess inline function set(pos:Int, value:T ) : T return untyped this[idx] = value; public var length(get,never) : Int; @:extern inline public function get_length() : Int return this.length; // concat( a:Array ) : Array ? @:extern inline public function concat( a : VirtualArray ) : VirtualArray return this.concat(a); @:extern inline public function join( sep : String ) : String return this.join(sep); @:extern inline public function pop() : Dynamic return this.pop(); @:extern inline public function push(x : Dynamic) : Int return this.push(x); @:extern inline public function reverse() : Void this.reverse(); @:extern inline public function shift() : Dynamic return this.shift(); @:extern inline public function slice( pos : Int, ?end : Int ) : VirtualArray return this.slice(pos,end); @:extern inline public function sort( f : Dynamic -> Dynamic -> Int ) : Void this.sort(f); @:extern inline public function splice( pos : Int, len : Int ) : VirtualArray return this.slice(pos,len); @:extern inline public function unshift( x : Dynamic ) : Void this.unshift(x); @:extern inline public function insert( pos : Int, x : Dynamic ) : Void this.insert(pos,x); @:extern inline public function remove( x : Dynamic ) : Bool return this.remove(x); @:extern inline public function indexOf( x : Dynamic, ?fromIndex:Int ) : Int return this.indexOf(x,fromIndex); @:extern inline public function lastIndexOf( x : Dynamic, ?fromIndex:Int ) : Int return this.lastIndexOf(x,fromIndex); @:extern inline public function copy() : VirtualArray return this.copy(); @:extern inline public function iterator() : Iterator return this.iterator(); @:extern inline public function map( f : Dynamic -> S ) : VirtualArray return this.map(f); @:extern inline public function filter( f : Dynamic -> Bool ) : VirtualArray return this.filter(f); } haxe_3.4.4.orig/std/cpp/Void.hx0000664000175000017500000000223313166552354016232 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp; @:native("void") extern class Void { } haxe_3.4.4.orig/std/cpp/_std/Date.hx0000664000175000017500000000624513166552354017146 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi class Date { private var mSeconds:Float; public function new(year : Int, month : Int, day : Int, hour : Int, min : Int, sec : Int ) : Void { mSeconds = untyped __global__.__hxcpp_new_date(year,month,day,hour,min,sec); } public function getTime() : Float { return mSeconds * 1000.0; } public function getHours() : Int { return untyped __global__.__hxcpp_get_hours(mSeconds); } public function getMinutes() : Int { return untyped __global__.__hxcpp_get_minutes(mSeconds); } public function getSeconds() : Int { return untyped __global__.__hxcpp_get_seconds(mSeconds); } public function getFullYear() : Int { return untyped __global__.__hxcpp_get_year(mSeconds); } public function getMonth() : Int { return untyped __global__.__hxcpp_get_month(mSeconds); } public function getDate() : Int { return untyped __global__.__hxcpp_get_date(mSeconds); } public function getDay() : Int { return untyped __global__.__hxcpp_get_day(mSeconds); } public function toString():String { return untyped __global__.__hxcpp_to_string(mSeconds); } public static function now() : Date { return fromTime( untyped __global__.__hxcpp_date_now()*1000.0); } private static function new1(t : Dynamic) : Date { return new Date(2005,1,1,0,0,0); } public static function fromTime( t : Float ) : Date { var result = new Date(0,0,0,0,0,0); result.mSeconds = t*0.001; return result; } public static function fromString( s : String ) : Date { switch( s.length ) { case 8: // hh:mm:ss var k = s.split(":"); var d : Date = new Date(0,0,0,Std.parseInt(k[0]),Std.parseInt(k[1]),Std.parseInt(k[2])); return d; case 10: // YYYY-MM-DD var k = s.split("-"); return new Date(Std.parseInt(k[0]),Std.parseInt(k[1])-1,Std.parseInt(k[2]),0,0,0); case 19: // YYYY-MM-DD hh:mm:ss var k = s.split(" "); var y = k[0].split("-"); var t = k[1].split(":"); return new Date(Std.parseInt(y[0]),Std.parseInt(y[1]) - 1,Std.parseInt(y[2]), Std.parseInt(t[0]),Std.parseInt(t[1]),Std.parseInt(t[2])); default: throw "Invalid date format : " + s; } } } haxe_3.4.4.orig/std/cpp/_std/EReg.hx0000664000175000017500000001206413166552354017107 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:buildXml('') @:coreApi class EReg { var r : Dynamic; var last : String; var global : Bool; public function new( r : String, opt : String ) : Void { var a = opt.split("g"); global = a.length > 1; if( global ) opt = a.join(""); this.r = _hx_regexp_new_options(r, opt); } public function match( s : String ) : Bool { var p = _hx_regexp_match(r,s,0,s.length); if( p ) last = s; else last = null; return p; } public function matched( n : Int ) : String { var m = _hx_regexp_matched(r,n); return m; } public function matchedLeft() : String { var p = _hx_regexp_matched_pos(r,0); return last.substr(0,p.pos); } public function matchedRight() : String { var p = _hx_regexp_matched_pos(r,0); var sz = p.pos+p.len; return last.substr(sz,last.length-sz); } public function matchedPos() : { pos : Int, len : Int } { return _hx_regexp_matched_pos(r,0); } public function matchSub( s : String, pos : Int, len : Int = -1):Bool { var p = _hx_regexp_match(r, s, pos, len < 0 ? s.length - pos : len); if (p) last = s; else last = null; return p; } public function split( s : String ) : Array { var pos = 0; var len = s.length; var a = new Array(); var first = true; do { if( !_hx_regexp_match(r,s,pos,len) ) break; var p = _hx_regexp_matched_pos(r,0); if( p.len == 0 && !first ) { if( p.pos == s.length ) break; p.pos += 1; } a.push(s.substr(pos,p.pos - pos)); var tot = p.pos + p.len - pos; pos += tot; len -= tot; first = false; } while( global ); a.push(s.substr(pos,len)); return a; } public function replace( s : String, by : String ) : String { var b = new StringBuf(); var pos = 0; var len = s.length; var a = by.split("$"); var first = true; do { if( !_hx_regexp_match(r,s,pos,len) ) break; var p = _hx_regexp_matched_pos(r,0); if( p.len == 0 && !first ) { if( p.pos == s.length ) break; p.pos += 1; } b.addSub(s,pos,p.pos-pos); if( a.length > 0 ) b.add(a[0]); var i = 1; while( i < a.length ) { var k = a[i]; var c = k.charCodeAt(0); // 1...9 if( c >= 49 && c <= 57 ) { var p = try _hx_regexp_matched_pos(r,Std.int(c)-48) catch( e : String ) null; if( p == null ){ b.add("$"); b.add(k); }else{ b.addSub(s,p.pos,p.len); b.addSub(k,1,k.length - 1); } } else if( c == null ) { b.add("$"); i++; var k2 = a[i]; if( k2 != null && k2.length > 0 ) b.add(k2); } else b.add("$"+k); i++; } var tot = p.pos + p.len - pos; pos += tot; len -= tot; first = false; } while( global ); b.addSub(s,pos,len); return b.toString(); } public function map( s : String, f : EReg -> String ) : String { var offset = 0; var buf = new StringBuf(); do { if (offset >= s.length) break; else if (!matchSub(s, offset)) { buf.add(s.substr(offset)); break; } var p = _hx_regexp_matched_pos(r,0); buf.add(s.substr(offset, p.pos - offset)); buf.add(f(this)); if (p.len == 0) { buf.add(s.substr(p.pos, 1)); offset = p.pos + 1; } else offset = p.pos + p.len; } while (global); if (!global && offset > 0 && offset < s.length) buf.add(s.substr(offset)); return buf.toString(); } @:extern @:native("_hx_regexp_new_options") static function _hx_regexp_new_options(s:String, options:String) : Dynamic return null; @:extern @:native("_hx_regexp_match") static function _hx_regexp_match(handler: Dynamic, string:String, pos:Int, len:Int) : Bool return false; @:extern @:native("_hx_regexp_matched") static function _hx_regexp_matched(handle:Dynamic, pos:Int) : String return null; @:extern @:native("_hx_regexp_matched_pos") static function _hx_regexp_matched_pos(handle:Dynamic, match:Int) : {pos:Int, len:Int} return null; } haxe_3.4.4.orig/std/cpp/_std/Reflect.hx0000664000175000017500000001005013166552354017642 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import cpp.ObjectType; @:coreApi @:analyzer(ignore) class Reflect { public static function hasField( o : Dynamic, field : String ) : Bool untyped { return o!=null && o.__HasField(field); } public static function field( o : Dynamic, field : String ) : Dynamic untyped { return (o==null) ? null : o.__Field(field,untyped __cpp__("hx::paccNever") ); } public static function setField( o : Dynamic, field : String, value : Dynamic ) : Void untyped { if (o!=null) o.__SetField(field,value,untyped __cpp__("hx::paccNever") ); } public static function getProperty( o : Dynamic, field : String ) : Dynamic { return (o==null) ? null : o.__Field(field,untyped __cpp__("hx::paccAlways") ); } public static function setProperty( o : Dynamic, field : String, value : Dynamic ) : Void { if (o!=null) o.__SetField(field,value,untyped __cpp__("hx::paccAlways") ); } public static function callMethod( o : Dynamic, func : haxe.Constraints.Function, args : Array ) : Dynamic untyped { if (func!=null && func.__GetType()==ObjectType.vtString) func = o.__Field(func,untyped __cpp__("hx::paccDynamic")); untyped func.__SetThis(o); return untyped func.__Run(args); } public static function fields( o : Dynamic ) : Array untyped { if( o == null ) return new Array(); var a : Array = []; o.__GetFields(a); return a; } public static function isFunction( f : Dynamic ) : Bool untyped { return f!=null && f.__GetType() == ObjectType.vtFunction; } public static function compare( a : T, b : T ) : Int { return ( a == b ) ? 0 : (((a:Dynamic) > (b:Dynamic)) ? 1 : -1); } public static function compareMethods( f1 : Dynamic, f2 : Dynamic ) : Bool { if( f1 == f2 ) return true; if( !isFunction(f1) || !isFunction(f2) ) return false; return untyped __global__.__hxcpp_same_closure(f1,f2); } public static function isObject( v : Dynamic ) : Bool untyped { if (v==null) return false; var t:Int = v.__GetType(); return t == ObjectType.vtObject || t==ObjectType.vtClass || t==ObjectType.vtString || t==ObjectType.vtArray; } public static function isEnumValue( v : Dynamic ) : Bool untyped { return v!=null && v.__GetType() == ObjectType.vtEnum; } public static function deleteField( o : Dynamic, field : String ) : Bool untyped { if (o==null) return false; return untyped __global__.__hxcpp_anon_remove(o,field); } public static function copy( o : T ) : T { if (o==null) return null; if(untyped o.__GetType()==ObjectType.vtString ) return o; if(untyped o.__GetType()==ObjectType.vtArray ) return untyped o.__Field("copy", untyped __cpp__("hx::paccDynamic"))(); var o2 : Dynamic = {}; for( f in Reflect.fields(o) ) Reflect.setField(o2,f,Reflect.field(o,f)); return o2; } @:overload(function( f : Array -> Void ) : Dynamic {}) public static function makeVarArgs( f : Array -> Dynamic ) : Dynamic { return untyped __global__.__hxcpp_create_var_args(f); } } haxe_3.4.4.orig/std/cpp/_std/Std.hx0000664000175000017500000000371413166552354017021 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi class Std { @:keep public static function is( v : Dynamic, t : Dynamic ) : Bool { return untyped __global__.__instanceof(v,t); } @:keep public static function instance( value : T, c : Class ) : S { return Std.is(value, c) ? cast value : null; } @:keep public static function string( s : Dynamic ) : String { return untyped s==null ? "null" : s.toString(); } @:keep public static function int( x : Float ) : Int { return untyped __global__.__int__(x); } @:keep public static function parseInt( x : String ) : Null { return untyped __global__.__hxcpp_parse_int(x); } @:keep public static function parseFloat( x : String ) : Float { return untyped __global__.__hxcpp_parse_float(x); } @:keep public static function random( x : Int ) : Int { if (x <= 0) return 0; return untyped __global__.__hxcpp_irand(x); } } haxe_3.4.4.orig/std/cpp/_std/StringBuf.hx0000664000175000017500000000521313166552354020166 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import cpp.NativeString; using cpp.NativeArray; @:coreApi class StringBuf { private var b : Array; public var length(get,never) : Int; var charBuf:Array; public function new() : Void { } private function charBufAsString() : String { var len = charBuf.length; charBuf.push(0); return NativeString.fromGcPointer( charBuf.address(0), len ); } private function flush() : Void{ if (b==null) b = [charBufAsString()]; else b.push( charBufAsString() ); charBuf = null; } function get_length() : Int { var len = 0; if (charBuf!=null) len = charBuf.length; if (b!=null) for(s in b) len += s==null ? 4 : s.length; return len; } public inline function add( x : T ) : Void { if (charBuf!=null) flush(); if (b==null) b = [Std.string(x)]; else b.push(Std.string(x)); } public #if !cppia inline #end function addSub( s : String, pos : Int, ?len : Int ) : Void { if (charBuf!=null) flush(); if (b==null) b = [s.substr(pos,len)]; else b.push(s.substr(pos,len)); } public #if !cppia inline #end function addChar( c : Int ) : Void { if (charBuf==null) charBuf = new Array(); charBuf.push(c); } public function toString() : String { if (charBuf!=null) flush(); if (b==null || b.length==0) return ""; if (b.length==1) return b[0]; return b.join(""); } } haxe_3.4.4.orig/std/cpp/_std/Sys.hx0000664000175000017500000000753513166552354017052 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import cpp.NativeSys; @:coreApi class Sys { public static function print( v : Dynamic ) : Void { untyped __global__.__hxcpp_print(v); } public static function println( v : Dynamic ) : Void { untyped __global__.__hxcpp_println(v); } @:access(sys.io.FileInput) public static function stdin() : haxe.io.Input { return new sys.io.FileInput(cpp.NativeFile.file_stdin()); } @:access(sys.io.FileOutput) public static function stdout() : haxe.io.Output { return new sys.io.FileOutput(cpp.NativeFile.file_stdout()); } @:access(sys.io.FileOutput) public static function stderr() : haxe.io.Output { return new sys.io.FileOutput(cpp.NativeFile.file_stderr()); } public static function getChar( echo : Bool ) : Int { return NativeSys.sys_getch(echo); } public static function args() : Array untyped { return __global__.__get_args(); } public static function getEnv( s : String ):String { var v = NativeSys.get_env(s); if( v == null ) return null; return v; } public static function putEnv( s : String, v : String ) : Void { NativeSys.put_env(s,v); } public static function sleep( seconds : Float ) : Void { NativeSys.sys_sleep(seconds); } public static function setTimeLocale( loc : String ) : Bool { return NativeSys.set_time_locale(loc); } public static function getCwd() : String { return NativeSys.get_cwd(); } public static function setCwd( s : String ) : Void { NativeSys.set_cwd(s); } public static function systemName() : String { return NativeSys.sys_string(); } public static function command( cmd : String, ?args : Array ) : Int { if (args == null) { return NativeSys.sys_command(cmd); } else { switch (systemName()) { case "Windows": cmd = [ for (a in [StringTools.replace(cmd, "/", "\\")].concat(args)) StringTools.quoteWinArg(a, true) ].join(" "); return NativeSys.sys_command(cmd); case _: cmd = [cmd].concat(args).map(StringTools.quoteUnixArg).join(" "); return NativeSys.sys_command(cmd); } } } public static function exit( code : Int ) : Void { untyped __global__.__hxcpp_exit(code); } public static function time() : Float { return NativeSys.sys_time(); } public static function cpuTime() : Float { return NativeSys.sys_cpu_time(); } @:deprecated("Use programPath instead") public static function executablePath() : String { return NativeSys.sys_exe_path(); } public static function programPath() : String { return NativeSys.sys_exe_path(); } public static function environment() : Map { var vars:Array = NativeSys.sys_env(); var result = new haxe.ds.StringMap(); var i = 0; while(i ); TEnum( e : Enum ); TUnknown; } @:coreApi class Type { public static function getClass( o : T ) : Class untyped { if (o==null || !Reflect.isObject(o)) return null; var c = o.__GetClass(); switch(c.toString()) { case "__Anon" : return null; case "Class" : return null; } return c; } public static function getEnum( o : EnumValue ) : Enum untyped { if (o==null) return null; return untyped o.__GetClass(); } public static function getSuperClass( c : Class ) : Class untyped { return c.GetSuper(); } public static function getClassName( c : Class ) : String { if( c == null ) return null; return untyped c.mName; } public static function getEnumName( e : Enum ) : String { return untyped e.__ToString(); } public static function resolveClass( name : String ) : Class untyped { var result:Class = Class.Resolve(name); if (result!=null && result.__IsEnum() ) return null; return result; } public static function resolveEnum( name : String ) : Enum untyped { var result:Class = Class.Resolve(name); if (result!=null && !result.__IsEnum() ) return null; return result; } public static function createInstance( cl : Class, args : Array ) : T untyped { if (cl!=null) return cl.ConstructArgs(args); return null; } public static function createEmptyInstance( cl : Class ) : T untyped { return cl.ConstructEmpty(); } public static function createEnum( e : Enum, constr : String, ?params : Array ) : T { return untyped e.ConstructEnum(constr,params); } public static function createEnumIndex( e : Enum, index : Int, ?params : Array ) : T { var c = Type.getEnumConstructs(e)[index]; if( c == null ) throw index+" is not a valid enum constructor index"; return createEnum(e,c,params); } public static function getInstanceFields( c : Class ) : Array { return untyped c.GetInstanceFields(); } public static function getClassFields( c : Class ) : Array { return untyped c.GetClassFields(); } public static function getEnumConstructs( e : Enum ) : Array untyped { return untyped e.GetClassFields(); } public static function typeof( v : Dynamic ) : ValueType untyped { if (v==null) return TNull; var t:Int = untyped v.__GetType(); switch(t) { case 2 : return TBool; case 0xFF : return TInt; case 1 : return TFloat; case 6 : return TFunction; case 4 : return TObject; case 7 : return TEnum(v.__GetClass()); default: return untyped TClass(v.__GetClass()); } } public static function enumEq( a : T, b : T ) : Bool untyped { return a==b; } public static function enumConstructor( e : EnumValue ) : String { var value:cpp.EnumBase = cast e; return value._hx_getTag(); } public static function enumParameters( e : EnumValue ) : Array { var value:cpp.EnumBase = cast e; return value._hx_getParameters(); } @:extern @:native("_hx_getEnumValueIndex") private static function getEnumValueIndex( e : EnumValue ) : Int return 0; #if !cppia inline #end public static function enumIndex( e : EnumValue ) : Int { return getEnumValueIndex(e); } public static function allEnums( e : Enum ) : Array { var names:Array = untyped e.GetClassFields(); var enums = new Array(); for(name in names) { try { var result:T = untyped e.ConstructEnum(name,null); if (result!=null) enums.push( result ); } catch ( invalidArgCount:String) { } } return enums; } } haxe_3.4.4.orig/std/cpp/_std/haxe/Int64.hx0000664000175000017500000003412413166552354020117 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; import haxe.Int64Helper; @:notNull @:include("cpp/Int64.h") @:native("cpp::Int64Struct") private extern class ___Int64 { public function get():cpp.Int64; @:native("_hx_int64_make") public static function make(high:Int32, low:Int32): __Int64 return null; @:native(" ::cpp::Int64Struct") public static function ofInt(value:Int): __Int64 return null; @:native(" ::cpp::Int64Struct::is") public static function is(d:Dynamic):Bool return false; @:native("_hx_int64_is_neg") public static function isNeg(a:__Int64):Bool return false; @:native("_hx_int64_is_zero") public static function isZero(a:__Int64):Bool return false; @:native("_hx_int64_compare") public static function compare(a:__Int64, b:__Int64):Int return 0; @:native("_hx_int64_ucompare") public static function ucompare(a:__Int64, b:__Int64):Int return 0; @:native("_hx_int64_to_string") public static function toString(a:__Int64):String return null; @:native("_hx_int64_neg") public static function neg(a:__Int64): __Int64 return null; @:native("_hx_int64_pre_increment") public static function preIncrement(a:__Int64): __Int64 return null; @:native("_hx_int64_post_increment") public static function postIncrement(a:__Int64): __Int64 return null; @:native("_hx_int64_pre_decrement") public static function preDecrement(a:__Int64): __Int64 return null; @:native("_hx_int64_post_decrement") public static function postDecrement(a:__Int64): __Int64 return null; @:native("_hx_int64_add") public static function add(a:__Int64, b:__Int64): __Int64 return null; @:native("_hx_int64_add") public static function addInt(a:__Int64, b:Int): __Int64 return null; @:native("_hx_int64_sub") public static function sub(a:__Int64, b:__Int64): __Int64 return null; @:native("_hx_int64_sub") public static function subInt(a:__Int64, b:Int): __Int64 return null; @:native("_hx_int64_sub") public static function intSub(a:Int, b:__Int64): __Int64 return null; @:native("_hx_int64_mul") public static function mul(a:__Int64, b:__Int64): __Int64 return null; @:native("_hx_int64_div") public static function div(a:__Int64, b:__Int64): __Int64 return null; @:native("_hx_int64_mod") public static function mod(a:__Int64, b:__Int64): __Int64 return null; @:native("_hx_int64_eq") public static function eq(a:__Int64, b:__Int64): Bool return null; @:native("_hx_int64_eq") public static function eqInt(a:__Int64, b:Int): Bool return null; @:native("_hx_int64_neq") public static function neq(a:__Int64, b:__Int64): Bool return null; @:native("_hx_int64_neq") public static function neqInt(a:__Int64, b:Int): Bool return null; @:native("_hx_int64_complement") public static function complement(a:__Int64): __Int64 return null; @:native("_hx_int64_and") public static function bitAnd(a:__Int64, b:__Int64): __Int64 return null; @:native("_hx_int64_or") public static function bitOr(a:__Int64, b:__Int64): __Int64 return null; @:native("_hx_int64_xor") public static function bitXor(a:__Int64, b:__Int64): __Int64 return null; @:native("_hx_int64_shl") public static function shl(a:__Int64, b:Int): __Int64 return null; @:native("_hx_int64_shr") public static function shr(a:__Int64, b:Int): __Int64 return null; @:native("_hx_int64_ushr") public static function ushr(a:__Int64, b:Int): __Int64 return null; @:native("_hx_int64_high") public static function high(a:__Int64):Int32 return 0; @:native("_hx_int64_low") public static function low(a:__Int64):Int32 return 0; } private typedef __Int64 = ___Int64; @:coreApi abstract Int64( __Int64 ) from __Int64 to __Int64 { /** Makes a copy of `this` Int64. **/ public #if !cppia inline #end function copy():Int64 return this; public static #if !cppia inline #end function make( high : Int32, low : Int32 ) : Int64 { return __Int64.make(high,low); } @:from public static #if !cppia inline #end function ofInt( x : Int ) : Int64 { return __Int64.ofInt(x); } /** Returns an Int with the value of the Int64 `x`. Throws an exception if `x` cannot be represented in 32 bits. **/ public static #if !cppia inline #end function toInt( x : Int64 ) : Int { if( x.high != x.low >> 31 ) throw "Overflow"; return x.low; } /** Returns whether the value `val` is of type `haxe.Int64` **/ public static #if !cppia inline #end function is( val : Dynamic ) : Bool return __Int64.is(val); /** Returns the high 32-bit word of `x`. **/ @:deprecated("Use high instead") public static #if !cppia inline #end function getHigh( x : Int64 ) : Int32 return x.high; /** Returns the low 32-bit word of `x`. **/ @:deprecated("Use low instead") public static #if !cppia inline #end function getLow( x : Int64 ) : Int32 return x.low; /** Returns `true` if `x` is less than zero. **/ public static #if !cppia inline #end function isNeg( x : Int64) : Bool return __Int64.isNeg(x); /** Returns `true` if `x` is exactly zero. **/ public static #if !cppia inline #end function isZero( x : Int64 ) : Bool return __Int64.isZero(x); /** Compares `a` and `b` in signed mode. Returns a negative value if `a < b`, positive if `a > b`, or 0 if `a == b`. **/ public static #if !cppia inline #end function compare( a : Int64, b : Int64 ) : Int return __Int64.compare(a,b); /** Compares `a` and `b` in unsigned mode. Returns a negative value if `a < b`, positive if `a > b`, or 0 if `a == b`. **/ public static #if !cppia inline #end function ucompare( a : Int64, b : Int64 ) : Int return __Int64.ucompare(a,b); /** Returns a signed decimal `String` representation of `x`. **/ public static #if !cppia inline #end function toStr(x:Int64) : String return x.toString(); private #if !cppia inline #end function toString() : String return __Int64.toString(this); public static function parseString( sParam : String ) : Int64 { return Int64Helper.parseString( sParam ); } public static function fromFloat( f : Float ) : Int64 { return Int64Helper.fromFloat( f ); } /** Performs signed integer divison of `dividend` by `divisor`. Returns `{ quotient : Int64, modulus : Int64 }`. **/ public static function divMod( dividend : Int64, divisor : Int64 ) : { quotient : Int64, modulus : Int64 } { var q = dividend/divisor; if (isZero(divisor)) throw "divide by zero"; var m = dividend - q*divisor; return { quotient : q, modulus : m }; } /** Returns the negative of `x`. **/ @:op(-A) public static #if !cppia inline #end function neg( x : Int64 ) : Int64 return __Int64.neg(x); @:op(++A) private inline function preIncrement() : Int64 { #if cppia this = this + make(0,1); return this; #else return __Int64.preIncrement(this); #end } @:op(A++) private inline function postIncrement() : Int64 { #if cppia var result = this; this = this + make(0,1); return result; #else return __Int64.postIncrement(this); #end } @:op(--A) private inline function preDecrement() : Int64 { #if cppia untyped this = this - make(0,1); return this; #else return __Int64.preDecrement(this); #end } @:op(A--) private inline function postDecrement() : Int64 { #if cppia var result = this; this = this - make(0,1); return result; #else return __Int64.postDecrement(this); #end } /** Returns the sum of `a` and `b`. **/ @:op(A + B) public static #if !cppia inline #end function add( a : Int64, b : Int64 ) : Int64 return __Int64.add(a,b); @:op(A + B) @:commutative private static #if !cppia inline #end function addInt( a : Int64, b : Int ) : Int64 return __Int64.addInt(a,b); /** Returns `a` minus `b`. **/ @:op(A - B) public static #if !cppia inline #end function sub( a : Int64, b : Int64 ) : Int64 { return __Int64.sub(a,b); } @:op(A - B) private static #if !cppia inline #end function subInt( a : Int64, b : Int ) : Int64 return __Int64.subInt( a, b ); @:op(A - B) private static #if !cppia inline #end function intSub( a : Int, b : Int64 ) : Int64 return __Int64.intSub( a, b ); /** Returns the product of `a` and `b`. **/ @:op(A * B) public static #if !cppia inline #end function mul( a : Int64, b : Int64 ) : Int64 return __Int64.mul( a, b ); @:op(A * B) @:commutative private static #if !cppia inline #end function mulInt( a : Int64, b : Int ) : Int64 return mul( a, b ); /** Returns the quotient of `a` divided by `b`. **/ @:op(A / B) public static #if !cppia inline #end function div( a : Int64, b : Int64 ) : Int64 { if (__Int64.isZero(b)) throw "divide by zero"; return __Int64.div(a,b); } @:op(A / B) private static #if !cppia inline #end function divInt( a : Int64, b : Int ) : Int64 return div( a, b ); @:op(A / B) private static #if !cppia inline #end function intDiv( a : Int, b : Int64 ) : Int64 return toInt(div( a, b )); /** Returns the modulus of `a` divided by `b`. **/ @:op(A % B) public static #if !cppia inline #end function mod( a : Int64, b : Int64 ) : Int64 { if (__Int64.isZero(b)) throw "divide by zero"; return __Int64.mod(a, b); } @:op(A % B) private static #if !cppia inline #end function modInt( a : Int64, b : Int ) : Int64 return toInt(mod( a, b )); @:op(A % B) private static #if !cppia inline #end function intMod( a : Int, b : Int64 ) : Int64 return toInt(mod( a, b )); /** Returns `true` if `a` is equal to `b`. **/ @:op(A == B) public static #if !cppia inline #end function eq( a : Int64, b : Int64 ) : Bool return __Int64.eq(a,b); @:op(A == B) @:commutative private static #if !cppia inline #end function eqInt( a : Int64, b : Int ) : Bool return __Int64.eqInt( a, b ); /** Returns `true` if `a` is not equal to `b`. **/ @:op(A != B) public static #if !cppia inline #end function neq( a : Int64, b : Int64 ) : Bool return __Int64.neq( a, b ); @:op(A != B) @:commutative private static #if !cppia inline #end function neqInt( a : Int64, b : Int ) : Bool return neq( a, b ); @:op(A < B) private static #if !cppia inline #end function lt( a : Int64, b : Int64 ) : Bool return compare(a, b) < 0; @:op(A < B) private static #if !cppia inline #end function ltInt( a : Int64, b : Int ) : Bool return lt(a, b); @:op(A < B) private static #if !cppia inline #end function intLt( a : Int, b : Int64 ) : Bool return lt(a, b); @:op(A <= B) private static #if !cppia inline #end function lte( a : Int64, b : Int64 ) : Bool return compare(a, b) <= 0; @:op(A <= B) private static #if !cppia inline #end function lteInt( a : Int64, b : Int ) : Bool return lte(a, b); @:op(A <= B) private static #if !cppia inline #end function intLte( a : Int, b : Int64 ) : Bool return lte(a, b); @:op(A > B) private static #if !cppia inline #end function gt( a : Int64, b : Int64 ) : Bool return compare(a, b) > 0; @:op(A > B) private static #if !cppia inline #end function gtInt( a : Int64, b : Int ) : Bool return gt(a, b); @:op(A > B) private static #if !cppia inline #end function intGt( a : Int, b : Int64 ) : Bool return gt( a, b ); @:op(A >= B) private static #if !cppia inline #end function gte( a : Int64, b : Int64 ) : Bool return compare(a, b) >= 0; @:op(A >= B) private static #if !cppia inline #end function gteInt( a : Int64, b : Int ) : Bool return gte(a, b); @:op(A >= B) private static #if !cppia inline #end function intGte( a : Int, b : Int64 ) : Bool return gte(a, b); /** Returns the bitwise NOT of `a`. **/ @:op(~A) private static #if !cppia inline #end function complement( a : Int64 ) : Int64 return __Int64.complement(a); /** Returns the bitwise AND of `a` and `b`. **/ @:op(A & B) public static #if !cppia inline #end function and( a : Int64, b : Int64 ) : Int64 return __Int64.bitAnd(a,b); /** Returns the bitwise OR of `a` and `b`. **/ @:op(A | B) public static #if !cppia inline #end function or( a : Int64, b : Int64 ) : Int64 return __Int64.bitOr(a,b); /** Returns the bitwise XOR of `a` and `b`. **/ @:op(A ^ B) public static #if !cppia inline #end function xor( a : Int64, b : Int64 ) : Int64 return __Int64.bitXor(a,b); /** Returns `a` left-shifted by `b` bits. **/ @:op(A << B) public static #if !cppia inline #end function shl( a : Int64, b : Int ) : Int64 return __Int64.shl(a,b); /** Returns `a` right-shifted by `b` bits in signed mode. `a` is sign-extended. **/ @:op(A >> B) public static #if !cppia inline #end function shr( a : Int64, b : Int) : Int64 return __Int64.shr(a,b); /** Returns `a` right-shifted by `b` bits in unsigned mode. `a` is padded with zeroes. **/ @:op(A >>> B) public static #if !cppia inline #end function ushr( a : Int64, b : Int ) : Int64 return __Int64.ushr(a,b); public var high(get, never) : Int32; private #if !cppia inline #end function get_high() : Int32 return __Int64.high(this); public var low(get, never) : Int32; private #if !cppia inline #end function get_low() : Int32 return __Int64.low(this); } haxe_3.4.4.orig/std/cpp/_std/haxe/Resource.hx0000664000175000017500000000312313166552354020775 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; @:coreApi class Resource { public static function listNames() : Array { return untyped __global__.__hxcpp_resource_names(); } public static function getString(name:String) : String { return untyped __global__.__hxcpp_resource_string(name); } public static function getBytes(name:String) : haxe.io.Bytes { var array:haxe.io.BytesData = untyped __global__.__hxcpp_resource_bytes(name); if (array==null) return null; return haxe.io.Bytes.ofData(array); } } haxe_3.4.4.orig/std/cpp/_std/haxe/Utf8.hx0000664000175000017500000000540513166552354020041 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; using cpp.NativeString; @:coreApi class Utf8 { var __s:Array; public function new( ?size : Null ) : Void { __s = new Array(); if (size!=null && size>0) cpp.NativeArray.reserve(__s,size); } public function addChar( c : Int ) : Void { __s.push(c); } public function toString() : String { return untyped __global__.__hxcpp_char_array_to_utf8_string(__s); } // Incoming string is array of bytes containing possibly invalid utf8 chars // Result is the same string with the bytes expanded into utf8 sequences public static function encode( s : String ) : String { return untyped __global__.__hxcpp_char_bytes_to_utf8_string(s); } // Incoming string is array of bytes representing valid utf8 chars // Result is a string containing the compressed bytes public static function decode( s : String ) : String { return untyped __global__.__hxcpp_utf8_string_to_char_bytes(s); } public #if !cppia inline #end static function iter( s : String, chars : Int -> Void ) : Void { var src = s.c_str(); var end = src.add( s.length ); while(src.lt(end)) chars(src.ptr.utf8DecodeAdvance()); } public static function charCodeAt( s : String, index : Int ) : Int { return s.utf8CharCodeAt(index); } public static function validate( s : String ) : Bool { return s.utf8IsValid(); } public static function length( s : String ) : Int { return s.utf8Length(); } public static function compare( a : String, b : String ) : Int { return a.compare(b); } public static function sub( s : String, pos : Int, len : Int ) : String { return s.utf8Sub(pos,len); } } haxe_3.4.4.orig/std/cpp/_std/haxe/ds/IntMap.hx0000664000175000017500000000672213166552354021014 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:headerClassCode(" inline void set(int key, ::null value) { __int_hash_set(h,key,value); } inline void set(int key, bool value) { __int_hash_set(h,key,value); } inline void set(int key, char value) { __int_hash_set_int(h,key,value); } inline void set(int key, unsigned char value) { __int_hash_set_int(h,key,value); } inline void set(int key, signed char value) { __int_hash_set_int(h,key,value); } inline void set(int key, short value) { __int_hash_set_int(h,key,value); } inline void set(int key, unsigned short value) { __int_hash_set_int(h,key,value); } inline void set(int key, int value) { __int_hash_set_int(h,key,value); } inline void set(int key, unsigned int value) { __int_hash_set_int(h,key,value); } inline void set(int key, float value) { __int_hash_set_float(h,key,value); } inline void set(int key, double value) { __int_hash_set_float(h,key,value); } inline void set(int key, ::String value) { __int_hash_set_string(h,key,value); } template inline void set(int key, const ::cpp::Struct &value) {__int_hash_set(h,key,value); } template inline void set(int key, const ::cpp::Function &value) {__int_hash_set(h,key,value); } template inline void set(int key, const ::cpp::Pointer &value) {__int_hash_set(h,key,(Dynamic)value ); } template inline void set(Dynamic &key, const VALUE &value) { set( (int)key, value ); } ") @:coreApi class IntMap implements haxe.Constraints.IMap { @:ifFeature("haxe.ds.IntMap.*") private var h : Dynamic; public function new() : Void { } public function set( key : Int, value : T ) : Void { untyped __global__.__int_hash_set(h,key,value); } public function get( key : Int ) : Null { return untyped __global__.__int_hash_get(h,key); } public function exists( key : Int ) : Bool { return untyped __global__.__int_hash_exists(h,key); } public function remove( key : Int ) : Bool { return untyped __global__.__int_hash_remove(h,key); } public function keys() : Iterator { var a:Array = untyped __global__.__int_hash_keys(h); return a.iterator(); } public function iterator() : Iterator { var a:Array = untyped __global__.__int_hash_values(h); return a.iterator(); } public function toString() : String { return untyped __global__.__int_hash_to_string(h); } } haxe_3.4.4.orig/std/cpp/_std/haxe/ds/ObjectMap.hx0000664000175000017500000000675413166552354021475 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:headerClassCode(" inline void set(Dynamic key, ::null value) { __object_hash_set(h,key,value); } inline void set(Dynamic key, bool value) { __object_hash_set(h,key,value); } inline void set(Dynamic key, char value) { __object_hash_set_int(h,key,value); } inline void set(Dynamic key, unsigned char value) { __object_hash_set_int(h,key,value); } inline void set(Dynamic key, signed char value) { __object_hash_set_int(h,key,value); } inline void set(Dynamic key, short value) { __object_hash_set_int(h,key,value); } inline void set(Dynamic key, unsigned short value) { __object_hash_set_int(h,key,value); } inline void set(Dynamic key, int value) { __object_hash_set_int(h,key,value); } inline void set(Dynamic key, unsigned int value) { __object_hash_set_int(h,key,value); } inline void set(Dynamic key, float value) { __object_hash_set_float(h,key,value); } inline void set(Dynamic key, double value) { __object_hash_set_float(h,key,value); } inline void set(Dynamic key, ::String value) { __object_hash_set_string(h,key,value); } template inline void set(Dynamic key, const ::cpp::Struct &value) {__object_hash_set(h,key,value); } template inline void set(Dynamic key, const ::cpp::Function &value) {__object_hash_set(h,key,(Dynamic)value ); } template inline void set(Dynamic key, const ::cpp::Pointer &value) {__object_hash_set(h,key,(Dynamic)value ); } ") @:coreApi class ObjectMap implements haxe.Constraints.IMap { @:ifFeature("haxe.ds.ObjectMap.*") private var h : Dynamic; public function new() : Void { } public function set( key : K, value : V ) : Void { untyped __global__.__object_hash_set(h,key,value); } public function get( key : K ) : Null { return untyped __global__.__object_hash_get(h,key); } public function exists( key : K ) : Bool { return untyped __global__.__object_hash_exists(h,key); } public function remove( key : K ) : Bool { return untyped __global__.__object_hash_remove(h,key); } public function keys() : Iterator { var a:Array = untyped __global__.__object_hash_keys(h); return a.iterator(); } public function iterator() : Iterator { var a:Array = untyped __global__.__object_hash_values(h); return a.iterator(); } public function toString() : String { return untyped __global__.__object_hash_to_string(h); } } haxe_3.4.4.orig/std/cpp/_std/haxe/ds/StringMap.hx0000664000175000017500000000715013166552354021524 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:headerClassCode(" inline void set(String key, ::null value) { __string_hash_set(h,key,value); } inline void set(String key, bool value) { __string_hash_set(h,key,value); } inline void set(String key, char value) { __string_hash_set_int(h,key,value); } inline void set(String key, unsigned char value) { __string_hash_set_int(h,key,value); } inline void set(String key, signed char value) { __string_hash_set_int(h,key,value); } inline void set(String key, short value) { __string_hash_set_int(h,key,value); } inline void set(String key, unsigned short value) { __string_hash_set_int(h,key,value); } inline void set(String key, int value) { __string_hash_set_int(h,key,value); } inline void set(String key, unsigned int value) { __string_hash_set_int(h,key,value); } inline void set(String key, float value) { __string_hash_set_float(h,key,value); } inline void set(String key, double value) { __string_hash_set_float(h,key,value); } inline void set(String key, ::String value) { __string_hash_set_string(h,key,value); } template inline void set(String key, const ::cpp::Struct &value) {__string_hash_set(h,key,value); } template inline void set(String key, const ::cpp::Function &value) {__string_hash_set(h,key,(Dynamic)value ); } template inline void set(String key, const ::cpp::Pointer &value) {__string_hash_set(h,key,(Dynamic)value ); } template inline void set(Dynamic &key, const VALUE &value) { set( (String)key, value ); } ") @:coreApi class StringMap implements haxe.Constraints.IMap { @:ifFeature("haxe.ds.StringMap.*") private var h : Dynamic; public function new() : Void { } public function set( key : String, value : T ) : Void { untyped __global__.__string_hash_set(h,key,value); } public function get( key : String ) : Null { return untyped __global__.__string_hash_get(h,key); } public function exists( key : String ) : Bool { return untyped __global__.__string_hash_exists(h,key); } public function remove( key : String ) : Bool { return untyped __global__.__string_hash_remove(h,key); } public function keys() : Iterator { var a:Array = untyped __global__.__string_hash_keys(h); return a.iterator(); } public function iterator() : Iterator { var a:Array = untyped __global__.__string_hash_values(h); return a.iterator(); } public function toString() : String { return untyped __global__.__string_hash_to_string(h); } } haxe_3.4.4.orig/std/cpp/_std/haxe/ds/WeakMap.hx0000664000175000017500000000706613166552354021153 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:headerClassCode(" inline void set(Dynamic key, ::null value) { __object_hash_set(h,key,value,true); } inline void set(Dynamic key, bool value) { __object_hash_set(h,key,value,true); } inline void set(Dynamic key, char value) { __object_hash_set_int(h,key,value,true); } inline void set(Dynamic key, unsigned char value) { __object_hash_set_int(h,key,value,true); } inline void set(Dynamic key, signed char value) { __object_hash_set_int(h,key,value,true); } inline void set(Dynamic key, short value) { __object_hash_set_int(h,key,value,true); } inline void set(Dynamic key, unsigned short value) { __object_hash_set_int(h,key,value,true); } inline void set(Dynamic key, int value) { __object_hash_set_int(h,key,value,true); } inline void set(Dynamic key, unsigned int value) { __object_hash_set_int(h,key,value,true); } inline void set(Dynamic key, float value) { __object_hash_set_float(h,key,value,true); } inline void set(Dynamic key, double value) { __object_hash_set_float(h,key,value,true); } inline void set(Dynamic key, ::String value) { __object_hash_set_string(h,key,value,true); } template inline void set(Dynamic key, const ::cpp::Struct &value) {__object_hash_set(h,key,value,true); } template inline void set(Dynamic key, const ::cpp::Pointer &value) {__object_hash_set(h,key,(Dynamic)value,true ); } template inline void set(Dynamic key, const ::cpp::Function &value) {__object_hash_set(h,key,(Dynamic)value,true ); } ") @:coreApi class WeakMap implements haxe.Constraints.IMap { @:ifFeature("haxe.ds.WeakMap.*") private var h : Dynamic; public function new() : Void { } public function set( key : K, value : V ) : Void { untyped __global__.__object_hash_set(h,key,value,true); } public function get( key : K ) : Null { return untyped __global__.__object_hash_get(h,key); } public function exists( key : K ) : Bool { return untyped __global__.__object_hash_exists(h,key); } public function remove( key : K ) : Bool { return untyped __global__.__object_hash_remove(h,key); } public function keys() : Iterator { var a:Array = untyped __global__.__object_hash_keys(h); return a.iterator(); } public function iterator() : Iterator { var a:Array = untyped __global__.__object_hash_values(h); return a.iterator(); } public function toString() : String { return untyped __global__.__object_hash_to_string(h); } } haxe_3.4.4.orig/std/cpp/_std/haxe/zip/Compress.hx0000664000175000017500000000525413166552354021612 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; @:coreApi @:buildXml('') class Compress { var s : Dynamic; public function new( level : Int ) : Void { s = _deflate_init(level); } public function execute( src : haxe.io.Bytes, srcPos : Int, dst : haxe.io.Bytes, dstPos : Int ) : { done : Bool, read : Int, write : Int } { return _deflate_buffer(s,src.getData(),srcPos,dst.getData(),dstPos); } public function setFlushMode( f : FlushMode ) : Void { _set_flush_mode(s,Std.string(f)); } public function close() : Void { _deflate_end(s); } public static function run( s : haxe.io.Bytes, level : Int ) : haxe.io.Bytes { var c = new Compress(level); c.setFlushMode(FlushMode.FINISH); var out = haxe.io.Bytes.alloc(_deflate_bound(c.s,s.length)); var r = c.execute(s,0,out,0); c.close(); if( !r.done || r.read != s.length ) throw "Compression failed"; return out.sub(0,r.write); } @:extern @:native("_hx_deflate_init") static function _deflate_init(level:Int) : Dynamic return null; @:extern @:native("_hx_deflate_bound") static function _deflate_bound(handle:Dynamic,length:Int):Int return 0; @:extern @:native("_hx_deflate_buffer") static function _deflate_buffer(handle:Dynamic, src:haxe.io.BytesData, srcPos:Int, dest:haxe.io.BytesData, destPos:Int) : { done : Bool, read : Int, write : Int } return null; @:extern @:native("_hx_deflate_end") static function _deflate_end(handle:Dynamic) : Void { } @:extern @:native("_hx_zip_set_flush_mode") static function _set_flush_mode(handle:Dynamic, flushMode:String):Void { } } haxe_3.4.4.orig/std/cpp/_std/haxe/zip/Uncompress.hx0000664000175000017500000000527613166552354022161 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; @:coreApi @:buildXml('') class Uncompress { var s : Dynamic; public function new( ?windowBits : Int ) : Void { s = _inflate_init(windowBits); } public function execute( src : haxe.io.Bytes, srcPos : Int, dst : haxe.io.Bytes, dstPos : Int ) : { done : Bool, read : Int, write : Int } { return _inflate_buffer(s,src.getData(),srcPos,dst.getData(),dstPos); } public function setFlushMode( f : FlushMode ) : Void { _set_flush_mode(s,untyped f.__Tag()); } public function close() : Void { _inflate_end(s); } public static function run( src : haxe.io.Bytes, ?bufsize : Int ) : haxe.io.Bytes { var u = new Uncompress(null); if( bufsize == null ) bufsize = 1 << 16; // 64K var tmp = haxe.io.Bytes.alloc(bufsize); var b = new haxe.io.BytesBuffer(); var pos = 0; u.setFlushMode(FlushMode.SYNC); while( true ) { var r = u.execute(src,pos,tmp,0); b.addBytes(tmp,0,r.write); pos += r.read; if( r.done ) break; } u.close(); return b.getBytes(); } @:extern @:native("_hx_inflate_init") static function _inflate_init(windowBits:Dynamic) : Dynamic return null; @:extern @:native("_hx_inflate_buffer") static function _inflate_buffer(handle:Dynamic, src:haxe.io.BytesData, srcPos:Int, dest:haxe.io.BytesData, destPos:Int) : { done : Bool, read : Int, write : Int } return null; @:extern @:native("_hx_inflate_end") static function _inflate_end(handle:Dynamic):Void { } @:extern @:native("_hx_zip_set_flush_mode") static function _set_flush_mode(handle:Dynamic, flushMode:String):Void { } } haxe_3.4.4.orig/std/cpp/_std/sys/FileSystem.hx0000664000175000017500000000661613166552354021175 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys; import cpp.NativeSys; @:buildXml('') @:coreApi class FileSystem { public static function exists( path : String ) : Bool { return NativeSys.sys_exists(makeCompatiblePath(path)); } public static function rename( path : String, newPath : String ) : Void { NativeSys.sys_rename(path,newPath); } public static function stat( path : String ) : FileStat { var s : FileStat = NativeSys.sys_stat(makeCompatiblePath(path)); if (s==null) return { gid:0, uid:0, atime:Date.fromTime(0), mtime:Date.fromTime(0), ctime:Date.fromTime(0), dev:0, ino:0, nlink:0, rdev:0, size:0, mode:0 }; s.atime = Date.fromTime(1000.0*(untyped s.atime)); s.mtime = Date.fromTime(1000.0*(untyped s.mtime)); s.ctime = Date.fromTime(1000.0*(untyped s.ctime)); return s; } public static function fullPath( relPath : String ) : String { return NativeSys.file_full_path(relPath); } public static function absolutePath ( relPath : String ) : String { if (haxe.io.Path.isAbsolute(relPath)) return relPath; return haxe.io.Path.join([Sys.getCwd(), relPath]); } inline static function kind( path : String ) : String { return NativeSys.sys_file_type(makeCompatiblePath(path)); } public static function isDirectory( path : String ) : Bool { return kind(path) == "dir"; } public static function createDirectory( path : String ) : Void { var path = haxe.io.Path.addTrailingSlash(path); var _p = null; var parts = []; while (path != (_p = haxe.io.Path.directory(path))) { parts.unshift(path); path = _p; } for (part in parts) { if (part.charCodeAt(part.length - 1) != ":".code && !exists(part) && !NativeSys.sys_create_dir( part, 493 )) throw "Could not create directory:" + part; } } public static function deleteFile( path : String ) : Void { NativeSys.file_delete(path); } public static function deleteDirectory( path : String ) : Void { NativeSys.sys_remove_dir(path); } public static function readDirectory( path : String ) : Array { return NativeSys.sys_read_dir(path); } private static inline function makeCompatiblePath(path:String):String { return if (path.charCodeAt(1) == ":".code && path.length <= 3) { haxe.io.Path.addTrailingSlash(path); } else { haxe.io.Path.removeTrailingSlashes(path); } } } haxe_3.4.4.orig/std/cpp/_std/sys/db/Mysql.hx0000664000175000017500000001411313166552354020572 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.db; @:keep private class D { @:extern @:native("_hx_mysql_connect") public static function connect(params:Dynamic):Dynamic return null; @:extern @:native("_hx_mysql_select_db") public static function select_db(handle:Dynamic, db:String):Void { } @:extern @:native("_hx_mysql_request") public static function request(handle:Dynamic,req:String):Dynamic return null; @:extern @:native("_hx_mysql_close") public static function close(handle:Dynamic):Dynamic return null; @:extern @:native("_hx_mysql_escape") public static function escape(handle:Dynamic,str:String):String return null; @:extern @:native("_hx_mysql_result_get_length") public static function result_get_length(handle:Dynamic):Int return 0; @:extern @:native("_hx_mysql_result_get_nfields") public static function result_get_nfields(handle:Dynamic):Int return 0; @:extern @:native("_hx_mysql_result_next") public static function result_next(handle:Dynamic):Dynamic return null; @:extern @:native("_hx_mysql_result_get") public static function result_get(handle:Dynamic,i:Int) : String return null; @:extern @:native("_hx_mysql_result_get_int") public static function result_get_int(handle:Dynamic,i:Int) : Int return 0; @:extern @:native("_hx_mysql_result_get_float") public static function result_get_float(handle:Dynamic,i:Int):Float return 0.0; @:extern @:native("_hx_mysql_result_get_fields_names") public static function result_fields_names(handle:Dynamic):Array return null; @:extern @:native("_hx_mysql_set_conversion") public static function set_conv_funs( charsToBytes: cpp.Callable< Dynamic -> Dynamic >, intToDate: cpp.Callable< Float -> Dynamic > ) : Void {} public static function charsToBytes(data:Dynamic) : Dynamic return haxe.io.Bytes.ofData(data); public static function secondsToDate(seconds:Float) : Dynamic return Date.fromTime(seconds); } private class MysqlResultSet implements sys.db.ResultSet { public var length(get,null) : Int; public var nfields(get,null) : Int; private var __r : Dynamic; private var cache : Dynamic; public function new(r) { __r = r; } private function get_length() { return D.result_get_length(__r); } private function get_nfields() { return D.result_get_nfields(__r); } public function hasNext() { if( cache == null ) cache = next(); return (cache != null); } public function next() : Dynamic { var c = cache; if( c != null ) { cache = null; return c; } c = D.result_next(__r); return c; } public function results() : List { var l = new List(); while( hasNext() ) l.add(next()); return l; } public function getResult( n : Int ) { return D.result_get(__r,n); } public function getIntResult( n : Int ) : Int { return D.result_get_int(__r,n); } public function getFloatResult( n : Int ) : Float { return D.result_get_float(__r,n); } public function getFieldsNames() : Array { var a = D.result_fields_names(__r); return a; } } private class MysqlConnection implements sys.db.Connection { private var __c : Dynamic; public function new(c) { __c = c; D.set_conv_funs( cpp.Function.fromStaticFunction(D.charsToBytes), cpp.Function.fromStaticFunction(D.secondsToDate) ); } public function request( s : String ) : sys.db.ResultSet { var r = D.request(this.__c, s); return new MysqlResultSet(r); } public function close() { D.close(__c); } public function escape( s : String ) { return D.escape(__c,s); } public function quote( s : String ) { return "'"+escape(s)+"'"; } public function addValue( s : StringBuf, v : Dynamic ) { if (v == null) { s.add(v); } else if (Std.is(v,Bool)) { s.add( v ? 1 : 0 ); } else { var t:Int = untyped v.__GetType(); if( t == 0xff ) s.add(v); else if( t == 2 ) s.add( untyped v.__GetInt() ? "1".code : "0".code ); else { s.addChar("'".code); s.add(escape(Std.string(v))); s.addChar("'".code); } } } public function lastInsertId() { return request("SELECT LAST_INSERT_ID()").getIntResult(0); } public function dbName() { return "MySQL"; } public function startTransaction() { request("START TRANSACTION"); } public function commit() { request("COMMIT"); } public function rollback() { request("ROLLBACK"); } private static var __use_date = Date; } @:buildXml('') @:coreApi class Mysql { public static function connect( params : { host : String, ?port : Int, user : String, pass : String, ?socket : String, database : String } ) : sys.db.Connection { var o = { host : params.host, port : if( params.port == null ) 3306 else params.port, user : params.user, pass : params.pass, socket : if( params.socket == null ) null else params.socket }; var c = D.connect(o); try { D.select_db(c,params.database); } catch( e : Dynamic ) { D.close(c); cpp.Lib.rethrow(e); } return new MysqlConnection(c); } } haxe_3.4.4.orig/std/cpp/_std/sys/db/Sqlite.hx0000664000175000017500000001234513166552354020733 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.db; private class SqliteConnection implements Connection { var c : Dynamic; public function new( file : String ) { c = _connect(file); } public function close() { _close(c); } public function request( s : String ) : ResultSet { try { return new SqliteResultSet(_request(c,s)); } catch( e : String ) { throw "Error while executing "+s+" ("+e+")"; } } public function escape( s : String ) { return s.split("'").join("''"); } public function quote( s : String ) { if( s.indexOf("\000") >= 0 ) { var hexChars = new Array(); for(i in 0...s.length) hexChars.push( StringTools.hex( StringTools.fastCodeAt(s,i),2 ) ); return "x'"+ hexChars.join("") +"'"; } return "'"+s.split("'").join("''")+"'"; } public function addValue( s : StringBuf, v : Dynamic ) { if (v == null) { s.add(v); } else if (Std.is(v,Bool)) { s.add( v ? 1 : 0 ); } else { var t:Int = untyped v.__GetType(); if( t == 0xff ) s.add(v); else if( t == 2 ) s.add( untyped v.__GetInt() ); else s.add(quote(Std.string(v))); } } public function lastInsertId() : Int{ return _last_id(c); } public function dbName() { return "SQLite"; } public function startTransaction() { request("BEGIN TRANSACTION"); } public function commit() { request("COMMIT"); startTransaction(); // match mysql usage } public function rollback() { request("ROLLBACK"); startTransaction(); // match mysql usage } @:extern @:native("_hx_sqlite_connect") public static function _connect(filename:String):Dynamic return null; @:extern @:native("_hx_sqlite_request") public static function _request(handle:Dynamic,req:String):Dynamic return null; @:extern @:native("_hx_sqlite_close") public static function _close(handle:Dynamic):Void { }; @:extern @:native("_hx_sqlite_last_insert_id") public static function _last_id(handle:Dynamic):Int return 0; } private class SqliteResultSet implements ResultSet { public var length(get,null) : Int; public var nfields(get,null) : Int; var r : Dynamic; var cache : List; public function new( r ) { cache = new List(); this.r = r; hasNext(); // execute the request } function get_length() { if( nfields != 0 ) { while( true ) { var c = result_next(r); if( c == null ) break; cache.add(c); } return cache.length; } return result_get_length(r); } function get_nfields() { return result_get_nfields(r); } public function hasNext() { var c = next(); if( c == null ) return false; cache.push(c); return true; } public function next() : Dynamic { var c = cache.pop(); if( c != null ) return c; return result_next(r); } public function results() : List { var l = new List(); while( true ) { var c = next(); if( c == null ) break; l.add(c); } return l; } public function getResult( n : Int ) { return new String(result_get(r,n)); } public function getIntResult( n : Int ) : Int { return result_get_int(r,n); } public function getFloatResult( n : Int ) : Float { return result_get_float(r,n); } public function getFieldsNames() : Array { return null; } @:extern @:native("_hx_sqlite_result_next") public static function result_next(handle:Dynamic):Dynamic return null; @:extern @:native("_hx_sqlite_result_get_length") public static function result_get_length(handle:Dynamic):Int return 0; @:extern @:native("_hx_sqlite_result_get_nfields") public static function result_get_nfields(handle:Dynamic):Int return 0; @:extern @:native("_hx_sqlite_result_get") public static function result_get(handle:Dynamic,i:Int) : String return null; @:extern @:native("_hx_sqlite_result_get_int") public static function result_get_int(handle:Dynamic,i:Int) : Int return 0; @:extern @:native("_hx_sqlite_result_get_float") public static function result_get_float(handle:Dynamic,i:Int):Float return 0.0; } @:buildXml('') @:coreApi class Sqlite { public static function open( file : String ) : Connection { return new SqliteConnection(file); } } haxe_3.4.4.orig/std/cpp/_std/sys/io/File.hx0000664000175000017500000000464713166552354020401 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; import cpp.NativeFile; @:coreApi class File { public static function getContent( path : String ) : String { return NativeFile.file_contents_string(path); } public static function getBytes( path : String ) : haxe.io.Bytes { var data = NativeFile.file_contents_bytes(path); return haxe.io.Bytes.ofData(data); } public static function saveContent( path : String, content : String ) : Void { var f = write(path); f.writeString(content); f.close(); } public static function saveBytes( path : String, bytes : haxe.io.Bytes ) : Void { var f = write(path); f.write(bytes); f.close(); } public static function read( path : String, binary : Bool = true ) : FileInput { return untyped new FileInput(NativeFile.file_open(path,(if( binary ) "rb" else "r"))); } public static function write( path : String, binary : Bool = true ) : FileOutput { return untyped new FileOutput(NativeFile.file_open(path,(if( binary ) "wb" else "w"))); } public static function append( path : String, binary : Bool = true ) : FileOutput { return untyped new FileOutput(NativeFile.file_open(path,(if( binary ) "ab" else "a"))); } public static function copy( srcPath : String, dstPath : String ) : Void { var s = read(srcPath,true); var d = write(dstPath,true); d.writeInput(s); s.close(); d.close(); } } haxe_3.4.4.orig/std/cpp/_std/sys/io/FileInput.hx0000664000175000017500000000424113166552354021407 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; import sys.io.FileSeek; import cpp.NativeFile; @:coreApi class FileInput extends haxe.io.Input { private var __f : Dynamic; function new(f:Dynamic) : Void { __f = f; } public override function readByte() : Int { return try { NativeFile.file_read_char(__f); } catch( e : Dynamic ) { if( untyped e.__IsArray() ) throw new haxe.io.Eof(); else throw haxe.io.Error.Custom(e); } } public override function readBytes( s : haxe.io.Bytes, p : Int, l : Int ) : Int { return try { NativeFile.file_read(__f,s.getData(),p,l); } catch( e : Dynamic ) { if( untyped e.__IsArray() ) throw new haxe.io.Eof(); else throw haxe.io.Error.Custom(e); } } public override function close() : Void { super.close(); NativeFile.file_close(__f); } public function seek( p : Int, pos : FileSeek ) : Void { NativeFile.file_seek(__f,p,pos==SeekBegin ? 0 : pos==SeekCur ? 1 : 2 ); } public function tell() : Int { return NativeFile.file_tell(__f); } public function eof() : Bool { return NativeFile.file_eof(__f); } } haxe_3.4.4.orig/std/cpp/_std/sys/io/FileOutput.hx0000664000175000017500000000400513166552354021606 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; import sys.io.FileSeek; import cpp.NativeFile; @:coreApi class FileOutput extends haxe.io.Output { private var __f : Dynamic; function new(f:Dynamic) : Void { __f = f; } public override function writeByte( c : Int ) : Void { try NativeFile.file_write_char(__f,c) catch( e : Dynamic ) throw haxe.io.Error.Custom(e); } public override function writeBytes( s : haxe.io.Bytes, p : Int, l : Int ) : Int { return try NativeFile.file_write(__f,s.getData(),p,l) catch( e : Dynamic ) throw haxe.io.Error.Custom(e); } public override function flush() : Void { NativeFile.file_flush(__f); } public override function close() : Void { super.close(); NativeFile.file_close(__f); } public function seek( p : Int, pos : FileSeek ) : Void { NativeFile.file_seek(__f,p, pos == SeekBegin ? 0 : pos == SeekCur ? 1 : 2); } public function tell() : Int { return NativeFile.file_tell(__f); } } haxe_3.4.4.orig/std/cpp/_std/sys/io/Process.hx0000664000175000017500000000645013166552354021132 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; import cpp.NativeProcess; private class Stdin extends haxe.io.Output { var p : Dynamic; var buf : haxe.io.Bytes; public function new(p) { this.p = p; buf = haxe.io.Bytes.alloc(1); } public override function close() { super.close(); NativeProcess.process_stdin_close(p); } public override function writeByte(c) { buf.set(0,c); writeBytes(buf,0,1); } public override function writeBytes( buf : haxe.io.Bytes, pos : Int, len : Int ) : Int { try { return NativeProcess.process_stdin_write(p,buf.getData(),pos,len); } catch( e : Dynamic ) { throw new haxe.io.Eof(); } return 0; } } private class Stdout extends haxe.io.Input { var p : Dynamic; var out : Bool; var buf : haxe.io.Bytes; public function new(p,out) { this.p = p; this.out = out; buf = haxe.io.Bytes.alloc(1); } public override function readByte() { if( readBytes(buf,0,1) == 0 ) throw haxe.io.Error.Blocked; return buf.get(0); } public override function readBytes( str : haxe.io.Bytes, pos : Int, len : Int ) : Int { var result:Int; try { result = out? NativeProcess.process_stdout_read(p,str.getData(),pos,len) : NativeProcess.process_stderr_read(p,str.getData(),pos,len); } catch( e : Dynamic ) { throw new haxe.io.Eof(); } if (result==0)throw new haxe.io.Eof(); return result; } } @:coreApi class Process { var p : Dynamic; public var stdout(default,null) : haxe.io.Input; public var stderr(default,null) : haxe.io.Input; public var stdin(default,null) : haxe.io.Output; public function new( cmd : String, ?args : Array ) : Void { p = try NativeProcess.process_run(cmd,args) catch( e : Dynamic ) throw "Process creation failure : "+cmd; stdin = new Stdin(p); stdout = new Stdout(p,true); stderr = new Stdout(p,false); } public function getPid() : Int { return NativeProcess.process_pid(p); } public function exitCode( block : Bool = true ) : Null { if( block == false ) throw "Non blocking exitCode() not supported on this platform"; return NativeProcess.process_exit(p); } public function close() : Void { NativeProcess.process_close(p); } public function kill() : Void { throw "Not implemented"; } } haxe_3.4.4.orig/std/cpp/_std/sys/net/Host.hx0000664000175000017500000000367013166552354020611 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.net; import cpp.NativeSocket; @:coreApi class Host { public var host(default,null) : String; public var ip(default,null) : Int; private var ipv6(default,null) : haxe.io.BytesData; public function new( name : String ) : Void { host = name; try { ip = NativeSocket.host_resolve(name); } catch(e:Dynamic) { ipv6 = NativeSocket.host_resolve_ipv6(name); } } public function toString() : String { return ipv6==null ? NativeSocket.host_to_string(ip) : NativeSocket.host_to_string_ipv6(ipv6); } public function reverse() : String { return ipv6==null ? NativeSocket.host_reverse(ip) : NativeSocket.host_reverse_ipv6(ipv6); } public static function localhost() : String { return NativeSocket.host_local(); } static function __init__() : Void { NativeSocket.socket_init(); } } haxe_3.4.4.orig/std/cpp/_std/sys/net/Socket.hx0000664000175000017500000001670213166552354021124 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.net; import haxe.io.Error; import cpp.NativeSocket; private class SocketInput extends haxe.io.Input { var __s : Dynamic; public function new(s) { __s = s; } public override function readByte() { return try { NativeSocket.socket_recv_char(__s); } catch( e : Dynamic ) { if( e == "Blocking" ) throw Blocked; else if( __s == null ) throw Custom(e); else throw new haxe.io.Eof(); } } public override function readBytes( buf : haxe.io.Bytes, pos : Int, len : Int ) : Int { var r; if (__s==null) throw "Invalid handle"; try { r = NativeSocket.socket_recv(__s,buf.getData(),pos,len); } catch( e : Dynamic ) { if( e == "Blocking" ) throw Blocked; else throw Custom(e); } if( r == 0 ) throw new haxe.io.Eof(); return r; } public override function close() { super.close(); if( __s != null ) NativeSocket.socket_close(__s); } } private class SocketOutput extends haxe.io.Output { var __s : Dynamic; public function new(s) { __s = s; } public override function writeByte( c : Int ) { if (__s==null) throw "Invalid handle"; try { NativeSocket.socket_send_char(__s, c); } catch( e : Dynamic ) { if( e == "Blocking" ) throw Blocked; else throw Custom(e); } } public override function writeBytes( buf : haxe.io.Bytes, pos : Int, len : Int) : Int { return try { NativeSocket.socket_send(__s, buf.getData(), pos, len); } catch( e : Dynamic ) { if( e == "Blocking" ) throw Blocked; else if (e == "EOF") throw new haxe.io.Eof(); else throw Custom(e); } } public override function close() { super.close(); if( __s != null ) NativeSocket.socket_close(__s); } } @:coreApi class Socket { private var __s : Dynamic; public var input(default,null) : haxe.io.Input; public var output(default,null) : haxe.io.Output; public var custom : Dynamic; public function new() : Void { init(); } private function init() : Void { if( __s == null )__s = NativeSocket.socket_new(false); input = new SocketInput(__s); output = new SocketOutput(__s); } public function close() : Void { NativeSocket.socket_close(__s); untyped { var input : SocketInput = cast input; var output : SocketOutput = cast output; input.__s = null; output.__s = null; } input.close(); output.close(); } public function read() : String { var bytes:haxe.io.BytesData = NativeSocket.socket_read(__s); if (bytes==null) return ""; return bytes.toString(); } public function write( content : String ) : Void { NativeSocket.socket_write(__s, haxe.io.Bytes.ofString(content).getData() ); } public function connect(host : Host, port : Int) : Void { try { if (host.ip==0 && host.host!="0.0.0.0") { // hack, hack, hack var ipv6:haxe.io.BytesData = Reflect.field(host,"ipv6"); if (ipv6!=null) { close(); __s = NativeSocket.socket_new_ip(false,true); init(); NativeSocket.socket_connect_ipv6(__s, ipv6, port); } else throw "Unresolved host"; } else NativeSocket.socket_connect(__s, host.ip, port); } catch( s : String ) { if( s == "Invalid socket handle" ) throw "Failed to connect on "+host.toString()+":"+port; else if (s == "Blocking") { // Do nothing, this is not a real error, it simply indicates // that a non-blocking connect is in progress } else cpp.Lib.rethrow(s); } } public function listen(connections : Int) : Void { NativeSocket.socket_listen(__s, connections); } public function shutdown( read : Bool, write : Bool ) : Void { NativeSocket.socket_shutdown(__s,read,write); } public function bind(host : Host, port : Int) : Void { if (host.ip==0 && host.host!="0.0.0.0") { var ipv6:haxe.io.BytesData = Reflect.field(host,"ipv6"); if (ipv6!=null) { close(); __s = NativeSocket.socket_new_ip(false,true); init(); NativeSocket.socket_bind_ipv6(__s, ipv6, port); } else throw "Unresolved host"; } else NativeSocket.socket_bind(__s, host.ip, port); } public function accept() : Socket { var c = NativeSocket.socket_accept(__s); var s = Type.createEmptyInstance(Socket); s.__s = c; s.input = new SocketInput(c); s.output = new SocketOutput(c); return s; } public function peer() : { host : Host, port : Int } { var a : Dynamic = NativeSocket.socket_peer(__s); if (a == null) { return null; } var h = new Host("127.0.0.1"); untyped h.ip = a[0]; return { host : h, port : a[1] }; } public function host() : { host : Host, port : Int } { var a : Dynamic = NativeSocket.socket_host(__s); if (a == null) { return null; } var h = new Host("127.0.0.1"); untyped h.ip = a[0]; return { host : h, port : a[1] }; } public function setTimeout( timeout : Float ) : Void { NativeSocket.socket_set_timeout(__s, timeout); } public function waitForRead() : Void { select([this],null,null,null); } public function setBlocking( b : Bool ) : Void { NativeSocket.socket_set_blocking(__s,b); } public function setFastSend( b : Bool ) : Void { NativeSocket.socket_set_fast_send(__s,b); } public static function select(read : Array, write : Array, others : Array, ?timeout : Float ) : {read: Array,write: Array,others: Array} { var neko_array = NativeSocket.socket_select(read,write,others, timeout); if (neko_array==null) throw "Select error"; return @:fixed { read: neko_array[0], write: neko_array[1], others: neko_array[2] }; } } haxe_3.4.4.orig/std/cpp/_std/sys/net/UdpSocket.hx0000664000175000017500000000365613166552354021601 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.net; import haxe.io.Error; import cpp.NativeSocket; @:coreApi class UdpSocket extends Socket { private override function init() : Void { __s = NativeSocket.socket_new(true); super.init(); } public function sendTo( buf : haxe.io.Bytes, pos : Int, len : Int, addr : Address ) : Int { return try { NativeSocket.socket_send_to(__s, buf.getData(), pos, len, addr); } catch( e : Dynamic ) { if( e == "Blocking" ) throw Blocked; else throw Custom(e); } } public function readFrom( buf : haxe.io.Bytes, pos : Int, len : Int, addr : Address ) : Int { var r; try { r = NativeSocket.socket_recv_from(__s,buf.getData(),pos,len,addr); } catch( e : Dynamic ) { if( e == "Blocking" ) throw Blocked; else throw Custom(e); } if( r == 0 ) throw new haxe.io.Eof(); return r; } } haxe_3.4.4.orig/std/cpp/_std/sys/ssl/Certificate.hx0000664000175000017500000000575113166552354022133 0ustar andyandy00000000000000package sys.ssl; import cpp.NativeSsl; @:coreApi class Certificate { var __h : Null; var __x : Dynamic; @:allow(sys.ssl.Socket) function new( x : Dynamic, ?h: Null ){ __x = x; __h = h; } public static function loadFile( file : String ) : Certificate { return new Certificate( NativeSsl.cert_load_file( file ) ); } public static function loadPath( path : String ) : Certificate { return new Certificate( NativeSsl.cert_load_path( path ) ); } public static function fromString( str : String ) : Certificate { return new Certificate( NativeSsl.cert_add_pem(null, str) ); } public static function loadDefaults() : Certificate { var x = NativeSsl.cert_load_defaults(); if ( x != null ) return new Certificate( x ); var defPaths = null; switch( Sys.systemName() ){ case "Linux": defPaths = [ "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL "/etc/ssl/ca-bundle.pem", // OpenSUSE "/etc/pki/tls/cacert.pem", // OpenELEC "/etc/ssl/certs", // SLES10/SLES11 "/system/etc/security/cacerts" // Android ]; case "BSD": defPaths = [ "/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly "/etc/ssl/cert.pem", // OpenBSD "/etc/openssl/certs/ca-certificates.crt", // NetBSD ]; case "Android": defPaths = ["/system/etc/security/cacerts"]; default: } if( defPaths != null ){ for ( path in defPaths ){ if ( sys.FileSystem.exists(path) ){ if( sys.FileSystem.isDirectory(path) ) return loadPath(path); else return loadFile(path); } } } return null; } public var commonName(get,null) : Null; public var altNames(get, null) : Array; public var notBefore(get,null) : Date; public var notAfter(get,null) : Date; function get_commonName() : Null { return subject("CN"); } function get_altNames() : Array { return NativeSsl.cert_get_altnames(__x); } public function subject( field : String ) : Null { return NativeSsl.cert_get_subject(__x, field); } public function issuer( field : String ) : Null { return NativeSsl.cert_get_issuer(__x, field); } function get_notBefore() : Date { var a = NativeSsl.cert_get_notbefore( __x ); return new Date( a[0], a[1] - 1, a[2], a[3], a[4], a[5] ); } function get_notAfter() : Date { var a = NativeSsl.cert_get_notafter( __x ); return new Date( a[0], a[1] - 1, a[2], a[3], a[4], a[5] ); } public function next() : Null { var n = NativeSsl.cert_get_next(__x); return n == null ? null : new Certificate( n, __h==null ? this : __h ); } public function add( pem : String ) : Void { NativeSsl.cert_add_pem(__x,pem); } public function addDER( der : haxe.io.Bytes ) : Void { NativeSsl.cert_add_der(__x,der.getData()); } static function __init__() : Void { NativeSsl.init(); } } haxe_3.4.4.orig/std/cpp/_std/sys/ssl/Digest.hx0000664000175000017500000000127313166552354021123 0ustar andyandy00000000000000package sys.ssl; import cpp.NativeSsl; @:coreApi class Digest { public static function make( data : haxe.io.Bytes, alg : DigestAlgorithm ) : haxe.io.Bytes { return haxe.io.Bytes.ofData( NativeSsl.dgst_make( data.getData(), alg ) ); } public static function sign( data : haxe.io.Bytes, privKey : Key, alg : DigestAlgorithm ) : haxe.io.Bytes { return haxe.io.Bytes.ofData( NativeSsl.dgst_sign( data.getData(), @:privateAccess privKey.__k, alg ) ); } public static function verify( data : haxe.io.Bytes, signature : haxe.io.Bytes, pubKey : Key, alg : DigestAlgorithm ) : Bool{ return NativeSsl.dgst_verify( data.getData(), signature.getData(), @:privateAccess pubKey.__k, alg ); } } haxe_3.4.4.orig/std/cpp/_std/sys/ssl/Key.hx0000664000175000017500000000155513166552354020437 0ustar andyandy00000000000000package sys.ssl; import cpp.NativeSsl; private typedef PKEY = Dynamic; @:coreApi class Key { private var __k : PKEY; private function new( k : PKEY ){ __k = k; } public static function loadFile( file : String, ?isPublic : Bool, ?pass : String ) : Key { var data = sys.io.File.getBytes( file ); var str = cpp.Lib.stringReference(data); if( str.indexOf("-----BEGIN ") >= 0 ) return readPEM( str, isPublic==true, pass ); else return readDER( data, isPublic==true ); } public static function readPEM( data : String, isPublic : Bool, ?pass : String ) : Key { return new Key( NativeSsl.key_from_pem( data, isPublic, pass ) ); } public static function readDER( data : haxe.io.Bytes, isPublic : Bool ) : Key { return new Key( NativeSsl.key_from_der( data.getData(), isPublic ) ); } static function __init__() : Void { NativeSsl.init(); } } haxe_3.4.4.orig/std/cpp/_std/sys/ssl/Socket.hx0000664000175000017500000001535713166552354021144 0ustar andyandy00000000000000package sys.ssl; import cpp.NativeSocket; import cpp.NativeSsl; private typedef SocketHandle = Dynamic; private typedef CONF = Dynamic; private typedef SSL = Dynamic; private class SocketInput extends haxe.io.Input { @:allow(sys.ssl.Socket) private var __s : Socket; public function new( s : Socket ) { this.__s = s; } public override function readByte() { return try { __s.handshake(); NativeSsl.ssl_recv_char( @:privateAccess __s.ssl ); } catch( e : Dynamic ) { if( e == "Blocking" ) throw haxe.io.Error.Blocked; else if( __s == null ) throw haxe.io.Error.Custom(e); else throw new haxe.io.Eof(); } } public override function readBytes( buf : haxe.io.Bytes, pos : Int, len : Int ) : Int { var r : Int; if( __s == null ) throw "Invalid handle"; try { __s.handshake(); r = NativeSsl.ssl_recv( @:privateAccess __s.ssl, buf.getData(), pos, len ); } catch( e : Dynamic ) { if( e == "Blocking" ) throw haxe.io.Error.Blocked; else throw haxe.io.Error.Custom(e); } if( r == 0 ) throw new haxe.io.Eof(); return r; } public override function close() { super.close(); if( __s != null ) __s.close(); } } private class SocketOutput extends haxe.io.Output { @:allow(sys.ssl.Socket) private var __s : Socket; public function new( s : Socket ) { this.__s = s; } public override function writeByte( c : Int ) { if( __s == null ) throw "Invalid handle"; try { __s.handshake(); NativeSsl.ssl_send_char( @:privateAccess __s.ssl, c ); } catch( e : Dynamic ) { if( e == "Blocking" ) throw haxe.io.Error.Blocked; else throw haxe.io.Error.Custom(e); } } public override function writeBytes( buf : haxe.io.Bytes, pos : Int, len : Int) : Int { return try { __s.handshake(); NativeSsl.ssl_send( @:privateAccess __s.ssl, buf.getData(), pos, len ); } catch( e : Dynamic ) { if( e == "Blocking" ) throw haxe.io.Error.Blocked; else throw haxe.io.Error.Custom(e); } } public override function close() { super.close(); if( __s != null ) __s.close(); } } @:coreApi class Socket extends sys.net.Socket { public static var DEFAULT_VERIFY_CERT : Null = true; public static var DEFAULT_CA : Null; private var conf : CONF; private var ssl : SSL; public var verifyCert : Null; private var caCert : Null; private var hostname : String; private var ownCert : Null; private var ownKey : Null; private var altSNIContexts : NullBool, key: Key, cert: Certificate}>>; private var sniCallback : Dynamic; private var handshakeDone : Bool; private override function init() : Void { __s = NativeSocket.socket_new( false ); input = new SocketInput( this ); output = new SocketOutput( this ); if( DEFAULT_VERIFY_CERT && DEFAULT_CA == null ){ try { DEFAULT_CA = Certificate.loadDefaults(); }catch( e : Dynamic ){} } caCert = DEFAULT_CA; verifyCert = DEFAULT_VERIFY_CERT; } public override function connect(host : sys.net.Host, port : Int) : Void { try { conf = buildSSLConfig( false ); ssl = NativeSsl.ssl_new( conf ); handshakeDone = false; NativeSsl.ssl_set_socket( ssl, __s ); if( hostname == null ) hostname = host.host; if( hostname != null ) NativeSsl.ssl_set_hostname( ssl, hostname ); NativeSocket.socket_connect( __s, host.ip, port ); handshake(); } catch( s : String ) { if( s == "Invalid socket handle" ) throw "Failed to connect on "+host.host+":"+port; else cpp.Lib.rethrow(s); } catch( e : Dynamic ) { cpp.Lib.rethrow(e); } } public function handshake() : Void { if( !handshakeDone ){ try { NativeSsl.ssl_handshake( ssl ); handshakeDone = true; } catch( e : Dynamic ) { if( e == "Blocking" ) throw haxe.io.Error.Blocked; else cpp.Lib.rethrow( e ); } } } public function setCA( cert : Certificate ) : Void { caCert = cert; } public function setHostname( name : String ) : Void { hostname = name; } public function setCertificate( cert : Certificate, key : Key ) : Void { ownCert = cert; ownKey = key; } public override function read() : String { handshake(); var b = NativeSsl.ssl_read( ssl ); if( b == null ) return ""; return haxe.io.Bytes.ofData(b).toString(); } public override function write( content : String ) : Void { handshake(); NativeSsl.ssl_write( ssl, haxe.io.Bytes.ofString(content).getData() ); } public override function close() : Void { if( ssl != null ) NativeSsl.ssl_close( ssl ); if( conf != null ) NativeSsl.conf_close( conf ); if( altSNIContexts != null ) sniCallback = null; NativeSocket.socket_close( __s ); var input : SocketInput = cast input; var output : SocketOutput = cast output; @:privateAccess input.__s = output.__s = null; input.close(); output.close(); } public function addSNICertificate( cbServernameMatch : String->Bool, cert : Certificate, key : Key ) : Void { if( altSNIContexts == null ) altSNIContexts = []; altSNIContexts.push( {match: cbServernameMatch, cert: cert, key: key} ); } public override function bind( host : sys.net.Host, port : Int ) : Void { conf = buildSSLConfig( true ); NativeSocket.socket_bind( __s, host.ip, port ); } public override function accept() : Socket { var c = NativeSocket.socket_accept( __s ); var ssl = NativeSsl.ssl_new( conf ); NativeSsl.ssl_set_socket( ssl, c ); var s = Type.createEmptyInstance( sys.ssl.Socket ); s.__s = c; s.ssl = ssl; s.input = new SocketInput(s); s.output = new SocketOutput(s); s.handshakeDone = false; return s; } public function peerCertificate() : sys.ssl.Certificate { var x = NativeSsl.ssl_get_peer_certificate( ssl ); return x==null ? null : new sys.ssl.Certificate( x ); } private function buildSSLConfig( server : Bool ) : CONF { var conf : CONF = NativeSsl.conf_new( server ); if( ownCert != null && ownKey != null ) NativeSsl.conf_set_cert( conf, @:privateAccess ownCert.__x, @:privateAccess ownKey.__k ); if ( altSNIContexts != null ) { sniCallback = function(servername) { var servername = new String(cast servername); for( c in altSNIContexts ){ if( c.match(servername) ) return @:privateAccess {key: c.key.__k, cert: c.cert.__x}; } if( ownKey != null && ownCert != null ) return @:privateAccess { key: ownKey.__k, cert: ownCert.__x }; return null; } NativeSsl.conf_set_servername_callback( conf, sniCallback ); } if ( caCert != null ) NativeSsl.conf_set_ca( conf, caCert == null ? null : @:privateAccess caCert.__x ); if( verifyCert == null ) NativeSsl.conf_set_verify( conf, 2 ); else NativeSsl.conf_set_verify( conf, verifyCert ? 1 : 0 ); return conf; } static function __init__() : Void { NativeSsl.init(); } } haxe_3.4.4.orig/std/cpp/abi/Abi.hx0000664000175000017500000000231013166552354016553 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.abi; // Base case, for calling conventions - means "use default" extern class Abi { } haxe_3.4.4.orig/std/cpp/abi/CDecl.hx0000664000175000017500000000225313166552354017040 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.abi; @:abi("__cdecl") extern class CDecl extends Abi { } haxe_3.4.4.orig/std/cpp/abi/FastCall.hx0000664000175000017500000000226113166552354017556 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.abi; @:abi("__fastcall") extern class FastCall extends Abi { } haxe_3.4.4.orig/std/cpp/abi/StdCall.hx0000664000175000017500000000225713166552354017420 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.abi; @:abi("__stdcall") extern class StdCall extends Abi { } haxe_3.4.4.orig/std/cpp/abi/ThisCall.hx0000664000175000017500000000226113166552354017570 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.abi; @:abi("__thiscall") extern class ThisCall extends Abi { } haxe_3.4.4.orig/std/cpp/abi/Winapi.hx0000664000175000017500000000225613166552354017320 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.abi; @:abi("__stdcall") extern class Winapi extends Abi { } haxe_3.4.4.orig/std/cpp/cppia/Host.hx0000664000175000017500000000350213166552354017342 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.cppia; class Host { public static function run(source:String) { var module = Module.fromString(source); module.boot(); module.run(); } public static function runFile(filename:String) { run( sys.io.File.getContent(filename) ); } public static function main() { var script = Sys.args()[0]; #if (!scriptable && !doc_gen) #error "Please define scriptable to use cppia" #end if (script==null) { Sys.println("Usage : Cppia scriptname"); } else { var source = sys.io.File.getContent(script); var module = Module.fromString(source); module.boot(); module.run(); } } } haxe_3.4.4.orig/std/cpp/cppia/HostClasses.hx0000664000175000017500000001555513166552354020673 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.cppia; import haxe.macro.Compiler; import haxe.macro.Context; import haxe.macro.Type; #if !macro #if cppia @:build(cpp.cppia.HostClasses.exclude()) #end class HostClasses { } #else import Sys; import haxe.Constraints; @:noPackageRestrict class HostClasses { static var classes = [ "cpp.Lib", "cpp.NativeArray", "cpp.NativeString", "cpp.vm.Debugger", "cpp.vm.Deque", "cpp.vm.ExecutionTrace", "cpp.vm.Gc", "cpp.vm.Lock", "cpp.vm.Mutex", "cpp.vm.Profiler", "cpp.vm.Thread", "cpp.vm.Tls", "cpp.vm.Unsafe", "cpp.vm.WeakRef", "cpp.Object", "cpp.Int64", "cpp.Finalizable", "Std", "StringBuf", "sys.db.Mysql", "sys.db.Sqlite", "sys.FileSystem", "sys.io.File", "sys.io.FileInput", "sys.net.UdpSocket", "sys.net.Socket", "sys.ssl.Certificate", "sys.ssl.Digest", "sys.ssl.Key", "sys.ssl.Socket", "Enum", "EnumValue", //"Sys", "Type", "Xml", "Date", "Lambda", "DateTools", "List", "Math", "Reflect", "StringBuf", "StringTools", "haxe.ds.IntMap", "haxe.ds.ObjectMap", "haxe.ds.StringMap", "haxe.ds.BalancedTree", "haxe.CallStack", "haxe.Serializer", "haxe.Unserializer", "haxe.Resource", "haxe.Template", "haxe.Utf8", "haxe.Log", "haxe.zip.Compress", "haxe.zip.Uncompress", "haxe.crypto.BaseCode", "haxe.crypto.Sha256", "haxe.crypto.Hmac", "haxe.crypto.Crc32", "haxe.crypto.Base64", "haxe.crypto.Adler32", "haxe.crypto.Md5", "haxe.crypto.Sha1", "haxe.io.BufferInput", "haxe.io.Bytes", "haxe.io.BytesBuffer", "haxe.io.BytesData", "haxe.io.BytesInput", "haxe.io.BytesOutput", "haxe.io.Eof", "haxe.io.Error", "haxe.io.FPHelper", "haxe.io.Input", "haxe.io.Output", "haxe.io.Path", "haxe.io.StringInput", "haxe.xml.Parser", "haxe.Json", "haxe.CallStack", "haxe.Resource", "haxe.Utf8", "haxe.Int64", "haxe.Int32", "haxe.Serializer", "haxe.Unserializer", "haxe.ds.ArraySort", "haxe.ds.GenericStack", "haxe.ds.ObjectMap", "haxe.ds.Vector", "haxe.ds.BalancedTree", "haxe.ds.HashMap", "haxe.ds.Option", "haxe.ds.WeakMap", "haxe.ds.EnumValueMap", "haxe.ds.IntMap", "haxe.ds.StringMap", "StdTypes", "Array", "Class", "Date", "EReg", "Enum", "EnumValue", // "IntIterator", "List", "Map", "String", ]; static function parseClassInfo(externs:Map, filename:String) { if (sys.FileSystem.exists(filename)) { var file = sys.io.File.read(filename); try { while(true) { var line = file.readLine(); var parts = line.split(" "); if (parts[0]=="class" || parts[0]=="interface" || parts[0]=="enum") externs.set(parts[1],true); } } catch( e : Dynamic ) { } if (file!=null) file.close(); } } static function onGenerateCppia(types:Array):Void { var externs = new Map(); externs.set("Sys",true); externs.set("haxe.IMap",true); externs.set("haxe.crypto.HashMethod",true); externs.set("haxe._Int64.Int64_Impl_",true); externs.set("haxe._Int64.___Int64",true); externs.set("haxe._Int32.Int32_Impl_",true); externs.set("haxe._Int32.___Int32",true); // Hidded in implementation classes //externs.set("sys.db.RecordType",true); externs.set("sys.db._Sqlite.SqliteConnection",true); externs.set("sys.db._Sqlite.SqliteResultSet",true); externs.set("sys.db._Mysql.MysqlConnection",true); externs.set("sys.db._Mysql.MysqlResultSet",true); externs.set("sys.net._Socket.SocketInput",true); externs.set("sys.net._Socket.SocketOutput",true); externs.set("sys.ssl._Socket.SocketInput",true); externs.set("sys.ssl._Socket.SocketOutput",true); externs.set("haxe.ds.TreeNode",true); externs.set("haxe.xml.XmlParserException",true); for(e in classes) externs.set(e,true); var define = Context.defined("dll_import") ? Context.definedValue("dll_import") : "1"; if (define!="1") parseClassInfo(externs,define); else { var tried = new Map(); for(path in Context.getClassPath()) if (!tried.exists(path)) { tried.set(path,true); parseClassInfo(externs,path + "/export_classes.info"); } } for(type in types) { switch(type) { case TInst(classRef, params): if (externs.exists(classRef.toString())) classRef.get().exclude(); case TEnum(enumRef, params): if (externs.exists(enumRef.toString())) enumRef.get().exclude(); default: } } } // Exclude the standard classes, and any described in 'export_classes.info' files found in the classpath public static function exclude() { if (Context.defined("cppia")) Context.onGenerate(onGenerateCppia); else Context.error("cpp.cppia.excludeHostFiles is only for cppia code", Context.currentPos()); return Context.getBuildFields(); } // Ensure that the standard classes are included in the host public static function include() { Compiler.keep("haxe.IMap"); Compiler.keep("haxe.crypto.HashMethod"); Compiler.keep("haxe._Int64.Int64_Impl_"); Compiler.keep("haxe._Int32.Int32_Impl_"); Compiler.keep("haxe._Int64.___Int64"); Compiler.keep("haxe._Int32.___Int32"); for(cls in classes) { Context.getModule(cls); Compiler.keep(cls); } return Context.getBuildFields(); } } #end haxe_3.4.4.orig/std/cpp/cppia/Module.hx0000664000175000017500000000271313166552354017655 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.cppia; @:native("hx::CppiaLoadedModule") @:build(cpp.cppia.HostClasses.include()) extern class Module { @:native("__scriptable_cppia_from_string") public static function fromString(sourceCode:String) : Module; public function boot():Void; public function run():Void; public function resolveClass(inName:String):Class; } haxe_3.4.4.orig/std/cpp/link/StaticMysql.hx0000664000175000017500000000277613166552354020557 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.link; #if (hxcpp_api_level>=330) class StaticMysql { } #else @:cppFileCode( 'extern "C" int mysql_register_prims();') @:buildXml(" ") @:keep class StaticMysql { static function __init__() { untyped __cpp__("mysql_register_prims();"); } } #end haxe_3.4.4.orig/std/cpp/link/StaticRegexp.hx0000664000175000017500000000273213166552354020674 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.link; #if (hxcpp_api_level>=330) class StaticRegexp { } #else @:cppFileCode( 'extern "C" int regexp_register_prims();') @:buildXml(" ") @:keep class StaticRegexp { static function __init__() { untyped __cpp__("regexp_register_prims();"); } } #end haxe_3.4.4.orig/std/cpp/link/StaticSqlite.hx0000664000175000017500000000277713166552354020714 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.link; #if (hxcpp_api_level>=330) class StaticSqlite { } #else @:cppFileCode( 'extern "C" int sqlite_register_prims();') @:buildXml(" ") @:keep class StaticSqlite { static function __init__() { untyped __cpp__("sqlite_register_prims();"); } } #end haxe_3.4.4.orig/std/cpp/link/StaticStd.hx0000664000175000017500000000276413166552354020201 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.link; #if (hxcpp_api_level>=330) class StaticStd { } #else @:cppFileCode( 'extern "C" int std_register_prims();') @:buildXml(" ") @:keep class StaticStd { static function __init__() { untyped __cpp__("std_register_prims();"); } } #end haxe_3.4.4.orig/std/cpp/link/StaticZlib.hx0000664000175000017500000000272113166552354020340 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.link; #if (hxcpp_api_level>=330) class StaticZlib { } #else @:cppFileCode( 'extern "C" int zlib_register_prims();') @:buildXml(" ") @:keep class StaticZlib { static function __init__() { untyped __cpp__("zlib_register_prims();"); } } #end haxe_3.4.4.orig/std/cpp/net/Poll.hx0000664000175000017500000000355613166552354017036 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.net; import sys.net.Socket; import cpp.NativeSocket; class Poll { var mPollHandle : Dynamic; public var readIndexes : Array; public var writeIndexes : Array; public function new( n : Int ) { mPollHandle = NativeSocket.socket_poll_alloc(n); readIndexes = []; writeIndexes = []; } public function prepare( read : Array, write : Array ) { var k = NativeSocket.socket_poll_prepare(mPollHandle,read,write); readIndexes = k[0]; writeIndexes = k[1]; } public function events( ?t : Float ) { if (t==null) t=-1.0; NativeSocket.socket_poll_events(mPollHandle,t); } public function poll( a : Array, ?t : Float ) : Array { if (t==null) t=-1.0; return NativeSocket.socket_poll(a,mPollHandle,t); } } haxe_3.4.4.orig/std/cpp/net/ThreadServer.hx0000664000175000017500000003151513166552354020522 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.net; import cpp.vm.Thread; import cpp.net.Poll; import cpp.vm.Lock; private typedef ThreadInfos = { var id : Int; var t : Thread; var p : Poll; var socks : Array; } private typedef ClientInfos = { var client : Client; var sock : sys.net.Socket; var thread : ThreadInfos; var buf : haxe.io.Bytes; var bufpos : Int; } /** The ThreadServer can be used to easily create a multithreaded server where each thread polls multiple connections. To use it, at a minimum you must override or rebind clientConnected, readClientMessage, and clientMessage and you must define your Client and Message. **/ class ThreadServer { var threads : Array; var sock : sys.net.Socket; var worker : Thread; var timer : Thread; /** Number of total connections the server will accept. **/ public var listen : Int; /** Number of server threads. **/ public var nthreads : Int; /** Polling timeout. **/ public var connectLag : Float; /** Stream to send error messages. **/ public var errorOutput : haxe.io.Output; /** Space allocated to buffers when they are created. **/ public var initialBufferSize : Int; /** Maximum size of buffered data read from a socket. An exception is thrown if the buffer exceeds this value. **/ public var maxBufferSize : Int; /** Minimum message size. **/ public var messageHeaderSize : Int; /** Time between calls to update. **/ public var updateTime : Float; /** The most sockets a thread will handle. **/ public var maxSockPerThread : Int; /** Creates a ThreadServer. **/ public function new() { threads = new Array(); nthreads = if( Sys.systemName() == "Windows" ) 150 else 10; messageHeaderSize = 1; listen = 10; connectLag = 0.5; errorOutput = Sys.stderr(); initialBufferSize = (1 << 10); maxBufferSize = (1 << 16); maxSockPerThread = 64; updateTime = 1; } function runThread(t) { while( true ) { try { loopThread(t); } catch( e : Dynamic ) { logError(e); } } } function readClientData( c : ClientInfos ) { var available = c.buf.length - c.bufpos; if( available == 0 ) { var newsize = c.buf.length * 2; if( newsize > maxBufferSize ) { newsize = maxBufferSize; if( c.buf.length == maxBufferSize ) throw "Max buffer size reached"; } var newbuf = haxe.io.Bytes.alloc(newsize); newbuf.blit(0,c.buf,0,c.bufpos); c.buf = newbuf; available = newsize - c.bufpos; } var bytes = c.sock.input.readBytes(c.buf,c.bufpos,available); var pos = 0; var len = c.bufpos + bytes; while( len >= messageHeaderSize ) { var m = readClientMessage(c.client,c.buf,pos,len); if( m == null ) break; pos += m.bytes; len -= m.bytes; work(clientMessage.bind(c.client,m.msg)); } if( pos > 0 ) c.buf.blit(0,c.buf,pos,len); c.bufpos = len; } function loopThread( t : ThreadInfos ) { if( t.socks.length > 0 ) for( s in t.p.poll(t.socks,connectLag) ) { var infos : ClientInfos = s.custom; try { readClientData(infos); } catch( e : Dynamic ) { t.socks.remove(s); if( !Std.is(e,haxe.io.Eof) && !Std.is(e,haxe.io.Error) ) logError(e); work(doClientDisconnected.bind(s,infos.client)); } } while( true ) { var m : { s : sys.net.Socket, cnx : Bool } = Thread.readMessage(t.socks.length == 0); if( m == null ) break; if( m.cnx ) t.socks.push(m.s); else if( t.socks.remove(m.s) ) { var infos : ClientInfos = m.s.custom; work(doClientDisconnected.bind(m.s,infos.client)); } } } function doClientDisconnected(s,c) { try s.close() catch( e : Dynamic ) {}; clientDisconnected(c); } function runWorker() { while( true ) { var f = Thread.readMessage(true); try { f(); } catch( e : Dynamic ) { logError(e); } try { afterEvent(); } catch( e : Dynamic ) { logError(e); } } } /** Internally used to delegate something to the worker thread. **/ public function work( f : Void -> Void ) { worker.sendMessage(f); } function logError( e : Dynamic ) { var stack = haxe.CallStack.exceptionStack(); if( Thread.current() == worker ) onError(e,stack); else work(onError.bind(e,stack)); } function addClient( sock : sys.net.Socket ) { var start = Std.random(nthreads); for( i in 0...nthreads ) { var t = threads[(start + i)%nthreads]; if( t.socks.length < maxSockPerThread ) { var infos : ClientInfos = { thread : t, client : clientConnected(sock), sock : sock, buf : haxe.io.Bytes.alloc(initialBufferSize), bufpos : 0, }; sock.custom = infos; infos.thread.t.sendMessage({ s : sock, cnx : true }); return; } } refuseClient(sock); } function refuseClient( sock : sys.net.Socket) { // we have reached maximum number of active clients sock.close(); } function runTimer() { var l = new Lock(); while( true ) { l.wait(updateTime); work(update); } } function init() { worker = Thread.create(runWorker); timer = Thread.create(runTimer); for( i in 0...nthreads ) { var t = { id : i, t : null, socks : new Array(), p : new Poll(maxSockPerThread), }; threads.push(t); t.t = Thread.create(runThread.bind(t)); } } /** Called when the server gets a new connection. **/ public function addSocket( s : sys.net.Socket ) { s.setBlocking(false); work(addClient.bind(s)); } /** Start the server at the specified host and port. **/ public function run( host, port ) { sock = new sys.net.Socket(); sock.bind(new sys.net.Host(host),port); sock.listen(listen); init(); while( true ) { try { addSocket(sock.accept()); } catch( e : Dynamic ) { logError(e); } } } /** Send data to a client. **/ public function sendData( s : sys.net.Socket, data : String ) { try { s.write(data); } catch( e : Dynamic ) { stopClient(s); } } /** Shutdown a client's connection and remove them from the server. **/ public function stopClient( s : sys.net.Socket ) { var infos : ClientInfos = s.custom; try s.shutdown(true,true) catch( e : Dynamic ) { }; infos.thread.t.sendMessage({ s : s, cnx : false }); } // --- CUSTOMIZABLE API --- /** Called when an error has ocurred. **/ public dynamic function onError( e : Dynamic, stack ) { var estr = try Std.string(e) catch( e2 : Dynamic ) "???" + try "["+Std.string(e2)+"]" catch( e : Dynamic ) ""; errorOutput.writeString( estr + "\n" + haxe.CallStack.toString(stack) ); errorOutput.flush(); } /** Called when a client connects. Returns a client object. **/ public dynamic function clientConnected( s : sys.net.Socket ) : Client { return null; } /** Called when a client disconnects or an error forces the connection to close. **/ public dynamic function clientDisconnected( c : Client ) { } /** Called when data has been read from a socket. This method should try to extract a message from the buffer. The available data resides in buf, starts at pos, and is len bytes wide. Return the new message and the number of bytes read from the buffer. If no message could be read, return null. **/ public dynamic function readClientMessage( c : Client, buf : haxe.io.Bytes, pos : Int, len : Int ) : { msg : Message, bytes : Int } { return { msg : null, bytes : len, }; } /** Called when a message has been recieved. Message handling code should go here. **/ public dynamic function clientMessage( c : Client, msg : Message ) { } /** This method is called periodically. It can be used to do server maintenance. **/ public dynamic function update() { } /** Called after a client connects, disconnects, a message is received, or an update is performed. **/ public dynamic function afterEvent() { } } haxe_3.4.4.orig/std/cpp/objc/NSData.hx0000664000175000017500000000426213166552354017364 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.objc; @:native("NSData") @:objc extern class NSDataData { } @:objc extern abstract NSData( NSDataData ) { @:native("_hx_value_to_objc") @:extern static function to_data(b:haxe.io.BytesData) : NSData return null; @:native("_hx_value_to_objc") @:extern static function to_data_data(b:haxe.io.BytesData) : NSDataData return null; @:native("_hx_objc_to_bytes") @:extern static function NSDataDataToBytes(d:NSDataData) : haxe.io.BytesData return null; inline function new(d:NSDataData) this = d; @:from @:extern static public inline function fromBytesData(d:haxe.io.BytesData):NSData return new NSData( to_data_data(d) ); @:from @:extern static public inline function fromBytes(d:haxe.io.Bytes):NSData return new NSData( to_data_data(d.getData()) ); @:to @:extern public inline function toBytesData():haxe.io.BytesData return NSDataDataToBytes(this); @:to @:extern public inline function toBytes():haxe.io.Bytes return haxe.io.Bytes.ofData(NSDataDataToBytes(this)); @:to @:extern public inline function toNSObject():NSObject return cast this; } haxe_3.4.4.orig/std/cpp/objc/NSDictionary.hx0000664000175000017500000000361213166552354020616 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.objc; @:native("NSDictionary") @:objc extern class DictionaryData { } @:objc extern abstract NSDictionary( DictionaryData ) { @:native("_hx_obj_to_nsdictionary") @:extern static function _hx_obj_to_nsdictionary(obj:Dynamic) : DictionaryData return null; @:native("_hx_nsdictionary_to_obj") @:extern static function _hx_nsdictionary_to_obj(d:DictionaryData) : Dynamic return null; inline function new(dict:DictionaryData) this = dict; @:from @:extern static public inline function fromDynamic(o:Dynamic):NSDictionary return new NSDictionary( _hx_obj_to_nsdictionary(o) ); @:to @:extern public inline function toDynamic():Dynamic return _hx_nsdictionary_to_obj(this); @:to @:extern public inline function toNSObject():NSObject return cast this; } haxe_3.4.4.orig/std/cpp/objc/NSError.hx0000664000175000017500000000234713166552354017606 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.objc; @:objc @:native("NSError") extern class NSError { public var localizedDescription(default,null):NSString; } haxe_3.4.4.orig/std/cpp/objc/NSLog.hx0000664000175000017500000000254313166552354017234 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.objc; extern class NSLog { @:native("NSLog") @:overload(function(format:NSString,a0:NSObject):Void { }) @:overload(function(format:NSString,a0:NSObject,a1:NSObject):Void { }) public static function log(format:NSString):Void; } haxe_3.4.4.orig/std/cpp/objc/NSObject.hx0000664000175000017500000000331613166552354017720 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.objc; @:native("id") @:objc extern class NSObjectData { } @:objc extern abstract NSObject( NSObjectData ) { @:native("_hx_value_to_objc") @:extern static function _hx_value_to_objc(obj:Dynamic) : NSObject return null; @:native("_hx_objc_to_dynamic") @:extern static function _hx_objc_to_dynamic(d:NSObjectData) : Dynamic return null; inline function new(d:NSObjectData) this = d; @:from @:extern static public inline function fromHaxe(d:Dynamic):NSObject return _hx_value_to_objc(d); @:to @:extern public inline function toHaxe():Dynamic return _hx_objc_to_dynamic(this); } haxe_3.4.4.orig/std/cpp/objc/NSString.hx0000664000175000017500000000353613166552354017764 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.objc; @:native("NSString") @:objc extern class NSStringData { } @:objc extern abstract NSString( NSStringData ) { inline function new(s:NSStringData) this = s; @:native("(id)") @:extern static function toObject(d:NSStringData) : NSObject return null; @:native("(NSString *)") @:extern static function castFromString(s:String) : NSString return null; @:native("String") @:extern static function castToString(s:NSStringData) : String return null; @:from @:extern static public inline function fromString(s:String):NSString return castFromString(s); @:to @:extern public inline function toString():String return castToString(this); @:to @:extern public inline function toNSObject():NSObject return toObject(this); } haxe_3.4.4.orig/std/cpp/objc/ObjcBlock.hx0000664000175000017500000000223213166552354020075 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.objc; @:objc typedef ObjcBlock = T; haxe_3.4.4.orig/std/cpp/objc/Protocol.hx0000664000175000017500000000225113166552354020047 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.objc; @:objc typedef Protocol = T; haxe_3.4.4.orig/std/cpp/rtti/FieldIntegerLookup.hx0000664000175000017500000000250013166552354022043 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.rtti; /** If you implement this interface, then the backend will generate code that allows fast dynamic access to fields by integer id. This should speed up the CFFI. **/ interface FieldIntegerLookup { } haxe_3.4.4.orig/std/cpp/rtti/FieldNumericIntegerLookup.hx0000664000175000017500000000250713166552354023375 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.rtti; /** If you implement this interface, then the backend will generate code that allows fast numeric access to fields by integer id. This should speed up the CFFI. **/ interface FieldNumericIntegerLookup { } haxe_3.4.4.orig/std/cpp/vm/Debugger.hx0000664000175000017500000004016513166552354017505 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.vm; /** * Parameter describes a function parameter. Instances of this class are * embedded in stack frame objects to describe the function parameters that * were used in the invocation of the function that defines that stack frame. **/ class Parameter { public var name(default, null) : String; public var value(default, null) : Dynamic; public function new(name : String, value : Dynamic) { this.name = name; this.value = value; } } /** * StackFrame describes one call stack frame. **/ class StackFrame { public var fileName(default, null) : String; public var lineNumber(default, null) : Int; public var className(default, null) : String; public var functionName(default, null) : String; public var parameters(default, null) : Array; public function new(fileName : String, lineNumber : Int, className : String, functionName : String) { this.fileName = fileName; this.lineNumber = lineNumber; this.className = className; this.functionName = functionName; this.parameters = new Array(); } } /** * ThreadInfo describes the state of a single thread. **/ class ThreadInfo { public static inline var STATUS_RUNNING = 1; public static inline var STATUS_STOPPED_BREAK_IMMEDIATE = 2; public static inline var STATUS_STOPPED_BREAKPOINT = 3; public static inline var STATUS_STOPPED_UNCAUGHT_EXCEPTION = 4; public static inline var STATUS_STOPPED_CRITICAL_ERROR = 5; // 0 is never a valid thread number public var number(default, null) : Int; public var status(default, null) : Int; // If status is "stopped breakpoint", this is the breakpoint number public var breakpoint(default, null) : Int; // If status is "critical error", this describes the error public var criticalErrorDescription(default, null) : String; // Stack will be listed with the lowest frame first public var stack(default, null) : Array; public function new(number : Int, status : Int, breakpoint : Int = -1, criticalErrorDescription : String = null) { this.number = number; this.status = status; this.breakpoint = breakpoint; this.criticalErrorDescription = criticalErrorDescription; this.stack = new Array(); } } /** * This class wraps the hxcpp C++ implementation to provide a Haxe interface * to the low level debugging features **/ class Debugger { public static inline var THREAD_CREATED = 1; public static inline var THREAD_TERMINATED = 2; public static inline var THREAD_STARTED = 3; public static inline var THREAD_STOPPED = 4; public static inline var STEP_INTO = 1; public static inline var STEP_OVER = 2; public static inline var STEP_OUT = 3; // This tagging value is returned by getStackVariableValue() and // setStackVariableValue if the requested value does not exist at the // requested stack frame public static var NONEXISTENT_VALUE = new String("NONEXISTENT_VALUE"); // This tagging value is returned by getStackVariableValue and // setStackVariableValue if the stack variable that is being set is on a // thread that is running, in which case the set does not take place. public static var THREAD_NOT_STOPPED = new String("THREAD_NOT_STOPPED"); /** * Sets the handler callback to be made when asynchronous events occur, * specifically, when threads are created, terminated, started, or * stopped. The calling thread becomes the "debugger" thread, which means * that it will be discluded from any breakpoints and will not be reported * on by any thread reporting requests. * * Be aware that this callback is made asynchronously and possibly by * multiple threads simultaneously. * * Setting this to null prevents further callbacks. * * Throws a string exception if the program does not support debugging * because it was not compiled with the HXCPP_DEBUGGER flag set. * * @param handler is a function that will be called back by asynchronous * thread events. Note that this function is called directly from * the thread experiencing the event and the handler should return * quickly to avoid blocking the calling thread unnecessarily. * The parameters to handler are: * - threadNumber, the thread number of the event * - event, one of THREAD_CREATED, THREAD_TERMINATED, * THREAD_STARTED, or THREAD_STOPPED * - stackFrame, the stack frame number at which the thread is stopped, * undefined if event is not THREAD_STOPPED * - className, the class name at which the thread is stopped, * undefined if event is not THREAD_STOPPED * - functionName, the function name at which the thread is * stopped, undefined if event is not THREAD_STOPPED * - fileName, the file name at which the thread is stopped, * undefined if event is not THREAD_STOPPED * - lineNumber, the line number at which the thread is stopped, * undefined if event is not THREAD_STOPPED **/ public static function setEventNotificationHandler( handler : Int -> Int -> Int -> String -> String -> String -> Int -> Void) { untyped __global__.__hxcpp_dbg_setEventNotificationHandler(handler); } /** * This can be called to turn off (and then back on) all stopping of * debugged threads temporarily. It should only be used by classes that * actually implement the debugger to hide themselves from the debugger as * necessary. **/ public static function enableCurrentThreadDebugging(enabled : Bool) { untyped __global__.__hxcpp_dbg_enableCurrentThreadDebugging(enabled); } /** * Returns the thread number of the calling thread. * * @return the thread number of the calling thread. **/ public static function getCurrentThreadNumber() : Int { return untyped __global__.__hxcpp_dbg_getCurrentThreadNumber(); } /** * Returns the set of source files known to the debugger. This is a copy * of the original array and could be quite large. The caller should * cache this value to avoid multiple copies needing to be made. * * @return the set of source files known to the debugger. **/ public static function getFiles() : Array { return untyped __global__.__hxcpp_dbg_getFiles(); } /** * Returns the full paths of the set of source files known to the debugger. * This is a copy of the original array and could be quite large. * It is possible that this set will be empty, in which case the full paths are not known. * The index of these files matches the index from "getFiles", so the full path for * a given short path can be calculated. * * @return the known full paths of the set of source files **/ public static function getFilesFullPath() : Array { return untyped __global__.__hxcpp_dbg_getFilesFullPath(); } /** * Returns the set of class names of all classes known to the debugger. * This is a copy of the original array and could be quite large. The * caller should cache this value to avoid multiple copies needing to be * made. * * @return the set of class names of all classes known to the debugger. **/ public static function getClasses() : Array { return untyped __global__.__hxcpp_dbg_getClasses(); } /** * Returns a ThreadInfo object describing every thread that existed at the * moment that the call was made, except for the debugger thread. **/ public static function getThreadInfos() : Array { return untyped __global__.__hxcpp_dbg_getThreadInfos(); } /** * Returns a ThreadInfo object describing a single thread, or null if * there is no such thread or the thread queried about was the debugger * thread and unsafe was not true. **/ public static function getThreadInfo(threadNumber : Int, unsafe : Bool) : ThreadInfo { return untyped __global__.__hxcpp_dbg_getThreadInfo (threadNumber, unsafe); } /** * Adds a new file:line breakpoint. The breakpoint number of the newly * added breakpoint is returned. **/ public static function addFileLineBreakpoint(file : String, line : Int) : Int { return untyped __global__.__hxcpp_dbg_addFileLineBreakpoint (file, line); } /** * Adds a new class:function breakpoint. The breakpoint number of the * newly added breakpoint is returned. **/ public static function addClassFunctionBreakpoint(className : String, functionName : String) : Int { return untyped __global__.__hxcpp_dbg_addClassFunctionBreakpoint (className, functionName); } /** * Deletes a breakpoint, or all breakpoints. **/ public static function deleteBreakpoint(number : Null) { if (number == null) { untyped __global__.__hxcpp_dbg_deleteAllBreakpoints(); } else { untyped __global__.__hxcpp_dbg_deleteBreakpoint (cast (number, Int)); } } /** * Breaks all threads except the debugger thread (which should be the same * as the calling thread!). * * If `wait` is true, waits up to 2 seconds for all threads to be broken. * Threads which are in blocking system calls and cannot break after 2 * seconds remain running when this function returns. **/ public static function breakNow(wait : Bool = true) { untyped __global__.__hxcpp_dbg_breakNow(wait); } /** * Continue execution of all stopped threads. If specialThreadNumber * is a valid thread number, then it will be continued past * `continueCount` breakpoints instead of just 1 like all of the other * threads. **/ public static function continueThreads(specialThreadNumber : Int, continueCount : Int) { untyped __global__.__hxcpp_dbg_continueThreads (specialThreadNumber, continueCount); } /** * Single steps the given thread. **/ public static function stepThread(threadNumber : Int, stepType : Int, stepCount : Int = 1) { untyped __global__.__hxcpp_dbg_stepThread (threadNumber, stepType, stepCount); } /** * Returns the list of local variables (including "this", function * arguments, and local variables) visible to the given thread at the * given stack frame. * * Returns a list with a single entry, THREAD_NOT_STOPPED, if the * thread is not stopped and thus variables cannot be fetched and * unsafe is not true. * * @return the list of local variables (including "this", function * arguments, and local variables) visible to the given thread at * the given stack frame. **/ public static function getStackVariables(threadNumber : Int, stackFrameNumber : Int, unsafe : Bool) : Array { return untyped __global__.__hxcpp_dbg_getStackVariables (threadNumber, stackFrameNumber, unsafe, THREAD_NOT_STOPPED); } /** * Returns the value of a stack variable, or NONEXISTENT_VALUE if the * requested value does not exist. If the thread is actively running * and unsafe is not true, returns THREAD_NOT_STOPPED. **/ public static function getStackVariableValue(threadNumber : Int, stackFrameNumber : Int, name : String, unsafe : Bool) : Dynamic { return untyped __global__.__hxcpp_dbg_getStackVariableValue (threadNumber, stackFrameNumber, name, unsafe, NONEXISTENT_VALUE, THREAD_NOT_STOPPED); } /** * Sets the value of a stack variable and returns that value. If the * variable does not exist, on the stack, this function returns * NONEXISTENT_VALUE. If the thread is actively running and unsafe is not * true, returns THREAD_NOT_STOPPED, and the value is not set. **/ public static function setStackVariableValue(threadNumber : Int, stackFrameNumber : Int, name : String, value : Dynamic, unsafe : Bool) : Dynamic { return untyped __global__.__hxcpp_dbg_setStackVariableValue (threadNumber, stackFrameNumber, name, value, unsafe, NONEXISTENT_VALUE, THREAD_NOT_STOPPED); } // The hxcpp runtime calls back through these functions to create Haxe // objects as needed, which allows the C++ implementation code to create // Haxe objects without having to actually know the structure of those // objects private static function __init__() { untyped __global__.__hxcpp_dbg_setNewParameterFunction ( function (name : String, value : Dynamic) : Dynamic { return new Parameter(name, value); } ); untyped __global__.__hxcpp_dbg_setNewStackFrameFunction ( function (fileName : String, lineNumber : Int, className : String, functionName : String) { return new StackFrame(fileName, lineNumber, className, functionName); } ); untyped __global__.__hxcpp_dbg_setNewThreadInfoFunction ( function (number : Int, status : Int, breakpoint : Int, criticalErrorDescription : String) : Dynamic { return new ThreadInfo(number, status, breakpoint, criticalErrorDescription); } ); untyped __global__.__hxcpp_dbg_setAddParameterToStackFrameFunction ( function(inStackFrame : Dynamic, inParameter : Dynamic) { var stackFrame : StackFrame = cast inStackFrame; var parameter : Parameter = cast inParameter; stackFrame.parameters.push(parameter); } ); untyped __global__.__hxcpp_dbg_setAddStackFrameToThreadInfoFunction ( function(inThreadInfo : Dynamic, inStackFrame : Dynamic) { var threadInfo : ThreadInfo = cast inThreadInfo; var stackFrame : StackFrame = cast inStackFrame; threadInfo.stack.push(stackFrame); } ); } } haxe_3.4.4.orig/std/cpp/vm/Deque.hx0000664000175000017500000000276713166552354017032 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.vm; class Deque { var q : Dynamic; public function new() { q = untyped __global__.__hxcpp_deque_create(); } public function add( i : T ) { untyped __global__.__hxcpp_deque_add(q,i); } public function push( i : T ) { untyped __global__.__hxcpp_deque_push(q,i); } public function pop( block : Bool ) : Null { return untyped __global__.__hxcpp_deque_pop(q,block); } } haxe_3.4.4.orig/std/cpp/vm/ExecutionTrace.hx0000664000175000017500000000264213166552354020701 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.vm; class ExecutionTrace { public static function traceOff() { untyped __hxcpp_execution_trace(0); } public static function traceFunctions() { untyped __hxcpp_execution_trace(1); } public static function traceLines() { untyped __hxcpp_execution_trace(2); } } haxe_3.4.4.orig/std/cpp/vm/Gc.hx0000664000175000017500000000753713166552354016320 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.vm; class Gc { public static inline var MEM_INFO_USAGE = 0; public static inline var MEM_INFO_RESERVED = 1; public static inline var MEM_INFO_CURRENT = 2; public static inline var MEM_INFO_LARGE = 3; // Introduced hxcpp_api_level 310 // Returns stats on memory usage: // MEM_INFO_USAGE - estimate of how much is needed by program (at last collect) // MEM_INFO_RESERVED - memory allocated for possible use // MEM_INFO_CURRENT - memory in use, includes uncollected garbage. // This will generally saw-tooth between USAGE and RESERVED // MEM_INFO_LARGE - Size of separate pool used for large allocs. Included in all the above. static public function memInfo(inWhatInfo:Int) : Int { return Std.int(NativeGc.memInfo(inWhatInfo)); } // Returns Float static public function memInfo64(inWhatInfo:Int) : Float { return NativeGc.memInfo(inWhatInfo); } static public function memUsage() : Int { return Std.int(NativeGc.memInfo(MEM_INFO_USAGE)); } static public function versionCheck() { return true; } static public function trace(sought:Class,printInstances:Bool=true) : Int { return cpp.NativeGc.nativeTrace(sought,printInstances); } #if !cppia inline #end static public function enable(inEnable:Bool) : Void cpp.NativeGc.enable(inEnable); #if !cppia inline #end static public function run(major:Bool) : Void cpp.NativeGc.run(major); #if !cppia inline #end static public function compact() : Void cpp.NativeGc.compact(); #if !cppia inline #end static public function doNotKill(inObject:Dynamic) : Void cpp.NativeGc.doNotKill(inObject); #if !cppia inline #end static public function getNextZombie() : Dynamic return cpp.NativeGc.getNextZombie(); #if !cppia inline #end static public function safePoint() : Void cpp.NativeGc.safePoint(); #if !cppia inline #end static public function enterGCFreeZone() : Void cpp.NativeGc.enterGCFreeZone(); #if !cppia inline #end static public function exitGCFreeZone() : Void cpp.NativeGc.exitGCFreeZone(); #if !cppia inline #end static public function setMinimumFreeSpace(inBytes:Int) : Void cpp.NativeGc.setMinimumFreeSpace(inBytes); #if !cppia inline #end static public function setTargetFreeSpacePercentage(inPercentage:Int) : Void cpp.NativeGc.setTargetFreeSpacePercentage(inPercentage); #if !cppia inline #end static public function setMinimumWorkingMemory(inBytes:Int) : Void cpp.NativeGc.setMinimumWorkingMemory(inBytes); #if !cppia @:native("__hxcpp_set_finalizer") @:extern static public function setFinalizer(inObject:T, inFinalizer:cpp.CallableVoid> ) : Void { } #end } haxe_3.4.4.orig/std/cpp/vm/Lock.hx0000664000175000017500000000264613166552354016653 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.vm; class Lock { var l : Dynamic; public function new() { l = untyped __global__.__hxcpp_lock_create(); } public function wait( ?timeout : Float = -1) : Bool { return untyped __global__.__hxcpp_lock_wait(l,timeout); } public function release() { untyped __global__.__hxcpp_lock_release(l); } } haxe_3.4.4.orig/std/cpp/vm/Mutex.hx0000664000175000017500000000274013166552354017060 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.vm; class Mutex { var m : Dynamic; public function new() { m = untyped __global__.__hxcpp_mutex_create(); } public function acquire() { untyped __global__.__hxcpp_mutex_acquire(m); } public function tryAcquire() : Bool { return untyped __global__.__hxcpp_mutex_try(m); } public function release() { untyped __global__.__hxcpp_mutex_release(m); } } haxe_3.4.4.orig/std/cpp/vm/Profiler.hx0000664000175000017500000000256313166552354017543 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.vm; class Profiler { static public function start(?inDumpFile:String) : Void { untyped __global__.__hxcpp_start_profiler(inDumpFile); } static public function stop() : Void { untyped __global__.__hxcpp_stop_profiler(); } } haxe_3.4.4.orig/std/cpp/vm/Thread.hx0000664000175000017500000000432213166552354017163 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.vm; typedef ThreadHandle = Dynamic; class Thread { public var handle(default,null) : ThreadHandle; function new(h) { handle = h; } /** Send a message to the thread queue. This message can be read by using `readMessage`. **/ public function sendMessage( msg : Dynamic ) { untyped __global__.__hxcpp_thread_send(handle,msg); } /** Returns the current thread. **/ public static function current() { return new Thread(untyped __global__.__hxcpp_thread_current()); } /** Creates a new thread that will execute the `callb` function, then exit. **/ public static function create( callb : Void -> Void ) { return new Thread(untyped __global__.__hxcpp_thread_create(callb)); } /** Reads a message from the thread queue. If `block` is true, the function blocks until a message is available. If `block` is false, the function returns `null` if no message is available. **/ public static function readMessage( block : Bool ) : Dynamic { return untyped __global__.__hxcpp_thread_read_message(block); } @:keep function __compare(t) : Int { return handle == t.handle ? 0 : 1; } } haxe_3.4.4.orig/std/cpp/vm/Tls.hx0000664000175000017500000000270013166552354016514 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.vm; class Tls { static var sFreeSlot = 0; var mTLSID : Int; public var value(get,set) : T; public function new() { mTLSID = sFreeSlot++; } function get_value() : T { return untyped __global__.__hxcpp_tls_get(mTLSID); } function set_value( v : T ) { untyped __global__.__hxcpp_tls_set(mTLSID,v); return v; } } haxe_3.4.4.orig/std/cpp/vm/Unsafe.hx0000664000175000017500000000244713166552354017203 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.vm; class Unsafe { public static inline function unsafeSet(outForced:Dynamic,inValue:Dynamic) : Void { untyped __global__.__hxcpp_unsafe_set(outForced,inValue); } } haxe_3.4.4.orig/std/cpp/vm/WeakRef.hx0000664000175000017500000000334313166552354017302 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.vm; class WeakRef { var ref:Dynamic; var hardRef:Bool; public function new(inObject:T, inHard:Bool = false) { hardRef = inHard; if (hardRef) ref = inObject; else ref = untyped __global__.__hxcpp_weak_ref_create(inObject); } public function get():T { if (hardRef) return ref; return untyped __global__.__hxcpp_weak_ref_get(ref); } public function set(inObject:T):T { if (hardRef) ref = inObject; else ref = untyped __global__.__hxcpp_weak_ref_create(inObject); return inObject; } public function toString():String { return "WeakRef(" + get() + ")"; } } haxe_3.4.4.orig/std/cpp/zip/Compress.hx0000664000175000017500000000226613166552354017734 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.zip; #if (haxe_ver < 4.0) typedef Compress = haxe.zip.Compress; #endhaxe_3.4.4.orig/std/cpp/zip/Flush.hx0000664000175000017500000000226413166552354017220 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.zip; #if (haxe_ver < 4.0) typedef Flush = haxe.zip.FlushMode; #endhaxe_3.4.4.orig/std/cpp/zip/Uncompress.hx0000664000175000017500000000227213166552354020274 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cpp.zip; #if (haxe_ver < 4.0) typedef Uncompress = haxe.zip.Uncompress; #endhaxe_3.4.4.orig/std/cs/Boot.hx0000664000175000017500000000320113166552354016053 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs; import cs.internal.Exceptions; import cs.internal.FieldLookup; import cs.internal.Function; import cs.internal.HxObject; import cs.internal.Runtime; // TODO (see Gencommon.IteratorsInterfaceModf) //import cs.internal.Iterator; #if !erase_generics import cs.internal.Null; #end import cs.internal.StringExt; #if unsafe import cs.internal.BoxedPointer; #end import cs.StdTypes; import haxe.ds.StringMap; import Reflect; @:dox(hide) class Boot { @:keep public static function init():Void { cs.Lib.applyCultureChanges(); } } haxe_3.4.4.orig/std/cs/Flags.hx0000664000175000017500000000766613166552354016227 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs; /** Use this type to have access to the bitwise operators of C# enums that have a `cs.system.FlagsAttribute` attribute. Usage example: ```haxe import cs.system.reflection.BindingFlags; var binding = new Flags(BindingFlags.Public) | BindingFlags.Static | BindingFlags.NonPublic; ``` **/ abstract Flags(T) from T to T { /** Creates a new `Flags` type with an optional initial value. If no initial value was specified, the default enum value for an empty flags attribute is specified **/ @:extern inline public function new(?initial:T) this = initial; /** Accessible through the bitwise OR operator (`|`). Returns a new `Flags` type with the flags passed at `flags` added to it. **/ @:op(A|B) @:extern inline public function add(flags:Flags):Flags { return new Flags(underlying() | flags.underlying()); } /** Accessible through the bitwise AND operator (`&`). Returns a new `Flags` type with the flags that are set on both `this` and `flags` **/ @:op(A&B) @:extern inline public function bitAnd(flags:Flags):Flags { return new Flags(underlying() & flags.underlying()); } /** Accessible through the bitwise XOR operator (`^`). **/ @:op(A^B) @:extern inline public function bitXor(flags:Flags):Flags { return new Flags(underlying() & flags.underlying()); } /** Accesible through the bitwise negation operator (`~`). Returns a new `Flags` type with all unset flags as set - but the ones that are set already. **/ @:op(~A) @:extern inline public function bitNeg():Flags { return new Flags(~underlying()); } /** Returns a new `Flags` type with all flags set by `flags` unset **/ @:extern inline public function remove(flags:Flags):Flags { return new Flags(underlying() & ~flags.underlying()); } /** Returns whether `flag` is present on `this` type **/ @:extern inline public function has(flag:T):Bool { return underlying() & new Flags(flag).underlying() != null; } /** Returns whether `this` type has any flag set by `flags` also set **/ @:extern inline public function hasAny(flags:Flags):Bool { return underlying() & flags.underlying() != null; } /** Returns whether `this` type has all flags set by `flags` also set **/ @:extern inline public function hasAll(flags:Flags):Bool { return underlying() & flags.underlying() == flags.underlying(); } @:extern inline private function underlying():EnumUnderlying return this; } @:coreType private abstract EnumUnderlying from T to T { @:op(A|B) public static function or(lhs:EnumUnderlying, rhs:EnumUnderlying):T; @:op(A^B) public static function xor(lhs:EnumUnderlying, rhs:EnumUnderlying):T; @:op(A&B) public static function and(lhs:EnumUnderlying, rhs:EnumUnderlying):T; @:op(~A) public static function bneg(t:EnumUnderlying):T; } haxe_3.4.4.orig/std/cs/Lib.hx0000664000175000017500000002273313166552354015671 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs; import cs.system.Type; /** Platform-specific C# Library. Provides some platform-specific functions for the C# target, such as conversion from haxe types to native types and vice-versa. **/ class Lib { private static var decimalSeparator:String; /** Changes the current culture settings to allow a consistent cross-target behavior. Currently the only change made is in regard to the decimal separator, which is always set to "." **/ public static function applyCultureChanges():Void { var ci = new cs.system.globalization.CultureInfo(cs.system.threading.Thread.CurrentThread.CurrentCulture.Name, true); decimalSeparator = ci.NumberFormat.NumberDecimalSeparator; ci.NumberFormat.NumberDecimalSeparator = "."; cs.system.threading.Thread.CurrentThread.CurrentCulture = ci; } /** Reverts the culture changes to the default settings. **/ public static function revertDefaultCulture():Void { var ci = new cs.system.globalization.CultureInfo(cs.system.threading.Thread.CurrentThread.CurrentCulture.Name, true); cs.system.threading.Thread.CurrentThread.CurrentCulture = ci; } /** Returns a native array from the supplied Array. This native array is unsafe to be written on, as it may or may not be linked to the actual Array implementation. If equalLengthRequired is true, the result might be a copy of an array with the correct size. **/ @:extern inline public static function nativeArray(arr:Array, equalLengthRequired:Bool):NativeArray { var ret = new cs.NativeArray(arr.length); #if erase_generics for (i in 0...arr.length) ret[i] = arr[i]; #else p_nativeArray(arr,ret); #end return ret; } #if !erase_generics static function p_nativeArray(arr:Array, ret:cs.system.Array):Void { var native:NativeArray = untyped arr.__a; var len = arr.length; cs.system.Array.Copy(native, 0, ret, 0, len); } #end /** Provides support for the "as" keyword in C#. If the object is not of the supplied type "T", it will return null instead of rasing an exception. This function will not work with Value Types (such as Int, Float, Bool...) **/ @:pure @:extern public static inline function as(obj:Dynamic, cl:Class):T { return untyped __as__(obj); } /** Returns a Class<> equivalent to the native System.Type type. Currently Haxe's Class<> is equivalent to System.Type, but this is an implementation detail. This may change in the future, so use this function whenever you need to perform such conversion. **/ public static inline function fromNativeType(t:cs.system.Type):Class { return untyped t; } /** Returns a System.Type equivalent to the Haxe Class<> type. Currently Haxe's Class<> is equivalent to System.Type, but this is an implementation detail. This may change in the future, so use this function whenever you need to perform such conversion. **/ public static inline function toNativeType(cl:Class):Type { return untyped cl; } /** Returns a System.Type equivalent to the Haxe Enum<> type. **/ public static inline function toNativeEnum(cl:Enum):Type { return untyped cl; } /** Gets the native System.Type from the supplied object. Will throw an exception in case of null being passed. [deprecated] - use `getNativeType` instead **/ @:deprecated('The function `nativeType` is deprecated and will be removed in later versions. Please use `getNativeType` instead') public static inline function nativeType(obj:Dynamic):Type { return untyped obj.GetType(); } /** Gets the native System.Type from the supplied object. Will throw an exception in case of null being passed. **/ public static inline function getNativeType(obj:Dynamic):Type { return untyped obj.GetType(); } #if erase_generics inline private static function mkDynamic(native:NativeArray):NativeArray { var ret = new cs.NativeArray(native.Length); for (i in 0...native.Length) ret[i] = native[i]; return ret; } #end /** Returns a Haxe Array of a native Array. Unless `erase_generics` is defined, it won't copy the contents of the native array, so unless any operation triggers an array resize, all changes made to the Haxe array will affect the native array argument. **/ inline public static function array(native:cs.NativeArray):Array { #if erase_generics var dyn:NativeArray = mkDynamic(native); return @:privateAccess Array.ofNative(dyn); #else return @:privateAccess Array.ofNative(native); #end } /** Allocates a new Haxe Array with a predetermined size **/ inline public static function arrayAlloc(size:Int):Array { return @:privateAccess Array.alloc(size); } /** Rethrow an exception. This is useful when manually filtering an exception in order to keep the previous exception stack. **/ @:extern inline public static function rethrow(e:Dynamic):Void { untyped __rethrow__(); } /** Creates a "checked" block, which throws exceptions for overflows. Usage: cs.Lib.checked({ var x = 1000; while(true) { x *= x; } }); This method only exists at compile-time, so it can't be called via reflection. **/ @:extern public static inline function checked(block:V):Void { untyped __checked__(block); } /** Ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread attempts to enter a locked code, it will wait, block, until the object is released. This method only exists at compile-time, so it can't be called via reflection. **/ @:extern public static inline function lock(obj:O, block:V):Void { untyped __lock__(obj, block); } //Unsafe code manipulation #if unsafe /** Marks its parameters as fixed objects inside the defined block. The first variable declarations that use cs.Lib.pointerOfArray() will be the fixed definitions. Usage: cs.Lib.fixed({ var obj1 = cs.Lib.pointerOfArray(someArray); var obj2 = cs.Lib.pointerOfArray(someArray2); var obj3 = cs.Lib.pointerOfArray(someArray3); //from now on, obj1, obj2 and obj3 are fixed //we cannot change obj1, obj2 or obj3 variables like this: //obj1++; }); This method only exists at compile-time, so it can't be called via reflection. **/ @:extern public static inline function fixed(block:V):Void { untyped __fixed__(block); } /** Marks the contained block as an unsafe block, meaning that it can contain unsafe code. Usage: cs.Lib.unsafe({ //unsafe code is allowed inside here }); This method only exists at compile-time, so it can't be called via reflection. **/ @:extern public static inline function unsafe(block:V):Void { untyped __unsafe__(block); } /** Gets the pointer to the address of current local. Equivalent to the "&" operator in C# Usage: var x:Int = 0; cs.Lib.unsafe({ var addr = cs.Lib.addressOf(x); x[0] = 42; }); trace(x); //42 This method only exists at compile-time, so it can't be called via reflection. Warning: This method will only work if a local variable is passed as an argument. **/ @:extern public static inline function addressOf(variable:T):cs.Pointer { return untyped __addressOf__(variable); } /** Gets the value of the pointer address. Usage: var x:Int = 0; cs.Lib.unsafe({ var addr = cs.Lib.addressOf(x); trace(cs.Lib.valueOf(addr)); //0 addr[0] = 42; trace(cs.Lib.valueOf(addr)); //42 }); trace(x); //42 This method only exists at compile-time, so it can't be called via reflection. **/ @:extern public static inline function valueOf(pointer:cs.Pointer):T { return untyped __valueOf__(pointer); } /** Transforms a managed native array into a Pointer. Must be inside a fixed statement Usage: var x:cs.NativeArray = new cs.NativeArray(1); cs.Lib.unsafe({ cs.Lib.fixed({ var addr = cs.Lib.pointerOfArray(x); trace(cs.Lib.valueOf(addr)); //0 addr[0] = 42; trace(cs.Lib.valueOf(addr)); //42 }); }); trace(x[0]); //42 This method only exists at compile-time, so it can't be called via reflection. **/ @:extern public static inline function pointerOfArray(array:cs.NativeArray):cs.Pointer { return untyped __ptr__(array); } /** Returns the byte size of the given struct. Only works with structs and basic types. **/ @:extern public static inline function sizeof(struct:Class):Int { return untyped __sizeof__(struct); } #end } haxe_3.4.4.orig/std/cs/NativeArray.hx0000664000175000017500000000450413166552354017404 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs; import haxe.extern.Rest; /** Represents a C# fixed-size Array (`T[]`) **/ extern class NativeArray extends cs.system.Array implements ArrayAccess { /** Creates a new array with the specified elements. Usage: ```haxe var elements = NativeArray.make(1,2,3,4,5,6); ``` **/ public static function make(elements:Rest):NativeArray; /** Allocates a new array with size `len` **/ public function new(len:Int):Void; /** Alias to array's `Length` property. Returns the size of the array **/ public var length(get,never):Int; @:extern inline private function get_length():Int return this.Length; static function Reverse(arr:cs.system.Array):Void; /** Returns an iterator so it's possible to use `for` with C#'s `NativeArray` **/ @:extern inline public function iterator():NativeArrayIterator return new NativeArrayIterator(this); } @:dce private class NativeArrayIterator { public var arr(default,null):NativeArray; public var idx(default,null):UInt; inline public function new(arr) { this.arr = arr; this.idx = 0; } inline public function hasNext():Bool return this.idx < this.arr.Length; inline public function next():T { return this.arr[this.idx++]; } } haxe_3.4.4.orig/std/cs/Out.hx0000664000175000017500000000272113166552354015725 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs; /** This type represents "out" types for C# function parameters. It only has effect on function parameters, and conversion to/from the referenced type is automatic. Note: Using this type should be considered a bad practice unless overriding a native function is needed. **/ @:analyzer(no_simplification) @:analyzer(no_local_dce) typedef Out = T;haxe_3.4.4.orig/std/cs/Pointer.hx0000664000175000017500000001125113166552354016574 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs; import cs.StdTypes.Int64; /** This type represents pointer types for C# function parameters. It should only be used inside an unsafe context (not checked by the Haxe compiler) C# code: int[] src; fixed (int* pSrc = src) { ... } Haxe code: var src:NativeArray; cs.Lib.fixed({ var pSrc:cs.Pointer = cs.Lib.pointerOfArray(src); ... }); **/ #if !unsafe #error "You need to define 'unsafe' to be able to use unsafe code in hxcs" #else @:runtimeValue @:coreType abstract Pointer from Int64 from PointerAccess to PointerAccess { @:op(A+B) public static function addIp(lhs:Pointer, rhs:Int):Pointer; @:op(A+B) public static function addp(lhs:Pointer, rhs:Int64):Pointer; @:op(A*B) public static function mulIp(lhs:Pointer, rhs:Int):Pointer; @:op(A*B) public static function mulp(lhs:Pointer, rhs:Int64):Pointer; @:op(A%B) public static function modIp(lhs:Pointer, rhs:Int):Pointer; @:op(A%B) public static function modp(lhs:Pointer, rhs:Int64):Pointer; @:op(A-B) public static function subIp(lhs:Pointer, rhs:Int):Pointer; @:op(A-B) public static function subp(lhs:Pointer, rhs:Int64):Pointer; @:op(A/B) public static function divIp(lhs:Pointer, rhs:Int):Pointer; @:op(A/B) public static function divp(lhs:Pointer, rhs:Int64):Pointer; @:op(A|B) public static function orIp(lhs:Pointer, rhs:Int):Pointer; @:op(A|B) public static function orp(lhs:Pointer, rhs:Int64):Pointer; @:op(A^B) public static function xorIp(lhs:Pointer, rhs:Int):Pointer; @:op(A^B) public static function xorp(lhs:Pointer, rhs:Int64):Pointer; @:op(A&B) public static function andIp(lhs:Pointer, rhs:Int):Pointer; @:op(A&B) public static function andp(lhs:Pointer, rhs:Int64):Pointer; @:op(A<(lhs:Pointer, rhs:Int):Pointer; @:op(A<(lhs:Pointer, rhs:Int64):Pointer; @:op(A>>B) public static function shrIp(lhs:Pointer, rhs:Int):Pointer; @:op(A>>B) public static function shrp(lhs:Pointer, rhs:Int64):Pointer; @:op(A>B) public static function gtp(lhs:Pointer, rhs:Pointer):Bool; @:op(A>=B) public static function gtep(lhs:Pointer, rhs:Pointer):Bool; @:op(A(lhs:Pointer, rhs:Pointer):Bool; @:op(A<=B) public static function ltep(lhs:Pointer, rhs:Pointer):Bool; @:op(~A) public static function bnegp(t:Pointer):Pointer; @:op(A++) public static function prepp(t:Pointer):Pointer; @:op(A--) public static function prenn(t:Pointer):Pointer; @:op(++A) public static function postpp(t:Pointer):Pointer; @:op(--A) public static function postnn(t:Pointer):Pointer; /** Returns a `cs.PointerAccess` type, which in turn allows the underlying Pointer's fields to be accessed. **/ // @:analyzer(no_simplification) public var acc(get,never):PointerAccess; // @:analyzer(no_simplification) @:extern inline private function get_acc():PointerAccess return (cast this : PointerAccess); // backwards compatibility inline public function add(i:Int):Pointer { return this + i; } @:arrayAccess public static function getIp(p:Pointer, at:Int):T; @:arrayAccess public static function setIp(p:Pointer, at:Int, val:T):T; @:arrayAccess public static function getp(p:Pointer, at:Int64):T; @:arrayAccess public static function setp(p:Pointer, at:Int64, val:T):T; } @:forward abstract PointerAccess(T) { } #end haxe_3.4.4.orig/std/cs/Ref.hx0000664000175000017500000000267013166552354015675 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs; /** This type represents "ref" types for C# function parameters. It only has effect on function parameters, and conversion to/from the referenced type is automatic. Note: Using this type should be considered a bad practice unless overriding a native function is needed. **/ @:analyzer(no_simplification) typedef Ref = T;haxe_3.4.4.orig/std/cs/StdTypes.hx0000664000175000017500000001304713166552354016740 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs; @:notNull @:runtimeValue @:coreType extern abstract Int8 to Int {} @:notNull @:runtimeValue @:coreType extern abstract Int16 to Int {} @:notNull @:runtimeValue @:coreType extern abstract Char16 from Int {} @:notNull @:runtimeValue @:coreType extern abstract UInt8 to Int from Int {} @:notNull @:runtimeValue @:coreType extern abstract UInt16 to Int {} @:notNull @:runtimeValue @:coreType extern abstract Int64 from Int from Float { @:op(A+B) public static function addI(lhs:Int64, rhs:Int):Int64; @:op(A+B) public static function add(lhs:Int64, rhs:Int64):Int64; @:op(A*B) public static function mulI(lhs:Int64, rhs:Int):Int64; @:op(A*B) public static function mul(lhs:Int64, rhs:Int64):Int64; @:op(A%B) public static function modI(lhs:Int64, rhs:Int):Int64; @:op(A%B) public static function mod(lhs:Int64, rhs:Int64):Int64; @:op(A-B) public static function subI(lhs:Int64, rhs:Int):Int64; @:op(A-B) public static function sub(lhs:Int64, rhs:Int64):Int64; @:op(A/B) public static function divI(lhs:Int64, rhs:Int):Int64; @:op(A/B) public static function div(lhs:Int64, rhs:Int64):Int64; @:op(A|B) public static function orI(lhs:Int64, rhs:Int):Int64; @:op(A|B) public static function or(lhs:Int64, rhs:Int64):Int64; @:op(A^B) public static function xorI(lhs:Int64, rhs:Int):Int64; @:op(A^B) public static function xor(lhs:Int64, rhs:Int64):Int64; @:op(A&B) public static function andI(lhs:Int64, rhs:Int):Int64; @:op(A&B) public static function and(lhs:Int64, rhs:Int64):Int64; @:op(A<>B) public static function shrI(lhs:Int64, rhs:Int):Int64; @:op(A>>B) public static function shr(lhs:Int64, rhs:Int64):Int64; @:op(A>B) public static function gt(lhs:Int64, rhs:Int64):Bool; @:op(A>=B) public static function gte(lhs:Int64, rhs:Int64):Bool; @:op(A>B) public static function shrI(lhs:UInt64, rhs:Int):UInt64; @:op(A>>B) public static function shr(lhs:UInt64, rhs:UInt64):UInt64; @:op(A>B) public static function gt(lhs:UInt64, rhs:UInt64):Bool; @:op(A>=B) public static function gte(lhs:UInt64, rhs:UInt64):Bool; @:op(A implements ArrayAccess { public var length(default,null) : Int; private var __a:NativeArray; #if erase_generics inline private static function ofNative(native:NativeArray):Array { return new Array(native); } #else inline private static function ofNative(native:NativeArray):Array { return new Array(native); } #end inline private static function alloc(size:Int):Array { return new Array(new NativeArray(size)); } @:overload public function new() : Void { this.length = 0; this.__a = new NativeArray(0); } #if erase_generics @:overload private function new(native:NativeArray) { this.length = native.Length; this.__a = untyped native; } #else @:overload private function new(native:NativeArray) { this.length = native.Length; this.__a = native; } #end public function concat( a : Array ) : Array { var len = length + a.length; var retarr = new NativeArray(len); cs.system.Array.Copy(__a, 0, retarr, 0, length); cs.system.Array.Copy(a.__a, 0, retarr, length, a.length); return ofNative(retarr); } private function concatNative( a : NativeArray ) : Void { var __a = __a; var len = length + a.Length; if (__a.Length >= len) { cs.system.Array.Copy(a, 0, __a, length, length); } else { var newarr = new NativeArray(len); cs.system.Array.Copy(__a, 0, newarr, 0, length); cs.system.Array.Copy(a, 0, newarr, length, a.Length); this.__a = newarr; } this.length = len; } public function indexOf( x : T, ?fromIndex:Int ) : Int { var len = length, i:Int = (fromIndex == null) ? 0 : fromIndex; if (i < 0) { i += len; if (i < 0) i = 0; } else if (i >= len) { return -1; } return cs.system.Array.IndexOf(__a, x, i, len - i); } public function lastIndexOf( x : T, ?fromIndex:Int ) : Int { var len = length, i:Int = (fromIndex == null) ? len - 1 : fromIndex; if (i >= len) { i = len - 1; } else if (i < 0) { i += len; if (i < 0) return -1; } return cs.system.Array.LastIndexOf(__a, x, i, i + 1); } public function join( sep : String ) : String { var buf = new StringBuf(); var i = -1; var first = true; var length = length; while (++i < length) { if (first) first = false; else buf.add(sep); buf.add(__a[i]); } return buf.toString(); } public function pop() : Null { var __a = __a; var length = length; if (length > 0) { var val = __a[--length]; __a[length] = null; this.length = length; return val; } else { return null; } } public function push(x : T) : Int { if (length >= __a.Length) { var newLen = (length << 1) + 1; var newarr = new NativeArray(newLen); __a.CopyTo(newarr, 0); this.__a = newarr; } __a[length] = x; return ++length; } public function reverse() : Void { var i = 0; var l = this.length; var a = this.__a; var half = l >> 1; l -= 1; while ( i < half ) { var tmp = a[i]; a[i] = a[l-i]; a[l-i] = tmp; i += 1; } } public function shift() : Null { var l = this.length; if( l == 0 ) return null; var a = this.__a; var x = a[0]; l -= 1; cs.system.Array.Copy(a, 1, a, 0, length-1); a[l] = null; this.length = l; return x; } public function slice( pos : Int, ?end : Int ) : Array { if( pos < 0 ){ pos = this.length + pos; if( pos < 0 ) pos = 0; } if( end == null ) end = this.length; else if( end < 0 ) end = this.length + end; if( end > this.length ) end = this.length; var len = end - pos; if ( len < 0 ) return new Array(); var newarr = new NativeArray(len); cs.system.Array.Copy(__a, pos, newarr, 0, len); return ofNative(newarr); } public function sort( f : T -> T -> Int ) : Void { if (length == 0) return; quicksort(0, length - 1, f); } private function quicksort( lo : Int, hi : Int, f : T -> T -> Int ) : Void { var buf = __a; var i = lo, j = hi; var p = buf[(i + j) >> 1]; while ( i <= j ) { while ( i < hi && f(buf[i], p) < 0 ) i++; while ( j > lo && f(buf[j], p) > 0 ) j--; if ( i <= j ) { var t = buf[i]; buf[i++] = buf[j]; buf[j--] = t; } } if( lo < j ) quicksort( lo, j, f ); if( i < hi ) quicksort( i, hi, f ); } public function splice( pos : Int, len : Int ) : Array { if( len < 0 ) return new Array(); if( pos < 0 ) { pos = this.length + pos; if( pos < 0 ) pos = 0; } if( pos > this.length ) { pos = 0; len = 0; } else if( pos + len > this.length ) { len = this.length - pos; if( len < 0 ) len = 0; } var a = this.__a; var ret = new NativeArray(len); cs.system.Array.Copy(a, pos, ret, 0, len); var ret = ofNative(ret); var end = pos + len; cs.system.Array.Copy(a, end, a, pos, this.length - end); this.length -= len; while( --len >= 0 ) a[this.length + len] = null; return ret; } private function spliceVoid( pos : Int, len : Int ) : Void { if( len < 0 ) return; if( pos < 0 ) { pos = this.length + pos; if( pos < 0 ) pos = 0; } if( pos > this.length ) { pos = 0; len = 0; } else if( pos + len > this.length ) { len = this.length - pos; if( len < 0 ) len = 0; } var a = this.__a; var end = pos + len; cs.system.Array.Copy(a, end, a, pos, this.length - end); this.length -= len; while( --len >= 0 ) a[this.length + len] = null; } public function toString() : String { var ret = new StringBuf(); var a = __a; ret.add("["); var first = true; for (i in 0...length) { if (first) first = false; else ret.add(","); ret.add(a[i]); } ret.add("]"); return ret.toString(); } public function unshift( x : T ) : Void { var __a = __a; var length = length; if (length >= __a.Length) { var newLen = (length << 1) + 1; var newarr = new NativeArray(newLen); cs.system.Array.Copy(__a, 0, newarr, 1, length); this.__a = newarr; } else { cs.system.Array.Copy(__a, 0, __a, 1, length); } this.__a[0] = x; ++this.length; } public function insert( pos : Int, x : T ) : Void { var l = this.length; if( pos < 0 ) { pos = l + pos; if( pos < 0 ) pos = 0; } if ( pos >= l ) { this.push(x); return; } else if (pos == 0) { this.unshift(x); return; } if (l >= __a.Length) { var newLen = (length << 1) + 1; var newarr = new NativeArray(newLen); cs.system.Array.Copy(__a, 0, newarr, 0, pos); newarr[pos] = x; cs.system.Array.Copy(__a, pos, newarr, pos + 1, l - pos); this.__a = newarr; ++this.length; } else { var __a = __a; cs.system.Array.Copy(__a, pos, __a, pos + 1, l - pos); cs.system.Array.Copy(__a, 0, __a, 0, pos); __a[pos] = x; ++this.length; } } public function remove( x : T ) : Bool { var __a = __a; var i = -1; var length = length; while (++i < length) { if (__a[i] == x) { cs.system.Array.Copy(__a, i + 1, __a, i, length - i - 1); __a[--this.length] = null; return true; } } return false; } public function map( f : T -> S ) : Array { var ret = []; for (elt in this) ret.push(f(elt)); return ret; } public function filter( f : T -> Bool ) : Array { var ret = []; for (elt in this) if (f(elt)) ret.push(elt); return ret; } public function copy() : Array { var len = length; var __a = __a; var newarr = new NativeArray(len); cs.system.Array.Copy(__a, 0, newarr, 0, len); return ofNative(newarr); } public inline function iterator() : Iterator { return new ArrayIterator(this); } private function __get(idx:Int):T { return if ((cast idx : UInt) >= length) null else __a[idx]; } private function __set(idx:Int, v:T):T { var idx:UInt = idx; var __a = __a; if (idx >= __a.Length) { var len = idx + 1; if (idx == __a.Length) len = (idx << 1) + 1; var newArr = new NativeArray(len); __a.CopyTo(newArr, 0); this.__a = __a = newArr; } if (idx >= length) this.length = idx + 1; return __a[idx] = v; } private inline function __unsafe_get(idx:Int):T { return __a[idx]; } private inline function __unsafe_set(idx:Int, val:T):T { return __a[idx] = val; } } @:final private class ArrayIterator { var arr:Array; var len:Int; var i:Int; public inline function new(a:Array) { arr = a; len = a.length; i = 0; } public inline function hasNext():Bool return i < len; public inline function next():T return arr[i++]; } haxe_3.4.4.orig/std/cs/_std/Date.hx0000664000175000017500000000747113166552354016773 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package; import cs.system.DateTime; import cs.system.TimeSpan; import haxe.Int64; #if core_api_serialize @:meta(System.Serializable) #end @:coreApi class Date { @:readOnly private static var epochTicks:Int64 = new DateTime(1970, 1, 1).Ticks; private var date:DateTime; @:overload public function new(year : Int, month : Int, day : Int, hour : Int, min : Int, sec : Int ) : Void { if (day <= 0) day = 1; if (year <= 0) year = 1; date = new DateTime(year, month + 1, day, hour, min, sec); } @:overload private function new(native:DateTime) { date = native; } public inline function getTime() : Float { return cast(cs.system.TimeZone.CurrentTimeZone.ToUniversalTime(date).Ticks - epochTicks, Float) / cast(TimeSpan.TicksPerMillisecond, Float); } public inline function getHours() : Int { return date.Hour; } public inline function getMinutes() : Int { return date.Minute; } public inline function getSeconds() : Int { return date.Second; } public inline function getFullYear() : Int { return date.Year; } public inline function getMonth() : Int { return date.Month - 1; } public inline function getDate() : Int { return date.Day; } public inline function getDay() : Int { return cast(date.DayOfWeek, Int); } public function toString():String { var m = getMonth() + 1; var d = getDate(); var h = getHours(); var mi = getMinutes(); var s = getSeconds(); return (getFullYear()) +"-"+(if( m < 10 ) "0"+m else ""+m) +"-"+(if( d < 10 ) "0"+d else ""+d) +" "+(if( h < 10 ) "0"+h else ""+h) +":"+(if( mi < 10 ) "0"+mi else ""+mi) +":"+(if( s < 10 ) "0"+s else ""+s); } static public inline function now() : Date { return new Date(DateTime.Now); } static public inline function fromTime( t : Float ) : Date { return new Date(cs.system.TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(cast(t * cast(TimeSpan.TicksPerMillisecond, Float), Int64) + epochTicks))); } static public function fromString( s : String ) : Date { switch( s.length ) { case 8: // hh:mm:ss var k = s.split(":"); var d : Date = new Date(1, 1, 1, Std.parseInt(k[0]), Std.parseInt(k[1]), Std.parseInt(k[2])); return d; case 10: // YYYY-MM-DD var k = s.split("-"); return new Date(Std.parseInt(k[0]),Std.parseInt(k[1]) - 1,Std.parseInt(k[2]),0,0,0); case 19: // YYYY-MM-DD hh:mm:ss var k = s.split(" "); var y = k[0].split("-"); var t = k[1].split(":"); return new Date(Std.parseInt(y[0]),Std.parseInt(y[1]) - 1,Std.parseInt(y[2]),Std.parseInt(t[0]),Std.parseInt(t[1]),Std.parseInt(t[2])); default: throw "Invalid date format : " + s; } } private static inline function fromNative( d : cs.system.DateTime ) : Date { return new Date(d); } } haxe_3.4.4.orig/std/cs/_std/EReg.hx0000664000175000017500000000740313166552354016733 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import cs.system.text.regularexpressions.Regex; import cs.system.text.regularexpressions.Match; import cs.system.text.regularexpressions.RegexOptions; import cs.system.text.regularexpressions.*; @:coreApi @:final class EReg { private var regex : Regex; private var m : Match; private var isGlobal : Bool; private var cur : String; public function new( r : String, opt : String ) : Void { var opts:Int = cast CultureInvariant; for (i in 0...opt.length) untyped { switch(cast(opt[i], Int)) { case 'i'.code: opts |= cast(IgnoreCase, Int); case 'g'.code: isGlobal = true; case 'm'.code: opts |= cast(Multiline, Int); #if (!unity && !unity_std_target) case 'c'.code: opts |= cast(Compiled, Int); #end } } this.regex = new Regex(r, cast(opts, RegexOptions)); } public function match( s : String ) : Bool { m = regex.Match(s); cur = s; return m.Success; } public function matched( n : Int ) : String { if (m == null || cast(n, UInt) > m.Groups.Count) throw "EReg::matched"; if (!m.Groups[n].Success) return null; return m.Groups[n].Value; } public function matchedLeft() : String { return untyped cur.Substring(0, m.Index); } public function matchedRight() : String { return untyped cur.Substring(m.Index + m.Length); } public function matchedPos() : { pos : Int, len : Int } { return { pos : m.Index, len : m.Length }; } public function matchSub( s : String, pos : Int, len : Int = -1):Bool { m= if (len<0) regex.Match(s,pos) else regex.Match(s, pos, len); cur = s; return m.Success; } public function split( s : String ) : Array { if (isGlobal) return cs.Lib.array(regex.Split(s)); var m = regex.Match(s); if (!m.Success) return [s]; return untyped [s.Substring(0, m.Index), s.Substring(m.Index + m.Length)]; } inline function start(group:Int) : Int { return m.Groups[group].Index; } inline function len(group:Int) : Int { return m.Groups[group].Length; } public function replace( s : String, by : String ) : String { return (isGlobal) ? regex.Replace(s, by): regex.Replace(s,by,1); } public function map( s : String, f : EReg -> String ) : String { var offset = 0; var buf = new StringBuf(); do { if (offset >= s.length) break; else if (!matchSub(s, offset)) { buf.add(s.substr(offset)); break; } var p = matchedPos(); buf.add(s.substr(offset, p.pos - offset)); buf.add(f(this)); if (p.len == 0) { buf.add(s.substr(p.pos, 1)); offset = p.pos + 1; } else offset = p.pos + p.len; } while (isGlobal); if (!isGlobal && offset > 0 && offset < s.length) buf.add(s.substr(offset)); return buf.toString(); } } haxe_3.4.4.orig/std/cs/_std/Math.hx0000664000175000017500000000753113166552354017004 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi @:nativeGen class Math { @:readOnly private static var rand = new cs.system.Random(); @:readOnly public static var PI(default,null) = cs.system.Math.PI; @:readOnly public static var NaN(default,null) = cs.system.Double.NaN; @:readOnly public static var NEGATIVE_INFINITY(default,null) = cs.system.Double.NegativeInfinity; @:readOnly public static var POSITIVE_INFINITY(default,null) = cs.system.Double.PositiveInfinity; public static inline function abs(v:Float):Float { return cs.system.Math.Abs(v); } public static inline function min(a:Float, b:Float):Float { return cs.system.Math.Min(a,b); } public static inline function max(a:Float, b:Float):Float { return cs.system.Math.Max(a,b); } public static inline function sin(v:Float):Float { return cs.system.Math.Sin(v); } public static inline function cos(v:Float):Float { return cs.system.Math.Cos(v); } public static inline function atan2(y:Float, x:Float):Float { return cs.system.Math.Atan2(y, x); } public static inline function tan(v:Float):Float { return cs.system.Math.Tan(v); } public static inline function exp(v:Float):Float { return cs.system.Math.Exp(v); } public static inline function log(v:Float):Float { return cs.system.Math.Log(v); } public static inline function sqrt(v:Float):Float { return cs.system.Math.Sqrt(v); } public static inline function fround(v:Float):Float { return cs.system.Math.Floor(v + 0.5); } public static inline function ffloor(v:Float):Float { return cs.system.Math.Floor(v); } public static inline function fceil(v:Float):Float { return cs.system.Math.Ceiling(v); } public static function round(v:Float):Int { var vint = Std.int(v); var dec = v - vint; if (dec >= 1 || dec <= -1) return vint; //overflow if (dec >= .5) return vint + 1; if (dec < -.5) return vint - 1; return vint; } public static inline function floor(v:Float):Int { return Std.int(cs.system.Math.Floor(v)); } public static inline function ceil(v:Float):Int { return Std.int(cs.system.Math.Ceiling(v)); } public static inline function atan(v:Float):Float { return cs.system.Math.Atan(v); } public static inline function asin(v:Float):Float { return cs.system.Math.Asin(v); } public static inline function acos(v:Float):Float { return cs.system.Math.Acos(v); } public static inline function pow(v:Float, exp:Float):Float { return cs.system.Math.Pow(v, exp); } public static inline function random() : Float { return rand.NextDouble(); } public static inline function isFinite( f : Float ) : Bool { return !cs.system.Double.IsInfinity(f) && !cs.system.Double.IsNaN(f); } public static inline function isNaN( f : Float ) : Bool { return cs.system.Double.IsNaN(f); } } haxe_3.4.4.orig/std/cs/_std/Reflect.hx0000664000175000017500000001231313166552354017471 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import cs.internal.Function; import cs.system.reflection.*; import cs.internal.*; import cs.internal.HxObject; import cs.internal.Runtime; import cs.Flags; import cs.Lib; import cs.system.Object; import cs.system.reflection.*; @:coreApi class Reflect { public static function hasField( o : Dynamic, field : String ) : Bool { var ihx:IHxObject = Lib.as(o,IHxObject); if (ihx != null) return untyped ihx.__hx_getField(field, FieldLookup.hash(field), false, true, false) != Runtime.undefined; return Runtime.slowHasField(o,field); } @:keep public static function field( o : Dynamic, field : String ) : Dynamic { var ihx:IHxObject = Lib.as(o,IHxObject); if (ihx != null) return untyped ihx.__hx_getField(field, FieldLookup.hash(field), false, false, false); return Runtime.slowGetField(o,field,false); } @:keep public static function setField( o : Dynamic, field : String, value : Dynamic ) : Void { var ihx:IHxObject = Lib.as(o,IHxObject); if (ihx != null) untyped ihx.__hx_setField(field, FieldLookup.hash(field), value, false); else Runtime.slowSetField(o,field,value); } public static function getProperty( o : Dynamic, field : String ) : Dynamic { var ihx:IHxObject = Lib.as(o,IHxObject); if (ihx != null) return untyped ihx.__hx_getField(field, FieldLookup.hash(field), false, false, true); if (Runtime.slowHasField(o, "get_" + field)) return Runtime.slowCallField(o, "get_" + field, null); return Runtime.slowGetField(o, field, false); } public static function setProperty( o : Dynamic, field : String, value : Dynamic ) : Void { var ihx:IHxObject = Lib.as(o,IHxObject); if (ihx != null) untyped ihx.__hx_setField(field, FieldLookup.hash(field), value, true); else if (Runtime.slowHasField(o, 'set_$field')) Runtime.slowCallField(o, 'set_$field', [value]); else Runtime.slowSetField(o,field,value); } public static function callMethod( o : Dynamic, func : haxe.Constraints.Function, args : Array ) : Dynamic { return untyped cast(func, Function).__hx_invokeDynamic(args); } @:keep public static function fields( o : Dynamic ) : Array { var ihx = Lib.as(o,IHxObject); if (ihx != null) { var ret = []; untyped ihx.__hx_getFields(ret); return ret; } else if (Std.is(o, cs.system.Type)) { return Type.getClassFields(o); } else { return instanceFields( untyped o.GetType() ); } } private static function instanceFields( c : Class ) : Array { var c = cs.Lib.toNativeType(c); var ret = []; var mis = c.GetFields(new cs.Flags(BindingFlags.Public) | BindingFlags.Instance | BindingFlags.FlattenHierarchy); for (i in 0...mis.Length) { var i = mis[i]; ret.push(i.Name); } return ret; } inline public static function isFunction( f : Dynamic ) : Bool { return Std.is(f, Function); } public static function compare( a : T, b : T ) : Int { return cs.internal.Runtime.compare(a, b); } @:access(cs.internal.Closure) public static function compareMethods( f1 : Dynamic, f2 : Dynamic ) : Bool { if (f1 == f2) return true; if (Std.is(f1, Closure) && Std.is(f2, Closure)) { var f1c:Closure = cast f1; var f2c:Closure = cast f2; return Runtime.refEq(f1c.obj, f2c.obj) && f1c.field == f2c.field; } return false; } public static function isObject( v : Dynamic ) : Bool { return v != null && !(Std.is(v, HxEnum) || Std.is(v, Function) || Std.is(v, cs.system.ValueType)); } public static function isEnumValue( v : Dynamic ) : Bool { return v != null && (Std.is(v, HxEnum) || Std.is(v, cs.system.Enum)); } public static function deleteField( o : Dynamic, field : String ) : Bool { var ihx = Lib.as(o,DynamicObject); if (ihx != null) return untyped ihx.__hx_deleteField(field, FieldLookup.hash(field)); return false; } public static function copy( o : T ) : T { var o2 : Dynamic = {}; for( f in Reflect.fields(o) ) Reflect.setField(o2,f,Reflect.field(o,f)); return cast o2; } @:overload(function( f : Array -> Void ) : Dynamic {}) public static function makeVarArgs( f : Array -> Dynamic ) : Dynamic { return new VarArgsFunction(f); } } haxe_3.4.4.orig/std/cs/_std/Std.hx0000664000175000017500000001143113166552354016637 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import cs.Boot; import cs.Lib; import cs.internal.Exceptions; @:coreApi @:nativeGen class Std { public static function is( v : Dynamic, t : Dynamic ) : Bool { if (v == null) return t == Dynamic; if (t == null) return false; var clt = cs.Lib.as(t, cs.system.Type); if (clt == null) return false; switch(clt.ToString()) { case "System.Double": return untyped __cs__('{0} is double || {0} is int', v); case "System.Int32": return cs.internal.Runtime.isInt(v); case "System.Boolean": return untyped __cs__('{0} is bool', v); case "System.Object": return true; } var vt = cs.Lib.getNativeType(v); if (clt.IsAssignableFrom(vt)) return true; #if !erase_generics for (iface in clt.GetInterfaces()) { var g = cs.internal.Runtime.getGenericAttr(iface); if (g != null && g.generic == clt) { return iface.IsAssignableFrom(vt); } } #end return false; } public static function string( s : Dynamic ) : String { if (s == null) return "null"; if (Std.is(s, Bool)) return cast(s, Bool) ? "true" : "false"; return s.ToString(); } public static function int( x : Float ) : Int { return cast x; } public static function parseInt( x : String ) : Null { if (x == null) return null; var ret = 0; var base = 10; var i = -1; var len = x.length; if (StringTools.startsWith(x, "0") && len > 2) { var c:Int = cast untyped x[1]; if (c == 'x'.code || c == 'X'.code) { i = 1; base = 16; } } var foundAny = i != -1; var isNeg = false; while (++i < len) { var c = cast(untyped x[i], Int); //fastCodeAt if (!foundAny) { switch(c) { case '-'.code: isNeg = true; continue; case ' '.code, '\t'.code, '\n'.code, '\r'.code, '+'.code: if (isNeg) return null; continue; } } if (c >= '0'.code && c <= '9'.code) { if (!foundAny && c == '0'.code) { foundAny = true; continue; } ret *= base; foundAny = true; ret += c - '0'.code; } else if (base == 16) { if (c >= 'a'.code && c <= 'f'.code) { ret *= base; foundAny = true; ret += c - 'a'.code + 10; } else if (c >= 'A'.code && c <= 'F'.code) { ret *= base; foundAny = true; ret += c - 'A'.code + 10; } else { break; } } else { break; } } if (foundAny) return isNeg ? -ret : ret; else return null; } public static function parseFloat( x : String ) : Float { if (x == null) return Math.NaN; x = StringTools.ltrim(x); var found = false, hasDot = false, hasSign = false, hasE = false, hasESign = false, hasEData = false; var i = -1; inline function getch(i:Int):Int return cast ((untyped x : cs.system.String)[i]); while (++i < x.length) { var chr = getch(i); if (chr >= '0'.code && chr <= '9'.code) { if (hasE) { hasEData = true; } found = true; } else switch (chr) { case 'e'.code | 'E'.code if(!hasE): hasE = true; case '.'.code if (!hasDot): hasDot = true; case '-'.code, '+'.code if (!found && !hasSign): hasSign = true; case '-'.code | '+'.code if (found && !hasESign && hasE && !hasEData): hasESign = true; case _: break; } } if (hasE && !hasEData) { i--; if (hasESign) i--; } if (i != x.length) { x = x.substr(0,i); } return try cs.system.Double.Parse(x, cs.system.globalization.CultureInfo.InvariantCulture) catch(e:Dynamic) Math.NaN; } @:extern inline public static function instance( value : T, c : Class ) : S { return cs.Lib.as(value,c); } public static function random( x : Int ) : Int { if (x <= 0) return 0; return untyped Math.rand.Next(x); } } haxe_3.4.4.orig/std/cs/_std/String.hx0000664000175000017500000000476013166552354017362 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import cs.StdTypes; @:coreApi extern class String implements ArrayAccess { @:overload private static function Compare(s1:String, s2:String):Int; @:overload private static function Compare(s1:String, s2:String, kind:cs.system.StringComparison):Int; var length(default,null) : Int; function new(string:String) : Void; function toUpperCase() : String; function toLowerCase() : String; function charAt( index : Int) : String; function charCodeAt( index : Int) : Null; function indexOf( str : String, ?startIndex : Int ) : Int; function lastIndexOf( str : String, ?startIndex : Int ) : Int; function split( delimiter : String ) : Array; function substr( pos : Int, ?len : Int ) : String; function substring( startIndex : Int, ?endIndex : Int ) : String; function toString() : String; static function fromCharCode( code : Int ) : String; private function IndexOf(value:String, startIndex:Int, comparisonType:cs.system.StringComparison):Int; private function Replace(oldValue:String, newValue:String):String; private function StartsWith(value:String):Bool; private function EndsWith(value:String):Bool; private function TrimStart():String; private function TrimEnd():String; private function Trim():String; private function CompareTo(obj:Dynamic):Int; @:overload(function(startIndex:Int):String {}) private function Substring(startIndex:Int, length:Int):String; } haxe_3.4.4.orig/std/cs/_std/StringBuf.hx0000664000175000017500000000340113166552354020006 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import cs.system.text.StringBuilder; @:coreApi class StringBuf { private var b : StringBuilder; public var length(get,never) : Int; public inline function new() : Void { b = new StringBuilder(); } inline function get_length() : Int { return b.Length; } public inline function add( x : T ) : Void { b.Append(Std.string(x)); } public inline function addSub( s : String, pos : Int, ?len : Int ) : Void { b.Append(s, pos, (len == null) ? (s.length - pos) : len); } public inline function addChar( c : Int ) : Void untyped { b.Append(cast(c, cs.StdTypes.Char16)); } public inline function toString() : String { return b.ToString(); } }haxe_3.4.4.orig/std/cs/_std/Sys.hx0000664000175000017500000001245113166552354016666 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import sys.io.Process; import cs.system.Environment; import cs.system.threading.Thread; @:coreApi class Sys { private static var _env:haxe.ds.StringMap; private static var _args:Array; public static inline function print( v : Dynamic ) : Void { cs.system.Console.Write(v); } public static inline function println( v : Dynamic ) : Void { cs.system.Console.WriteLine(v); } public static function args() : Array { if (_args == null) { var ret = cs.Lib.array(Environment.GetCommandLineArgs()); ret.shift(); _args = ret; } return _args.copy(); } public static inline function getEnv( s : String ) : String { return Environment.GetEnvironmentVariable(s); } public static function putEnv( s : String, v : String ) : Void { Environment.SetEnvironmentVariable(s, v); if (_env != null) _env.set(s, v); } public static function environment() : Map { if (_env == null) { var e = _env = new haxe.ds.StringMap(); var nenv = Environment.GetEnvironmentVariables().GetEnumerator(); while (nenv.MoveNext()) { e.set(nenv.Key, nenv.Value); } } return _env; } public static inline function sleep( seconds : Float ) : Void { Thread.Sleep( Std.int(seconds * 1000) ); } public static function setTimeLocale( loc : String ) : Bool { //TODO C# return false; } public static inline function getCwd() : String { return cs.system.io.Directory.GetCurrentDirectory(); } public static inline function setCwd( s : String ) : Void { cs.system.io.Directory.SetCurrentDirectory(s); } public static function systemName() : String { //doing a switch with strings since MacOS might not be available switch(Environment.OSVersion.Platform + "") { case "Unix": return "Linux"; case "Xbox": return "Xbox"; case "MacOSX": return "Mac"; default: var ver = cast(Environment.OSVersion.Platform, Int); if (ver == 4 || ver == 6 || ver == 128) return "Linux"; return "Windows"; } } public static function command( cmd : String, ?args : Array ) : Int { var proc = Process.createNativeProcess(cmd, args); proc.add_OutputDataReceived(new cs.system.diagnostics.DataReceivedEventHandler( function(p, evtArgs) { var data = evtArgs.Data; if (data != null && data != "") println(data); } )); var stderr = stderr(); proc.add_ErrorDataReceived(new cs.system.diagnostics.DataReceivedEventHandler( function(p, evtArgs) { var data = evtArgs.Data; if (data != null && data != "") stderr.writeString(data + "\n"); } )); proc.Start(); proc.BeginOutputReadLine(); proc.BeginErrorReadLine(); proc.WaitForExit(); var exitCode = proc.ExitCode; proc.Dispose(); return exitCode; } public static inline function exit( code : Int ) : Void { Environment.Exit(code); } @:readOnly static var epochTicks = new cs.system.DateTime(1970, 1, 1).Ticks; public static function time() : Float { return cast((cs.system.DateTime.UtcNow.Ticks - epochTicks), Float) / cast(cs.system.TimeSpan.TicksPerSecond, Float); } public static inline function cpuTime() : Float { return Environment.TickCount / 1000; } @:deprecated("Use programPath instead") public static inline function executablePath() : String { return cs.system.reflection.Assembly.GetExecutingAssembly().GetName().CodeBase; } public static function programPath() : String { return cs.system.reflection.Assembly.GetExecutingAssembly().Location; } public static function getChar( echo : Bool ) : Int { #if !(Xbox || CF || MF) //Xbox, Compact Framework, Micro Framework return cast(cs.system.Console.ReadKey(!echo).KeyChar, Int); #else return -1; #end } public static inline function stdin() : haxe.io.Input { #if !(Xbox || CF || MF) return new cs.io.NativeInput(cs.system.Console.OpenStandardInput()); #else return null; #end } public static inline function stdout() : haxe.io.Output { #if !(Xbox || CF || MF) return new cs.io.NativeOutput(cs.system.Console.OpenStandardOutput()); #else return null; #end } public static inline function stderr() : haxe.io.Output { #if !(Xbox || CF || MF) return new cs.io.NativeOutput(cs.system.Console.OpenStandardError()); #else return null; #end } } haxe_3.4.4.orig/std/cs/_std/Type.hx0000664000175000017500000002340213166552354017027 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import cs.Lib; import cs.internal.HxObject; import cs.internal.Runtime; import cs.internal.Function; import cs.Flags; import cs.system.Object; import cs.system.reflection.*; using StringTools; enum ValueType { TNull; TInt; TFloat; TBool; TObject; TFunction; TClass( c : Class ); TEnum( e : Enum ); TUnknown; } @:coreApi class Type { public static function getClass( o : T ) : Class untyped { if (Object.ReferenceEquals(o,null) || Std.is(o,DynamicObject) || Std.is(o,cs.system.Type)) return null; return untyped o.GetType(); } public static function getEnum( o : EnumValue ) : Enum untyped { if (Std.is(o, cs.system.Enum) || Std.is(o,HxEnum)) return untyped o.GetType(); return null; } public static function getSuperClass( c : Class ) : Class { var t:cs.system.Type = Lib.toNativeType(c); var base = t.BaseType; if (base == null || base.ToString() == "haxe.lang.HxObject" || base.ToString() == "System.Object") return null; return Lib.fromNativeType(base); } public static function getClassName( c : Class ) : String { var ret:String = cast Lib.toNativeType(c); #if no_root if (ret.length > 10 && StringTools.startsWith(ret, "haxe.root.")) ret = ret.substr(10); #end return switch(ret) { case "System.Int32": "Int"; case "System.Double": "Float"; case "System.String": "String"; case "System.Object": "Dynamic"; case "System.Type": "Class"; default: ret.split("`")[0]; } } public static function getEnumName( e : Enum ) : String { var ret:String = cast Lib.toNativeType(untyped e); #if no_root if (ret.length > 10 && StringTools.startsWith(ret, "haxe.root.")) ret = ret.substr(10); #end if (ret.length == 14 && ret == "System.Boolean") return "Bool"; return ret; } public static function resolveClass( name : String ) : Class { #if no_root if (name.indexOf(".") == -1) name = "haxe.root." + name; #end var t:cs.system.Type = cs.system.Type._GetType(name); #if !CF if (t == null) { var all = cs.system.AppDomain.CurrentDomain.GetAssemblies().GetEnumerator(); while (all.MoveNext()) { var t2:cs.system.reflection.Assembly = all.Current; t = t2.GetType(name); if (t != null) break; } } #end if (t == null) { switch(name) { case #if no_root "haxe.root.Int" #else "Int" #end: return cast Int; case #if no_root "haxe.root.Float" #else "Float" #end: return cast Float; case #if no_root "haxe.root.Class" #else "Class" #end: return cast Class; case #if no_root "haxe.root.Dynamic" #else "Dynamic" #end: return cast Dynamic; case #if no_root "haxe.root.String" #else "String" #end: return cast String; default: return null; } #if !erase_generics } else if (t.IsInterface && cast(untyped __typeof__(IGenericObject), cs.system.Type).IsAssignableFrom(t)) { for (attr in t.GetCustomAttributes(true)) { var g = cs.Lib.as(attr, cs.internal.HxObject.GenericInterface); if (g != null) return Lib.fromNativeType(g.generic); } return Lib.fromNativeType(t); #end } else { return Lib.fromNativeType(t); } } public static function resolveEnum( name : String ) : Enum untyped { if (name == "Bool") return Bool; var t = Lib.toNativeType(resolveClass(name)); if (t != null && t.BaseType.Equals( Lib.toNativeType(cs.system.Enum) ) || Lib.toNativeType(HxEnum).IsAssignableFrom(t)) return t; return null; } public static function createInstance( cl : Class, args : Array ) : T { if (untyped cl == String) return args[0]; var t:cs.system.Type = Lib.toNativeType(cl); if (t.IsInterface) { //may be generic t = Lib.toNativeType(resolveClass(getClassName(cl))); } var ctors = t.GetConstructors(); return Runtime.callMethod(null, cast ctors, ctors.Length, args); } // cache empty constructor arguments so we don't allocate it on each createEmptyInstance call @:protected @:readOnly static var __createEmptyInstance_EMPTY_ARGS = cs.NativeArray.make((cs.internal.Runtime.EmptyObject.EMPTY : Any)); public static function createEmptyInstance( cl : Class ) : T { var t = Lib.toNativeType(cl); if (cs.system.Object.ReferenceEquals(t, String)) #if erase_generics return untyped ""; #else return untyped __cs__("(T)(object){0}", ""); #end var res = try cs.system.Activator.CreateInstance(t, __createEmptyInstance_EMPTY_ARGS) catch (_:cs.system.MissingMemberException) cs.system.Activator.CreateInstance(t); #if erase_generics return res; #else return untyped __cs__("(T){0}", res); #end } public static function createEnum( e : Enum, constr : String, ?params : Array ) : T { if (params == null || params.length == 0) { var ret = cs.internal.Runtime.slowGetField(e, constr, true); if (Reflect.isFunction(ret)) throw 'Constructor $constr needs parameters'; return ret; } else { return cs.internal.Runtime.slowCallField(e,constr,params); } } public static function createEnumIndex( e : Enum, index : Int, ?params : Array ) : T { var constr = getEnumConstructs(e); return createEnum(e, constr[index], params); } public static function getInstanceFields( c : Class ) : Array { if (c == String) return cs.internal.StringExt.StringRefl.fields; var c = cs.Lib.toNativeType(c); var ret = []; var mis = c.GetMembers(new cs.Flags(BindingFlags.Public) | BindingFlags.Instance | BindingFlags.FlattenHierarchy); for (i in 0...mis.Length) { var i = mis[i]; if (Std.is(i, PropertyInfo)) continue; var n = i.Name; if (!n.startsWith('__hx_') && n.fastCodeAt(0) != '.'.code) { switch(n) { case 'Equals' | 'ToString' | 'GetHashCode' | 'GetType': case _: ret.push(n); } } } return ret; } public static function getClassFields( c : Class ) : Array { if (Object.ReferenceEquals(c, String)) { return ['fromCharCode']; } var ret = []; var infos = Lib.toNativeType(c).GetMembers(new Flags(BindingFlags.Public) | BindingFlags.Static); for (i in 0...infos.Length) { var name = infos[i].Name; if (!name.startsWith('__hx_')) { ret.push(name); } } return ret; } public static function getEnumConstructs( e : Enum ) : Array { if (Reflect.hasField(e, "__hx_constructs")) { var ret:Array = cs.Lib.array(untyped e.__hx_constructs); return ret.copy(); } return cs.Lib.array(cs.system.Enum.GetNames(untyped e)); } public static function typeof( v : Dynamic ) : ValueType { if (v == null) return ValueType.TNull; var t:cs.system.Type = cs.Lib.as(v, cs.system.Type); if (t != null) { //class type return ValueType.TObject; } t = v.GetType(); if (t.IsEnum || Std.is(v, HxEnum)) return ValueType.TEnum(cast t); if (t.IsValueType) { var vc:cs.system.IConvertible = cast v; if (vc != null) { switch (vc.GetTypeCode()) { case cs.system.TypeCode.Boolean: return ValueType.TBool; case cs.system.TypeCode.Double: var d:Float = vc.ToDouble(null); if (d >= cs.system.Int32.MinValue && d <= cs.system.Int32.MaxValue && d == vc.ToInt32(null)) return ValueType.TInt; else return ValueType.TFloat; case cs.system.TypeCode.Int32: return ValueType.TInt; default: return ValueType.TClass(cast t); } } else { return ValueType.TClass(cast t); } } if (Std.is(v, IHxObject)) { if (Std.is(v, DynamicObject)) return ValueType.TObject; else if (Std.is(v, HxEnum)) return ValueType.TEnum(cast t); return ValueType.TClass(cast t); } else if (Std.is(v, Function)) { return ValueType.TFunction; } else { return ValueType.TClass(cast t); } } public static function enumEq( a : T, b : T ) : Bool { if (a == null) return b == null; else if (b == null) return false; else return untyped a.Equals(b); } public static function enumConstructor( e : EnumValue ) : String untyped { return Std.is(e, cs.system.Enum) ? e+'' : cast(e,HxEnum).getTag(); } public static function enumParameters( e : EnumValue ) : Array untyped { return Std.is(e, cs.system.Enum) ? [] : cast(e,HxEnum).getParams(); } @:pure public static function enumIndex( e : EnumValue ) : Int untyped { if (Std.is(e, cs.system.Enum)) { var values = cs.system.Enum.GetValues(Lib.getNativeType(e)); return cs.system.Array.IndexOf(values, e); } else { return cast(e, HxEnum).index; } } public static function allEnums( e : Enum ) : Array { var ctors = getEnumConstructs(e); var ret = []; for (ctor in ctors) { var v = Reflect.field(e, ctor); if (Std.is(v, e)) ret.push(v); } return ret; } } haxe_3.4.4.orig/std/cs/_std/haxe/Int64.hx0000664000175000017500000001675713166552354017756 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; using haxe.Int64; import haxe.Int64Helper; private typedef __Int64 = cs.StdTypes.Int64; @:coreApi abstract Int64(__Int64) from __Int64 to __Int64 { public static inline function make( high : Int32, low : Int32 ) : Int64 return new Int64( (cast(high, __Int64) << 32) | (cast(low, __Int64)& (untyped __cs__('0xffffffffL') : Int64)) ); private inline function new(x : __Int64) this = x; private var val( get, set ) : __Int64; inline function get_val() : __Int64 return this; inline function set_val( x : __Int64 ) : __Int64 return this = x; public var high( get, never ):Int32; public inline function get_high():Int32 return cast(this >> 32); public var low( get, never ):Int32; public inline function get_low():Int32 return cast this; public inline function copy():Int64 return new Int64( this ); @:from public static inline function ofInt( x : Int ) : Int64 return cast x; public static inline function toInt( x : Int64 ) : Int { if( x.val < 0x80000000 || x.val > 0x7FFFFFFF ) throw "Overflow"; return cast x.val; } inline public static function is( val : Dynamic ) : Bool return Std.is(val,cs.system.Int64); public static inline function getHigh( x : Int64 ) : Int32 return cast( x.val >> 32 ); public static inline function getLow( x : Int64 ) : Int32 return cast( x.val ); public static inline function isNeg( x : Int64 ) : Bool return x.val < 0; public static inline function isZero( x : Int64 ) : Bool return x.val == 0; public static inline function compare( a : Int64, b : Int64 ) : Int { if( a.val < b.val ) return -1; if( a.val > b.val ) return 1; return 0; } public static inline function ucompare( a : Int64, b : Int64 ) : Int { if( a.val < 0 ) return ( b.val < 0 ) ? compare( a, b ) : 1; return ( b.val < 0 ) ? -1 : compare( a, b ); } public static inline function toStr( x : Int64 ) : String return '${x.val}'; public static inline function divMod( dividend : Int64, divisor : Int64 ) : { quotient : Int64, modulus : Int64 } return { quotient: dividend / divisor, modulus: dividend % divisor }; private inline function toString() : String return '$this'; public static function parseString( sParam : String ) : Int64 { return Int64Helper.parseString( sParam ); } public static function fromFloat( f : Float ) : Int64 { return Int64Helper.fromFloat( f ); } @:op(-A) public static function neg( x : Int64 ) : Int64 return -x.val; @:op(++A) private inline function preIncrement() : Int64 return ++this; @:op(A++) private inline function postIncrement() : Int64 return this++; @:op(--A) private inline function preDecrement() : Int64 return --this; @:op(A--) private inline function postDecrement() : Int64 return this--; @:op(A + B) public static inline function add( a : Int64, b : Int64 ) : Int64 return a.val + b.val; @:op(A + B) @:commutative private static inline function addInt( a : Int64, b : Int ) : Int64 return a.val + b; @:op(A - B) public static inline function sub( a : Int64, b : Int64 ) : Int64 return a.val - b.val; @:op(A - B) private static inline function subInt( a : Int64, b : Int ) : Int64 return a.val - b; @:op(A - B) private static inline function intSub( a : Int, b : Int64 ) : Int64 return a - b.val; @:op(A * B) public static inline function mul( a : Int64, b : Int64 ) : Int64 return a.val * b.val; @:op(A * B) @:commutative private static inline function mulInt( a : Int64, b : Int ) : Int64 return a.val * b; @:op(A / B) public static inline function div( a : Int64, b : Int64 ) : Int64 return a.val / b.val; @:op(A / B) private static inline function divInt( a : Int64, b : Int ) : Int64 return a.val / b; @:op(A / B) private static inline function intDiv( a : Int, b : Int64 ) : Int64 return a / b.val; @:op(A % B) public static inline function mod( a : Int64, b : Int64 ) : Int64 return a.val % b.val; @:op(A % B) private static inline function modInt( a : Int64, b : Int ) : Int64 return a.val % b; @:op(A % B) private static inline function intMod( a : Int, b : Int64 ) : Int64 return a % b.val; @:op(A == B) public static inline function eq( a : Int64, b : Int64 ) : Bool return a.val == b.val; @:op(A == B) @:commutative private static inline function eqInt( a : Int64, b : Int ) : Bool return a.val == b; @:op(A != B) public static inline function neq( a : Int64, b : Int64 ) : Bool return a.val != b.val; @:op(A != B) @:commutative private static inline function neqInt( a : Int64, b : Int ) : Bool return a.val != b; @:op(A < B) private static inline function lt( a : Int64, b : Int64 ) : Bool return a.val < b.val; @:op(A < B) private static inline function ltInt( a : Int64, b : Int ) : Bool return a.val < b; @:op(A < B) private static inline function intLt( a : Int, b : Int64 ) : Bool return a < b.val; @:op(A <= B) private static inline function lte( a : Int64, b : Int64 ) : Bool return a.val <= b.val; @:op(A <= B) private static inline function lteInt( a : Int64, b : Int ) : Bool return a.val <= b; @:op(A <= B) private static inline function intLte( a : Int, b : Int64 ) : Bool return a <= b.val; @:op(A > B) private static inline function gt( a : Int64, b : Int64 ) : Bool return a.val > b.val; @:op(A > B) private static inline function gtInt( a : Int64, b : Int ) : Bool return a.val > b; @:op(A > B) private static inline function intGt( a : Int, b : Int64 ) : Bool return a > b.val; @:op(A >= B) private static inline function gte( a : Int64, b : Int64 ) : Bool return a.val >= b.val; @:op(A >= B) private static inline function gteInt( a : Int64, b : Int ) : Bool return a.val >= b; @:op(A >= B) private static inline function intGte( a : Int, b : Int64 ) : Bool return a >= b.val; @:op(~A) private static inline function complement( x : Int64 ) : Int64 return ~x.val; @:op(A & B) public static inline function and( a : Int64, b : Int64 ) : Int64 return a.val & b.val; @:op(A | B) public static inline function or( a : Int64, b : Int64 ) : Int64 return a.val | b.val; @:op(A ^ B) public static inline function xor( a : Int64, b : Int64 ) : Int64 return a.val ^ b.val; @:op(A << B) public static inline function shl( a : Int64, b : Int ) : Int64 return a.val << b; @:op(A >> B) public static inline function shr( a : Int64, b : Int ) : Int64 return a.val >> b; @:op(A >>> B) public static inline function ushr( a : Int64, b : Int ) : Int64 return cast ( (a.val : cs.StdTypes.UInt64) >> b ); } haxe_3.4.4.orig/std/cs/_std/haxe/Resource.hx0000664000175000017500000000466413166552354020633 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; @:coreApi class Resource { @:keep static var content : Array; static var paths : Map; @:keep static function getPaths():Map { if (paths != null) return paths; var p = new Map(); var all = cs.Lib.toNativeType(haxe.Resource).Assembly.GetManifestResourceNames(); for (i in 0...all.Length) { var path = all[i]; var name = path.substr(path.indexOf("Resources.") + 10); p.set(name, path); } return paths = p; } public static inline function listNames() : Array { return content.copy(); } @:access(haxe.io.Path.escape) public static function getString( name : String ) : String { name = haxe.io.Path.escape(name, true); var path = getPaths().get(name); if (path == null) return null; var str = cs.Lib.toNativeType(haxe.Resource).Assembly.GetManifestResourceStream(path); if (str != null) return new cs.io.NativeInput(str).readAll().toString(); return null; } @:access(haxe.io.Path.escape) public static function getBytes( name : String ) : haxe.io.Bytes { name = haxe.io.Path.escape(name, true); var path = getPaths().get(name); if (path == null) return null; var str = cs.Lib.toNativeType(haxe.Resource).Assembly.GetManifestResourceStream(path); if (str != null) return new cs.io.NativeInput(str).readAll(); return null; } } haxe_3.4.4.orig/std/cs/_std/haxe/ds/IntMap.hx0000664000175000017500000002600013166552354020626 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; import cs.NativeArray; /* * This IntMap implementation is based on khash (https://github.com/attractivechaos/klib/blob/master/khash.h) * Copyright goes to Attractive Chaos and his contributors * * Thanks also to Jonas Malaco Filho for his Haxe-written IntMap code inspired by Python tables. * (https://jonasmalaco.com/fossil/test/jonas-haxe/artifact/887b53126e237d6c68951111d594033403889304) */ @:coreApi class IntMap implements haxe.Constraints.IMap { private static inline var HASH_UPPER = 0.7; private var flags:NativeArray; private var _keys:NativeArray; private var vals:NativeArray; private var nBuckets:Int; private var size:Int; private var nOccupied:Int; private var upperBound:Int; #if !no_map_cache private var cachedKey:Int; private var cachedIndex:Int; #end public function new() : Void { #if !no_map_cache cachedIndex = -1; #end } public function set( key : Int, value : T ) : Void { var x:Int; if (nOccupied >= upperBound) { if (nBuckets > (size << 1)) resize(nBuckets - 1); //clear "deleted" elements else resize(nBuckets + 1); } var flags = flags, _keys = _keys; { var mask = nBuckets - 1; var site = x = nBuckets; var k = hash(key); var i = k & mask; var delKey = -1; //for speed up if (flagIsEmpty(flags, i)) { x = i; } else { var inc = getInc(k, mask); var last = i; while (! (flagIsEmpty(flags, i) || _keys[i] == key) ) { if (delKey == -1 && flagIsDel(flags,i)) delKey = i; i = (i + inc) & mask; #if DEBUG_HASHTBL if (i == last) { throw "assert"; } #end } if (flagIsEmpty(flags,i) && delKey != -1) x = delKey; else x = i; } } if (flagIsEmpty(flags, x)) { _keys[x] = key; vals[x] = value; setIsBothFalse(flags, x); size++; nOccupied++; } else if (flagIsDel(flags, x)) { _keys[x] = key; vals[x] = value; setIsBothFalse(flags, x); size++; } else { assert(_keys[x] == key); vals[x] = value; } } @:final private function lookup( key : Int ) : Int { if (nBuckets != 0) { var flags = flags, _keys = _keys; var mask = nBuckets - 1, k = hash(key); var i = k & mask; var inc = getInc(k, mask); /* inc == 1 for linear probing */ var last = i; while (!flagIsEmpty(flags, i) && (flagIsDel(flags, i) || _keys[i] != key)) { i = (i + inc) & mask; if (i == last) return -1; } return isEither(flags, i) ? -1 : i; } return -1; } public function get( key : Int ) : Null { var idx = -1; #if !no_map_cache if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } #end idx = lookup(key); if (idx != -1) { #if !no_map_cache cachedKey = key; cachedIndex = idx; #end return vals[idx]; } return null; } private function getDefault( key : Int, def : T ) : T { var idx = -1; #if !no_map_cache if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } #end idx = lookup(key); if (idx != -1) { #if !no_map_cache cachedKey = key; cachedIndex = idx; #end return vals[idx]; } return def; } public function exists( key : Int ) : Bool { var idx = -1; #if !no_map_cache if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return true; } #end idx = lookup(key); if (idx != -1) { #if !no_map_cache cachedKey = key; cachedIndex = idx; #end return true; } return false; } public function remove( key : Int ) : Bool { var idx = -1; #if !no_map_cache if (! (cachedKey == key && ( (idx = cachedIndex) != -1 ))) #end { idx = lookup(key); } if (idx == -1) { return false; } else { #if !no_map_cache if (cachedKey == key) cachedIndex = -1; #end if (!isEither(flags, idx)) { setIsDelTrue(flags, idx); --size; vals[idx] = null; _keys[idx] = 0; } return true; } } @:final private function resize(newNBuckets:Int) : Void { //This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. var newFlags = null; var j = 1; { newNBuckets = roundUp(newNBuckets); if (newNBuckets < 4) newNBuckets = 4; if (size >= (newNBuckets * HASH_UPPER + 0.5)) /* requested size is too small */ { j = 0; } else { /* hash table size to be changed (shrink or expand); rehash */ var nfSize = flagsSize(newNBuckets); newFlags = new NativeArray( nfSize ); for (i in 0...nfSize) newFlags[i] = 0xaaaaaaaa; if (nBuckets < newNBuckets) //expand { var k = new NativeArray(newNBuckets); if (_keys != null) arrayCopy(_keys, 0, k, 0, nBuckets); _keys = k; var v = new NativeArray(newNBuckets); if (vals != null) arrayCopy(vals, 0, v, 0, nBuckets); vals = v; } //otherwise shrink } } if (j != 0) { //rehashing is required #if !no_map_cache //resetting cache cachedKey = 0; cachedIndex = -1; #end j = -1; var nBuckets = nBuckets, _keys = _keys, vals = vals, flags = flags; var newMask = newNBuckets - 1; while (++j < nBuckets) { if (!isEither(flags, j)) { var key = _keys[j]; var val = vals[j]; setIsDelTrue(flags, j); while (true) /* kick-out process; sort of like in Cuckoo hashing */ { var k = hash(key); var inc = getInc(k, newMask); var i = k & newMask; while (!flagIsEmpty(newFlags, i)) i = (i + inc) & newMask; setIsEmptyFalse(newFlags, i); if (i < nBuckets && !isEither(flags, i)) /* kick out the existing element */ { { var tmp = _keys[i]; _keys[i] = key; key = tmp; } { var tmp = vals[i]; vals[i] = val; val = tmp; } setIsDelTrue(flags, i); /* mark it as deleted in the old hash table */ } else { /* write the element and jump out of the loop */ _keys[i] = key; vals[i] = val; break; } } } } if (nBuckets > newNBuckets) /* shrink the hash table */ { { var k = new NativeArray(newNBuckets); arrayCopy(_keys, 0, k, 0, newNBuckets); this._keys = k; } { var v = new NativeArray(newNBuckets); arrayCopy(vals, 0, v, 0, newNBuckets); this.vals = v; } } this.flags = newFlags; this.nBuckets = newNBuckets; this.nOccupied = size; this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5); } } /** Returns an iterator of all keys in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public inline function keys() : Iterator { return new IntMapKeyIterator(this); } /** Returns an iterator of all values in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public inline function iterator() : Iterator { return new IntMapValueIterator(this); } /** Returns an displayable representation of the hashtable content. **/ public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(i); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } private static inline function assert(x:Bool):Void { #if debug if (!x) throw "assert failed"; #end } private static inline function defaultK():Int return 0; private static inline function arrayCopy(sourceArray:cs.system.Array, sourceIndex:Int, destinationArray:cs.system.Array, destinationIndex:Int, length:Int):Void cs.system.Array.Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length); private static inline function getInc(k:Int, mask:Int):Int return (((k) >> 3 ^ (k) << 3) | 1) & (mask); private static inline function hash(i:Int):Int return i; private static inline function flagIsEmpty(flag:NativeArray, i:Int):Bool return ( (flag[i >> 4] >>> ((i & 0xf) << 1)) & 2 ) != 0; private static inline function flagIsDel(flag:NativeArray, i:Int):Bool return ((flag[i >> 4] >>> ((i & 0xf) << 1)) & 1) != 0; private static inline function isEither(flag:NativeArray, i:Int):Bool return ((flag[i >> 4] >>> ((i & 0xf) << 1)) & 3) != 0; private static inline function setIsDelFalse(flag:NativeArray, i:Int):Void flag[i >> 4] &= ~(1 << ((i & 0xf) << 1)); private static inline function setIsEmptyFalse(flag:NativeArray, i:Int):Void flag[i >> 4] &= ~(2 << ((i & 0xf) << 1)); private static inline function setIsBothFalse(flag:NativeArray, i:Int):Void flag[i >> 4] &= ~(3 << ((i & 0xf) << 1)); private static inline function setIsDelTrue(flag:NativeArray, i:Int):Void flag[i >> 4] |= 1 << ((i & 0xf) << 1); private static inline function roundUp(x:Int):Int { --x; x |= (x) >>> 1; x |= (x) >>> 2; x |= (x) >>> 4; x |= (x) >>> 8; x |= (x) >>> 16; return ++x; } private static inline function flagsSize(m:Int):Int return ((m) < 16? 1 : (m) >> 4); } @:access(haxe.ds.IntMap) @:final private class IntMapKeyIterator { var m:IntMap; var i:Int; var len:Int; public function new(m:IntMap) { this.i = 0; this.m = m; this.len = m.nBuckets; } public function hasNext():Bool { for (j in i...len) { if (!IntMap.isEither(m.flags, j)) { i = j; return true; } } return false; } public function next():Int { var ret = m._keys[i]; #if !no_map_cache m.cachedIndex = i; m.cachedKey = ret; #end i++; return ret; } } @:access(haxe.ds.IntMap) @:final private class IntMapValueIterator { var m:IntMap; var i:Int; var len:Int; public function new(m:IntMap) { this.i = 0; this.m = m; this.len = m.nBuckets; } public function hasNext():Bool { for (j in i...len) { if (!IntMap.isEither(m.flags, j)) { i = j; return true; } } return false; } public inline function next():T { return m.vals[i++]; } } haxe_3.4.4.orig/std/cs/_std/haxe/ds/ObjectMap.hx0000664000175000017500000002672413166552354021317 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; import cs.NativeArray; @:coreApi class ObjectMap implements haxe.Constraints.IMap { @:extern private static inline var HASH_UPPER = 0.77; @:extern private static inline var FLAG_EMPTY = 0; @:extern private static inline var FLAG_DEL = 1; /** * This is the most important structure here and the reason why it's so fast. * It's an array of all the hashes contained in the table. These hashes cannot be 0 nor 1, * which stand for "empty" and "deleted" states. * * The lookup algorithm will keep looking until a 0 or the key wanted is found; * The insertion algorithm will do the same but will also break when FLAG_DEL is found; */ private var hashes:NativeArray; private var _keys:NativeArray; private var vals:NativeArray; private var nBuckets:Int; private var size:Int; private var nOccupied:Int; private var upperBound:Int; #if !no_map_cache private var cachedKey:K; private var cachedIndex:Int; #end #if DEBUG_HASHTBL private var totalProbes:Int; private var probeTimes:Int; private var sameHash:Int; private var maxProbe:Int; #end public function new() : Void { #if !no_map_cache cachedIndex = -1; #end } public function set( key : K, value : V ) : Void { var x:Int, k:Int; if (nOccupied >= upperBound) { if (nBuckets > (size << 1)) resize(nBuckets - 1); //clear "deleted" elements else resize(nBuckets + 2); } var hashes = hashes, keys = _keys, hashes = hashes; { var mask = (nBuckets == 0) ? 0 : nBuckets - 1; var site = x = nBuckets; k = hash(key); var i = k & mask, nProbes = 0; var delKey = -1; //for speed up if (isEmpty(hashes[i])) { x = i; } else { //var inc = getInc(k, mask); var last = i, flag; while(! (isEmpty(flag = hashes[i]) || (flag == k && _keys[i] == key)) ) { if (isDel(flag) && delKey == -1) delKey = i; i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } if (isEmpty(flag) && delKey != -1) x = delKey; else x = i; } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end } var flag = hashes[x]; if (isEmpty(flag)) { keys[x] = key; vals[x] = value; hashes[x] = k; size++; nOccupied++; } else if (isDel(flag)) { keys[x] = key; vals[x] = value; hashes[x] = k; size++; } else { assert(_keys[x] == key); vals[x] = value; } #if !no_map_cache cachedIndex = x; cachedKey = key; #end } @:final private function lookup( key : K ) : Int { if (nBuckets != 0) { var hashes = hashes, keys = _keys; var mask = nBuckets - 1, hash = hash(key), k = hash, nProbes = 0; var i = k & mask; var last = i, flag; //var inc = getInc(k, mask); while (!isEmpty(flag = hashes[i]) && (isDel(flag) || flag != k || keys[i] != key)) { i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end return isEither(flag) ? -1 : i; } return -1; } @:final @:private function resize(newNBuckets:Int) : Void { //This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. var newHash = null; var j = 1; { newNBuckets = roundUp(newNBuckets); if (newNBuckets < 4) newNBuckets = 4; if (size >= (newNBuckets * HASH_UPPER + 0.5)) /* requested size is too small */ { j = 0; } else { /* hash table size to be changed (shrink or expand); rehash */ var nfSize = newNBuckets; newHash = new NativeArray( nfSize ); if (nBuckets < newNBuckets) //expand { var k = new NativeArray(newNBuckets); if (_keys != null) arrayCopy(_keys, 0, k, 0, nBuckets); _keys = k; var v = new NativeArray(newNBuckets); if (vals != null) arrayCopy(vals, 0, v, 0, nBuckets); vals = v; } //otherwise shrink } } if (j != 0) { //rehashing is required #if !no_map_cache //resetting cache cachedKey = null; cachedIndex = -1; #end j = -1; var nBuckets = nBuckets, _keys = _keys, vals = vals, hashes = hashes; var newMask = newNBuckets - 1; while (++j < nBuckets) { var k; if (!isEither(k = hashes[j])) { var key = _keys[j]; var val = vals[j]; hashes[j] = FLAG_DEL; while (true) /* kick-out process; sort of like in Cuckoo hashing */ { var nProbes = 0; //var inc = getInc(k, newMask); var i = k & newMask; while (!isEmpty(newHash[i])) i = (i + ++nProbes) & newMask; newHash[i] = k; if (i < nBuckets && !isEither(k = hashes[i])) /* kick out the existing element */ { { var tmp = _keys[i]; _keys[i] = key; key = tmp; } { var tmp = vals[i]; vals[i] = val; val = tmp; } hashes[i] = FLAG_DEL; /* mark it as deleted in the old hash table */ } else { /* write the element and jump out of the loop */ _keys[i] = key; vals[i] = val; break; } } } } if (nBuckets > newNBuckets) /* shrink the hash table */ { { var k = new NativeArray(newNBuckets); arrayCopy(_keys, 0, k, 0, newNBuckets); this._keys = k; } { var v = new NativeArray(newNBuckets); arrayCopy(vals, 0, v, 0, newNBuckets); this.vals = v; } } this.hashes = newHash; this.nBuckets = newNBuckets; this.nOccupied = size; this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5); } } public function get( key : K ) : Null { var idx = -1; #if !no_map_cache if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } #end idx = lookup(key); if (idx != -1) { #if !no_map_cache cachedKey = key; cachedIndex = idx; #end return vals[idx]; } return null; } private function getDefault( key : K, def : V ) : V { var idx = -1; #if !no_map_cache if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } #end idx = lookup(key); if (idx != -1) { #if !no_map_cache cachedKey = key; cachedIndex = idx; #end return vals[idx]; } return def; } public function exists( key : K ) : Bool { var idx = -1; #if !no_map_cache if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return true; } #end idx = lookup(key); if (idx != -1) { #if !no_map_cache cachedKey = key; cachedIndex = idx; #end return true; } return false; } public function remove( key : K ) : Bool { var idx = -1; #if !no_map_cache if (! (cachedKey == key && ( (idx = cachedIndex) != -1 ))) #end { idx = lookup(key); } if (idx == -1) { return false; } else { #if !no_map_cache if (cachedKey == key) cachedIndex = -1; #end hashes[idx] = FLAG_DEL; _keys[idx] = null; vals[idx] = null; --size; return true; } } /** Returns an iterator of all keys in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function keys() : Iterator { return new ObjectMapKeyIterator(this); } /** Returns an iterator of all values in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function iterator() : Iterator { return new ObjectMapValueIterator(this); } /** Returns an displayable representation of the hashtable content. **/ public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(Std.string(i)); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } @:extern private static inline function roundUp(x:Int):Int { --x; x |= (x) >>> 1; x |= (x) >>> 2; x |= (x) >>> 4; x |= (x) >>> 8; x |= (x) >>> 16; return ++x; } @:extern private static inline function getInc(k:Int, mask:Int):Int //return 1 for linear probing return (((k) >> 3 ^ (k) << 3) | 1) & (mask); @:extern private static inline function isEither(v:HashType):Bool return (v & 0xFFFFFFFE) == 0; @:extern private static inline function isEmpty(v:HashType):Bool return v == FLAG_EMPTY; @:extern private static inline function isDel(v:HashType):Bool return v == FLAG_DEL; //guarantee: Whatever this function is, it will never return 0 nor 1 @:extern private static inline function hash(s:K):HashType { var k:Int = untyped s.GetHashCode(); //k *= 357913941; //k ^= k << 24; //k += ~357913941; //k ^= k >> 31; //k ^= k << 31; k = (k+0x7ed55d16) + (k<<12); k = (k^0xc761c23c) ^ (k>>19); k = (k+0x165667b1) + (k<<5); k = (k+0xd3a2646c) ^ (k<<9); k = (k+0xfd7046c5) + (k<<3); k = (k^0xb55a4f09) ^ (k>>16); var ret = k; if (isEither(ret)) { if (ret == 0) ret = 2; else ret = 0xFFFFFFFF; } return ret; } @:extern private static inline function arrayCopy(sourceArray:cs.system.Array, sourceIndex:Int, destinationArray:cs.system.Array, destinationIndex:Int, length:Int):Void cs.system.Array.Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length); @:extern private static inline function assert(x:Bool):Void { #if DEBUG_HASHTBL if (!x) throw "assert failed"; #end } } @:access(haxe.ds.ObjectMap) @:final private class ObjectMapKeyIterator { var m:ObjectMap; var i:Int; var len:Int; public function new(m:ObjectMap) { this.i = 0; this.m = m; this.len = m.nBuckets; } public function hasNext():Bool { for (j in i...len) { if (!ObjectMap.isEither(m.hashes[j])) { i = j; return true; } } return false; } public function next() : T { var ret = m._keys[i]; #if !no_map_cache m.cachedIndex = i; m.cachedKey = ret; #end i = i + 1; return ret; } } @:access(haxe.ds.ObjectMap) @:final private class ObjectMapValueIterator { var m:ObjectMap; var i:Int; var len:Int; public function new(m:ObjectMap) { this.i = 0; this.m = m; this.len = m.nBuckets; } public function hasNext() : Bool { for (j in i...len) { if (!ObjectMap.isEither(m.hashes[j])) { i = j; return true; } } return false; } public inline function next():T { var ret = m.vals[i]; i = i + 1; return ret; } } private typedef HashType = Int; haxe_3.4.4.orig/std/cs/_std/haxe/ds/StringMap.hx0000664000175000017500000002663713166552354021362 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; import cs.NativeArray; @:coreApi class StringMap implements haxe.Constraints.IMap { @:extern private static inline var HASH_UPPER = 0.77; @:extern private static inline var FLAG_EMPTY = 0; @:extern private static inline var FLAG_DEL = 1; /** * This is the most important structure here and the reason why it's so fast. * It's an array of all the hashes contained in the table. These hashes cannot be 0 nor 1, * which stand for "empty" and "deleted" states. * * The lookup algorithm will keep looking until a 0 or the key wanted is found; * The insertion algorithm will do the same but will also break when FLAG_DEL is found; */ private var hashes:NativeArray; private var _keys:NativeArray; private var vals:NativeArray; private var nBuckets:Int; private var size:Int; private var nOccupied:Int; private var upperBound:Int; #if !no_map_cache private var cachedKey:String; private var cachedIndex:Int; #end #if DEBUG_HASHTBL private var totalProbes:Int; private var probeTimes:Int; private var sameHash:Int; private var maxProbe:Int; #end public function new() : Void { #if !no_map_cache cachedIndex = -1; #end } public function set( key : String, value : T ) : Void { var x:Int, k:Int; if (nOccupied >= upperBound) { if (nBuckets > (size << 1)) resize(nBuckets - 1); //clear "deleted" elements else resize(nBuckets + 2); } var hashes = hashes, keys = _keys, hashes = hashes; { var mask = (nBuckets == 0) ? 0 : nBuckets - 1; var site = x = nBuckets; k = hash(key); var i = k & mask, nProbes = 0; var delKey = -1; //for speed up if (isEmpty(hashes[i])) { x = i; } else { var last = i, flag; while(! (isEmpty(flag = hashes[i]) || (flag == k && _keys[i] == key)) ) { if (isDel(flag) && delKey == -1) delKey = i; i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } if (isEmpty(flag) && delKey != -1) x = delKey; else x = i; } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end } var flag = hashes[x]; if (isEmpty(flag)) { keys[x] = key; vals[x] = value; hashes[x] = k; size++; nOccupied++; } else if (isDel(flag)) { keys[x] = key; vals[x] = value; hashes[x] = k; size++; } else { assert(_keys[x] == key); vals[x] = value; } #if !no_map_cache cachedIndex = x; cachedKey = key; #end } @:final private function lookup( key : String ) : Int { if (nBuckets != 0) { var hashes = hashes, keys = _keys; var mask = nBuckets - 1, hash = hash(key), k = hash, nProbes = 0; var i = k & mask; var last = i, flag; //var inc = getInc(k, mask); while (!isEmpty(flag = hashes[i]) && (isDel(flag) || flag != k || keys[i] != key)) { i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end return isEither(flag) ? -1 : i; } return -1; } @:final @:private function resize(newNBuckets:Int) : Void { //This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. var newHash = null; var j = 1; { newNBuckets = roundUp(newNBuckets); if (newNBuckets < 4) newNBuckets = 4; if (size >= (newNBuckets * HASH_UPPER + 0.5)) /* requested size is too small */ { j = 0; } else { /* hash table size to be changed (shrink or expand); rehash */ var nfSize = newNBuckets; newHash = new NativeArray( nfSize ); if (nBuckets < newNBuckets) //expand { var k = new NativeArray(newNBuckets); if (_keys != null) arrayCopy(_keys, 0, k, 0, nBuckets); _keys = k; var v = new NativeArray(newNBuckets); if (vals != null) arrayCopy(vals, 0, v, 0, nBuckets); vals = v; } //otherwise shrink } } if (j != 0) { //rehashing is required //resetting cache #if !no_map_cache cachedKey = null; cachedIndex = -1; #end j = -1; var nBuckets = nBuckets, _keys = _keys, vals = vals, hashes = hashes; var newMask = newNBuckets - 1; while (++j < nBuckets) { var k; if (!isEither(k = hashes[j])) { var key = _keys[j]; var val = vals[j]; hashes[j] = FLAG_DEL; while (true) /* kick-out process; sort of like in Cuckoo hashing */ { var nProbes = 0; //var inc = getInc(k, newMask); var i = k & newMask; while (!isEmpty(newHash[i])) i = (i + ++nProbes) & newMask; newHash[i] = k; if (i < nBuckets && !isEither(k = hashes[i])) /* kick out the existing element */ { { var tmp = _keys[i]; _keys[i] = key; key = tmp; } { var tmp = vals[i]; vals[i] = val; val = tmp; } hashes[i] = FLAG_DEL; /* mark it as deleted in the old hash table */ } else { /* write the element and jump out of the loop */ _keys[i] = key; vals[i] = val; break; } } } } if (nBuckets > newNBuckets) /* shrink the hash table */ { { var k = new NativeArray(newNBuckets); arrayCopy(_keys, 0, k, 0, newNBuckets); this._keys = k; } { var v = new NativeArray(newNBuckets); arrayCopy(vals, 0, v, 0, newNBuckets); this.vals = v; } } this.hashes = newHash; this.nBuckets = newNBuckets; this.nOccupied = size; this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5); } } public function get( key : String ) : Null { var idx = -1; #if !no_map_cache if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } #end idx = lookup(key); if (idx != -1) { #if !no_map_cache cachedKey = key; cachedIndex = idx; #end return vals[idx]; } return null; } private function getDefault( key : String, def : T ) : T { var idx = -1; #if !no_map_cache if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } #end idx = lookup(key); if (idx != -1) { #if !no_map_cache cachedKey = key; cachedIndex = idx; #end return vals[idx]; } return def; } public function exists( key : String ) : Bool { var idx = -1; #if !no_map_cache if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return true; } #end idx = lookup(key); if (idx != -1) { #if !no_map_cache cachedKey = key; cachedIndex = idx; #end return true; } return false; } public function remove( key : String ) : Bool { var idx = -1; #if !no_map_cache if (! (cachedKey == key && ( (idx = cachedIndex) != -1 ))) #end { idx = lookup(key); } if (idx == -1) { return false; } else { #if !no_map_cache if (cachedKey == key) cachedIndex = -1; #end hashes[idx] = FLAG_DEL; _keys[idx] = null; vals[idx] = null; --size; return true; } } /** Returns an iterator of all keys in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public inline function keys() : Iterator { return new StringMapKeyIterator(this); } /** Returns an iterator of all values in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public inline function iterator() : Iterator { return new StringMapValueIterator(this); } /** Returns an displayable representation of the hashtable content. **/ public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(i); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } @:extern private static inline function roundUp(x:Int):Int { --x; x |= (x) >>> 1; x |= (x) >>> 2; x |= (x) >>> 4; x |= (x) >>> 8; x |= (x) >>> 16; return ++x; } @:extern private static inline function getInc(k:Int, mask:Int):Int //return 1 for linear probing return (((k) >> 3 ^ (k) << 3) | 1) & (mask); @:extern private static inline function isEither(v:HashType):Bool return (v & 0xFFFFFFFE) == 0; @:extern private static inline function isEmpty(v:HashType):Bool return v == FLAG_EMPTY; @:extern private static inline function isDel(v:HashType):Bool return v == FLAG_DEL; //guarantee: Whatever this function is, it will never return 0 nor 1 @:extern private static inline function hash(s:String):HashType { var k:Int = untyped s.GetHashCode(); //k *= 357913941; //k ^= k << 24; //k += ~357913941; //k ^= k >> 31; //k ^= k << 31; k = (k+0x7ed55d16) + (k<<12); k = (k^0xc761c23c) ^ (k>>19); k = (k+0x165667b1) + (k<<5); k = (k+0xd3a2646c) ^ (k<<9); k = (k+0xfd7046c5) + (k<<3); k = (k^0xb55a4f09) ^ (k>>16); var ret = k; if (isEither(ret)) { if (ret == 0) ret = 2; else ret = 0xFFFFFFFF; } return ret; } @:extern private static inline function arrayCopy(sourceArray:cs.system.Array, sourceIndex:Int, destinationArray:cs.system.Array, destinationIndex:Int, length:Int):Void cs.system.Array.Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length); @:extern private static inline function assert(x:Bool):Void { #if DEBUG_HASHTBL if (!x) throw "assert failed"; #end } } private typedef HashType = Int; @:final @:access(haxe.ds.StringMap) private class StringMapKeyIterator { var m:StringMap; var i:Int; var len:Int; public function new(m:StringMap) { this.m = m; this.i = 0; this.len = m.nBuckets; } public function hasNext():Bool { for (j in i...len) { if (!StringMap.isEither(m.hashes[j])) { i = j; return true; } } return false; } public function next():String { var ret = m._keys[i]; #if !no_map_cache m.cachedIndex = i; m.cachedKey = ret; #end i++; return ret; } } @:final @:access(haxe.ds.StringMap) private class StringMapValueIterator { var m:StringMap; var i:Int; var len:Int; public function new(m:StringMap) { this.m = m; this.i = 0; this.len = m.nBuckets; } public function hasNext():Bool { for (j in i...len) { if (!StringMap.isEither(m.hashes[j])) { i = j; return true; } } return false; } public inline function next():T { return m.vals[i++]; } } haxe_3.4.4.orig/std/cs/_std/haxe/ds/WeakMap.hx20000664000175000017500000003127713166552354021061 0ustar andyandy00000000000000/* * 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. */ package haxe.ds; import cs.NativeArray; import cs.system.WeakReference; // This implementation works by lazily evaluating the weak references, and only cleaning them up when needed. @:coreApi class WeakMap implements haxe.Constraints.IMap { @:extern private static inline var HASH_UPPER = 0.77; @:extern private static inline var FLAG_EMPTY = 0; @:extern private static inline var FLAG_DEL = 1; /** * This is the most important structure here and the reason why it's so fast. * It's an array of all the hashes contained in the table. These hashes cannot be 0 nor 1, * which stand for "empty" and "deleted" states. * * The lookup algorithm will keep looking until a 0 or the key wanted is found; * The insertion algorithm will do the same but will also break when FLAG_DEL is found; */ private var hashes:NativeArray; private var entries:NativeArray>; private var nBuckets:Int; private var size:Int; private var nOccupied:Int; private var upperBound:Int; private var cachedEntry:Entry; private var cachedIndex:Int; #if DEBUG_HASHTBL private var totalProbes:Int; private var probeTimes:Int; private var sameHash:Int; private var maxProbe:Int; #end public function new() : Void { cachedIndex = -1; } @:final private function checkSize():Void { //iterate over the hashes and remove dead references var size = size, entries = entries, hashes = hashes; if (entries == null) return; for (i in 0...entries.Length) { var e = entries[i]; if (e != null && e.Target == null) { --size; hashes[i] = FLAG_DEL; entries[i] = null; } } this.size = size; } public function set( key : K, value : V ) : Void { var x:Int, k:Int; if (nOccupied >= upperBound) { if (nBuckets > (size << 1)) resize(nBuckets - 1); //clear "deleted" elements else resize(nBuckets + 2); } k = hash(key); var hashes = hashes, entries = entries; { var mask = (nBuckets == 0) ? 0 : nBuckets - 1; var site = x = nBuckets; var i = k & mask, nProbes = 0; //for speed up var delKey = -1; if (isEmpty(hashes[i])) { x = i; } else { //var inc = getInc(k, mask); var last = i, flag; while(! (isEmpty(flag = hashes[i]) || (flag == k && entries[i].keyEquals(key) )) ) { if (delKey == -1 && isDel(flag)) delKey = i; var entry = entries[i]; if (entry.Target == null) { hashes[i] = FLAG_DEL; entries[i] = null; --size; if (delKey == -1) delKey = i; } i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } if (isEmpty(flag) && delKey != -1) x = delKey; else x = i; } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end } var flag = hashes[x], entry = new Entry(key,value,k); if (isEmpty(flag)) { entries[x] = entry; hashes[x] = k; size++; nOccupied++; } else if (isDel(flag)) { entries[x] = entry; hashes[x] = k; size++; } else { assert(entries[x].keyEquals(key)); entries[x] = entry; } cachedIndex = x; cachedEntry = entry; } @:final private function lookup( key : K ) : Int { if (nBuckets != 0) { var hashes = hashes, entries = entries; var mask = nBuckets - 1, hash = hash(key), k = hash, nProbes = 0; var i = k & mask; var last = i, flag; //var inc = getInc(k, mask); while (!isEmpty(flag = hashes[i]) && (isDel(flag) || flag != k || !entries[i].keyEquals(key))) { if (!isDel(flag)) { var entry = entries[i]; if (entry.Target == null) { entries[i] = null; hashes[i] = FLAG_DEL; --size; } } i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end return isEither(flag) ? -1 : i; } return -1; } @:final @:private function resize(newNBuckets:Int) : Void { //This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. var newHash = null; var j = 1; { newNBuckets = roundUp(newNBuckets); if (newNBuckets < 4) newNBuckets = 4; if (size >= (newNBuckets * HASH_UPPER + 0.5)) /* requested size is too small */ { j = 0; } else { /* hash table size to be changed (shrink or expand); rehash */ var nfSize = newNBuckets; newHash = new NativeArray( nfSize ); if (nBuckets < newNBuckets) //expand { var e = new NativeArray(newNBuckets); if (entries != null) arrayCopy(entries, 0, e, 0, nBuckets); entries = e; } //otherwise shrink } } if (j != 0) { //rehashing is required //resetting cache cachedEntry = null; cachedIndex = -1; j = -1; var nBuckets = nBuckets, entries = entries, hashes = hashes; var newMask = newNBuckets - 1; while (++j < nBuckets) { var k; if (!isEither(k = hashes[j])) { var entry = entries[j]; if (entry.Target != null) { hashes[j] = FLAG_DEL; while (true) /* kick-out process; sort of like in Cuckoo hashing */ { var nProbes = 0; var i = k & newMask; while (!isEmpty(newHash[i])) i = (i + ++nProbes) & newMask; newHash[i] = k; if (i < nBuckets && !isEither(k = hashes[i])) /* kick out the existing element */ { { var tmp = entries[i]; entries[i] = entry; entry = tmp; } hashes[i] = FLAG_DEL; /* mark it as deleted in the old hash table */ } else { /* write the element and jump out of the loop */ entries[i] = entry; break; } } } } } if (nBuckets > newNBuckets) /* shrink the hash table */ { { var e = new NativeArray(newNBuckets); arrayCopy(entries, 0, e, 0, newNBuckets); this.entries = e; } } this.hashes = newHash; this.nBuckets = newNBuckets; this.nOccupied = size; this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5); } } public function get( key : K ) : Null { var idx = -1; if (cachedEntry != null && cachedEntry.keyEquals(key) && ( (idx = cachedIndex) != -1 )) { return cachedEntry.value; } idx = lookup(key); if (idx != -1) { var entry = entries[idx]; cachedEntry = entry; cachedIndex = idx; return entry.value; } return null; } private function getDefault( key : K, def : V ) : V { var idx = -1; if (cachedEntry != null && cachedEntry.keyEquals(key) && ( (idx = cachedIndex) != -1 )) { return cachedEntry.value; } idx = lookup(key); if (idx != -1) { var entry = entries[idx]; cachedEntry = entry; cachedIndex = idx; return entry.value; } return def; } public function exists( key : K ) : Bool { var idx = -1; if (cachedEntry != null && cachedEntry.keyEquals(key) && ( (idx = cachedIndex) != -1 )) { return true; } idx = lookup(key); if (idx != -1) { var entry = entries[idx]; cachedEntry = entry; cachedIndex = idx; return true; } return false; } public function remove( key : K ) : Bool { var idx = -1; if ( !(cachedEntry != null && cachedEntry.keyEquals(key) && ( (idx = cachedIndex) != -1 )) ) { idx = lookup(key); } if (idx == -1) { return false; } else { if (cachedEntry != null && cachedEntry.keyEquals(key)) { cachedIndex = -1; cachedEntry = null; } hashes[idx] = FLAG_DEL; entries[idx] = null; --size; return true; } } /** Returns an iterator of all keys in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function keys() : Iterator { var i = 0; var len = nBuckets; var lastKey = null; //keep a strong reference to the key while iterating, so it can't be collected while iterating return { hasNext: function() { for (j in i...len) { if (!isEither(hashes[j])) { var entry = entries[j]; var last = entry.Target; if (last != null) { lastKey = last; cachedIndex = i; cachedEntry = entry; i = j; return true; } else { --size; hashes[j] = FLAG_DEL; entries[j] = null; } } } return false; }, next: function() { i = i + 1; return lastKey; } }; } /** Returns an iterator of all values in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function iterator() : Iterator { var i = 0; var len = nBuckets; var lastKey = null; //keep a strong reference to the key while iterating, so it can't be collected while iterating return { hasNext: function() { for (j in i...len) { if (!isEither(hashes[j])) { var entry = entries[j]; var last = entry.Target; if (last != null) { lastKey = last; cachedIndex = i; cachedEntry = entry; i = j; return true; } else { --size; hashes[j] = FLAG_DEL; entries[j] = null; } } } return false; }, next: function() { var ret = entries[i].value; i = i + 1; return ret; } }; } /** Returns an displayable representation of the hashtable content. **/ public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(Std.string(i)); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } @:extern private static inline function roundUp(x:Int):Int { --x; x |= (x) >>> 1; x |= (x) >>> 2; x |= (x) >>> 4; x |= (x) >>> 8; x |= (x) >>> 16; return ++x; } @:extern private static inline function getInc(k:Int, mask:Int):Int //return 1 for linear probing return (((k) >> 3 ^ (k) << 3) | 1) & (mask); @:extern private static inline function isEither(v:HashType):Bool return (v & 0xFFFFFFFE) == 0; @:extern private static inline function isEmpty(v:HashType):Bool return v == FLAG_EMPTY; @:extern private static inline function isDel(v:HashType):Bool return v == FLAG_DEL; //guarantee: Whatever this function is, it will never return 0 nor 1 @:extern private static inline function hash(s:Dynamic):HashType { var k:Int = untyped s.GetHashCode(); //k *= 357913941; //k ^= k << 24; //k += ~357913941; //k ^= k >> 31; //k ^= k << 31; // k = (k+0x7ed55d16) + (k<<12); // k = (k^0xc761c23c) ^ (k>>19); // k = (k+0x165667b1) + (k<<5); // k = (k+0xd3a2646c) ^ (k<<9); // k = (k+0xfd7046c5) + (k<<3); // k = (k^0xb55a4f09) ^ (k>>16); var ret = k; if (isEither(ret)) { if (ret == 0) ret = 2; else ret = 0xFFFFFFFF; } return ret; } @:extern private static inline function arrayCopy(sourceArray:cs.system.Array, sourceIndex:Int, destinationArray:cs.system.Array, destinationIndex:Int, length:Int):Void cs.system.Array.Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length); @:extern private static inline function assert(x:Bool):Void { #if DEBUG_HASHTBL if (!x) throw "assert failed"; #end } } private class Entry extends WeakReference { public var value:V; public var hash(default, null):Int; public function new(key:K, value:V, hash:Int) { super(key, false); this.value = value; this.hash = hash; } public function reuse(key,hash) { this.Target = key; this.hash = hash; } @:final inline public function keyEquals(k:K):Bool { return k != null && untyped k.Equals(Target); } } private typedef HashType = Int; haxe_3.4.4.orig/std/cs/_std/sys/FileSystem.hx0000664000175000017500000001010013166552354020777 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys; import cs.system.io.DirectoryInfo; import cs.system.io.File; import cs.system.io.Directory; import cs.system.io.FileInfo; @:coreApi class FileSystem { public static function exists( path : String ) : Bool { return (File.Exists(path) || Directory.Exists(path)); } public static function rename( path : String, newPath : String ) : Void { Directory.Move(path, newPath); } @:access(Date.fromNative) public static function stat( path : String ) : FileStat { if (File.Exists(path)) { var fi = new FileInfo(path); return { gid: 0, //C# doesn't let you get this info uid: 0, //same atime: Date.fromNative(fi.LastAccessTime), mtime: Date.fromNative(fi.LastWriteTime), ctime: Date.fromNative(fi.CreationTime), size: cast(fi.Length, Int), //TODO: maybe change to Int64 for Haxe 3? dev: 0, //FIXME: not sure what that is ino: 0, //FIXME: not sure what that is nlink: 0, //FIXME: not sure what that is rdev: 0, //FIXME: not sure what that is mode: 0 //FIXME: not sure what that is }; } else if (Directory.Exists(path)) { var fi = new DirectoryInfo(path); return { gid: 0, //C# doesn't let you get this info uid: 0, //same atime: Date.fromNative(fi.LastAccessTime), mtime: Date.fromNative(fi.LastWriteTime), ctime: Date.fromNative(fi.CreationTime), size: 0, //TODO: maybe change to Int64 for Haxe 3? dev: 0, //FIXME: not sure what that is ino: 0, //FIXME: not sure what that is nlink: 0, //FIXME: not sure what that is rdev: 0, //FIXME: not sure what that is mode: 0 //FIXME: not sure what that is }; } else { throw "Path '" + path + "' doesn't exist"; } } public static function fullPath( relPath : String ) : String { return new FileInfo(relPath).FullName; } public static function absolutePath ( relPath : String ) : String { if (haxe.io.Path.isAbsolute(relPath)) return relPath; return haxe.io.Path.join([Sys.getCwd(), relPath]); } public static function isDirectory( path : String ) : Bool { var isdir = Directory.Exists(path); if (isdir != File.Exists(path)) return isdir; throw "Path '" + path + "' doesn't exist"; } public static function createDirectory( path : String ) : Void { Directory.CreateDirectory(path); } public static function deleteFile( path : String ) : Void { if (!File.Exists(path)) throw "Path '" + path + "' doesn't exist"; File.Delete(path); } public static function deleteDirectory( path : String ) : Void { if (!Directory.Exists(path)) throw "Path '" + path + "' doesn't exist"; Directory.Delete(path); } public static function readDirectory( path : String ) : Array { var ret = Directory.GetFileSystemEntries(path); if (ret.Length > 0) { var fst = ret[0]; var sep = "/"; if (fst.lastIndexOf(sep) < fst.lastIndexOf("\\")) sep = "\\"; for (i in 0...ret.Length) { var path = ret[i]; ret[i] = path.substr(path.lastIndexOf(sep) + 1); } } return cs.Lib.array( ret ); } } haxe_3.4.4.orig/std/cs/_std/sys/db/Sqlite.hx0000664000175000017500000000451613166552354020557 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.db; class Sqlite { static var type:Class; /** Opens a new SQLite connection on the specified path. Note that you will need a SQLite ADO.NET Provider (see http://www.mono-project.com/docs/database-access/providers/sqlite/). Also note that this will try to open an assembly named `Mono.Data.Sqlite` if it wasn't loaded yet. **/ public static function open(file:String):sys.db.Connection { var cnxString = 'Data Source=$file'; if (type == null) { var t = null; var assemblies = cs.system.AppDomain.CurrentDomain.GetAssemblies(); for (i in 0...assemblies.Length) { var a = assemblies[i]; t = a.GetType('Mono.Data.Sqlite.SqliteConnection'); if (t == null) t = a.GetType('System.Data.SQLite.SQLiteConnection'); if (t != null) { break; } } if (t == null) { var asm = cs.system.reflection.Assembly.Load('Mono.Data.Sqlite'); t = asm.GetType('Mono.Data.Sqlite.SqliteConnection'); } if (t != null) type = cast cs.Lib.fromNativeType(t); } if (type == null) { throw "No ADO.NET SQLite provider was found!"; } var ret = Type.createInstance(type,[cnxString]); ret.Open(); return cs.db.AdoNet.create(ret,'SQLite'); } } haxe_3.4.4.orig/std/cs/_std/sys/io/File.hx0000664000175000017500000000556613166552354020225 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; @:coreApi class File { public static function getContent( path : String ) : String { var f = read(path, false); var ret = f.readAll().toString(); f.close(); return ret; } public static function saveContent( path : String, content : String ) : Void { var f = write(path, false); f.writeString(content); f.close(); } public static function getBytes( path : String ) : haxe.io.Bytes { var f = read(path, true); var ret = f.readAll(); f.close(); return ret; } public static function saveBytes( path : String, bytes : haxe.io.Bytes ) : Void { var f = write(path, true); f.writeBytes(bytes, 0, bytes.length); f.close(); } public static function read( path : String, binary : Bool = true ) : FileInput { #if std_buffer //standardize 4kb buffers var stream = new cs.system.io.FileStream(path, Open, Read, ReadWrite, 4096); #else var stream = new cs.system.io.FileStream(path, Open, Read, ReadWrite); #end return new FileInput(stream); } public static function write( path : String, binary : Bool = true ) : FileOutput { #if std_buffer //standardize 4kb buffers var stream = new cs.system.io.FileStream(path, Create, Write, ReadWrite, 4096); #else var stream = new cs.system.io.FileStream(path, Create, Write, ReadWrite); #end return new FileOutput(stream); } public static function append( path : String, binary : Bool = true ) : FileOutput { #if std_buffer //standardize 4kb buffers var stream = new cs.system.io.FileStream(path, Append, Write, ReadWrite, 4096); #else var stream = new cs.system.io.FileStream(path, Append, Write, ReadWrite); #end return new FileOutput(stream); } public static function copy( srcPath : String, dstPath : String ) : Void { cs.system.io.File.Copy(srcPath, dstPath); } } haxe_3.4.4.orig/std/cs/_std/sys/io/FileInput.hx0000664000175000017500000000235713166552354021240 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; class FileInput extends cs.io.NativeInput { public function new(stream:cs.system.io.FileStream) { super(stream); } } haxe_3.4.4.orig/std/cs/_std/sys/io/FileOutput.hx0000664000175000017500000000236113166552354021434 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; class FileOutput extends cs.io.NativeOutput { public function new(stream:cs.system.io.FileStream) { super(stream); } } haxe_3.4.4.orig/std/cs/_std/sys/io/Process.hx0000664000175000017500000000776613166552354020770 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; import haxe.io.BytesInput; import cs.system.io.StreamReader; import cs.system.io.StreamWriter; import cs.system.diagnostics.Process as NativeProcess; import cs.system.diagnostics.ProcessStartInfo as NativeStartInfo; @:coreApi class Process { public var stdout(default,null) : haxe.io.Input; public var stderr(default,null) : haxe.io.Input; public var stdin(default, null) : haxe.io.Output; private var native:NativeProcess; public function new( cmd : String, ?args : Array ) : Void { this.native = createNativeProcess(cmd, args); native.Start(); this.stdout = new cs.io.NativeInput(native.StandardOutput.BaseStream); this.stderr = new cs.io.NativeInput(native.StandardError.BaseStream); this.stdin = new cs.io.NativeOutput(native.StandardInput.BaseStream); } @:allow(Sys) private static function createNativeProcess( cmd : String, ?args : Array ) : NativeProcess { var native = new NativeProcess(); native.StartInfo.CreateNoWindow = true; native.StartInfo.RedirectStandardError = native.StartInfo.RedirectStandardInput = native.StartInfo.RedirectStandardOutput = true; if (args != null) { // mono 4.2.1 on Windows doesn't support relative path correctly if (cmd.indexOf("/") != -1 || cmd.indexOf("\\") != -1) cmd = sys.FileSystem.fullPath(cmd); native.StartInfo.FileName = cmd; native.StartInfo.UseShellExecute = false; native.StartInfo.Arguments = buildArgumentsString(args); } else { switch (Sys.systemName()) { case "Windows": native.StartInfo.FileName = switch (Sys.getEnv("COMSPEC")) { case null: "cmd.exe"; case comspec: comspec; } native.StartInfo.Arguments = '/C "$cmd"'; case _: native.StartInfo.FileName = "/bin/sh"; native.StartInfo.Arguments = buildArgumentsString(["-c", cmd]); } native.StartInfo.UseShellExecute = false; } return native; } private static function buildArgumentsString(args:Array):String { return switch (Sys.systemName()) { case "Windows": [ for (a in args) StringTools.quoteWinArg(a, false) ].join(" "); case _: // mono uses a slightly different quoting/escaping rule... // https://bugzilla.xamarin.com/show_bug.cgi?id=19296 [ for (arg in args) { var b = new StringBuf(); b.add('"'); for (i in 0...arg.length) { var c = arg.charCodeAt(i); switch (c) { case '"'.code | '\\'.code: b.addChar('\\'.code); case _: //pass } b.addChar(c); } b.add('"'); b.toString(); } ].join(" "); } } public function getPid() : Int { return native.Id; } public function exitCode( block : Bool = true ) : Null { if( block == false && !native.HasExited ) return null; native.WaitForExit(); return native.ExitCode; } public function close() : Void { native.Close(); } public function kill() : Void { native.Kill(); } } haxe_3.4.4.orig/std/cs/_std/sys/net/Host.hx0000664000175000017500000000523313166552354020431 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.net; import cs.system.Array; import cs.system.net.Dns; import cs.system.net.IPAddress; import cs.system.net.IPHostEntry; import cs.system.net.sockets.AddressFamily; import haxe.io.Bytes; import haxe.io.BytesInput; /** A given IP host name. **/ @:coreapi class Host { public var hostEntry(default, null) : IPHostEntry; public var ipAddress(default, null) : IPAddress; /** The provided host string. **/ var host(default,null) : String; /** The actual IP corresponding to the host. **/ public var ip(get, null) : Int; private function get_ip() : Int { return new BytesInput(Bytes.ofData( ipAddress.GetAddressBytes() )).readInt32(); } /** Creates a new Host : the name can be an IP in the form "127.0.0.1" or an host name such as "google.com", in which case the corresponding IP address is resolved using DNS. An exception occur if the host name could not be found. **/ public function new( name : String ) : Void { host = name; hostEntry = Dns.GetHostEntry(name); for (i in 0...hostEntry.AddressList.Length) { if (hostEntry.AddressList[i].AddressFamily == InterNetwork) { ipAddress = hostEntry.AddressList[i]; break; } } } /** Returns the IP representation of the host **/ public function toString() : String { return ipAddress.ToString(); } /** Perform a reverse-DNS query to resolve a host name from an IP. **/ public function reverse() : String { return hostEntry.HostName; } /** Returns the local computer host name **/ static public function localhost() : String { return Dns.GetHostName(); } } haxe_3.4.4.orig/std/cs/_std/sys/net/Socket.hx0000664000175000017500000001646613166552354020756 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.net; import cs.system.net.IPEndPoint; import cs.system.net.sockets.AddressFamily; import cs.system.net.sockets.NetworkStream; import cs.system.net.sockets.ProtocolType; import cs.system.net.sockets.SocketFlags; import cs.system.net.sockets.SocketShutdown; import cs.system.net.sockets.SocketType; import cs.system.threading.Thread; import haxe.io.Bytes; import haxe.io.Error; import haxe.io.Input; import haxe.io.Output; /** A TCP socket class : allow you to both connect to a given server and exchange messages or start your own server and wait for connections. **/ @:coreapi class Socket { private var sock : cs.system.net.sockets.Socket = null; /** The stream on which you can read available data. By default the stream is blocking until the requested data is available, use `setBlocking(false)` or `setTimeout` to prevent infinite waiting. **/ public var input(default,null) : haxe.io.Input; /** The stream on which you can send data. Please note that in case the output buffer you will block while writing the data, use `setBlocking(false)` or `setTimeout` to prevent that. **/ public var output(default,null) : haxe.io.Output; /** A custom value that can be associated with the socket. Can be used to retrieve your custom infos after a `select`. ***/ public var custom : Dynamic; /** Creates a new unconnected socket. **/ public function new() : Void { sock = new cs.system.net.sockets.Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); sock.Blocking = true; } /** Closes the socket : make sure to properly close all your sockets or you will crash when you run out of file descriptors. **/ public function close() : Void { sock.Close(); input = null; output = null; } /** Read the whole data available on the socket. **/ public function read() : String { return input.readAll().toString(); } /** Write the whole data to the socket output. **/ public function write( content : String ) : Void { output.writeString( content ); } /** Connect to the given server host/port. Throw an exception in case we couldn't successfully connect. **/ public function connect( host : Host, port : Int ) : Void { sock.Connect( host.ipAddress, port ); if (sock.Connected) { this.output = new cs.io.NativeOutput( new NetworkStream(sock) ); this.input = new cs.io.NativeInput( new NetworkStream(sock) ); } else { throw "Connection failed."; } } /** Allow the socket to listen for incoming questions. The parameter tells how many pending connections we can have until they get refused. Use `accept()` to accept incoming connections. **/ public function listen( connections : Int ) : Void { sock.Listen( connections ); } /** Shutdown the socket, either for reading or writing. **/ public function shutdown( read : Bool, write : Bool ) : Void { if ( read && write ) { sock.Shutdown( SocketShutdown.Both ); input = null; output = null; } else if ( read ) { sock.Shutdown( SocketShutdown.Receive ); input = null; } else if ( write ) { sock.Shutdown( SocketShutdown.Send ); output = null; } } /** Bind the socket to the given host/port so it can afterwards listen for connections there. **/ public function bind( host : Host, port : Int ) : Void { sock = new cs.system.net.sockets.Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); sock.Bind( new IPEndPoint(host.ipAddress, port) ); } /** Accept a new connected client. This will return a connected socket on which you can read/write some data. **/ public function accept() : Socket { var r = new Socket(); r.sock = sock.Accept(); r.output = new cs.io.NativeOutput( new NetworkStream(r.sock) ); r.input = new cs.io.NativeInput( new NetworkStream(r.sock) ); return r; } /** Return the information about the other side of a connected socket. **/ public function peer() : { host : Host, port : Int } { var remoteIP = cast(sock.RemoteEndPoint, IPEndPoint); return { host: new Host(remoteIP.Address.ToString()), port: remoteIP.Port }; } /** Return the information about our side of a connected socket. **/ public function host() : { host : Host, port : Int } { var localIP = cast(sock.LocalEndPoint, IPEndPoint); return { host: new Host(localIP.Address.ToString()), port: localIP.Port }; } /** Gives a timeout after which blocking socket operations (such as reading and writing) will abort and throw an exception. **/ public function setTimeout( timeout : Float ) : Void { sock.ReceiveTimeout = sock.SendTimeout = Math.round(timeout * 1000); } /** Block until some data is available for read on the socket. **/ public function waitForRead() : Void { var end = Date.now().getTime() + ((sock.ReceiveTimeout <= 0) ? Math.POSITIVE_INFINITY : sock.ReceiveTimeout); while ( sock.Available == 0 && Date.now().getTime() < end) { Thread.Sleep(5); } } /** Change the blocking mode of the socket. A blocking socket is the default behavior. A non-blocking socket will abort blocking operations immediately by throwing a haxe.io.Error.Blocking value. **/ public function setBlocking( b : Bool ) : Void { sock.Blocking = b; } /** Allows the socket to immediately send the data when written to its output : this will cause less ping but might increase the number of packets / data size, especially when doing a lot of small writes. **/ public function setFastSend( b : Bool ) : Void { sock.NoDelay = b; } /** Wait until one of the sockets groups is ready for the given operation : * `read` contains sockets on which we want to wait for available data to be read, * `write` contains sockets on which we want to wait until we are allowed to write some data to their output buffers, * `others` contains sockets on which we want to wait for exceptional conditions. * `select` will block until one of the condition is met, in which case it will return the sockets for which the condition was true. In case a `timeout` (in seconds) is specified, select might wait at worse until the timeout expires. **/ static public function select(read : Array, write : Array, others : Array, ?timeout : Float) : { read: Array,write: Array,others: Array } { throw "Not implemented yet."; return null; } } haxe_3.4.4.orig/std/cs/db/AdoNet.hx0000664000175000017500000002153513166552354016721 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.db; import sys.db.*; import cs.system.data.*; class AdoNet { public static function create(cnx:IDbConnection, dbName:String):Connection { return new AdoConnection(cnx,dbName); } } private class AdoConnection implements Connection { private static var ids = 0; private var id:Int; private var cnx:IDbConnection; //escape handling private var escapeRegex:EReg; private var escapes:Array; private var name:String; private var command:IDbCommand; private var transaction:IDbTransaction; public function new(cnx,name:String) { this.id = cs.system.threading.Interlocked.Increment(ids); this.cnx = cnx; this.name = name; this.escapes = []; this.command = cnx.CreateCommand(); this.escapeRegex = ~/@HX_ESCAPE(\d+)_(\d+)/; } public function close() : Void { cnx.Close(); } public function escape(s:String):String { var param = command.CreateParameter(); var name = "@HX_ESCAPE" + id + "_" +escapes.push(param) + ""; param.ParameterName = name; param.Value = s; return name; } public function quote(s:String):String { var param = command.CreateParameter(); var name = "@HX_ESCAPE" + id + "_" +escapes.push(param) + ""; param.ParameterName = name; param.Value = s; return name; } public function addValue(s:StringBuf, v:Dynamic) { if (Std.is(v, Date)) { v = Std.string(v); } else if (Std.is(v, haxe.io.Bytes)) { var bt:haxe.io.Bytes = v; v = bt.getData(); } var param = command.CreateParameter(); var name = "@HX_ESCAPE" + id + "_" +escapes.push(param) + ""; param.ParameterName = name; param.Value = v; s.add(name); } public function lastInsertId():Int { var ret = cnx.CreateCommand(); ret.CommandText = switch(name) { case 'SQLite': 'SELECT last_insert_rowid()'; case _: 'SELECT @@IDENTITY'; } ret.CommandType = CommandType.Text; var r = cast ret.ExecuteScalar(); ret.Dispose(); return r; } public function dbName() : String { return name; } public function startTransaction() : Void { if (this.transaction != null) throw 'Transaction already active'; this.transaction = cnx.BeginTransaction(); } public function commit() : Void { if (this.transaction == null) throw 'No transaction was initiated'; this.transaction.Commit(); } public function rollback() : Void { if (this.transaction == null) throw 'No transaction was initiated'; this.transaction.Rollback(); } private static function getFirstStatement(s:String) { var buf = new StringBuf(); var hasData = false; var chr = 0, i = 0; inline function getch() return chr = StringTools.fastCodeAt(s,i++); while ( !StringTools.isEof(getch()) ) { inline function peek() { var c = StringTools.fastCodeAt(s,i); if (StringTools.isEof(c)) break; return c; } switch(chr) { case ' '.code | '\t'.code | '\n'.code: if (hasData) return buf.toString(); case '-'.code if (peek() == '-'.code): if (hasData) return buf.toString(); while (!StringTools.isEof(getch())) { if (chr == '\n'.code) break; } case '#'.code: if (hasData) return buf.toString(); while (!StringTools.isEof(getch())) { if (chr == '\n'.code) break; } case '/'.code if (peek() == '*'.code): i++; if (hasData) return buf.toString(); while (!StringTools.isEof(getch())) { if (chr == '*'.code && peek() == '/'.code) { i++; break; } } case _: hasData = true; buf.addChar(chr); } } return buf.toString(); } public function request( s : String ) : ResultSet { var newst = new StringBuf(); //cycle through the request string, adding any @HX_ESCAPE reference to the command var ret:ResultSet = null; var r = escapeRegex; var myid = id + "", escapes = escapes, elen = escapes.length; var cmd = this.command; try { while (r.match(s)) { var id = r.matched(1); #if debug if (id != myid) throw "Request quotes are only valid for one single request; They can't be cached."; #end newst.add(r.matchedLeft()); var eid = Std.parseInt(r.matched(2)); #if debug if (eid == null || eid > elen) throw "Invalid request quote ID " + eid; #end cmd.Parameters.Add(escapes[eid - 1]); newst.add(escapes[eid-1].ParameterName); s = r.matchedRight(); } newst.add(s); s = newst.toString(); cmd.CommandText = s; var stmt = getFirstStatement(s).toLowerCase(); if (stmt == 'select') { ret = new AdoResultSet( cmd.ExecuteReader() ); } else { cmd.ExecuteNonQuery(); ret = EmptyResultSet.empty; } if (escapes.length != 0) this.escapes = []; this.id = cs.system.threading.Interlocked.Increment(ids); cmd.Dispose(); this.command = cnx.CreateCommand(); return ret; } catch(e:Dynamic) { if (escapes.length != 0) this.escapes = []; this.id = cs.system.threading.Interlocked.Increment(ids); try { cmd.Dispose(); } catch(e:Dynamic) {} this.command = cnx.CreateCommand(); cs.Lib.rethrow(e); } return null; } } private class AdoResultSet implements ResultSet { public var length(get,null) : Int; public var nfields(get,null) : Int; private var reader:IDataReader; private var didNext:Bool; private var names:Array; private var types:Array>; public function new(reader) { this.reader = reader; this.names = [ for (i in 0...reader.FieldCount) reader.GetName(i) ]; this.types = [ for (i in 0...names.length) cs.Lib.fromNativeType(reader.GetFieldType(i)) ]; } private function get_length() { return reader.Depth; } private function get_nfields() { return names.length; } public function hasNext() : Bool { didNext = true; return reader.Read(); } public function next() : Dynamic { if (!didNext && !hasNext()) return null; didNext = false; var ret = {}, names = names, types = types; for (i in 0...names.length) { var name = names[i], t = types[i], val:Dynamic = null; if (reader.IsDBNull(i)) { val = null; } else if (t == cs.system.Single) { val = reader.GetDouble(i); } else if (t == cs.system.DateTime || t == cs.system.TimeSpan) { var d = reader.GetDateTime(i); if (d != null) val = @:privateAccess Date.fromNative(d); } else if (t == cs.system.DBNull) { val = null; } else if (t == cs.system.Byte) { var v2:cs.StdTypes.UInt8 = reader.GetValue(i); val = cast(v2,Int); } else if (Std.string(t) == 'System.Byte[]') { val = haxe.io.Bytes.ofData(reader.GetValue(i)); } else { val = reader.GetValue(i); } if (Std.is(val,cs.system.DBNull)) val = null; Reflect.setField(ret, name, val); } return ret; } public function results() : List { var l = new List(); while (hasNext()) l.add(next()); return l; } public function getResult( n : Int ) : String { return reader.GetString(n); } public function getIntResult( n : Int ) : Int { return reader.GetInt32(n); } public function getFloatResult( n : Int ) : Float { return reader.GetDouble(n); } public function getFieldsNames() : Null> { return names; } } private class EmptyResultSet implements ResultSet { public static var empty = new EmptyResultSet(); public function new() { } public var length(get,null) : Int; public var nfields(get,null) : Int; private function get_length() { return 0; } private function get_nfields() { return 0; } public function hasNext() : Bool return false; public function next() : Dynamic return null; public function results() : List return new List(); public function getResult( n : Int ) : String return null; public function getIntResult( n : Int ) : Int return 0; public function getFloatResult( n : Int ) : Float return 0; public function getFieldsNames() : Null> return null; } haxe_3.4.4.orig/std/cs/internal/BoxedPointer.hx0000664000175000017500000000250413166552354021373 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.internal; @:unsafe @:keep @:native('haxe.lang.BoxedPointer') @:nativeGen class BoxedPointer { @:readonly public var value(default,null):Pointer; public function new(val) { this.value = val; } } haxe_3.4.4.orig/std/cs/internal/Exceptions.hx0000664000175000017500000000400313166552354021106 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.internal; import cs.system.Exception; @:nativeGen @:keep @:native("haxe.lang.Exceptions") class Exceptions { @:allow(haxe.CallStack) @:meta(System.ThreadStaticAttribute) static var exception:cs.system.Exception; } //should NOT be usable inside Haxe code @:classCode('override public string Message { get { return this.toString(); } }\n\n') @:nativeGen @:keep @:native("haxe.lang.HaxeException") private class HaxeException extends Exception { private var obj:Dynamic; public function new(obj:Dynamic) { super(); if (Std.is(obj, HaxeException)) { var _obj:HaxeException = cast obj; obj = _obj.getObject(); } this.obj = obj; } public function getObject():Dynamic { return obj; } public function toString():String { return Std.string(obj); } public static function wrap(obj:Dynamic):Exception { if (Std.is(obj, Exception)) return obj; return new HaxeException(obj); } } haxe_3.4.4.orig/std/cs/internal/FieldLookup.hx0000664000175000017500000002372513166552354021216 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.internal; @:native('haxe.lang.FieldHashConflict') @:final @:nativeGen @:keep class FieldHashConflict { @:readOnly public var hash(default,never):Int; @:readOnly public var name(default,never):String; public var value:Dynamic; public var next:FieldHashConflict; public function new(hash, name, value, next) { untyped this.hash = hash; untyped this.name = name; this.value = value; this.next = next; } } @:native('haxe.lang.FieldLookup') @:final @:nativeGen @:classCode("#pragma warning disable 628\n") @:keep @:static class FieldLookup { @:protected private static var fieldIds:cs.NativeArray; @:protected private static var fields:cs.NativeArray; @:protected private static var length:Int; static function __init__() { length = fieldIds.Length; } private static function addFields(nids:cs.NativeArray, nfields:cs.NativeArray):Void { // first see if we need to add anything var cids = fieldIds, cfields = fields; var nlen = nids.Length; var clen = length; if (nfields.Length != nlen) throw 'Different fields length: $nlen and ${nfields.Length}'; //TODO optimize var needsChange = false; for (i in nids) { if (findHash(i, cids, clen) < 0) { needsChange = true; break; } } // if we do, lock and merge if (needsChange) { cs.Lib.lock(FieldLookup, { // trace(cs.Lib.array(nids), cs.Lib.array(cids)); var ansIds = new cs.NativeArray(clen + nlen), ansFields = new cs.NativeArray(clen + nlen); var ci = 0, ni = 0, ansi = 0; while (ci < clen && ni < nlen) { if (cids[ci] < nids[ni]) { ansIds[ansi] = cids[ci]; ansFields[ansi] = cfields[ci]; ++ci; } else { ansIds[ansi] = nids[ni]; ansFields[ansi] = nfields[ni]; ++ni; } ++ansi; } if (ci < clen) { cs.system.Array.Copy(cids, ci, ansIds, ansi, clen - ci); cs.system.Array.Copy(cfields, ci, ansFields, ansi, clen - ci); ansi += clen - ci; } if (ni < nlen) { cs.system.Array.Copy(nids, ni, ansIds, ansi, nlen - ni); cs.system.Array.Copy(nfields, ni, ansFields, ansi, nlen - ni); ansi += nlen - ni; } // trace(cs.Lib.array(ansIds)); fieldIds = ansIds; fields = ansFields; length = ansi; }); } } //s cannot be null here private static inline function doHash(s:String):Int { var acc = 0; //alloc_int for (i in 0...s.length) { acc = (( 223 * (acc >> 1) + cast(s[i], Int)) << 1); } return acc >>> 1; //always positive } public static function lookupHash(key:Int):String { //start of binary search algorithm var ids = fieldIds; var min = 0; var max = length; while (min < max) { var mid = min + Std.int((max - min) / 2); var imid = ids[mid]; if (key < imid) { max = mid; } else if (key > imid) { min = mid + 1; } else { return fields[mid]; } } //if not found, it's definitely an error throw "Field not found for hash " + key; } public static function hash(s:String):Int { if (s == null) return 0; var key = doHash(s); //start of binary search algorithm var ids = fieldIds, fld = fields; var min = 0; var max = length; var len = length; while (min < max) { var mid = Std.int(min + (max - min) / 2); //overflow safe var imid = ids[mid]; if (key < imid) { max = mid; } else if (key > imid) { min = mid + 1; } else { var field = fld[mid]; if (field != s) return ~key; //special case return key; } } //if not found, min holds the value where we should insert the key //ensure thread safety: cs.Lib.lock(FieldLookup, { if (len != length) //race condition which will very rarely happen - other thread modified sooner. return hash(s); //since we already own the lock, this second try will always succeed #if erase_generics fieldIds = insertInt(fieldIds, length, min, key); fields = insertString(fields, length, min, s); #else insert(fieldIds, length, min, key); insert(fields, length, min, s); // ids.insert(min, key); // fields.insert(min, s); #end ++length; }); return key; } public static function findHash(hash:Int, hashs:cs.NativeArray, length:Int):Int { var min = 0; var max = length; while (min < max) { var mid = Std.int((max + min) / 2); //overflow safe var imid = hashs[mid]; if (hash < imid) { max = mid; } else if (hash > imid) { min = mid + 1; } else { return mid; } } //if not found, return a negative value of where it should be inserted return ~min; } #if !erase_generics static function remove(a:cs.NativeArray, length:Int, pos:Int) { cs.system.Array.Copy(a, pos + 1, a, pos, length - pos - 1); a[length - 1] = null; } static function insert(a:cs.Ref>, length:Int, pos:Int, x:T) { var capacity = a.Length; if (pos == length) { if (capacity == length) { var newarr = new NativeArray((length << 1) + 1); a.CopyTo(newarr, 0); a = newarr; } } else if (pos == 0) { if (capacity == length) { var newarr = new NativeArray((length << 1) + 1); cs.system.Array.Copy(a, 0, newarr, 1, length); a = newarr; } else { cs.system.Array.Copy(a, 0, a, 1, length); } } else { if (capacity == length) { var newarr = new NativeArray((length << 1) + 1); cs.system.Array.Copy(a, 0, newarr, 0, pos); cs.system.Array.Copy(a, pos, newarr, pos + 1, length - pos); a = newarr; } else { cs.system.Array.Copy(a, pos, a, pos + 1, length - pos); cs.system.Array.Copy(a, 0, a, 0, pos); } } a[pos] = x; } #else static function removeInt(a:cs.NativeArray, length:Int, pos:Int) { cs.system.Array.Copy(a, pos + 1, a, pos, length - pos - 1); a[length - 1] = 0; } static function removeFloat(a:cs.NativeArray, length:Int, pos:Int) { cs.system.Array.Copy(a, pos + 1, a, pos, length - pos - 1); a[length - 1] = 0; } static function removeDynamic(a:cs.NativeArray, length:Int, pos:Int) { cs.system.Array.Copy(a, pos + 1, a, pos, length - pos - 1); a[length - 1] = null; } @:extern static inline function __insert(a:cs.NativeArray, length:Int, pos:Int, x:T):cs.NativeArray { var capacity = a.Length; if (pos == length) { if (capacity == length) { var newarr = new NativeArray((length << 1) + 1); a.CopyTo(newarr, 0); a = newarr; } } else if (pos == 0) { if (capacity == length) { var newarr = new NativeArray((length << 1) + 1); cs.system.Array.Copy(a, 0, newarr, 1, length); a = newarr; } else { cs.system.Array.Copy(a, 0, a, 1, length); } } else { if (capacity == length) { var newarr = new NativeArray((length << 1) + 1); cs.system.Array.Copy(a, 0, newarr, 0, pos); cs.system.Array.Copy(a, pos, newarr, pos + 1, length - pos); a = newarr; } else { cs.system.Array.Copy(a, pos, a, pos + 1, length - pos); cs.system.Array.Copy(a, 0, a, 0, pos); } } a[pos] = x; return a; } static function insertInt(a:cs.NativeArray, length:Int, pos:Int, x:Int):cs.NativeArray return __insert(a, length, pos, x); static function insertFloat(a:cs.NativeArray, length:Int, pos:Int, x:Float):cs.NativeArray return __insert(a, length, pos, x); static function insertDynamic(a:cs.NativeArray, length:Int, pos:Int, x:Dynamic):cs.NativeArray return __insert(a, length, pos, x); static function insertString(a:cs.NativeArray, length:Int, pos:Int, x:Dynamic):cs.NativeArray return __insert(a, length, pos, x); #end static function getHashConflict(head:FieldHashConflict, hash:Int, name:String):FieldHashConflict { while (head != null) { if (head.hash == hash && head.name == name) { return head; } head = head.next; } return null; } static function setHashConflict(head:cs.Ref, hash:Int, name:String, value:Dynamic):Void { var node = head; while (node != null) { if (node.hash == hash && node.name == name) { node.value = value; return; } node = node.next; } head = new FieldHashConflict(hash, name, value, head); } static function deleteHashConflict(head:cs.Ref, hash:Int, name:String):Bool { // no conflicting fields at all if (head == null) { return false; } // list head is conflicting - just point it to the next one if (head.hash == hash && head.name == name) { head = head.next; return true; } // loop through the list, removing node if there's one var prev = head, node = head.next; while (node != null) { if (node.hash == hash && node.name == name) { prev.next = node.next; return true; } node = node.next; } // not found return false; } static function addHashConflictNames(head:FieldHashConflict, arr:Array):Void { while (head != null) { arr.push(head.name); head = head.next; } } } haxe_3.4.4.orig/std/cs/internal/Function.hx0000664000175000017500000000521013166552354020553 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.internal; /** These classes are automatically generated by the compiler. They are only here so there is an option for e.g. defining them as externs if you are compiling in modules (untested). **/ @:keep @:abstract @:nativeGen @:native("haxe.lang.Function") class Function { function new(arity:Int, type:Int) { } } @:keep @:nativeGen @:native("haxe.lang.VarArgsBase") private class VarArgsBase extends Function { public function __hx_invokeDynamic(dynArgs:Array):Dynamic { throw "Abstract implementation"; } } @:keep @:nativeGen @:native('haxe.lang.VarArgsFunction') class VarArgsFunction extends VarArgsBase { private var fun:Array->Dynamic; public function new(fun) { super(-1, -1); this.fun = fun; } override public function __hx_invokeDynamic(dynArgs:Array):Dynamic { return fun(dynArgs); } } @:keep @:nativeGen @:native('haxe.lang.Closure') class Closure extends VarArgsBase { private var obj:Dynamic; private var field:String; private var hash:Int; public function new(obj:Dynamic, field, hash) { super(-1, -1); this.obj = obj; this.field = field; this.hash = hash; } override public function __hx_invokeDynamic(dynArgs:Array):Dynamic { return Runtime.callField(obj, field, hash, dynArgs); } public function Equals(obj:Dynamic):Bool { var c = cs.Lib.as(obj, Closure); if (c == null) return false; return (c.obj == this.obj && c.field == this.field); } public function GetHashCode():Int { return obj.GetHashCode() ^ untyped field.GetHashCode(); } } haxe_3.4.4.orig/std/cs/internal/HxObject.hx0000664000175000017500000001030113166552354020471 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.internal; import cs.system.Type; import haxe.ds.Vector; private typedef StdType = std.Type; @:keep @:native('haxe.lang.HxObject') class HxObject implements IHxObject { } @:keep @:native('haxe.lang.IHxObject') interface IHxObject { } #if core_api_serialize @:meta(System.Serializable) #end @:keep @:native('haxe.lang.DynamicObject') class DynamicObject extends HxObject implements Dynamic { @:skipReflection public function toString():String { var ts = Reflect.field(this, "toString"); if (ts != null) return ts(); var ret = new StringBuf(); ret.add("{"); var first = true; for (f in Reflect.fields(this)) { if( first ) first = false; else ret.add(","); ret.add(" "); ret.add(f); ret.add(" : "); ret.add(Reflect.field(this, f)); } if (!first) ret.add(" "); ret.add("}"); return ret.toString(); } } #if !erase_generics @:keep @:native('haxe.lang.IGenericObject') interface IGenericObject { } @:nativeGen @:keep @:native('haxe.lang.GenericInterface') class GenericInterface extends cs.system.Attribute { @:readOnly public var generic(default,never):cs.system.Type; public function new(generic) { super(); untyped this.generic = generic; } } #end @:keep @:native('haxe.lang.Enum') @:nativeGen #if core_api_serialize @:meta(System.Serializable) #end class HxEnum { @:readOnly private var index(default,never):Int; public function new(index:Int) { untyped this.index = index; } public function getTag():String { return throw 'Not Implemented'; } public function getParams():Array<{}> { return []; } public function toString():String { return getTag(); } } @:keep @:native('haxe.lang.ParamEnum') @:nativeGen private class ParamEnum extends HxEnum { @:readOnly private var params(default,never):Vector; public function new(index:Int, params:Vector) { super(index); untyped this.params = params; } override public function getParams():Array<{}> { return params == null ? [] : cs.Lib.array(cast params.toData()); } override public function toString():String { if (params == null || params.length == 0) return getTag(); var ret = new StringBuf(); ret.add(getTag()); ret.add("("); var first = true; for (p in params) { if (first) first = false; else ret.add(","); ret.add(p); } ret.add(")"); return ret.toString(); } public function Equals(obj:Dynamic) { if (obj == this) //we cannot use == as .Equals ! return true; var obj:ParamEnum = Std.instance(obj, ParamEnum); var ret = obj != null && Std.is(obj, StdType.getClass(this)) && obj.index == this.index; if (!ret) return false; if (obj.params == this.params) return true; var len = 0; if (obj.params == null || this.params == null || (len = this.params.length) != obj.params.length) return false; for (i in 0...len) { if (!StdType.enumEq(obj.params[i], this.params[i])) return false; } return true; } public function GetHashCode():Int { var h:Int = 19; if (params != null) for (p in params) { h = h * 31; if (p != null) untyped h += p.GetHashCode(); } h += index; return h; } } haxe_3.4.4.orig/std/cs/internal/Iterator.hx0000664000175000017500000000262613166552354020567 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.internal; /* TODO (see Gencommon.IteratorsInterfaceModf) @:keep @:native('haxe.lang.Iterator') interface Iterator { public function hasNext():Bool; public function next():T; } @:keep @:native('haxe.lang.Iterable') interface Iterable { public function iterator():Iterator; } */ haxe_3.4.4.orig/std/cs/internal/Null.hx0000664000175000017500000000577613166552354017721 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.internal; @:classCode('//This function is here to be used with Reflection, when the haxe.lang.Null type is known public static haxe.lang.Null _ofDynamic(object obj) { if (obj == null) { return new haxe.lang.Null(default(T), false); } else if (typeof(T).Equals(typeof(double))) { return new haxe.lang.Null((T) (object) haxe.lang.Runtime.toDouble(obj), true); } else if (typeof(T).Equals(typeof(int))) { return new haxe.lang.Null((T) (object) haxe.lang.Runtime.toInt(obj), true); } else { return new haxe.lang.Null((T) obj, true); } } public static implicit operator haxe.lang.Null(T val) { return new haxe.lang.Null(val, true); } public static implicit operator Null(__NoValue__ noValue) { return new haxe.lang.Null(default(T), false); } public sealed class __NoValue__ { private __NoValue__() {} } ') #if core_api_serialize @:meta(System.Serializable) #end @:keep @:struct @:nativeGen @:native("haxe.lang.Null") private class Nullable { @:readOnly public var value(default,never):T; @:readOnly public var hasValue(default,never):Bool; public function new(v:T, hasValue:Bool) { if (hasValue && cs.system.Object.ReferenceEquals(v, null)) { hasValue = false; } untyped this.value = v; untyped this.hasValue = hasValue; } @:functionCode('if (obj == null) { return new haxe.lang.Null(default(D), false); } else if (typeof(D).Equals(typeof(double))) { return new haxe.lang.Null((D) (object) haxe.lang.Runtime.toDouble(obj), true); } else if (typeof(D).Equals(typeof(int))) { return new haxe.lang.Null((D) (object) haxe.lang.Runtime.toInt(obj), true); } else { return new haxe.lang.Null((D) obj, true); }') public static function ofDynamic(obj:Dynamic):Nullable { return null; } public function toDynamic():Dynamic { if (this.hasValue) return value; return null; } } haxe_3.4.4.orig/std/cs/internal/Runtime.hx0000664000175000017500000005765613166552354020436 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.internal; import cs.Lib; import cs.Lib.*; import cs.NativeArray; import cs.StdTypes; import cs.system.Activator; import cs.system.IConvertible; import cs.system.IComparable; import cs.system.reflection.MethodBase; import cs.system.reflection.MethodInfo; import cs.system.reflection.*; import cs.system.Type; import cs.system.Object; /** This class is meant for internal compiler use only. It provides the Haxe runtime compatibility to the host language. **/ @:nativeGen @:native('haxe.lang.Runtime') @:access(String) @:classCode(' public static object getField(haxe.lang.HxObject obj, string field, int fieldHash, bool throwErrors) { if (obj == null && !throwErrors) return null; return obj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false, false); } public static double getField_f(haxe.lang.HxObject obj, string field, int fieldHash, bool throwErrors) { if (obj == null && !throwErrors) return 0.0; return obj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false); } public static object setField(haxe.lang.HxObject obj, string field, int fieldHash, object value) { return obj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false); } public static double setField_f(haxe.lang.HxObject obj, string field, int fieldHash, double value) { return obj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false); } public static object callField(haxe.lang.HxObject obj, string field, int fieldHash, Array args) { return obj.__hx_invokeField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, args); } ') @:keep class Runtime { @:readOnly public static var undefined(default, never):Dynamic = new cs.system.Object(); public static function closure(obj:Dynamic, hash:Int, field:String):Dynamic { return new cs.internal.Function.Closure(obj, field, hash); } public static function eq(v1:Dynamic, v2:Dynamic):Bool { if (Object.ReferenceEquals(v1, v2)) return true; if (Object.ReferenceEquals(v1,null) || Object.ReferenceEquals(v2,null)) return false; var v1c = Lib.as(v1, IConvertible); if (v1c != null) { var v2c = Lib.as(v2, IConvertible); if (v2c == null) { return false; } var t1 = v1c.GetTypeCode(), t2 = v2c.GetTypeCode(); if (t1 == t2) return Object._Equals(v1c,v2c); if (t1 == cs.system.TypeCode.String || t2 == cs.system.TypeCode.String) return false; switch [t1,t2] { case [Decimal, _] | [_, Decimal]: return v1c.ToDecimal(null) == v2c.ToDecimal(null); case [Int64, _] | [_, Int64]: return v1c.ToInt64(null) == v2c.ToInt64(null); case [UInt64 | DateTime, _] | [_, UInt64 | DateTime]: return v1c.ToUInt64(null) == v2c.ToUInt64(null); case [Double | Single, _] | [_, Double | Single]: return v1c.ToDouble(null) == v2c.ToDouble(null); case _: return v1c.ToInt32(null) == v2c.ToInt32(null); } } var v1v = Lib.as(v1, cs.system.ValueType); if (v1v != null) { return v1.Equals(v2); #if !erase_generics } else { var v1t = Lib.as(v1, Type); if (v1t != null) { var v2t = Lib.as(v2, Type); if (v2t != null) return typeEq(v1t, v2t); return false; } #end } return false; } public static function refEq(v1: { }, v2: { } ):Bool { #if !erase_generics if (Std.is(v1, Type)) return typeEq(Lib.as(v1,Type), Lib.as(v2,Type)); #end return Object.ReferenceEquals(v1,v2); } public static function toDouble(obj:Dynamic):Float { return (obj == null) ? .0 : Std.is(obj,Float) ? cast obj : Lib.as(obj,IConvertible).ToDouble(null); } public static function toInt(obj:Dynamic):Int { return (obj == null) ? 0 : Std.is(obj,Int) ? cast obj : Lib.as(obj,IConvertible).ToInt32(null); } #if erase_generics public static function toLong(obj:Dynamic):Int64 { return (obj == null) ? 0 : Std.is(obj,Int64) ? cast obj : Lib.as(obj,IConvertible).ToInt64(null); } #end public static function isInt(obj:Dynamic):Bool { var cv1 = Lib.as(obj, IConvertible); if (cv1 != null) { switch (cv1.GetTypeCode()) { case Double: var d:Float = cast obj; return d >= cs.system.Int32.MinValue && d <= cs.system.Int32.MaxValue && d == ( cast(d,Int) ); case UInt32, Int32: return true; default: return false; } } return false; } public static function isUInt(obj:Dynamic):Bool { var cv1 = Lib.as(obj, IConvertible); if (cv1 != null) { switch (cv1.GetTypeCode()) { case Double: var d:Float = cast obj; return d >= cs.system.UInt32.MinValue && d <= cs.system.UInt32.MaxValue && d == ( cast(d,UInt) ); case UInt32: return true; default: return false; } } return false; } public static function compare(v1:Dynamic, v2:Dynamic):Int { if (Object.ReferenceEquals(v1,v2)) return 0; if (Object.ReferenceEquals(v1,null)) return -1; if (Object.ReferenceEquals(v2,null)) return 1; var cv1 = Lib.as(v1, IConvertible); if (cv1 != null) { var cv2 = Lib.as(v2, IConvertible); if (cv2 == null) { throw new cs.system.ArgumentException("Cannot compare " + getNativeType(v1).ToString() + " and " + getNativeType(v2).ToString()); } switch(cv1.GetTypeCode()) { case cs.system.TypeCode.String: if (cv2.GetTypeCode() != cs.system.TypeCode.String) throw new cs.system.ArgumentException("Cannot compare " + getNativeType(v1).ToString() + " and " + getNativeType(v2).ToString()); var s1 = Lib.as(v1,String); var s2 = Lib.as(v2,String); return String.Compare(s1,s2, cs.system.StringComparison.Ordinal); case cs.system.TypeCode.Double: var d1:Float = cast v1, d2:Float = cv2.ToDouble(null); return (d1 < d2) ? -1 : (d1 > d2) ? 1 : 0; default: var d1d = cv1.ToDouble(null); var d2d = cv2.ToDouble(null); return (d1d < d2d) ? -1 : (d1d > d2d) ? 1 : 0; } } var c1 = Lib.as(v1, IComparable); var c2 = Lib.as(v2, IComparable); if (c1 == null || c2 == null) { throw new cs.system.ArgumentException("Cannot compare " + getNativeType(v1).ToString() + " and " + getNativeType(v2).ToString()); } return c1.CompareTo(c2); } public static function plus(v1:Dynamic, v2:Dynamic):Dynamic { if (Std.is(v1,String) || Std.is(v2,String)) return Std.string(v1) + Std.string(v2); if (v1 == null) { if (v2 == null) return null; v1 = 0; } else if (v2 == null) v2 = 0; var cv1 = Lib.as(v1, IConvertible); if (cv1 != null) { var cv2 = Lib.as(v2, IConvertible); if (cv2 == null) { throw new cs.system.ArgumentException("Cannot dynamically add " + cs.Lib.getNativeType(v1).ToString() + " and " + cs.Lib.getNativeType(v2).ToString()); } return cv1.ToDouble(null) + cv2.ToDouble(null); } throw new cs.system.ArgumentException("Cannot dynamically add " + v1 + " and " + v2); } public static function slowGetField(obj:Dynamic, field:String, throwErrors:Bool):Dynamic { if (obj == null) if (throwErrors) throw new cs.system.NullReferenceException("Cannot access field \'" + field + "\' of null."); else return null; var t = Lib.as(obj, cs.system.Type); var bf = if (t == null) { var s = Lib.as(obj, String); if (s != null) return cs.internal.StringExt.StringRefl.handleGetField(s, field, throwErrors); t = obj.GetType(); new cs.Flags(BindingFlags.Instance) | BindingFlags.Public | BindingFlags.FlattenHierarchy; } else { if (t == Lib.toNativeType(String) && field == "fromCharCode") return new cs.internal.Function.Closure(StringExt, field, 0); obj = null; new cs.Flags(BindingFlags.Static) | BindingFlags.Public; } var f = t.GetField(field, bf); if (f != null) { return unbox(f.GetValue(obj)); } else { var prop = t.GetProperty(field, bf); if (prop == null) { var m = t.GetMember(field, bf); if (m.length == 0 && (field == "__get" || field == "__set")) m = t.GetMember(field == "__get" ? "get_Item" : "set_Item", bf); if (m.Length > 0) { return new cs.internal.Function.Closure(obj != null ? obj : t, field, 0); } else { // COM object handling if (t.IsCOMObject) { try { return t.InvokeMember(field, BindingFlags.GetProperty, null, obj, new cs.NativeArray(0)); } catch (e:cs.system.Exception) { //Closures of COM objects not supported currently } } if (throwErrors) throw "Cannot access field \'" + field + "\'."; else return null; } } return unbox(prop.GetValue(obj, null)); } } public static function slowHasField(obj:Dynamic, field:String):Bool { if (obj == null) return false; var t = Lib.as(obj, cs.system.Type); var bf = if (t == null) { var s = Lib.as(obj, String); if (s != null) return cs.internal.StringExt.StringRefl.handleGetField(s, field, false) != null; t = obj.GetType(); new cs.Flags(BindingFlags.Instance) | BindingFlags.Public | BindingFlags.FlattenHierarchy; } else { if (t == Lib.toNativeType(String)) return field == "fromCharCode"; obj = null; new cs.Flags(BindingFlags.Static) | BindingFlags.Public; } var mi = t.GetMember(field, bf); return mi != null && mi.length > 0; } public static function slowSetField(obj:Dynamic, field:String, value:Dynamic):Dynamic { if (obj == null) throw new cs.system.NullReferenceException("Cannot access field \'" + field + "\' of null."); var t = Lib.as(obj, cs.system.Type); var bf = if (t == null) { t = obj.GetType(); new cs.Flags(BindingFlags.Instance) | BindingFlags.Public | BindingFlags.FlattenHierarchy; } else { obj = null; new cs.Flags(BindingFlags.Static) | BindingFlags.Public; } var f = t.GetField(field, bf); if (f != null) { if (f.FieldType.ToString().StartsWith("haxe.lang.Null")) { value = mkNullable(value, f.FieldType); } if (value != null && Object.ReferenceEquals(Lib.toNativeType(cs.system.Double), Lib.getNativeType(value)) && !Object.ReferenceEquals(t, f.FieldType)) { var ic = Lib.as(value, IConvertible); value = ic.ToType(f.FieldType, null); } f.SetValue(obj, value); return value; } else { var prop = t.GetProperty(field, bf); if (prop == null) { // COM object handling if (t.IsCOMObject) { try { return t.InvokeMember(field, BindingFlags.SetProperty, null, obj, cs.NativeArray.make(value)); } catch (e:cs.system.Exception) { //Closures of COM objects not supported currently } } throw "Field \'" + field + "\' not found for writing from Class " + t; } if (prop.PropertyType.ToString().StartsWith("haxe.lang.Null")) { value = mkNullable(value, prop.PropertyType); } if (Object.ReferenceEquals(Lib.toNativeType(cs.system.Double), Lib.getNativeType(value)) && !Object.ReferenceEquals(t, f.FieldType)) { var ic = Lib.as(value, IConvertible); value = ic.ToType(f.FieldType, null); } prop.SetValue(obj, value, null); return value; } } public static function callMethod(obj:Dynamic, methods:NativeArray, methodLength:Int, args:Array):Dynamic { if (methodLength == 0) throw "No available methods"; var length = args.length; var oargs:NativeArray = new NativeArray(length); var ts:NativeArray = new NativeArray(length); var rates:NativeArray = new NativeArray(methods.Length); for (i in 0...length) { oargs[i] = args[i]; if (args[i] != null) ts[i] = Lib.getNativeType(args[i]); } var last = 0; //first filter by number of parameters and if it is assignable if (methodLength > 1) { for (i in 0...methodLength) { var params = methods[i].GetParameters(); if (params.Length != length) { continue; } else { var fits = true, crate = 0; for (i in 0...params.Length) { var param = params[i].ParameterType; var strParam = param + ""; if (param.IsAssignableFrom(ts[i]) || (ts[i] == null && !param.IsValueType)) { //if it is directly assignable, we'll give it top rate continue; } else if (untyped strParam.StartsWith("haxe.lang.Null") || ( (oargs[i] == null || Std.is(oargs[i], IConvertible) ) && cast(untyped __typeof__(IConvertible), Type).IsAssignableFrom(param) )) { //if it needs conversion, give a penalty. TODO rate penalty crate++; continue; } else if (!param.ContainsGenericParameters) { //generics don't appear as assignable, but may be in the end. no rate there. fits = false; break; } } if (fits) { rates[last] = crate; methods[last++] = methods[i]; } } } methodLength = last; } else if (methodLength == 1 && methods[0].GetParameters().Length != length) { methodLength = 0; } //At this time, we should be left with only one method. //Of course, realistically, we can be left with plenty of methods, if there are lots of variants with IConvertible //But at this time we still aren't rating the best methods //FIXME rate best methods if (methodLength == 0) throw "Invalid calling parameters for method " + methods[0].Name; var best = cs.system.Double.PositiveInfinity; var bestMethod = 0; for(i in 0...methodLength) { if (rates[i] < best) { bestMethod = i; best = rates[i]; } } methods[0] = methods[bestMethod]; var params = methods[0].GetParameters(); for (i in 0...params.Length) { var param = params[i].ParameterType; var strParam = param + "", arg = oargs[i]; if (StringTools.startsWith(strParam, "haxe.lang.Null")) { oargs[i] = mkNullable(arg, param); } else if (cast(untyped __typeof__(IConvertible), Type).IsAssignableFrom(param)) { if (arg == null) { if (param.IsValueType) oargs[i] = Activator.CreateInstance(param); } else if (!cs.Lib.getNativeType(arg).IsAssignableFrom(param)) { oargs[i] = cast(arg, IConvertible).ToType(param, null); } } } if (methods[0].ContainsGenericParameters && Std.is(methods[0], cs.system.reflection.MethodInfo)) { var m:MethodInfo = cast methods[0]; var tgs = m.GetGenericArguments(); for (i in 0...tgs.Length) { tgs[i] = untyped __typeof__(Dynamic); } m = m.MakeGenericMethod(tgs); var retg = m.Invoke(obj, oargs); return cs.internal.Runtime.unbox(retg); } var m = methods[0]; if (obj == null && Std.is(m, cs.system.reflection.ConstructorInfo)) { var ret = cast(m, cs.system.reflection.ConstructorInfo).Invoke(oargs); return unbox(ret); } var ret = m.Invoke(obj, oargs); return unbox(ret); } public static function unbox(dyn:Dynamic):Dynamic { if (dyn != null && untyped (Lib.getNativeType(dyn) + "").StartsWith("haxe.lang.Null")) { return dyn.toDynamic(); } else { return dyn; } } #if !erase_generics @:functionCode(' if (nullableType.ContainsGenericParameters) return haxe.lang.Null.ofDynamic(obj); return nullableType.GetMethod("_ofDynamic").Invoke(null, new object[] { obj }); ') public static function mkNullable(obj:Dynamic, nullableType:Type):Dynamic { return null; } #else public static function mkNullable(obj:Dynamic, nullable:Type):Dynamic { return obj; //do nothing } #end // @:functionCode(' // if (field == "toString") // { // if (args == null) // return obj.ToString(); // field = "ToString"; // } // if (args == null) args = new Array(); // System.Reflection.BindingFlags bf; // System.Type t = obj as System.Type; // if (t == null) // { // string s = obj as string; // if (s != null) // return haxe.lang.StringRefl.handleCallField(s, field, args); // t = obj.GetType(); // bf = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy; // } else { // if (t == typeof(string) && field.Equals("fromCharCode")) // return haxe.lang.StringExt.fromCharCode(toInt(args[0])); // obj = null; // bf = System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public; // } // System.Reflection.MethodInfo[] mis = t.GetMethods(bf); // int last = 0; // for (int i = 0; i < mis.Length; i++) // { // string name = mis[i].Name; // if (name.Equals(field)) // { // mis[last++] = mis[i]; // } // } // if (last == 0 && (field == "__get" || field == "__set")) // { // field = field == "__get" ? "get_Item" : "set_Item"; // for (int i = 0; i < mis.Length; i++) // { // string name = mis[i].Name; // if (name.Equals(field)) // { // mis[last++] = mis[i]; // } // } // } // if (last == 0 && t.IsCOMObject) // { // object[] oargs = new object[arrLen(args)]; // for (int i = 0; i < oargs.Length; i++) // { // oargs[i] = args[i]; // } // return t.InvokeMember(field, System.Reflection.BindingFlags.InvokeMethod, null, obj, oargs); // } // if (last == 0) // { // throw haxe.lang.HaxeException.wrap("Method \'" + field + "\' not found on type " + t); // } // return haxe.lang.Runtime.callMethod(obj, mis, last, args); // ') public static function slowCallField(obj:Dynamic, field:String, args:Array):Dynamic { if (field == "toString" && (args == null || args.length == 0)) { return obj.ToString(); } if (args == null) args = []; var bf:BindingFlags; var t = Lib.as(obj,cs.system.Type); if (t == null) { var s = Lib.as(obj,String); if (s != null) return cs.internal.StringExt.StringRefl.handleCallField(untyped s, untyped field, args); t = untyped obj.GetType(); bf = new Flags(BindingFlags.Instance) | BindingFlags.Public | BindingFlags.FlattenHierarchy; } else { if (t == Lib.toNativeType(String) && field == 'fromCharCode') return cs.internal.StringExt.fromCharCode(toInt(args[0])); obj = null; bf = new Flags(BindingFlags.Static) | BindingFlags.Public; } var mis:NativeArray = untyped t.GetMethods(bf); var last = 0; for (i in 0...mis.Length) { var name = mis[i].Name; if (name == field) mis[last++] = mis[i]; } if (last == 0 && (field == "__get" || field == "__set")) { field = field == "__get" ? "get_Item" : "set_Item"; for (i in 0...mis.Length) { var name = mis[i].Name; if (name == field) { mis[last++] = mis[i]; } } } if (last == 0 && t.IsCOMObject) { var oargs = new NativeArray(args.length); for (i in 0...oargs.Length) { oargs[i] = args[i]; } return t.InvokeMember(field, BindingFlags.InvokeMethod, null, obj, oargs); } if (last == 0) { throw 'Method "$field" not found on type $t'; } return Runtime.callMethod(obj, mis, last, args); } public static function callField(obj:Dynamic, field:String, fieldHash:Int, args:Array):Dynamic { var hxObj = Lib.as(obj, HxObject); if (hxObj != null) return untyped hxObj.__hx_invokeField(field, (fieldHash == 0) ? FieldLookup.hash(field) : fieldHash, args); return slowCallField(obj, field, args); } public static function getField(obj:Dynamic, field:String, fieldHash:Int, throwErrors:Bool):Dynamic { var hxObj = Lib.as(obj, HxObject); if (hxObj != null) return untyped hxObj.__hx_getField(field, (fieldHash == 0) ? FieldLookup.hash(field) : fieldHash, throwErrors, false, false); return slowGetField(obj, field, throwErrors); } public static function getField_f(obj:Dynamic, field:String, fieldHash:Int, throwErrors:Bool):Float { var hxObj = Lib.as(obj, HxObject); if (hxObj != null) return untyped hxObj.__hx_getField_f(field, (fieldHash == 0) ? FieldLookup.hash(field) : fieldHash, throwErrors, false); return toDouble(slowGetField(obj, field, throwErrors)); } public static function setField(obj:Dynamic, field:String, fieldHash:Int, value:Dynamic):Dynamic { var hxObj = Lib.as(obj, HxObject); if (hxObj != null) return untyped hxObj.__hx_setField(field, (fieldHash == 0) ? FieldLookup.hash(field) : fieldHash, value, false); return slowSetField(obj, field, value); } public static function setField_f(obj:Dynamic, field:String, fieldHash:Int, value:Float):Float { var hxObj = Lib.as(obj, HxObject); if (hxObj != null) return untyped hxObj.__hx_setField_f(field, (fieldHash == 0) ? FieldLookup.hash(field) : fieldHash, value, false); return toDouble(slowSetField(obj, field, value)); } public static function toString(obj:Dynamic):String { if (obj == null) return null; if (Std.is(obj, Bool)) if(obj) return "true"; else return "false"; return untyped obj.ToString(); } #if erase_generics inline #end public static function typeEq(t1:Type, t2:Type):Bool { if (t1 == null || t2 == null) return t1 == t2; #if !erase_generics var t1i = t1.IsInterface, t2i = t2.IsInterface; if (t1i != t2i) { if (t1i) { var g = getGenericAttr(t1); if (g != null) t1 = g.generic; } else { var g = getGenericAttr(t2); if (g != null) t2 = g.generic; } } #end if (t1.GetGenericArguments().Length > 0) t1 = t1.GetGenericTypeDefinition(); if (t2.GetGenericArguments().Length > 0) t2 = t2.GetGenericTypeDefinition(); return Object.ReferenceEquals(t1,t2); } #if !erase_generics public static function getGenericAttr(t:cs.system.Type):cs.internal.HxObject.GenericInterface { for (attr in t.GetCustomAttributes(true)) if (Std.is(attr,cs.internal.HxObject.GenericInterface)) return cast attr; return null; } #end #if !erase_generics @:functionCode(' if (obj is To) return (To) obj; else if (obj == null) return default(To); if (typeof(To) == typeof(double)) return (To)(object) toDouble(obj); else if (typeof(To) == typeof(int)) return (To)(object) toInt(obj); else if (typeof(To) == typeof(float)) return (To)(object)(float)toDouble(obj); else if (typeof(To) == typeof(long)) return (To)(object)(long)toDouble(obj); else return (To) obj; ') public static function genericCast(obj:Dynamic):To { return null; } #end @:functionCode(' return (s1 == null ? "null" : s1) + (s2 == null ? "null" : s2); ') public static function concat(s1:String, s2:String):String { return null; } public static function toBool(dyn:Dynamic):Bool { return if (dyn == null) false else untyped __cs__("(bool){0}", dyn); } //TODO: change from genericCast to getConverter, so we don't need to handle extra boxing associated with it /*@:functionCode(' if (typeof(To).TypeHandle == typeof(double).TypeHandle) return (System.Converter) new System.Converter(toDouble); else if (typeof(To).TypeHandle == typeof(double).TypeHandle) return (System.Converter) new System.Converter(toDouble); else return (System.Converter) delegate(object obj) { return (To) obj; }; ') public static function getConverter():cs.system.Converter { return null; }*/ } @:nativeGen @:keep @:native("haxe.lang.EmptyObject") enum EmptyObject { EMPTY; } haxe_3.4.4.orig/std/cs/internal/StringExt.hx0000664000175000017500000001275113166552354020725 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.internal; import cs.internal.Function; private typedef NativeString = cs.system.String; @:keep @:nativeGen @:native("haxe.lang.StringExt") class StringExt { @:readOnly static var empty(default,never) = new NativeString(cast 0,0); public static function charAt(me:NativeString, index:Int):NativeString { if (cast(index,UInt) >= me.Length) return empty; else return new NativeString(me[index], 1); } public static function charCodeAt(me:NativeString, index:Int):Null { if (cast(index,UInt) >= me.Length) return null; else return cast(me[index], Int); } public static function indexOf(me:NativeString, str:String, ?startIndex:Int):Int { var sIndex:Int = startIndex != null ? startIndex : 0; if (sIndex >= me.Length) return -1; return @:privateAccess me.IndexOf(str, sIndex, cs.system.StringComparison.Ordinal); } public static function lastIndexOf(me:NativeString, str:NativeString, ?startIndex:Int):Int { var sIndex:Int = startIndex == null ? me.Length - 1 : startIndex; if (sIndex >= me.Length) sIndex = me.Length - 1; else if (sIndex < 0) return -1; //TestBaseTypes.hx@133 fix if (startIndex != null) { var i = sIndex + 1; while (i --> 0) { var found = true; for (j in 0...str.Length) { if(me[i + j] != str[j]) { found = false; break; } } if (found) return i; } return -1; } else { return me.LastIndexOf(untyped str, sIndex, cs.system.StringComparison.Ordinal); } return -1; } public static function split(me:NativeString, delimiter:NativeString):Array { var native:NativeArray; if (delimiter.Length == 0) { var len = me.Length; native = new NativeArray(len); for (i in 0...len) native[i] = untyped new NativeString(me[i],1); } else { var str = new NativeArray(1); str[0] = cast delimiter; native = me.Split(str, cs.system.StringSplitOptions.None); } return cs.Lib.array(native); } public static function substr(me:NativeString, pos:Int, ?len:Int):String { var meLen = me.Length; var targetLen = meLen; if (len != null) { targetLen = len; if (targetLen == 0 || (pos != 0 && targetLen < 0)) return ""; } if (pos < 0) { pos = meLen + pos; if (pos < 0) pos = 0; } else if (targetLen < 0) { targetLen = meLen + targetLen - pos; } if (pos + targetLen > meLen) { targetLen = meLen - pos; } if (pos < 0 || targetLen <= 0) return ""; return me.Substring(pos, targetLen); } public static function substring(me:NativeString, startIndex:Int, ?endIndex:Int):String { var len = me.Length; var endIdx:Int; if (endIndex == null) endIdx = len; else if ( (endIdx = endIndex) < 0 ) endIdx = 0; else if (endIdx > len) endIdx = len; if (startIndex < 0) startIndex = 0; else if (startIndex > len) startIndex = len; if (startIndex > endIdx) { var tmp = startIndex; startIndex = endIdx; endIdx = tmp; } return me.Substring(startIndex, endIdx - startIndex); } public static function toString(me:NativeString):NativeString { return me; } public static function toLowerCase(me:NativeString):String { return me.ToLowerInvariant(); } public static function toUpperCase(me:NativeString):String { return me.ToUpperInvariant(); } public static function toNativeString(me:NativeString):NativeString { return me; } public static function fromCharCode(code:Int):NativeString { return new NativeString( cast(code,cs.StdTypes.Char16), 1 ); } } @:keep @:nativeGen @:native('haxe.lang.StringRefl') class StringRefl { public static var fields = ["length", "toUpperCase", "toLowerCase", "charAt", "charCodeAt", "indexOf", "lastIndexOf", "split", "substr", "substring"]; public static function handleGetField(str:String, f:String, throwErrors:Bool):Dynamic { switch(f) { case "length": return str.length; case "toUpperCase", "toLowerCase", "charAt", "charCodeAt", "indexOf", "lastIndexOf", "split", "substr", "substring": return new Closure(str, f, 0); default: if (throwErrors) throw "Field not found: '" + f + "' in String"; else return null; } } public static function handleCallField(str:NativeString, f:String, args:Array):Dynamic { var _args:Array = [str]; if (args == null) args = _args; else args = _args.concat(args); return Runtime.slowCallField(StringExt, f, args); } } haxe_3.4.4.orig/std/cs/io/NativeInput.hx0000664000175000017500000000470413166552354020036 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.io; import haxe.Int64; import haxe.io.Bytes; import haxe.io.Eof; import haxe.io.Error; import haxe.io.Input; class NativeInput extends Input { public var canSeek(get,never):Bool; var stream:cs.system.io.Stream; var _eof:Bool; public function new(stream) { this.stream = stream; this._eof = false; if (!stream.CanRead) throw "Write-only stream"; } override public function readByte():Int { var ret = stream.ReadByte(); if (ret == -1) { _eof = true; throw new Eof(); } return ret; } override public function readBytes(s:Bytes, pos:Int, len:Int):Int { if( pos < 0 || len < 0 || pos + len > s.length ) throw Error.OutsideBounds; var ret = stream.Read(s.getData(), pos, len); if (ret == 0) { _eof = true; throw new Eof(); } return ret; } override public function close():Void { stream.Close(); } private inline function get_canSeek():Bool { return stream.CanSeek; } public function seek( p : Int, pos : sys.io.FileSeek ) : Void { _eof = false; var pos = switch(pos) { case SeekBegin: cs.system.io.SeekOrigin.Begin; case SeekCur: cs.system.io.SeekOrigin.Current; case SeekEnd: cs.system.io.SeekOrigin.End; }; stream.Seek(cast(p, Int64), pos); } public function tell() : Int { return cast(stream.Position, Int); } public inline function eof() : Bool { return _eof; } }haxe_3.4.4.orig/std/cs/io/NativeOutput.hx0000664000175000017500000000426613166552354020242 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.io; import haxe.Int64; import haxe.io.Bytes; import haxe.io.Output; class NativeOutput extends Output { var canSeek(get,never):Bool; var stream:cs.system.io.Stream; public function new(stream) { this.stream = stream; if (!stream.CanWrite) throw "Read-only stream"; } override public function writeByte(c:Int):Void { stream.WriteByte(cast c); } override public function close():Void { stream.Close(); } override public function flush():Void { stream.Flush(); } override public function prepare(nbytes:Int):Void { //TODO see if implementation is correct stream.SetLength(haxe.Int64.add(stream.Length, cast(nbytes, Int64))); } private inline function get_canSeek():Bool { return stream.CanSeek; } public function seek( p : Int, pos : sys.io.FileSeek ) : Void { var p = switch(pos) { case SeekBegin: cs.system.io.SeekOrigin.Begin; case SeekCur: cs.system.io.SeekOrigin.Current; case SeekEnd: cs.system.io.SeekOrigin.End; }; stream.Seek(cast(p, Int64), p); } public function tell() : Int { return cast(stream.Position, Int); } } haxe_3.4.4.orig/std/cs/types/Char16.hx0000664000175000017500000000223413166552354017345 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.types; typedef Char16 = cs.StdTypes.Char16; haxe_3.4.4.orig/std/cs/types/Int16.hx0000664000175000017500000000223213166552354017220 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.types; typedef Int16 = cs.StdTypes.Int16; haxe_3.4.4.orig/std/cs/types/Int64.hx0000664000175000017500000000223313166552354017224 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.types; typedef Int64 = cs.StdTypes.Int64; haxe_3.4.4.orig/std/cs/types/Int8.hx0000664000175000017500000000223013166552354017137 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.types; typedef Int8 = cs.StdTypes.Int8; haxe_3.4.4.orig/std/cs/types/UInt16.hx0000664000175000017500000000223413166552354017347 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.types; typedef UInt16 = cs.StdTypes.UInt16; haxe_3.4.4.orig/std/cs/types/UInt64.hx0000664000175000017500000000223413166552354017352 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.types; typedef UInt64 = cs.StdTypes.UInt64; haxe_3.4.4.orig/std/cs/types/UInt8.hx0000664000175000017500000000223213166552354017266 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package cs.types; typedef UInt8 = cs.StdTypes.UInt8; haxe_3.4.4.orig/std/flash/Boot.hx0000664000175000017500000001773413166552354016563 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package flash; #if !as3 @:keep private class RealBoot extends Boot implements Dynamic { #if swc public function new() { super(); } public static function initSwc(mc) { flash.Lib.current = mc; new RealBoot().init(); } #else function new() { super(); if( flash.Lib.current == null ) flash.Lib.current = this; start(); } #end } #end @:dox(hide) @:keep class Boot extends flash.display.MovieClip { static var tf : flash.text.TextField; static var lines : Array; static var lastError : flash.errors.Error; public static var skip_constructor = false; function start() { #if dontWaitStage init(); #else var c = flash.Lib.current; try { untyped if( c == this && c.stage != null && c.stage.align == "" ) c.stage.align = "TOP_LEFT"; } catch( e : Dynamic ) { // security error when loading from different domain } if( c.stage == null ) c.addEventListener(flash.events.Event.ADDED_TO_STAGE, doInitDelay); else if( c.stage.stageWidth == 0 || c.stage.stageHeight == 0 ) untyped __global__["flash.utils.setTimeout"](start,1); else init(); #end } function doInitDelay(_) { flash.Lib.current.removeEventListener(flash.events.Event.ADDED_TO_STAGE, doInitDelay); start(); } #if (swc && swf_protected) public #end function init() { throw "assert"; } static var IN_E = 0; public static function enum_to_string( e : { tag : String, params : Array } ) { if( e.params == null ) return e.tag; var pstr = []; if( IN_E > 15 ) { pstr.push("..."); } else { IN_E++; for( p in e.params ) pstr.push(__string_rec(p, "")); IN_E--; } return e.tag+"("+pstr.join(",")+")"; } public static function __instanceof( v : Dynamic, t : Dynamic ) { try { if( t == Dynamic ) return true; return untyped __is__(v,t); } catch( e : Dynamic ) { } return false; } public static function __clear_trace() { if( tf == null ) return; tf.parent.removeChild(tf); tf = null; lines = null; } public static function __set_trace_color(rgb) { var tf = getTrace(); tf.textColor = rgb; tf.filters = []; } public static function getTrace() { var mc = flash.Lib.current; if( tf == null ) { tf = new flash.text.TextField(); #if flash10_2 var color = 0xFFFFFF, glow = 0; if( mc.stage != null ) { glow = mc.stage.color; color = 0xFFFFFF - glow; } tf.textColor = color; tf.filters = [new flash.filters.GlowFilter(glow, 1, 2, 2, 20)]; #end var format = tf.getTextFormat(); format.font = "_sans"; tf.defaultTextFormat = format; tf.selectable = false; tf.width = if( mc.stage == null ) 800 else mc.stage.stageWidth; tf.autoSize = flash.text.TextFieldAutoSize.LEFT; tf.mouseEnabled = false; } if( mc.stage == null ) mc.addChild(tf); else mc.stage.addChild(tf); // on top return tf; } public static function __trace( v : Dynamic, pos : haxe.PosInfos ) { var tf = getTrace(); var pstr = if( pos == null ) "(null)" else pos.fileName+":"+pos.lineNumber; if( lines == null ) lines = []; var str = pstr +": "+__string_rec(v, ""); if( pos != null && pos.customParams != null ) for( v in pos.customParams ) str += ","+__string_rec(v, ""); lines = lines.concat(str.split("\n")); tf.text = lines.join("\n"); var stage = flash.Lib.current.stage; if( stage == null ) return; while( lines.length > 1 && tf.height > stage.stageHeight ) { lines.shift(); tf.text = lines.join("\n"); } } public static function __string_rec( v : Dynamic, str : String ) { var cname = untyped __global__["flash.utils.getQualifiedClassName"](v); switch( cname ) { case "Object": var k : Array = untyped __keys__(v); var s = "{"; var first = true; for( i in 0...k.length ) { var key = k[i]; if( key == "toString" ) try return v.toString() catch( e : Dynamic ) {} if( first ) first = false; else s += ","; s += " "+key+" : "+__string_rec(v[untyped key],str); } if( !first ) s += " "; s += "}"; return s; case "Array": if( v == Array ) return "#Array"; var s = "["; var i; var first = true; var a : Array = v; for( i in 0...a.length ) { if( first ) first = false; else s += ","; s += __string_rec(a[i],str); } return s + "]"; default: switch( untyped __typeof__(v) ) { case "function": return ""; case "undefined": return "null"; } } return new String(v); } static function __unprotect__( s : String ) { return s; } static public function mapDynamic(d:Dynamic, f:Dynamic) { if (Std.is(d, Array)) { return untyped d["mapHX"](f); } else { return untyped d["map"](f); } } static public function filterDynamic(d:Dynamic, f:Dynamic) { if (Std.is(d, Array)) { return untyped d["filterHX"](f); } else { return untyped d["filter"](f); } } static function __init__() untyped { var aproto = Array.prototype; aproto.copy = function() { return __this__.slice(); }; aproto.insert = function(i,x) { __this__.splice(i,0,x); }; aproto.remove = function(obj) { var idx = __this__.indexOf(obj); if( idx == -1 ) return false; #if flash19 __this__.removeAt(idx); #else __this__.splice(idx,1); #end return true; } aproto.iterator = function() { var cur = 0; var arr : Array = __this__; return { hasNext : function() { return cur < arr.length; }, next : function() { return arr[cur++]; } } }; aproto.setPropertyIsEnumerable("copy", false); aproto.setPropertyIsEnumerable("insert", false); aproto.setPropertyIsEnumerable("remove", false); aproto.setPropertyIsEnumerable("iterator", false); #if (as3 || no_flash_override) aproto.filterHX = function(f) { var ret = []; var i = 0; var l = __this__.length; while ( i < l ) { if (f(__this__[i])) ret.push(__this__[i]); i++; } return ret; }; aproto.mapHX = function(f) { var ret = []; var i = 0; var l = __this__.length; while( i < l ) { ret.push(f(__this__[i])); i++; } return ret; }; aproto.setPropertyIsEnumerable("mapHX", false); aproto.setPropertyIsEnumerable("filterHX", false); String.prototype.charCodeAtHX = function(i) : Null { #else aproto["filter"] = function(f) { var ret = []; var i = 0; var l = __this__.length; while ( i < l ) { if (f(__this__[i])) ret.push(__this__[i]); i++; } return ret; }; aproto["map"] = function(f) { var ret = []; var i = 0; var l = __this__.length; while( i < l ) { ret.push(f(__this__[i])); i++; } return ret; }; aproto.setPropertyIsEnumerable("map", false); aproto.setPropertyIsEnumerable("filter", false); String.prototype.charCodeAt = function(i) : Null { #end var s : String = __this__; var x : Float = s.cca(i); if( __global__["isNaN"](x) ) return null; return Std.int(x); }; } } haxe_3.4.4.orig/std/flash/Lib.hx0000664000175000017500000000657013166552354016362 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package flash; /** Platform-specific Flash Library. Provides some platform-specific functions for the Flash target. **/ class Lib { public static var current : flash.display.MovieClip; public inline static function getTimer() : Int { return untyped __global__["flash.utils.getTimer"](); } public static function eval( path : String ) : Dynamic { var p = path.split("."); var fields = new Array(); var o : Dynamic = null; while( p.length > 0 ) { try { o = untyped __global__["flash.utils.getDefinitionByName"](p.join(".")); } catch( e : Dynamic ) { fields.unshift(p.pop()); } if( o != null ) break; } for( f in fields ) { if( o == null ) return null; o = untyped o[f]; } return o; } public static function getURL( url : flash.net.URLRequest, ?target : String ) { var f = untyped __global__["flash.net.navigateToURL"]; if( target == null ) f(url); else (cast f)(url,target); } public static function fscommand( cmd : String, ?param : String ) { untyped __global__["flash.system.fscommand"](cmd,if( param == null ) "" else param); } public static function trace( arg : Dynamic ) { untyped __global__["trace"](arg); } public static function describeType( value : Dynamic ) : flash.xml.XML { return untyped __global__["flash.utils.describeType"](value); } public static function attach( name : String ) : flash.display.MovieClip { var cl = untyped __as__(__global__["flash.utils.getDefinitionByName"](name),Class); return untyped __new__(cl); } public inline static function as( v : Dynamic, c : Class ) : Null { return untyped __as__(v,c); } public static function redirectTraces() { if (flash.external.ExternalInterface.available) haxe.Log.trace = traceToConsole; } static function traceToConsole(v : Dynamic, ?inf : haxe.PosInfos ) { var type = if( inf != null && inf.customParams != null ) inf.customParams[0] else null; if( type != "warn" && type != "info" && type != "debug" && type != "error" ) type = if( inf == null ) "error" else "log"; var str = if( inf == null ) "" else inf.fileName + ":" + inf.lineNumber + " : "; try str += Std.string(v) catch( e : Dynamic ) str += "????"; str = str.split("\\").join("\\\\"); flash.external.ExternalInterface.call("console."+type,str); } } haxe_3.4.4.orig/std/flash/Memory.hx0000664000175000017500000000520713166552354017120 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package flash; extern class Memory { public static inline function select( b : flash.utils.ByteArray ) : Void { flash.system.ApplicationDomain.currentDomain.domainMemory = b; } public static inline function setByte( addr : Int, v : Int ) : Void { untyped __vmem_set__(0,addr,v); } public static inline function setI16( addr : Int, v : Int ) : Void { untyped __vmem_set__(1,addr,v); } public static inline function setI32( addr : Int, v : Int ) : Void { untyped __vmem_set__(2,addr,v); } public static inline function setFloat( addr : Int, v : Float ) : Void { untyped __vmem_set__(3,addr,v); } public static inline function setDouble( addr : Int, v : Float ) : Void { untyped __vmem_set__(4,addr,v); } public static inline function getByte( addr : Int ) : Int { return untyped __vmem_get__(0,addr); } public static inline function getUI16( addr : Int ) : Int { return untyped __vmem_get__(1,addr); } public static inline function getI32( addr : Int ) : Int { return untyped __vmem_get__(2,addr); } public static inline function getFloat( addr : Int ) : Float { return untyped __vmem_get__(3,addr); } public static inline function getDouble( addr : Int ) : Float { return untyped __vmem_get__(4,addr); } public static inline function signExtend1( v : Int ) : Int { return untyped __vmem_sign__(0,v); } public static inline function signExtend8( v : Int ) : Int { return untyped __vmem_sign__(1,v); } public static inline function signExtend16( v : Int ) : Int { return untyped __vmem_sign__(2,v); } }haxe_3.4.4.orig/std/flash/NativeXml.hx0000664000175000017500000002761413166552354017565 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package flash; import flash.xml.XML; import flash.xml.XMLList; extern enum XmlType { } typedef NativeXml = Xml; class Xml { public static var Element(default,null) : XmlType; public static var PCData(default,null) : XmlType; public static var CData(default,null) : XmlType; public static var Comment(default,null) : XmlType; public static var DocType(default,null) : XmlType; public static var ProcessingInstruction(default,null) : XmlType; public static var Document(default,null) : XmlType; public var nodeType(default,null) : XmlType; public var nodeName(get,set) : String; public var nodeValue(get,set) : String; public var parent(get,null) : Xml; var _node : flash.xml.XML; public static function parse( str : String ) : Xml { XML.ignoreWhitespace = false; XML.ignoreProcessingInstructions = false; XML.ignoreComments = false; var prefix = "<__document"; var root = null; while( root == null ) { try { root = new flash.xml.XML(prefix+">" + str + ""); } catch( e : flash.errors.TypeError ) { // if we miss a namespace, let's add it ! var r = ~/"([^"]+)"/; //" if( e.errorID == 1083 && r.match(e.message) ) { var ns = r.matched(1); prefix += " xmlns:" + ns + '="@' + ns + '"'; } else throw e; } } return wrap( root, Xml.Document ); } @:keep #if as3 @:hack public #end static function compare( a : Xml, b : Xml ) : Bool { return a == null ? b == null : (b == null ? false : a._node == b._node); } private function new() : Void {} public static function createElement( name : String ) : Xml { return wrap( new flash.xml.XML("<"+name+"/>"), Xml.Element ); } public static function createPCData( data : String ) : Xml { XML.ignoreWhitespace = false; return wrap( new flash.xml.XML(data), Xml.PCData ); } public static function createCData( data : String ) : Xml { return wrap( new flash.xml.XML(""), Xml.CData ); } public static function createComment( data : String ) : Xml { XML.ignoreComments = false; return wrap( new flash.xml.XML(""), Xml.Comment ); } public static function createDocType( data : String ) : Xml { return wrap( new flash.xml.XML(""), Xml.DocType ); } public static function createProcessingInstruction( data : String ) : Xml { XML.ignoreProcessingInstructions = false; return wrap( new flash.xml.XML(""), Xml.ProcessingInstruction ); } public static function createDocument() : Xml { return wrap( new flash.xml.XML("<__document/>"), Xml.Document ); } private static function getNodeType( node : flash.xml.XML ) : XmlType { switch( node.nodeKind() ) { case "element": return Xml.Element; case "text": return Xml.PCData; case "processing-instruction": return Xml.ProcessingInstruction; case "comment": return Xml.Comment; default : throw "unimplemented node type: " + node.nodeType; } } private function get_nodeName() : String { if( nodeType != Xml.Element ) throw "bad nodeType"; var ns = _node.namespace(); return (ns.prefix == "") ? _node.localName() : ns.prefix+":"+_node.localName(); } private function set_nodeName( n : String ) : String { if( nodeType != Xml.Element ) throw "bad nodeType"; var ns = n.split(":"); if( ns.length == 1 ) _node.setLocalName(n); else { _node.setLocalName(ns[1]); _node.setNamespace(_node.namespace(ns[0])); } return n; } private function get_nodeValue() : String { var nodeType = nodeType; if( nodeType == Xml.Element || nodeType == Xml.Document ) throw "bad nodeType"; if( nodeType == Xml.Comment ) return _node.toString().substr(4,-7); return _node.toString(); } private function set_nodeValue( v : String ) : String { var nodeType = nodeType; var x = null; if( nodeType == Xml.Element || nodeType == Xml.Document ) throw "bad nodeType"; else if( nodeType == Xml.PCData ) x = createPCData(v); else if( nodeType == Xml.CData ) x = createCData(v); else if( nodeType == Xml.Comment ) x = createComment(v); else if( nodeType == Xml.DocType ) x = createDocType(v); else x = createProcessingInstruction(v); var p = _node.parent(); if( p != null ) { p.insertChildAfter(_node, x._node); var i = _node.childIndex(); var children = p.children(); untyped __delete__(children, Reflect.fields(children)[i]); } _node = x._node; return v; } private function get_parent() :Xml { var p = _node.parent(); return p == null ? null : wrap( p ); } private static function wrap( node : XML, ?type : XmlType ) : Xml { var x = new Xml(); x._node = node; x.nodeType = (type != null) ? type : getNodeType( node ); return x; } private function wraps( xList : XMLList ) : Array { var out = new Array(); for( i in 0...xList.length() ) out.push( wrap(xList[i]) ); return out; } function getAttribNS( cur : XML, ns : Array ) : XMLList { var n = cur.namespace(ns[0]); if( n == null ) { var parent = cur.parent(); if( parent == null ) { n = new flash.utils.Namespace(ns[0], "@"+ns[0]); cur.addNamespace(n); } else return getAttribNS(parent, ns); } return _node.attribute(new flash.utils.QName(n,ns[1])); } public function get( att : String ) : String { if( nodeType != Xml.Element ) throw "bad nodeType"; var ns = att.split(":"); if( ns[0] == "xmlns" ) { var n = _node.namespace((ns[1] == null) ? "" : ns[1]); return (n == null) ? null : n.uri; } if( ns.length == 1 ) { if( !Reflect.hasField(_node,"@"+att) ) return null; return Reflect.field(_node, "@"+att); } var a = getAttribNS(_node,ns); return (a.length() == 0) ? null : a.toString(); } public function set( att : String, value : String ) : Void { if( nodeType != Xml.Element ) throw "bad nodeType"; var ns = att.split(":"); if( ns[0] == "xmlns" ) { var n = _node.namespace((ns[1] == null) ? "" : ns[1]); if( n != null ) throw "Can't modify namespace"; if( ns[1] == null ) throw "Can't set default namespace"; _node.addNamespace(new flash.utils.Namespace(ns[1], value)); return; } if( ns.length == 1 ) Reflect.setField(_node, "@"+att, value); else { var a = getAttribNS(_node,ns); untyped a[0] = value; } } public function remove( att : String ) : Void{ if( nodeType != Xml.Element ) throw "bad nodeType"; var ns = att.split(":"); if( ns.length == 1 ) Reflect.deleteField(_node, "@"+att); else untyped __delete__(getAttribNS(_node,ns),0); } public function exists( att : String ) : Bool { if( nodeType != Xml.Element ) throw "bad nodeType"; var ns = att.split(":"); if( ns[0] == "xmlns" ) return _node.namespace((ns[1] == null) ? "" : ns[1]) != null; if( ns.length == 1 ) return Reflect.hasField(_node, "@"+att); return getAttribNS(_node,ns).length() > 0; } public function attributes() : Iterator { if( nodeType != Xml.Element ) throw "bad nodeType"; var attributes :XMLList = _node.attributes(); var names = Reflect.fields(attributes); var cur = 0; var nss = _node.namespaceDeclarations(); return { hasNext : function(){ return cur < names.length + nss.length; }, next : function() { if(cur { if( nodeType != Xml.Element && nodeType != Xml.Document ) throw "bad nodeType"; var children:XMLList = _node.children(); var wrappers :Array = wraps(children); var cur = 0; return { hasNext : function(){ return cur < wrappers.length; }, next : function(){ return wrappers[cur++]; } }; } public function elements() : Iterator { if( nodeType != Xml.Element && nodeType != Xml.Document ) throw "bad nodeType"; var elements:XMLList = _node.elements(); var wrappers :Array = wraps(elements); var cur = 0; return { hasNext : function(){ return cur < wrappers.length; }, next : function(){ return wrappers[cur++]; } }; } public function elementsNamed( name : String ) : Iterator { if( nodeType != Xml.Element && nodeType != Xml.Document ) throw "bad nodeType"; var ns = name.split(":"); var elements:XMLList; if( ns.length == 1 ) elements = _node.elements(name); else elements = _node.elements(); var wrappers :Array = wraps(elements); if( ns.length != 1 ) for( w in wrappers.copy() ) if( w._node.localName() != ns[1] || w._node.namespace().prefix != ns[0] ) wrappers.remove(w); var cur = 0; return { hasNext : function(){ return cur < wrappers.length; }, next : function(){ return wrappers[cur++]; } }; } public function firstChild() : Xml { if( nodeType != Xml.Element && nodeType != Xml.Document ) throw "bad nodeType"; var children:XMLList = _node.children(); if( children.length() == 0 ) return null; return wrap( children[0] ); } public function firstElement() : Xml { if( nodeType != Xml.Element && nodeType != Xml.Document ) throw "bad nodeType"; var elements:XMLList = _node.elements(); if( elements.length() == 0 ) return null; return wrap( elements[0] ); } public function addChild( x : Xml ) : Void { if( nodeType != Xml.Element && nodeType != Xml.Document ) throw "bad nodeType"; if (x.parent != null) x.parent.removeChild(x); var children:XMLList = _node.children(); _node.appendChild(x._node); } public function removeChild( x : Xml ) : Bool { if( nodeType != Xml.Element && nodeType != Xml.Document ) throw "bad nodeType"; var children:XMLList = _node.children(); if( _node != x._node.parent() ) return false; var i = x._node.childIndex(); untyped __delete__(children, Reflect.fields(children)[i]); return true; } public function insertChild( x : Xml, pos : Int ) : Void { if( nodeType != Xml.Element && nodeType != Xml.Document ) throw "bad nodeType"; if (x.parent != null) x.parent.removeChild(x); var children:XMLList = _node.children(); if( pos < children.length() ) _node.insertChildBefore(children[pos], x._node); else _node.appendChild(x._node); } public function toString() : String { XML.prettyPrinting = false; if( nodeType == Xml.Document ) { var str = _node.toXMLString(); // remove <__document xmlns....>STR wrapper str = str.substr(str.indexOf(">") + 1); str = str.substr(0, str.length - 13); return str; } return _node.toXMLString(); } static function __init__() : Void untyped { Element = "element"; PCData = "pcdata"; CData = "cdata"; Comment = "comment"; DocType = "doctype"; ProcessingInstruction = "processingInstruction"; Document = "document"; } }haxe_3.4.4.orig/std/flash/Vector.hx0000664000175000017500000000413713166552354017113 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package flash; /** The Vector class is very similar to Array but is only supported by the Flash Player 10+ **/ @:require(flash10) extern class Vector implements ArrayAccess { var length : Int; var fixed : Bool; function new( ?length : UInt, ?fixed : Bool ) : Void; function concat( ?a : Vector ) : Vector; function join( sep : String ) : String; function pop() : Null; function push(x : T) : Int; function reverse() : Void; function shift() : Null; function unshift( x : T ) : Void; function slice( ?pos : Int, ?end : Int ) : Vector; function sort( f : T -> T -> Int ) : Void; function splice( pos : Int, len : Int ) : Vector; function toString() : String; function indexOf( x : T, ?from : Int ) : Int; function lastIndexOf( x : T, ?from : Int ) : Int; public inline static function ofArray( v : Array ) : Vector { return untyped __vector__(v); } public inline static function convert( v : Vector ) : Vector { return untyped __vector__(v); } } haxe_3.4.4.orig/std/flash/_std/EReg.hx0000664000175000017500000000702613166552354017424 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi class EReg { var r : flash.utils.RegExp; var result : Dynamic; public function new( r : String, opt : String ) : Void { this.r = new flash.utils.RegExp(r,opt); } public function match( s : String ) : Bool { if( r.global ) r.lastIndex = 0; result = r.exec(s); return (result != null); } public function matched( n : Int ) : String { return if( result != null && n >= 0 && n < (result : Array).length ) result[n] else throw "EReg::matched"; } public function matchedLeft() : String { if( result == null ) throw "No string matched"; var s : String = untyped result.input; return s.substr(0,untyped result["index"]); } public function matchedRight() : String { if( result == null ) throw "No string matched"; var rl = (result[untyped "index"] : Int) + (result[0] : String).length; var s : String = untyped result.input; return s.substr(rl,s.length - rl); } public function matchedPos() : { pos : Int, len : Int } { if( result == null ) throw "No string matched"; return { pos : result[untyped "index"], len : (result[0] : String).length }; } public function matchSub( s : String, pos : Int, len : Int = -1):Bool { return if (r.global) { r.lastIndex = pos; result = r.exec(len < 0 ? s : s.substr(0, pos + len)); var b = result != null; if (b) { untyped result.input = s; } b; } else { var b = match( len < 0 ? s.substr(pos) : s.substr(pos,len) ); if (b) { untyped result.input = s; untyped result["index"] += pos; } b; } } public function split( s : String ) : Array { // we can't use directly s.split because it's ignoring the 'g' flag var d = "#__delim__#"; var s : String = untyped s.replace(r, d); return s.split(d); } public function replace( s : String, by : String ) : String { return untyped s.replace(r,by); } public function map( s : String, f : EReg -> String ) : String { var offset = 0; var buf = new StringBuf(); var first = true; do { if (offset >= s.length) break; else if (!matchSub(s, offset)) { buf.add(s.substr(offset)); break; } var p = matchedPos(); buf.add(s.substr(offset, p.pos - offset)); buf.add(f(this)); if (p.len == 0) { buf.add(s.substr(p.pos, 1)); offset = p.pos + 1; } else offset = p.pos + p.len; first = false; } while (r.global); if (!r.global && offset > 0 && offset < s.length) buf.add(s.substr(offset)); return buf.toString(); } } haxe_3.4.4.orig/std/flash/_std/Reflect.hx0000664000175000017500000000763713166552354020176 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi class Reflect { public static function hasField( o : Dynamic, field : String ) : Bool untyped { return o.hasOwnProperty( field ); } public static function field( o : Dynamic, field : String ) : Dynamic untyped { // sealed classes will throw an exception return try o[field] catch( e : Dynamic ) null; } public inline static function setField( o : Dynamic, field : String, value : Dynamic ) : Void untyped { o[field] = value; } public static function getProperty( o : Dynamic, field : String ) : Dynamic untyped { try { return o["get_" + field](); } catch( e : Dynamic ) try { return o[field]; } catch( e : Dynamic ) { return null; } } public static function setProperty( o : Dynamic, field : String, value : Dynamic ) : Void untyped { try { o["set_" + field](value); } catch( e : Dynamic ) { o[field] = value; } } public inline static function callMethod( o : Dynamic, func : haxe.Constraints.Function, args : Array ) : Dynamic untyped { return func.apply(o,args); } public static function fields( o : Dynamic ) : Array untyped { if( o == null ) return new Array(); #if as3 var a : Array = __keys__(o); var i = 0; while( i < a.length ){ if( !o.hasOwnProperty(a[i]) ) a.splice(i,1); else ++i; } #else var i = 0; var a = []; while( untyped __has_next__(o,i) ) { var prop = untyped __forin__(o,i); if( o.hasOwnProperty(prop) ) a.push(prop); } #end return a; } public static function isFunction( f : Dynamic ) : Bool untyped { return __typeof__(f) == "function"; } public static function compare( a : T, b : T ) : Int { var a : Dynamic = a; var b : Dynamic = b; return ( a == b ) ? 0 : ((a > b) ? 1 : -1); } public static function compareMethods( f1 : Dynamic, f2 : Dynamic ) : Bool { return f1 == f2; // VM-level closures } public static function isObject( v : Dynamic ) : Bool untyped { if( v == null ) return false; var t = __typeof__(v); if ( t == "object" ) { return !isEnumValue(v); } return (t == "string"); } public static function isEnumValue( v : Dynamic ) : Bool { #if as3 return try Type.getEnum(v) != null catch ( e: Dynamic) false; #else return try v.__enum__ == true catch ( e : Dynamic) false; #end } public static function deleteField( o : Dynamic, field : String ) : Bool untyped { if( o.hasOwnProperty(field) != true ) return false; __delete__(o,field); return true; } public static function copy( o : T ) : T { var o2 : Dynamic = {}; for( f in Reflect.fields(o) ) Reflect.setField(o2,f,Reflect.field(o,f)); return o2; } @:overload(function( f : Array -> Void ) : Dynamic {}) public static function makeVarArgs( f : Array -> Dynamic ) : Dynamic { return function(__arguments__) { return f(__arguments__); }; } } haxe_3.4.4.orig/std/flash/_std/Std.hx0000664000175000017500000000371013166552354017330 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import flash.Boot; @:coreApi class Std { public static function is( v : Dynamic, t : Dynamic ) : Bool { return untyped flash.Boot.__instanceof(v,t); } public static inline function instance( value : T, c : Class ) : S { return flash.Lib.as(value, c); } public static function string( s : Dynamic ) : String { return untyped flash.Boot.__string_rec(s,""); } public inline static function int( x : Float ) : Int { return untyped __int__(x); } public static function parseInt( x : String ) : Null untyped { var v = __global__["parseInt"](x); if( __global__["isNaN"](v) ) return null; return v; } public static function parseFloat( x : String ) : Float { return untyped __global__["parseFloat"](x); } public static function random( x : Int ) : Int { return untyped x <= 0 ? 0 : Math.floor(Math.random()*x); } } haxe_3.4.4.orig/std/flash/_std/Type.hx0000664000175000017500000002221013166552354017513 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ enum ValueType { TNull; TInt; TFloat; TBool; TObject; TFunction; TClass( c : Class ); TEnum( e : Enum ); TUnknown; } @:coreApi class Type { public static function getClass( o : T ) : Class untyped { var cname = __global__["flash.utils.getQualifiedClassName"](o); if( cname == "null" || cname == "Object" || cname == "int" || cname == "Number" || cname == "Boolean" ) return null; if( o.hasOwnProperty("prototype") ) return null; var c = __as__(__global__["flash.utils.getDefinitionByName"](cname),Class); if( c.__isenum ) return null; return c; } public static function getEnum( o : EnumValue ) : Enum untyped { var cname = __global__["flash.utils.getQualifiedClassName"](o); if( cname == "null" || cname.substr(0,8) == "builtin." ) return null; // getEnum(Enum) should be null if( o.hasOwnProperty("prototype") ) return null; var c = __as__(__global__["flash.utils.getDefinitionByName"](cname),Class); if( !c.__isenum ) return null; return c; } public static function getSuperClass( c : Class ) : Class untyped { var cname = __global__["flash.utils.getQualifiedSuperclassName"](c); if( cname == null || cname == "Object" ) return null; return __as__(__global__["flash.utils.getDefinitionByName"](cname),Class); } public static function getClassName( c : Class ) : String { if( c == null ) return null; var str : String = untyped __global__["flash.utils.getQualifiedClassName"](c); switch( str ) { case "int": return "Int"; case "Number": return "Float"; case "Boolean": return "Bool"; #if as3 case "Object": return "Dynamic"; #end default: } return str.split("::").join("."); } public static function getEnumName( e : Enum ) : String { return getClassName(cast e); } public static function resolveClass( name : String ) : Class untyped { var cl : Class; try { cl = __as__(__global__["flash.utils.getDefinitionByName"](name),Class); if( cl.__isenum ) return null; return cl; // skip test below } catch( e : Dynamic ) { switch( name ) { case "Int": return Int; case "Float": return Float; #if as3 case "Dynamic": return Dynamic; #end } return null; } // ensure that this is a class if( cl == null || cl.__name__ == null ) return null; return cl; } public static function resolveEnum( name : String ) : Enum untyped { var e : Dynamic; try { e = __global__["flash.utils.getDefinitionByName"](name); if( !e.__isenum ) return null; return e; } catch( e : Dynamic ) { if( name == "Bool" ) return Bool; return null; } // ensure that this is an enum if( e == null || e.__ename__ == null ) return null; return e; } public static function createInstance( cl : Class, args : Array ) : T untyped { return switch( args.length ) { case 0: __new__(cl); case 1: __new__(cl,args[0]); case 2: __new__(cl,args[0],args[1]); case 3: __new__(cl,args[0],args[1],args[2]); case 4: __new__(cl,args[0],args[1],args[2],args[3]); case 5: __new__(cl,args[0],args[1],args[2],args[3],args[4]); case 6: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5]); case 7: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6]); case 8: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]); case 9: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]); case 10: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]); case 11: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]); case 12: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11]); case 13: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12]); case 14: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13]); default: throw "Too many arguments"; } } public static function createEmptyInstance( cl : Class ) : T untyped { try { flash.Boot.skip_constructor = true; var i = __new__(cl); flash.Boot.skip_constructor = false; return i; } catch( e : Dynamic ) { flash.Boot.skip_constructor = false; throw e; } return null; } public static function createEnum( e : Enum, constr : String, ?params : Array ) : T { var f:Dynamic = untyped e[constr]; if( f == null ) throw "No such constructor "+constr; if( Reflect.isFunction(f) ) { if( params == null ) throw "Constructor "+constr+" need parameters"; return Reflect.callMethod(e,f,params); } if( params != null && params.length != 0 ) throw "Constructor "+constr+" does not need parameters"; return f; } public static function createEnumIndex( e : Enum, index : Int, ?params : Array ) : T { var c : String = (untyped e.__constructs__)[index]; if( c == null ) throw index+" is not a valid enum constructor index"; return createEnum(e,c,params); } static function describe( t : Dynamic, fact : Bool ) : Array untyped { var fields = new Array(); var xml : flash.xml.XML = __global__["flash.utils.describeType"](t); if( fact ) xml = xml.factory[0]; var methods = xml.child("method"); for( i in 0...methods.length() ) fields.push( Std.string(methods[i].attribute("name")) ); var vars = xml.child("variable"); for( i in 0...vars.length() ) fields.push( Std.string(vars[i].attribute("name")) ); var accs = xml.child("accessor"); for( i in 0...accs.length() ) fields.push( Std.string(accs[i].attribute("name")) ); return fields; } public static function getInstanceFields( c : Class ) : Array { return describe(c,true); } public static function getClassFields( c : Class ) : Array { var a = describe(c,false); a.remove("__construct__"); a.remove("prototype"); return a; } public static function getEnumConstructs( e : Enum ) : Array { var a : Array = untyped e.__constructs__; return a.copy(); } public static function typeof( v : Dynamic ) : ValueType untyped { var cname = __global__["flash.utils.getQualifiedClassName"](v); switch(cname) { case "null": return TNull; case "void": return TNull; // undefined case "int": return TInt; case "Number": // integers >28 bits are stored as Numbers in avm2 if( (v < -0x10000000 || v >= 0x10000000) && Std.int(v) == v ) return TInt; return TFloat; case "Boolean": return TBool; case "Object": return TObject; case "Function": return TFunction; default: var c : Dynamic = null; try { c = __global__["flash.utils.getDefinitionByName"](cname); if( v.hasOwnProperty("prototype") ) return TObject; if( c.__isenum ) return TEnum(c); return TClass(c); } catch( e : Dynamic ) { if( cname == "builtin.as$0::MethodClosure" || cname.indexOf("-") != -1 ) return TFunction; return if( c == null ) TFunction else TClass(c); } } return null; } public static function enumEq( a : T, b : T ) : Bool untyped { if( a == b ) return true; try { if( a.index != b.index ) return false; var ap : Array = a.params; var bp : Array = b.params; for( i in 0...ap.length ) if( !enumEq(ap[i],bp[i]) ) return false; } catch( e : Dynamic ) { return false; } return true; } public static function enumConstructor( e : EnumValue ) : String { return untyped e.tag; } public static function enumParameters( e : EnumValue ) : Array { return untyped if( e.params == null ) [] else e.params; } @:extern public inline static function enumIndex( e : EnumValue ) : Int { return untyped e.index; } public static function allEnums( e : Enum ) : Array { var all = []; var cst : Array = untyped e.__constructs__; for( c in cst ) { var v = Reflect.field(e,c); if( !Reflect.isFunction(v) ) all.push(v); } return all; } } haxe_3.4.4.orig/std/flash/_std/haxe/Json.hx0000664000175000017500000000307413166552354020437 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; @:coreApi #if (!haxeJSON && flash11) @:native("JSON") extern #end class Json { #if (haxeJSON || !flash11) inline #end public static function parse( text : String ) : Dynamic { return haxe.format.JsonParser.parse(text); } #if (haxeJSON || !flash11) inline #end public static function stringify( value : Dynamic, ?replacer:Dynamic -> Dynamic -> Dynamic, ?space:String ) : String { return haxe.format.JsonPrinter.print(value, replacer, space); } } haxe_3.4.4.orig/std/flash/_std/haxe/Resource.hx0000664000175000017500000000521113166552354021310 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; #if as3 @:coreApi class Resource { public static function listNames() : Array untyped { return __keys__(__resources__.list); } public static function getString( name : String ) : String { var b = resolve(name); return b == null ? null : b.readUTFBytes(b.length); } public static function getBytes( name : String ) : haxe.io.Bytes { var b = resolve(name); return b == null ? null : haxe.io.Bytes.ofData(b); } static function resolve( name : String) :flash.utils.ByteArray untyped { var n = __resources__.list[name]; if (n == null) return null; return untyped __new__(n); } static function __init__() : Void { untyped __resources__.__init__(); } } #else @:coreApi class Resource { static var content : Array<{ name : String }>; public static function listNames() : Array { var names = new Array(); for( x in content ) names.push(x.name); return names; } public static function getString( name : String ) : String { var b = resolve(name); return b == null ? null : b.readUTFBytes(b.length); } public static function getBytes( name : String ) : haxe.io.Bytes { var b = resolve(name); return b == null ? null : haxe.io.Bytes.ofData(b); } static function resolve( name : String ) : flash.utils.ByteArray { try untyped { var c = __as__(__global__["flash.utils.getDefinitionByName"]("_res._"+name.split(".").join("_")),Class); return __new__(c); } catch( e : Dynamic ) { return null; } } static function __init__() : Void { content = untyped __resources__(); } } #endhaxe_3.4.4.orig/std/flash/_std/haxe/ds/IntMap.hx0000664000175000017500000000734313166552354021327 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:coreApi class IntMap implements haxe.Constraints.IMap { private var h : flash.utils.Dictionary; public function new() : Void { h = new flash.utils.Dictionary(); } public inline function set( key : Int, value : T ) : Void { untyped h[key] = value; } public inline function get( key : Int ) : Null { return untyped h[key]; } public inline function exists( key : Int ) : Bool { return untyped __in__(key,h); } public function remove( key : Int ) : Bool { if( !exists(key) ) return false; untyped __delete__(h,key); return true; } #if as3 // unoptimized version public function keys() : Iterator { return untyped (__keys__(h)).iterator(); } @:analyzer(ignore) public function iterator() : Iterator { return untyped { ref : h, it : keys(), hasNext : function() { return __this__.it.hasNext(); }, next : function() { var i = __this__.it.next(); return __this__.ref[i]; } }; } #else public inline function keys() : Iterator { return new IntMapKeysIterator(h); } public inline function iterator() : Iterator { return new IntMapValuesIterator(h); } #end public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(i); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } } #if !as3 // this version uses __has_next__/__forin__ special SWF opcodes for iteration with no allocation @:allow(haxe.ds.IntMap) private class IntMapKeysIterator { var h:flash.utils.Dictionary; var index : Int; var nextIndex : Int; inline function new(h:flash.utils.Dictionary):Void { this.h = h; this.index = 0; hasNext(); } public inline function hasNext():Bool { var h = h, index = index; // tmp vars required for __has_next var n = untyped __has_next__(h, index); this.nextIndex = index; // store next index return n; } public inline function next():Int { var r : Int = untyped __forin__(h, nextIndex); index = nextIndex; return r; } } @:allow(haxe.ds.IntMap) private class IntMapValuesIterator { var h:flash.utils.Dictionary; var index : Int; var nextIndex : Int; inline function new(h:flash.utils.Dictionary):Void { this.h = h; this.index = 0; hasNext(); } public inline function hasNext():Bool { var h = h, index = index; // tmp vars required for __has_next var n = untyped __has_next__(h, index); this.nextIndex = index; // store next index return n; } public inline function next():T { var r = untyped __foreach__(h, nextIndex); index = nextIndex; return r; } } #end haxe_3.4.4.orig/std/flash/_std/haxe/ds/ObjectMap.hx0000664000175000017500000000670413166552354022003 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:coreApi class ObjectMap extends flash.utils.Dictionary implements haxe.Constraints.IMap { public function new() { super(false); } public inline function get( key : K ) : Null { return untyped this[key]; } public inline function set( key : K, value : V ):Void { untyped this[key] = value; } public inline function exists( key : K ) : Bool { return untyped this[key] != null; } public function remove( key : K ):Bool { var has = exists(key); untyped __delete__(this, key); return has; } #if as3 public function keys() : Iterator { return untyped __keys__(this).iterator(); } public function iterator() : Iterator { var ret = []; for (i in keys()) ret.push(get(i)); return ret.iterator(); } #else public function keys() : Iterator { return NativePropertyIterator.iterator(this); } public function iterator() : Iterator { return NativeValueIterator.iterator(this); } #end public function toString() : String { var s = ""; var it = keys(); for( i in it ) { s += (s == "" ? "" : ",") + Std.string(i); s += " => "; s += Std.string(get(i)); } return s + "}"; } } private class NativePropertyIterator { var collection:Dynamic; var index:Int = 0; public static inline function iterator(collection:Dynamic):NativePropertyIterator { var result = new NativePropertyIterator(); result.collection = collection; return result; } function new() {} public inline function hasNext():Bool { var c = collection; var i = index; var result = untyped __has_next__(c, i); collection = c; index = i; return result; } public inline function next():Dynamic { var i = index; var result = untyped __forin__(collection, i); index = i; return result; } } private class NativeValueIterator { var collection:Dynamic; var index:Int = 0; public static inline function iterator(collection:Dynamic):NativeValueIterator { var result = new NativeValueIterator(); result.collection = collection; return result; } function new() {} public inline function hasNext():Bool { var c = collection; var i = index; var result = untyped __has_next__(c, i); collection = c; index = i; return result; } public inline function next():Dynamic { var i = index; var result = untyped __foreach__(collection, i); index = i; return result; } } haxe_3.4.4.orig/std/flash/_std/haxe/ds/StringMap.hx0000664000175000017500000001176613166552354022047 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:coreApi class StringMap implements haxe.Constraints.IMap { private var h : Dynamic; private var rh : Dynamic; static var reserved = { }; public function new() : Void { h = {}; } inline function isReserved(key:String) : Bool { return untyped __in__(key,reserved); } public inline function set( key : String, value : T ) : Void { if( isReserved(key) ) setReserved(key, value); else untyped h[key] = value; } public inline function get( key : String ) : Null { if( isReserved(key) ) return getReserved(key); return untyped h[key]; } public inline function exists( key : String ) : Bool { if( isReserved(key) ) return existsReserved(key); return untyped __in__(key,h); } function setReserved( key : String, value : T ) : Void { if( rh == null ) rh = {}; untyped rh["$"+key] = value; } function getReserved( key : String ) : Null { return rh == null ? null : untyped rh["$"+key]; } function existsReserved( key : String ) : Bool { if( rh == null ) return false; return untyped __in__("$"+key,rh); } public function remove( key : String ) : Bool { if( isReserved(key) ) { key = "$" + key; if( rh == null || !untyped __in__(key,rh) ) return false; untyped __delete__(rh,key); return true; } else { if( !untyped __in__(key,h) ) return false; untyped __delete__(h,key); return true; } } #if as3 // unoptimized version public function keys() : Iterator { var out : Array = untyped __keys__(h); if( rh != null ) out = out.concat(untyped __hkeys__(rh)); return out.iterator(); } public function iterator() : Iterator { return untyped { it : keys(), hasNext : function() { return __this__.it.hasNext(); }, next : function() { return get(__this__.it.next()); } }; } #else public inline function keys() : Iterator { return new StringMapKeysIterator(h, rh); } public inline function iterator() : Iterator { return new StringMapValuesIterator(h, rh); } #end public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(i); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } } #if !as3 // this version uses __has_next__/__forin__ special SWF opcodes for iteration with no allocation @:allow(haxe.ds.StringMap) private class StringMapKeysIterator { var h:Dynamic; var rh:Dynamic; var index : Int; var nextIndex : Int; var isReserved : Bool; inline function new(h:Dynamic, rh:Dynamic):Void { this.h = h; this.rh = rh; this.index = 0; isReserved = false; hasNext(); } public inline function hasNext():Bool { var h = h, index = index; // tmp vars required for __has_next var n = untyped __has_next__(h, index); if( !n && rh != null ) { h = this.h = rh; index = this.index = 0; rh = null; isReserved = true; n = untyped __has_next__(h, index); } this.nextIndex = index; // store next index return n; } public inline function next():String { var r : String = untyped __forin__(h, nextIndex); index = nextIndex; if( isReserved ) r = r.substr(1); return r; } } @:allow(haxe.ds.StringMap) private class StringMapValuesIterator { var h:Dynamic; var rh:Dynamic; var index : Int; var nextIndex : Int; inline function new(h:Dynamic, rh:Dynamic):Void { this.h = h; this.rh = rh; this.index = 0; hasNext(); } public inline function hasNext():Bool { var h = h, index = index; // tmp vars required for __has_next var n = untyped __has_next__(h, index); if( !n && rh != null ) { h = this.h = rh; index = this.index = 0; rh = null; n = untyped __has_next__(h, index); } this.nextIndex = index; // store next index return n; } public inline function next():T { var r = untyped __foreach__(h, nextIndex); index = nextIndex; return r; } } #end haxe_3.4.4.orig/std/flash/_std/haxe/ds/UnsafeStringMap.hx0000664000175000017500000001006013166552354023173 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** This is similar to `StringMap` excepts that it does not sanitize the keys. As a result, it will be faster to access the map for reading, but it might fail with some reserved keys such as `constructor` or `prototype`. **/ class UnsafeStringMap implements haxe.Constraints.IMap { private var h : flash.utils.Dictionary; public function new() : Void { h = new flash.utils.Dictionary(); } public inline function set( key : String, value : T ) : Void { untyped h[key] = value; } public inline function get( key : String ) : Null { return untyped h[key]; } public inline function exists( key : String ) : Bool { return untyped __in__(key,h); } public function remove( key : String ) : Bool { if( untyped !h.hasOwnProperty(key) ) return false; untyped __delete__(h,key); return true; } #if as3 // unoptimized version public function keys() : Iterator { return untyped (__keys__(h)).iterator(); } public function iterator() : Iterator { return untyped { ref : h, it : __keys__(h).iterator(), hasNext : function() { return __this__.it.hasNext(); }, next : function() { var i : Dynamic = __this__.it.next(); return __this__.ref[i]; } }; } #else public inline function keys() : Iterator { return new UnsafeStringMapKeysIterator(h); } public inline function iterator() : Iterator { return new UnsafeStringMapValuesIterator(h); } #end public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(i); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } } #if !as3 // this version uses __has_next__/__forin__ special SWF opcodes for iteration with no allocation @:allow(haxe.ds.UnsafeStringMap) private class UnsafeStringMapKeysIterator { var h:flash.utils.Dictionary; var index : Int; var nextIndex : Int; inline function new(h:flash.utils.Dictionary):Void { this.h = h; this.index = 0; hasNext(); } public inline function hasNext():Bool { var h = h, index = index; // tmp vars required for __has_next var n = untyped __has_next__(h, index); this.nextIndex = index; // store next index return n; } public inline function next():String { var r : String = untyped __forin__(h, nextIndex); index = nextIndex; return r; } } @:allow(haxe.ds.UnsafeStringMap) private class UnsafeStringMapValuesIterator { var h:flash.utils.Dictionary; var index : Int; var nextIndex : Int; inline function new(h:flash.utils.Dictionary):Void { this.h = h; this.index = 0; hasNext(); } public inline function hasNext():Bool { var h = h, index = index; // tmp vars required for __has_next var n = untyped __has_next__(h, index); this.nextIndex = index; // store next index return n; } public inline function next():T { var r = untyped __foreach__(h, nextIndex); index = nextIndex; return r; } } #end haxe_3.4.4.orig/std/flash/_std/haxe/ds/WeakMap.hx0000664000175000017500000000670113166552354021461 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:coreApi class WeakMap extends flash.utils.Dictionary implements haxe.Constraints.IMap { public function new() { super(true); } public inline function get( key : K ) : Null { return untyped this[key]; } public inline function set( key : K, value : V ):Void { untyped this[key] = value; } public inline function exists( key : K ) : Bool { return untyped this[key] != null; } public function remove( key : K ):Bool { var has = exists(key); untyped __delete__(this, key); return has; } #if as3 public function keys() : Iterator { return untyped __keys__(this).iterator(); } public function iterator() : Iterator { var ret = []; for (i in keys()) ret.push(get(i)); return ret.iterator(); } #else public function keys() : Iterator { return NativePropertyIterator.iterator(this); } public function iterator() : Iterator { return NativeValueIterator.iterator(this); } #end public function toString() : String { var s = ""; var it = keys(); for( i in it ) { s += (s == "" ? "" : ",") + Std.string(i); s += " => "; s += Std.string(get(i)); } return s + "}"; } } private class NativePropertyIterator { var collection:Dynamic; var index:Int = 0; public static inline function iterator(collection:Dynamic):NativePropertyIterator { var result = new NativePropertyIterator(); result.collection = collection; return result; } function new() {} public inline function hasNext():Bool { var c = collection; var i = index; var result = untyped __has_next__(c, i); collection = c; index = i; return result; } public inline function next():Dynamic { var i = index; var result = untyped __forin__(collection, i); index = i; return result; } } private class NativeValueIterator { var collection:Dynamic; var index:Int = 0; public static inline function iterator(collection:Dynamic):NativeValueIterator { var result = new NativeValueIterator(); result.collection = collection; return result; } function new() {} public inline function hasNext():Bool { var c = collection; var i = index; var result = untyped __has_next__(c, i); collection = c; index = i; return result; } public inline function next():Dynamic { var i = index; var result = untyped __foreach__(collection, i); index = i; return result; } } haxe_3.4.4.orig/std/flash/_std/haxe/zip/Compress.hx0000664000175000017500000000370013166552354022117 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; @:coreApi class Compress { public function new( level : Int ) : Void { throw "Not implemented for this platform"; } public function execute( src : haxe.io.Bytes, srcPos : Int, dst : haxe.io.Bytes, dstPos : Int ) : { done : Bool, read : Int, write : Int } { return null; } public function setFlushMode( f : FlushMode ) : Void { } public function close() : Void { } public static function run( s : haxe.io.Bytes, level : Int ) : haxe.io.Bytes { if( s.length == 0 ) { // Flash returns 0 bytes for 0 length compress (which can't be decoded on other platforms...) var b = haxe.io.Bytes.alloc(8); b.set(0,0x78);b.set(1,0xDA);b.set(2,0x03); b.set(7,0x01); return b; } var tmp = new flash.utils.ByteArray(); tmp.writeBytes(s.getData(),0,s.length); tmp.compress(); return haxe.io.Bytes.ofData(tmp); } } haxe_3.4.4.orig/std/flash/_std/haxe/zip/Uncompress.hx0000664000175000017500000000334613166552354022470 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; @:coreApi class Uncompress { public function new( ?windowBits : Int ) : Void { throw "Not implemented for this platform"; } public function execute( src : haxe.io.Bytes, srcPos : Int, dst : haxe.io.Bytes, dstPos : Int ) : { done : Bool, read : Int, write : Int } { return null; } public function setFlushMode( f : FlushMode ) : Void { } public function close() : Void { } public static function run( src : haxe.io.Bytes, ?bufsize : Int ) : haxe.io.Bytes { var tmp = new flash.utils.ByteArray(); tmp.writeBytes(src.getData(),0,src.length); tmp.uncompress(); return haxe.io.Bytes.ofData(tmp); } } haxe_3.4.4.orig/std/flash/accessibility/Accessibility.hx0000664000175000017500000000042613166552354023264 0ustar andyandy00000000000000package flash.accessibility; extern class Accessibility { static var active(default,never) : Bool; static function sendEvent(source : flash.display.DisplayObject, childID : UInt, eventType : UInt, nonHTML : Bool = false) : Void; static function updateProperties() : Void; } haxe_3.4.4.orig/std/flash/accessibility/AccessibilityImplementation.hx0000664000175000017500000000150313166552354026167 0ustar andyandy00000000000000package flash.accessibility; extern class AccessibilityImplementation { var errno : UInt; var stub : Bool; function new() : Void; function accDoDefaultAction(childID : UInt) : Void; function accLocation(childID : UInt) : Dynamic; function accSelect(operation : UInt, childID : UInt) : Void; function getChildIDArray() : Array; function get_accDefaultAction(childID : UInt) : String; function get_accFocus() : UInt; function get_accName(childID : UInt) : String; function get_accRole(childID : UInt) : UInt; function get_accSelection() : Array; function get_accState(childID : UInt) : UInt; function get_accValue(childID : UInt) : String; function get_selectionActiveIndex() : Dynamic; function get_selectionAnchorIndex() : Dynamic; function isLabeledBy(labelBounds : flash.geom.Rectangle) : Bool; } haxe_3.4.4.orig/std/flash/accessibility/AccessibilityProperties.hx0000664000175000017500000000035713166552354025344 0ustar andyandy00000000000000package flash.accessibility; extern class AccessibilityProperties { var description : String; var forceSimple : Bool; var name : String; var noAutoLabeling : Bool; var shortcut : String; var silent : Bool; function new() : Void; } haxe_3.4.4.orig/std/flash/accessibility/ISearchableText.hx0000664000175000017500000000020113166552354023473 0ustar andyandy00000000000000package flash.accessibility; @:require(flash10_1) extern interface ISearchableText { var searchText(default,never) : String; } haxe_3.4.4.orig/std/flash/accessibility/ISimpleTextSelection.hx0000664000175000017500000000027513166552354024554 0ustar andyandy00000000000000package flash.accessibility; @:require(flash10_1) extern interface ISimpleTextSelection { var selectionActiveIndex(default,never) : Int; var selectionAnchorIndex(default,never) : Int; } haxe_3.4.4.orig/std/flash/automation/ActionGenerator.hx0000664000175000017500000000033313166552354023107 0ustar andyandy00000000000000package flash.automation; @:require(flash10_1) extern class ActionGenerator { function new() : Void; function generateAction(action : AutomationAction) : Void; function generateActions(a : Array) : Void; } haxe_3.4.4.orig/std/flash/automation/AutomationAction.hx0000664000175000017500000000017613166552354023306 0ustar andyandy00000000000000package flash.automation; @:require(flash10_1) extern class AutomationAction { var type : String; function new() : Void; } haxe_3.4.4.orig/std/flash/automation/Configuration.hx0000664000175000017500000000027213166552354022634 0ustar andyandy00000000000000package flash.automation; @:require(flash10_1) extern class Configuration { static var deviceConfiguration : String; static var testAutomationConfiguration(default,never) : String; } haxe_3.4.4.orig/std/flash/automation/KeyboardAutomationAction.hx0000664000175000017500000000043313166552354024763 0ustar andyandy00000000000000package flash.automation; @:require(flash10_1) extern class KeyboardAutomationAction extends AutomationAction { var keyCode : UInt; function new(type : String, keyCode : UInt = 0) : Void; static var KEY_DOWN(default,never) : String; static var KEY_UP(default,never) : String; } haxe_3.4.4.orig/std/flash/automation/MouseAutomationAction.hx0000664000175000017500000000123713166552354024316 0ustar andyandy00000000000000package flash.automation; @:require(flash10_1) extern class MouseAutomationAction extends AutomationAction { var delta : Int; var stageX : Float; var stageY : Float; function new(type : String, stageX : Float = 0, stageY : Float = 0, delta : Int = 0) : Void; static var MIDDLE_MOUSE_DOWN(default,never) : String; static var MIDDLE_MOUSE_UP(default,never) : String; static var MOUSE_DOWN(default,never) : String; static var MOUSE_MOVE(default,never) : String; static var MOUSE_UP(default,never) : String; static var MOUSE_WHEEL(default,never) : String; static var RIGHT_MOUSE_DOWN(default,never) : String; static var RIGHT_MOUSE_UP(default,never) : String; } haxe_3.4.4.orig/std/flash/automation/StageCapture.hx0000664000175000017500000000121113166552354022406 0ustar andyandy00000000000000package flash.automation; @:require(flash10_1) extern class StageCapture extends flash.events.EventDispatcher { var capturePTS : Float; var captureSource : String; var clipRect : flash.geom.Rectangle; var fileNameBase : String; function new() : Void; function cancel() : Void; function capture(type : String) : Void; function captureBitmapData() : flash.display.BitmapData; static var CURRENT(default,never) : String; static var MULTIPLE(default,never) : String; static var NEXT(default,never) : String; static var RASTER(default,never) : String; static var SCREEN(default,never) : String; static var STAGE(default,never) : String; } haxe_3.4.4.orig/std/flash/automation/StageCaptureEvent.hx0000664000175000017500000000062013166552354023413 0ustar andyandy00000000000000package flash.automation; @:require(flash10_1) extern class StageCaptureEvent extends flash.events.Event { var checksum(default,never) : UInt; var pts(default,never) : Float; var url(default,never) : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?url : String, checksum : UInt = 0, pts : Float = 0) : Void; static var CAPTURE(default,never) : String; } haxe_3.4.4.orig/std/flash/concurrent/Condition.hx0000664000175000017500000000046013166552354021754 0ustar andyandy00000000000000package flash.concurrent; @:final @:require(flash11_4) extern class Condition { var mutex(default,never) : Mutex; function new(mutex : Mutex) : Void; function notify() : Void; function notifyAll() : Void; function wait(timeout : Float = -1) : Bool; static var isSupported(default,never) : Bool; } haxe_3.4.4.orig/std/flash/concurrent/Mutex.hx0000664000175000017500000000034613166552354021133 0ustar andyandy00000000000000package flash.concurrent; @:final @:require(flash11_4) extern class Mutex { function new() : Void; function lock() : Void; function tryLock() : Bool; function unlock() : Void; static var isSupported(default,never) : Bool; } haxe_3.4.4.orig/std/flash/desktop/Clipboard.hx0000664000175000017500000000121413166552354021212 0ustar andyandy00000000000000package flash.desktop; @:require(flash10) extern class Clipboard { var formats(default,never) : Array; function clear() : Void; function clearData(format : ClipboardFormats) : Void; function getData(format : ClipboardFormats, ?transferMode : ClipboardTransferMode) : flash.utils.Object; function hasFormat(format : ClipboardFormats) : Bool; function setData(format : ClipboardFormats, data : flash.utils.Object, serializable : Bool = true) : Bool; function setDataHandler(format : ClipboardFormats, handler : flash.utils.Function, serializable : Bool = true) : Bool; static var generalClipboard(default,never) : Clipboard; } haxe_3.4.4.orig/std/flash/desktop/ClipboardFormats.hx0000664000175000017500000000043713166552354022554 0ustar andyandy00000000000000package flash.desktop; @:fakeEnum(String) @:require(flash10) extern enum ClipboardFormats { AIR_PREFIX; BITMAP_FORMAT; FILE_LIST_FORMAT; FILE_PROMISE_LIST_FORMAT; FLASH_PREFIX; HTML_FORMAT; REFERENCE_PREFIX; RICH_TEXT_FORMAT; SERIALIZATION_PREFIX; TEXT_FORMAT; URL_FORMAT; } haxe_3.4.4.orig/std/flash/desktop/ClipboardTransferMode.hx0000664000175000017500000000025013166552354023523 0ustar andyandy00000000000000package flash.desktop; @:fakeEnum(String) @:require(flash10) extern enum ClipboardTransferMode { CLONE_ONLY; CLONE_PREFERRED; ORIGINAL_ONLY; ORIGINAL_PREFERRED; } haxe_3.4.4.orig/std/flash/display/AVLoader.hx0000664000175000017500000000013113166552354020741 0ustar andyandy00000000000000package flash.display; extern class AVLoader extends Loader { function new() : Void; } haxe_3.4.4.orig/std/flash/display/AVM1Movie.hx0000664000175000017500000000046213166552354021017 0ustar andyandy00000000000000package flash.display; extern class AVM1Movie extends DisplayObject { function new() : Void; function addCallback(functionName : String, closure : flash.utils.Function) : Void; function call(functionName : String, ?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Dynamic; } haxe_3.4.4.orig/std/flash/display/ActionScriptVersion.hx0000664000175000017500000000015513166552354023262 0ustar andyandy00000000000000package flash.display; @:fakeEnum(UInt) extern enum ActionScriptVersion { ACTIONSCRIPT2; ACTIONSCRIPT3; } haxe_3.4.4.orig/std/flash/display/Bitmap.hx0000664000175000017500000000041113166552354020521 0ustar andyandy00000000000000package flash.display; extern class Bitmap extends DisplayObject { var bitmapData : BitmapData; var pixelSnapping : PixelSnapping; var smoothing : Bool; function new(?bitmapData : BitmapData, ?pixelSnapping : PixelSnapping, smoothing : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/display/BitmapCompressColorSpace.hx0000664000175000017500000000023013166552354024207 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) enum BitmapCompressColorSpace { COLORSPACE_4_2_0; COLORSPACE_4_2_2; COLORSPACE_4_4_4; COLORSPACE_AUTO; } haxe_3.4.4.orig/std/flash/display/BitmapData.hx0000664000175000017500000001056313166552354021324 0ustar andyandy00000000000000package flash.display; extern class BitmapData implements IBitmapDrawable { var height(default,never) : Int; var rect(default,never) : flash.geom.Rectangle; var transparent(default,never) : Bool; var width(default,never) : Int; function new(width : Int, height : Int, transparent : Bool = true, fillColor : UInt = 0xFFFFFFFF) : Void; function applyFilter(sourceBitmapData : BitmapData, sourceRect : flash.geom.Rectangle, destPoint : flash.geom.Point, filter : flash.filters.BitmapFilter) : Void; function clone() : BitmapData; function colorTransform(rect : flash.geom.Rectangle, colorTransform : flash.geom.ColorTransform) : Void; function compare(otherBitmapData : BitmapData) : flash.utils.Object; function copyChannel(sourceBitmapData : BitmapData, sourceRect : flash.geom.Rectangle, destPoint : flash.geom.Point, sourceChannel : UInt, destChannel : UInt) : Void; function copyPixels(sourceBitmapData : BitmapData, sourceRect : flash.geom.Rectangle, destPoint : flash.geom.Point, ?alphaBitmapData : BitmapData, ?alphaPoint : flash.geom.Point, mergeAlpha : Bool = false) : Void; @:require(flash11_4) function copyPixelsToByteArray(rect : flash.geom.Rectangle, data : flash.utils.ByteArray) : Void; function dispose() : Void; function draw(source : IBitmapDrawable, ?matrix : flash.geom.Matrix, ?colorTransform : flash.geom.ColorTransform, ?blendMode : BlendMode, ?clipRect : flash.geom.Rectangle, smoothing : Bool = false) : Void; @:require(flash11_3) function drawWithQuality(source : IBitmapDrawable, ?matrix : flash.geom.Matrix, ?colorTransform : flash.geom.ColorTransform, ?blendMode : BlendMode, ?clipRect : flash.geom.Rectangle, smoothing : Bool = false, ?quality : StageQuality) : Void; @:require(flash11_3) function encode(rect : flash.geom.Rectangle, compressor : flash.utils.Object, ?byteArray : flash.utils.ByteArray) : flash.utils.ByteArray; function fillRect(rect : flash.geom.Rectangle, color : UInt) : Void; function floodFill(x : Int, y : Int, color : UInt) : Void; function generateFilterRect(sourceRect : flash.geom.Rectangle, filter : flash.filters.BitmapFilter) : flash.geom.Rectangle; function getColorBoundsRect(mask : UInt, color : UInt, findColor : Bool = true) : flash.geom.Rectangle; function getPixel(x : Int, y : Int) : UInt; function getPixel32(x : Int, y : Int) : UInt; function getPixels(rect : flash.geom.Rectangle) : flash.utils.ByteArray; @:require(flash10) function getVector(rect : flash.geom.Rectangle) : flash.Vector; @:require(flash10) function histogram(?hRect : flash.geom.Rectangle) : flash.Vector>; function hitTest(firstPoint : flash.geom.Point, firstAlphaThreshold : UInt, secondObject : flash.utils.Object, ?secondBitmapDataPoint : flash.geom.Point, secondAlphaThreshold : UInt = 1) : Bool; function lock() : Void; function merge(sourceBitmapData : BitmapData, sourceRect : flash.geom.Rectangle, destPoint : flash.geom.Point, redMultiplier : UInt, greenMultiplier : UInt, blueMultiplier : UInt, alphaMultiplier : UInt) : Void; function noise(randomSeed : Int, low : UInt = 0, high : UInt = 255, channelOptions : UInt = 7, grayScale : Bool = false) : Void; function paletteMap(sourceBitmapData : BitmapData, sourceRect : flash.geom.Rectangle, destPoint : flash.geom.Point, ?redArray : Array, ?greenArray : Array, ?blueArray : Array, ?alphaArray : Array) : Void; function perlinNoise(baseX : Float, baseY : Float, numOctaves : UInt, randomSeed : Int, stitch : Bool, fractalNoise : Bool, channelOptions : UInt = 7, grayScale : Bool = false, ?offsets : Array) : Void; function pixelDissolve(sourceBitmapData : BitmapData, sourceRect : flash.geom.Rectangle, destPoint : flash.geom.Point, randomSeed : Int = 0, numPixels : Int = 0, fillColor : UInt = 0) : Int; function scroll(x : Int, y : Int) : Void; function setPixel(x : Int, y : Int, color : UInt) : Void; function setPixel32(x : Int, y : Int, color : UInt) : Void; function setPixels(rect : flash.geom.Rectangle, inputByteArray : flash.utils.ByteArray) : Void; @:require(flash10) function setVector(rect : flash.geom.Rectangle, inputVector : flash.Vector) : Void; function threshold(sourceBitmapData : BitmapData, sourceRect : flash.geom.Rectangle, destPoint : flash.geom.Point, operation : String, threshold : UInt, color : UInt = 0, mask : UInt = 0xFFFFFFFF, copySource : Bool = false) : UInt; function unlock(?changeRect : flash.geom.Rectangle) : Void; } haxe_3.4.4.orig/std/flash/display/BitmapDataChannel.hx0000664000175000017500000000031413166552354022606 0ustar andyandy00000000000000package flash.display; extern class BitmapDataChannel { public static inline var ALPHA = 8; public static inline var BLUE = 4; public static inline var GREEN = 2; public static inline var RED = 1; } haxe_3.4.4.orig/std/flash/display/BitmapEncodingColorSpace.hx0000664000175000017500000000023713166552354024151 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum BitmapEncodingColorSpace { COLORSPACE_4_2_0; COLORSPACE_4_2_2; COLORSPACE_4_4_4; COLORSPACE_AUTO; } haxe_3.4.4.orig/std/flash/display/BlendMode.hx0000664000175000017500000000032313166552354021140 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum BlendMode { ADD; ALPHA; DARKEN; DIFFERENCE; ERASE; HARDLIGHT; INVERT; LAYER; LIGHTEN; MULTIPLY; NORMAL; OVERLAY; SCREEN; SHADER; SUBTRACT; } haxe_3.4.4.orig/std/flash/display/CapsStyle.hx0000664000175000017500000000013513166552354021217 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum CapsStyle { NONE; ROUND; SQUARE; } haxe_3.4.4.orig/std/flash/display/ColorCorrection.hx0000664000175000017500000000016513166552354022421 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) @:require(flash10_1) extern enum ColorCorrection { DEFAULT; OFF; ON; } haxe_3.4.4.orig/std/flash/display/ColorCorrectionSupport.hx0000664000175000017500000000022013166552354024006 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) @:require(flash10_1) extern enum ColorCorrectionSupport { DEFAULT_OFF; DEFAULT_ON; UNSUPPORTED; } haxe_3.4.4.orig/std/flash/display/DisplayObject.hx0000664000175000017500000000343313166552354022050 0ustar andyandy00000000000000package flash.display; extern class DisplayObject extends flash.events.EventDispatcher implements IBitmapDrawable { var accessibilityProperties : flash.accessibility.AccessibilityProperties; var alpha : Float; var blendMode : BlendMode; @:require(flash10) var blendShader(never,default) : Shader; var cacheAsBitmap : Bool; var filters : Array; var height : Float; var loaderInfo(default,never) : LoaderInfo; var mask : DisplayObject; var mouseX(default,never) : Float; var mouseY(default,never) : Float; var name : String; var opaqueBackground : Null; var parent(default,never) : DisplayObjectContainer; var root(default,never) : DisplayObject; var rotation : Float; @:require(flash10) var rotationX : Float; @:require(flash10) var rotationY : Float; @:require(flash10) var rotationZ : Float; var scale9Grid : flash.geom.Rectangle; var scaleX : Float; var scaleY : Float; @:require(flash10) var scaleZ : Float; var scrollRect : flash.geom.Rectangle; var stage(default,never) : Stage; var transform : flash.geom.Transform; var visible : Bool; var width : Float; var x : Float; var y : Float; @:require(flash10) var z : Float; function getBounds(targetCoordinateSpace : DisplayObject) : flash.geom.Rectangle; function getRect(targetCoordinateSpace : DisplayObject) : flash.geom.Rectangle; function globalToLocal(point : flash.geom.Point) : flash.geom.Point; @:require(flash10) function globalToLocal3D(point : flash.geom.Point) : flash.geom.Vector3D; function hitTestObject(obj : DisplayObject) : Bool; function hitTestPoint(x : Float, y : Float, shapeFlag : Bool = false) : Bool; @:require(flash10) function local3DToGlobal(point3d : flash.geom.Vector3D) : flash.geom.Point; function localToGlobal(point : flash.geom.Point) : flash.geom.Point; } haxe_3.4.4.orig/std/flash/display/DisplayObjectContainer.hx0000664000175000017500000000234613166552354023715 0ustar andyandy00000000000000package flash.display; extern class DisplayObjectContainer extends InteractiveObject { var mouseChildren : Bool; var numChildren(default,never) : Int; var tabChildren : Bool; var textSnapshot(default,never) : flash.text.TextSnapshot; function new() : Void; function addChild(child : DisplayObject) : DisplayObject; function addChildAt(child : DisplayObject, index : Int) : DisplayObject; function areInaccessibleObjectsUnderPoint(point : flash.geom.Point) : Bool; function contains(child : DisplayObject) : Bool; function getChildAt(index : Int) : DisplayObject; function getChildByName(name : String) : DisplayObject; function getChildIndex(child : DisplayObject) : Int; function getObjectsUnderPoint(point : flash.geom.Point) : Array; function removeChild(child : DisplayObject) : DisplayObject; function removeChildAt(index : Int) : DisplayObject; @:require(flash11) function removeChildren(beginIndex : Int = 0, endIndex : Int = 2147483647) : Void; function setChildIndex(child : DisplayObject, index : Int) : Void; @:require(flash11_8) function stopAllMovieClips() : Void; function swapChildren(child1 : DisplayObject, child2 : DisplayObject) : Void; function swapChildrenAt(index1 : Int, index2 : Int) : Void; } haxe_3.4.4.orig/std/flash/display/FocusDirection.hx0000664000175000017500000000016513166552354022233 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) @:require(flash10_1) extern enum FocusDirection { BOTTOM; NONE; TOP; } haxe_3.4.4.orig/std/flash/display/FrameLabel.hx0000664000175000017500000000032713166552354021305 0ustar andyandy00000000000000package flash.display; @:final extern class FrameLabel extends flash.events.EventDispatcher { var frame(default,never) : Int; var name(default,never) : String; function new(name : String, frame : Int) : Void; } haxe_3.4.4.orig/std/flash/display/GradientType.hx0000664000175000017500000000013213166552354021704 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum GradientType { LINEAR; RADIAL; } haxe_3.4.4.orig/std/flash/display/Graphics.hx0000664000175000017500000000553013166552354021054 0ustar andyandy00000000000000package flash.display; @:final extern class Graphics { function new() : Void; function beginBitmapFill(bitmap : BitmapData, ?matrix : flash.geom.Matrix, repeat : Bool = true, smooth : Bool = false) : Void; function beginFill(color : UInt, alpha : Float = 1) : Void; function beginGradientFill(type : GradientType, colors : Array, alphas : Array, ratios : Array, ?matrix : flash.geom.Matrix, ?spreadMethod : SpreadMethod, ?interpolationMethod : InterpolationMethod, focalPointRatio : Float = 0) : Void; @:require(flash10) function beginShaderFill(shader : Shader, ?matrix : flash.geom.Matrix) : Void; function clear() : Void; @:require(flash10) function copyFrom(sourceGraphics : Graphics) : Void; @:require(flash11) function cubicCurveTo(controlX1 : Float, controlY1 : Float, controlX2 : Float, controlY2 : Float, anchorX : Float, anchorY : Float) : Void; function curveTo(controlX : Float, controlY : Float, anchorX : Float, anchorY : Float) : Void; function drawCircle(x : Float, y : Float, radius : Float) : Void; function drawEllipse(x : Float, y : Float, width : Float, height : Float) : Void; @:require(flash10) function drawGraphicsData(graphicsData : flash.Vector) : Void; @:require(flash10) function drawPath(commands : flash.Vector, data : flash.Vector, ?winding : GraphicsPathWinding) : Void; function drawRect(x : Float, y : Float, width : Float, height : Float) : Void; function drawRoundRect(x : Float, y : Float, width : Float, height : Float, ellipseWidth : Float, ellipseHeight : Null = 0) : Void; function drawRoundRectComplex(x : Float, y : Float, width : Float, height : Float, topLeftRadius : Float, topRightRadius : Float, bottomLeftRadius : Float, bottomRightRadius : Float) : Void; @:require(flash10) function drawTriangles(vertices : flash.Vector, ?indices : flash.Vector, ?uvtData : flash.Vector, ?culling : TriangleCulling) : Void; function endFill() : Void; @:require(flash10) function lineBitmapStyle(bitmap : BitmapData, ?matrix : flash.geom.Matrix, repeat : Bool = true, smooth : Bool = false) : Void; function lineGradientStyle(type : GradientType, colors : Array, alphas : Array, ratios : Array, ?matrix : flash.geom.Matrix, ?spreadMethod : SpreadMethod, ?interpolationMethod : InterpolationMethod, focalPointRatio : Float = 0) : Void; @:require(flash10) function lineShaderStyle(shader : Shader, ?matrix : flash.geom.Matrix) : Void; function lineStyle(thickness : Null = 0, color : UInt = 0, alpha : Float = 1, pixelHinting : Bool = false, ?scaleMode : LineScaleMode, ?caps : CapsStyle, ?joints : JointStyle, miterLimit : Float = 3) : Void; function lineTo(x : Float, y : Float) : Void; function moveTo(x : Float, y : Float) : Void; @:require(flash11_6) function readGraphicsData(recurse : Bool = true) : flash.Vector; } haxe_3.4.4.orig/std/flash/display/GraphicsBitmapFill.hx0000664000175000017500000000052713166552354023021 0ustar andyandy00000000000000package flash.display; @:final extern class GraphicsBitmapFill implements IGraphicsData implements IGraphicsFill { var bitmapData : BitmapData; var matrix : flash.geom.Matrix; var repeat : Bool; var smooth : Bool; function new(?bitmapData : BitmapData, ?matrix : flash.geom.Matrix, repeat : Bool = true, smooth : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/display/GraphicsEndFill.hx0000664000175000017500000000020313166552354022302 0ustar andyandy00000000000000package flash.display; extern class GraphicsEndFill implements IGraphicsData implements IGraphicsFill { function new() : Void; } haxe_3.4.4.orig/std/flash/display/GraphicsGradientFill.hx0000664000175000017500000000115513166552354023340 0ustar andyandy00000000000000package flash.display; @:final extern class GraphicsGradientFill implements IGraphicsData implements IGraphicsFill { var alphas : Array; var colors : Array; var focalPointRatio : Float; var interpolationMethod : InterpolationMethod; var matrix : flash.geom.Matrix; var ratios : Array; var spreadMethod : SpreadMethod; var type : GradientType; function new(?type : GradientType, ?colors : Array, ?alphas : Array, ?ratios : Array, ?matrix : flash.geom.Matrix, ?spreadMethod : SpreadMethod, ?interpolationMethod : InterpolationMethod, focalPointRatio : Float = 0) : Void; } haxe_3.4.4.orig/std/flash/display/GraphicsPath.hx0000664000175000017500000000141613166552354021670 0ustar andyandy00000000000000package flash.display; @:final extern class GraphicsPath implements IGraphicsData implements IGraphicsPath { var commands : flash.Vector; var data : flash.Vector; var winding : GraphicsPathWinding; function new(?commands : flash.Vector, ?data : flash.Vector, ?winding : GraphicsPathWinding) : Void; @:require(flash11) function cubicCurveTo(controlX1 : Float, controlY1 : Float, controlX2 : Float, controlY2 : Float, anchorX : Float, anchorY : Float) : Void; function curveTo(controlX : Float, controlY : Float, anchorX : Float, anchorY : Float) : Void; function lineTo(x : Float, y : Float) : Void; function moveTo(x : Float, y : Float) : Void; function wideLineTo(x : Float, y : Float) : Void; function wideMoveTo(x : Float, y : Float) : Void; } haxe_3.4.4.orig/std/flash/display/GraphicsPathCommand.hx0000664000175000017500000000056113166552354023167 0ustar andyandy00000000000000package flash.display; extern class GraphicsPathCommand { public static inline var LINE_TO = 2; public static inline var MOVE_TO = 1; public static inline var CURVE_TO = 3; @:require(flash11) public static inline var CUBIC_CURVE_TO = 6; public static inline var WIDE_LINE_TO = 5; public static inline var WIDE_MOVE_TO = 4; public static inline var NO_OP = 0; } haxe_3.4.4.orig/std/flash/display/GraphicsPathWinding.hx0000664000175000017500000000014513166552354023206 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum GraphicsPathWinding { EVEN_ODD; NON_ZERO; } haxe_3.4.4.orig/std/flash/display/GraphicsShaderFill.hx0000664000175000017500000000036213166552354023010 0ustar andyandy00000000000000package flash.display; @:final extern class GraphicsShaderFill implements IGraphicsData implements IGraphicsFill { var matrix : flash.geom.Matrix; var shader : Shader; function new(?shader : Shader, ?matrix : flash.geom.Matrix) : Void; } haxe_3.4.4.orig/std/flash/display/GraphicsSolidFill.hx0000664000175000017500000000032713166552354022655 0ustar andyandy00000000000000package flash.display; @:final extern class GraphicsSolidFill implements IGraphicsData implements IGraphicsFill { var alpha : Float; var color : UInt; function new(color : UInt = 0, alpha : Float = 1) : Void; } haxe_3.4.4.orig/std/flash/display/GraphicsStroke.hx0000664000175000017500000000076113166552354022245 0ustar andyandy00000000000000package flash.display; @:final extern class GraphicsStroke implements IGraphicsData implements IGraphicsStroke { var caps : CapsStyle; var fill : IGraphicsFill; var joints : JointStyle; var miterLimit : Float; var pixelHinting : Bool; var scaleMode : LineScaleMode; var thickness : Float; function new(thickness : Float = 0./*NaN*/, pixelHinting : Bool = false, ?scaleMode : LineScaleMode, ?caps : CapsStyle, ?joints : JointStyle, miterLimit : Float = 3, ?fill : IGraphicsFill) : Void; } haxe_3.4.4.orig/std/flash/display/GraphicsTrianglePath.hx0000664000175000017500000000062413166552354023356 0ustar andyandy00000000000000package flash.display; @:final extern class GraphicsTrianglePath implements IGraphicsData implements IGraphicsPath { var culling : TriangleCulling; var indices : flash.Vector; var uvtData : flash.Vector; var vertices : flash.Vector; function new(?vertices : flash.Vector, ?indices : flash.Vector, ?uvtData : flash.Vector, ?culling : TriangleCulling) : Void; } haxe_3.4.4.orig/std/flash/display/IBitmapCompressOptions.hx0000664000175000017500000000010413166552354023721 0ustar andyandy00000000000000package flash.display; extern interface IBitmapCompressOptions { } haxe_3.4.4.orig/std/flash/display/IBitmapDrawable.hx0000664000175000017500000000007513166552354022302 0ustar andyandy00000000000000package flash.display; extern interface IBitmapDrawable { } haxe_3.4.4.orig/std/flash/display/IDrawCommand.hx0000664000175000017500000000007213166552354021615 0ustar andyandy00000000000000package flash.display; extern interface IDrawCommand { } haxe_3.4.4.orig/std/flash/display/IGraphicsData.hx0000664000175000017500000000007313166552354021754 0ustar andyandy00000000000000package flash.display; extern interface IGraphicsData { } haxe_3.4.4.orig/std/flash/display/IGraphicsFill.hx0000664000175000017500000000007313166552354021771 0ustar andyandy00000000000000package flash.display; extern interface IGraphicsFill { } haxe_3.4.4.orig/std/flash/display/IGraphicsPath.hx0000664000175000017500000000007313166552354021777 0ustar andyandy00000000000000package flash.display; extern interface IGraphicsPath { } haxe_3.4.4.orig/std/flash/display/IGraphicsStroke.hx0000664000175000017500000000007513166552354022354 0ustar andyandy00000000000000package flash.display; extern interface IGraphicsStroke { } haxe_3.4.4.orig/std/flash/display/InteractiveObject.hx0000664000175000017500000000104413166552354022714 0ustar andyandy00000000000000package flash.display; extern class InteractiveObject extends DisplayObject { var accessibilityImplementation : flash.accessibility.AccessibilityImplementation; var contextMenu : flash.ui.ContextMenu; var doubleClickEnabled : Bool; var focusRect : Dynamic; var mouseEnabled : Bool; @:require(flash11) var needsSoftKeyboard : Bool; @:require(flash11) var softKeyboardInputAreaOfInterest : flash.geom.Rectangle; var tabEnabled : Bool; var tabIndex : Int; function new() : Void; @:require(flash11) function requestSoftKeyboard() : Bool; } haxe_3.4.4.orig/std/flash/display/InterpolationMethod.hx0000664000175000017500000000014213166552354023276 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum InterpolationMethod { LINEAR_RGB; RGB; } haxe_3.4.4.orig/std/flash/display/JPEGCompressOptions.hx0000664000175000017500000000024713166552354023131 0ustar andyandy00000000000000package flash.display; @:final extern class JPEGCompressOptions implements IBitmapCompressOptions { var quality : UInt; function new(quality : UInt = 80) : Void; } haxe_3.4.4.orig/std/flash/display/JPEGEncoderOptions.hx0000664000175000017500000000020413166552354022706 0ustar andyandy00000000000000package flash.display; @:final extern class JPEGEncoderOptions { var quality : UInt; function new(quality : UInt = 80) : Void; } haxe_3.4.4.orig/std/flash/display/JPEGXRCompressOptions.hx0000664000175000017500000000042613166552354023402 0ustar andyandy00000000000000package flash.display; @:final extern class JPEGXRCompressOptions implements IBitmapCompressOptions { var colorSpace : String; var quantization : UInt; var trimFlexBits : UInt; function new(quantization : UInt = 20, ?colorSpace : String, trimFlexBits : UInt = 0) : Void; } haxe_3.4.4.orig/std/flash/display/JPEGXREncoderOptions.hx0000664000175000017500000000042713166552354023167 0ustar andyandy00000000000000package flash.display; @:final extern class JPEGXREncoderOptions { var colorSpace : BitmapEncodingColorSpace; var quantization : UInt; var trimFlexBits : UInt; function new(quantization : UInt = 20, ?colorSpace : BitmapEncodingColorSpace, trimFlexBits : UInt = 0) : Void; } haxe_3.4.4.orig/std/flash/display/JointStyle.hx0000664000175000017500000000013613166552354021415 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum JointStyle { BEVEL; MITER; ROUND; } haxe_3.4.4.orig/std/flash/display/LineScaleMode.hx0000664000175000017500000000016113166552354021753 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum LineScaleMode { HORIZONTAL; NONE; NORMAL; VERTICAL; } haxe_3.4.4.orig/std/flash/display/Loader.hx0000664000175000017500000000114313166552354020516 0ustar andyandy00000000000000package flash.display; extern class Loader extends DisplayObjectContainer { var content(default,never) : DisplayObject; var contentLoaderInfo(default,never) : LoaderInfo; @:require(flash10_1) var uncaughtErrorEvents(default,never) : flash.events.UncaughtErrorEvents; function new() : Void; function close() : Void; function load(request : flash.net.URLRequest, ?context : flash.system.LoaderContext) : Void; function loadBytes(bytes : flash.utils.ByteArray, ?context : flash.system.LoaderContext) : Void; function unload() : Void; @:require(flash10) function unloadAndStop(gc : Bool = true) : Void; } haxe_3.4.4.orig/std/flash/display/LoaderInfo.hx0000664000175000017500000000241713166552354021337 0ustar andyandy00000000000000package flash.display; extern class LoaderInfo extends flash.events.EventDispatcher { var actionScriptVersion(default,never) : ActionScriptVersion; var applicationDomain(default,never) : flash.system.ApplicationDomain; var bytes(default,never) : flash.utils.ByteArray; var bytesLoaded(default,never) : UInt; var bytesTotal(default,never) : UInt; var childAllowsParent(default,never) : Bool; @:require(flash11_4) var childSandboxBridge : Dynamic; var content(default,never) : DisplayObject; var contentType(default,never) : String; var frameRate(default,never) : Float; var height(default,never) : Int; @:require(flash10_1) var isURLInaccessible(default,never) : Bool; var loader(default,never) : Loader; var loaderURL(default,never) : String; var parameters(default,never) : Dynamic; var parentAllowsChild(default,never) : Bool; @:require(flash11_4) var parentSandboxBridge : Dynamic; var sameDomain(default,never) : Bool; var sharedEvents(default,never) : flash.events.EventDispatcher; var swfVersion(default,never) : UInt; @:require(flash10_1) var uncaughtErrorEvents(default,never) : flash.events.UncaughtErrorEvents; var url(default,never) : String; var width(default,never) : Int; static function getLoaderInfoByDefinition(object : Dynamic) : LoaderInfo; } haxe_3.4.4.orig/std/flash/display/MorphShape.hx0000664000175000017500000000011213166552354021351 0ustar andyandy00000000000000package flash.display; extern class MorphShape extends DisplayObject { } haxe_3.4.4.orig/std/flash/display/MovieClip.hx0000664000175000017500000000201013166552354021171 0ustar andyandy00000000000000package flash.display; extern class MovieClip extends Sprite #if !flash_strict implements Dynamic #end { var currentFrame(default,never) : Int; @:require(flash10) var currentFrameLabel(default,never) : String; var currentLabel(default,never) : String; var currentLabels(default,never) : Array; var currentScene(default,never) : Scene; var enabled : Bool; var framesLoaded(default,never) : Int; @:require(flash11) var isPlaying(default,never) : Bool; var scenes(default,never) : Array; var totalFrames(default,never) : Int; var trackAsMenu : Bool; function new() : Void; function addFrameScript(?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void; function gotoAndPlay(frame : flash.utils.Object, ?scene : String) : Void; function gotoAndStop(frame : flash.utils.Object, ?scene : String) : Void; function nextFrame() : Void; function nextScene() : Void; function play() : Void; function prevFrame() : Void; function prevScene() : Void; function stop() : Void; } haxe_3.4.4.orig/std/flash/display/NativeMenu.hx0000664000175000017500000000020613166552354021362 0ustar andyandy00000000000000package flash.display; @:require(flash10_1) extern class NativeMenu extends flash.events.EventDispatcher { function new() : Void; } haxe_3.4.4.orig/std/flash/display/NativeMenuItem.hx0000664000175000017500000000023713166552354022205 0ustar andyandy00000000000000package flash.display; @:require(flash10_1) extern class NativeMenuItem extends flash.events.EventDispatcher { var enabled : Bool; function new() : Void; } haxe_3.4.4.orig/std/flash/display/PNGCompressOptions.hx0000664000175000017500000000016613166552354023030 0ustar andyandy00000000000000package flash.display; extern class PNGCompressOptions implements IBitmapCompressOptions { function new() : Void; } haxe_3.4.4.orig/std/flash/display/PNGEncoderOptions.hx0000664000175000017500000000022613166552354022611 0ustar andyandy00000000000000package flash.display; @:final extern class PNGEncoderOptions { var fastCompression : Bool; function new(fastCompression : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/display/PixelSnapping.hx0000664000175000017500000000014113166552354022066 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum PixelSnapping { ALWAYS; AUTO; NEVER; } haxe_3.4.4.orig/std/flash/display/SWFVersion.hx0000664000175000017500000000105713166552354021321 0ustar andyandy00000000000000package flash.display; extern class SWFVersion { static var FLASH1(default,never) : UInt; static var FLASH10(default,never) : UInt; static var FLASH11(default,never) : UInt; static var FLASH12(default,never) : UInt; static var FLASH2(default,never) : UInt; static var FLASH3(default,never) : UInt; static var FLASH4(default,never) : UInt; static var FLASH5(default,never) : UInt; static var FLASH6(default,never) : UInt; static var FLASH7(default,never) : UInt; static var FLASH8(default,never) : UInt; static var FLASH9(default,never) : UInt; } haxe_3.4.4.orig/std/flash/display/Scene.hx0000664000175000017500000000040113166552354020341 0ustar andyandy00000000000000package flash.display; @:final extern class Scene { var labels(default,never) : Array; var name(default,never) : String; var numFrames(default,never) : Int; function new(name : String, labels : Array, numFrames : Int) : Void; } haxe_3.4.4.orig/std/flash/display/Shader.hx0000664000175000017500000000035413166552354020521 0ustar andyandy00000000000000package flash.display; @:require(flash10) extern class Shader { var byteCode(never,default) : flash.utils.ByteArray; var data : ShaderData; var precisionHint : ShaderPrecision; function new(?code : flash.utils.ByteArray) : Void; } haxe_3.4.4.orig/std/flash/display/ShaderData.hx0000664000175000017500000000017713166552354021316 0ustar andyandy00000000000000package flash.display; extern class ShaderData implements Dynamic { function new(byteCode : flash.utils.ByteArray) : Void; } haxe_3.4.4.orig/std/flash/display/ShaderInput.hx0000664000175000017500000000035013166552354021535 0ustar andyandy00000000000000package flash.display; @:final extern class ShaderInput implements Dynamic { var channels(default,never) : Int; var height : Int; var index(default,never) : Int; var input : Dynamic; var width : Int; function new() : Void; } haxe_3.4.4.orig/std/flash/display/ShaderJob.hx0000664000175000017500000000060313166552354021151 0ustar andyandy00000000000000package flash.display; extern class ShaderJob extends flash.events.EventDispatcher { var height : Int; var progress(default,never) : Float; var shader : Shader; var target : Dynamic; var width : Int; function new(?shader : Shader, ?target : Dynamic, width : Int = 0, height : Int = 0) : Void; function cancel() : Void; function start(waitForCompletion : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/display/ShaderParameter.hx0000664000175000017500000000030213166552354022353 0ustar andyandy00000000000000package flash.display; @:final extern class ShaderParameter implements Dynamic { var index(default,never) : Int; var type(default,never) : ShaderParameterType; var value : Array; } haxe_3.4.4.orig/std/flash/display/ShaderParameterType.hx0000664000175000017500000000032013166552354023215 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum ShaderParameterType { BOOL; BOOL2; BOOL3; BOOL4; FLOAT; FLOAT2; FLOAT3; FLOAT4; INT; INT2; INT3; INT4; MATRIX2X2; MATRIX3X3; MATRIX4X4; } haxe_3.4.4.orig/std/flash/display/ShaderPrecision.hx0000664000175000017500000000013113166552354022366 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum ShaderPrecision { FAST; FULL; } haxe_3.4.4.orig/std/flash/display/Shape.hx0000664000175000017500000000020613166552354020347 0ustar andyandy00000000000000package flash.display; extern class Shape extends DisplayObject { var graphics(default,never) : Graphics; function new() : Void; } haxe_3.4.4.orig/std/flash/display/SimpleButton.hx0000664000175000017500000000072313166552354021740 0ustar andyandy00000000000000package flash.display; extern class SimpleButton extends InteractiveObject { var downState : DisplayObject; var enabled : Bool; var hitTestState : DisplayObject; var overState : DisplayObject; var soundTransform : flash.media.SoundTransform; var trackAsMenu : Bool; var upState : DisplayObject; var useHandCursor : Bool; function new(?upState : DisplayObject, ?overState : DisplayObject, ?downState : DisplayObject, ?hitTestState : DisplayObject) : Void; } haxe_3.4.4.orig/std/flash/display/SpreadMethod.hx0000664000175000017500000000014113166552354021664 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum SpreadMethod { PAD; REFLECT; REPEAT; } haxe_3.4.4.orig/std/flash/display/Sprite.hx0000664000175000017500000000117613166552354020564 0ustar andyandy00000000000000package flash.display; extern class Sprite extends DisplayObjectContainer { var buttonMode : Bool; var dropTarget(default,never) : DisplayObject; var graphics(default,never) : Graphics; var hitArea : Sprite; var soundTransform : flash.media.SoundTransform; var useHandCursor : Bool; function new() : Void; function startDrag(lockCenter : Bool = false, ?bounds : flash.geom.Rectangle) : Void; @:require(flash10_1) function startTouchDrag(touchPointID : Int, lockCenter : Bool = false, ?bounds : flash.geom.Rectangle) : Void; function stopDrag() : Void; @:require(flash10_1) function stopTouchDrag(touchPointID : Int) : Void; } haxe_3.4.4.orig/std/flash/display/Stage.hx0000664000175000017500000000261713166552354020362 0ustar andyandy00000000000000package flash.display; extern class Stage extends DisplayObjectContainer { var align : StageAlign; var allowsFullScreen(default,never) : Bool; @:require(flash11_3) var allowsFullScreenInteractive(default,never) : Bool; var browserZoomFactor(default,never) : Float; @:require(flash10_2) var color : UInt; @:require(flash10) var colorCorrection : ColorCorrection; @:require(flash10) var colorCorrectionSupport(default,never) : ColorCorrectionSupport; @:require(flash11_4) var contentsScaleFactor(default,never) : Float; @:require(flash11) var displayContextInfo(default,never) : String; var displayState : StageDisplayState; var focus : InteractiveObject; var frameRate : Float; var fullScreenHeight(default,never) : UInt; var fullScreenSourceRect : flash.geom.Rectangle; var fullScreenWidth(default,never) : UInt; @:require(flash11_2) var mouseLock : Bool; var quality : StageQuality; var scaleMode : StageScaleMode; var showDefaultContextMenu : Bool; @:require(flash11) var softKeyboardRect(default,never) : flash.geom.Rectangle; @:require(flash11) var stage3Ds(default,never) : flash.Vector; var stageFocusRect : Bool; var stageHeight : Int; @:require(flash10_2) var stageVideos(default,never) : flash.Vector; var stageWidth : Int; @:require(flash10_1) var wmodeGPU(default,never) : Bool; function invalidate() : Void; function isFocusInaccessible() : Bool; } haxe_3.4.4.orig/std/flash/display/Stage3D.hx0000664000175000017500000000065713166552354020553 0ustar andyandy00000000000000package flash.display; @:require(flash11) extern class Stage3D extends flash.events.EventDispatcher { var context3D(default,never) : flash.display3D.Context3D; var visible : Bool; var x : Float; var y : Float; function requestContext3D(?context3DRenderMode : String, ?profile : flash.display3D.Context3DProfile) : Void; @:require(flash12) function requestContext3DMatchingProfiles(profiles : flash.Vector) : Void; } haxe_3.4.4.orig/std/flash/display/StageAlign.hx0000664000175000017500000000023013166552354021322 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum StageAlign { BOTTOM; BOTTOM_LEFT; BOTTOM_RIGHT; LEFT; RIGHT; TOP; TOP_LEFT; TOP_RIGHT; } haxe_3.4.4.orig/std/flash/display/StageDisplayState.hx0000664000175000017500000000017613166552354022707 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum StageDisplayState { FULL_SCREEN; FULL_SCREEN_INTERACTIVE; NORMAL; } haxe_3.4.4.orig/std/flash/display/StageQuality.hx0000664000175000017500000000024313166552354021724 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum StageQuality { BEST; HIGH; HIGH_16X16; HIGH_16X16_LINEAR; HIGH_8X8; HIGH_8X8_LINEAR; LOW; MEDIUM; } haxe_3.4.4.orig/std/flash/display/StageScaleMode.hx0000664000175000017500000000017013166552354022127 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum StageScaleMode { EXACT_FIT; NO_BORDER; NO_SCALE; SHOW_ALL; } haxe_3.4.4.orig/std/flash/display/StageWorker.hx0000664000175000017500000000027013166552354021545 0ustar andyandy00000000000000package flash.display; @:require(flash11_2) @:final extern class StageWorker extends Sprite { var scaleMode : String; var viewport : flash.geom.Rectangle; function new() : Void; } haxe_3.4.4.orig/std/flash/display/TriangleCulling.hx0000664000175000017500000000015013166552354022370 0ustar andyandy00000000000000package flash.display; @:fakeEnum(String) extern enum TriangleCulling { NEGATIVE; NONE; POSITIVE; } haxe_3.4.4.orig/std/flash/display/Worker.hx0000664000175000017500000000044613166552354020566 0ustar andyandy00000000000000package flash.display; @:require(flash11_2) @:final extern class Worker extends flash.events.EventDispatcher { var running(default,null) : Bool; var view(default,null) : StageWorker; function new() : Void; function load(request : flash.net.URLRequest) : Void; function unload() : Void; } haxe_3.4.4.orig/std/flash/display3D/Context3D.hx0000664000175000017500000000765113166552354021324 0ustar andyandy00000000000000package flash.display3D; @:final extern class Context3D extends flash.events.EventDispatcher { var backBufferHeight(default,never) : Int; var backBufferWidth(default,never) : Int; var driverInfo(default,never) : String; var enableErrorChecking : Bool; var maxBackBufferHeight : Int; var maxBackBufferWidth : Int; @:require(flash12) var profile(default,never) : String; var totalGPUMemory(default,never) : Float; function clear(red : Float = 0, green : Float = 0, blue : Float = 0, alpha : Float = 1, depth : Float = 1, stencil : UInt = 0, mask : UInt = 0xFFFFFFFF) : Void; function configureBackBuffer(width : Int, height : Int, antiAlias : Int, enableDepthAndStencil : Bool = true, wantsBestResolution : Bool = false, wantsBestResolutionOnBrowserZoom : Bool = false) : Void; function createCubeTexture(size : Int, format : Context3DTextureFormat, optimizeForRenderToTexture : Bool, streamingLevels : Int = 0) : flash.display3D.textures.CubeTexture; function createIndexBuffer(numIndices : Int, ?bufferUsage : Context3DBufferUsage) : IndexBuffer3D; function createProgram() : Program3D; @:require(flash11_8) function createRectangleTexture(width : Int, height : Int, format : Context3DTextureFormat, optimizeForRenderToTexture : Bool) : flash.display3D.textures.RectangleTexture; function createTexture(width : Int, height : Int, format : Context3DTextureFormat, optimizeForRenderToTexture : Bool, streamingLevels : Int = 0) : flash.display3D.textures.Texture; function createVertexBuffer(numVertices : Int, data32PerVertex : Int, ?bufferUsage : Context3DBufferUsage) : VertexBuffer3D; function createVideoTexture() : flash.display3D.textures.VideoTexture; function dispose(recreate : Bool = true) : Void; function drawToBitmapData(destination : flash.display.BitmapData) : Void; function drawTriangles(indexBuffer : IndexBuffer3D, firstIndex : Int = 0, numTriangles : Int = -1) : Void; function present() : Void; function setBlendFactors(sourceFactor : Context3DBlendFactor, destinationFactor : Context3DBlendFactor) : Void; function setColorMask(red : Bool, green : Bool, blue : Bool, alpha : Bool) : Void; function setCulling(triangleFaceToCull : Context3DTriangleFace) : Void; function setDepthTest(depthMask : Bool, passCompareMode : Context3DCompareMode) : Void; function setProgram(program : Program3D) : Void; @:require(flash11_2) function setProgramConstantsFromByteArray(programType : Context3DProgramType, firstRegister : Int, numRegisters : Int, data : flash.utils.ByteArray, byteArrayOffset : UInt) : Void; function setProgramConstantsFromMatrix(programType : Context3DProgramType, firstRegister : Int, matrix : flash.geom.Matrix3D, transposedMatrix : Bool = false) : Void; function setProgramConstantsFromVector(programType : Context3DProgramType, firstRegister : Int, data : flash.Vector, numRegisters : Int = -1) : Void; function setRenderToBackBuffer() : Void; function setRenderToTexture(texture : flash.display3D.textures.TextureBase, enableDepthAndStencil : Bool = false, antiAlias : Int = 0, surfaceSelector : Int = 0, colorOutputIndex : Int = 0) : Void; @:require(flash11_6) function setSamplerStateAt(sampler : Int, wrap : Context3DWrapMode, filter : Context3DTextureFilter, mipfilter : Context3DMipFilter) : Void; function setScissorRectangle(rectangle : flash.geom.Rectangle) : Void; function setStencilActions(?triangleFace : Context3DTriangleFace, ?compareMode : Context3DCompareMode, ?actionOnBothPass : Context3DStencilAction, ?actionOnDepthFail : Context3DStencilAction, ?actionOnDepthPassStencilFail : Context3DStencilAction) : Void; function setStencilReferenceValue(referenceValue : UInt, readMask : UInt = 255, writeMask : UInt = 255) : Void; function setTextureAt(sampler : Int, texture : flash.display3D.textures.TextureBase) : Void; function setVertexBufferAt(index : Int, buffer : VertexBuffer3D, bufferOffset : Int = 0, ?format : Context3DVertexBufferFormat) : Void; static var supportsVideoTexture(default,never) : Bool; } haxe_3.4.4.orig/std/flash/display3D/Context3DBlendFactor.hx0000664000175000017500000000042313166552354023416 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DBlendFactor { DESTINATION_ALPHA; DESTINATION_COLOR; ONE; ONE_MINUS_DESTINATION_ALPHA; ONE_MINUS_DESTINATION_COLOR; ONE_MINUS_SOURCE_ALPHA; ONE_MINUS_SOURCE_COLOR; SOURCE_ALPHA; SOURCE_COLOR; ZERO; } haxe_3.4.4.orig/std/flash/display3D/Context3DBufferUsage.hx0000664000175000017500000000020213166552354023424 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) @:require(flash12) extern enum Context3DBufferUsage { DYNAMIC_DRAW; STATIC_DRAW; } haxe_3.4.4.orig/std/flash/display3D/Context3DClearMask.hx0000664000175000017500000000033613166552354023100 0ustar andyandy00000000000000package flash.display3D; extern class Context3DClearMask { static var ALL(default,never) : Int; static var COLOR(default,never) : Int; static var DEPTH(default,never) : Int; static var STENCIL(default,never) : Int; } haxe_3.4.4.orig/std/flash/display3D/Context3DCompareMode.hx0000664000175000017500000000024513166552354023430 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DCompareMode { ALWAYS; EQUAL; GREATER; GREATER_EQUAL; LESS; LESS_EQUAL; NEVER; NOT_EQUAL; } haxe_3.4.4.orig/std/flash/display3D/Context3DFillMode.hx0000664000175000017500000000016613166552354022732 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) @:require(flash16) extern enum Context3DFillMode { SOLID; WIREFRAME; } haxe_3.4.4.orig/std/flash/display3D/Context3DMipFilter.hx0000664000175000017500000000016313166552354023127 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DMipFilter { MIPLINEAR; MIPNEAREST; MIPNONE; } haxe_3.4.4.orig/std/flash/display3D/Context3DProfile.hx0000664000175000017500000000027213166552354022635 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DProfile { BASELINE; BASELINE_CONSTRAINED; BASELINE_EXTENDED; STANDARD; STANDARD_CONSTRAINED; STANDARD_EXTENDED; } haxe_3.4.4.orig/std/flash/display3D/Context3DProgramType.hx0000664000175000017500000000014613166552354023506 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DProgramType { FRAGMENT; VERTEX; } haxe_3.4.4.orig/std/flash/display3D/Context3DRenderMode.hx0000664000175000017500000000014313166552354023256 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DRenderMode { AUTO; SOFTWARE; } haxe_3.4.4.orig/std/flash/display3D/Context3DStencilAction.hx0000664000175000017500000000027513166552354023777 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DStencilAction { DECREMENT_SATURATE; DECREMENT_WRAP; INCREMENT_SATURATE; INCREMENT_WRAP; INVERT; KEEP; SET; ZERO; } haxe_3.4.4.orig/std/flash/display3D/Context3DTextureFilter.hx0000664000175000017500000000025013166552354024037 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DTextureFilter { ANISOTROPIC16X; ANISOTROPIC2X; ANISOTROPIC4X; ANISOTROPIC8X; LINEAR; NEAREST; } haxe_3.4.4.orig/std/flash/display3D/Context3DTextureFormat.hx0000664000175000017500000000025013166552354024042 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DTextureFormat { BGRA; BGRA_PACKED; BGR_PACKED; COMPRESSED; COMPRESSED_ALPHA; RGBA_HALF_FLOAT; } haxe_3.4.4.orig/std/flash/display3D/Context3DTriangleFace.hx0000664000175000017500000000017213166552354023560 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DTriangleFace { BACK; FRONT; FRONT_AND_BACK; NONE; } haxe_3.4.4.orig/std/flash/display3D/Context3DVertexBufferFormat.hx0000664000175000017500000000021313166552354025010 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DVertexBufferFormat { BYTES_4; FLOAT_1; FLOAT_2; FLOAT_3; FLOAT_4; } haxe_3.4.4.orig/std/flash/display3D/Context3DWrapMode.hx0000664000175000017500000000020613166552354022750 0ustar andyandy00000000000000package flash.display3D; @:fakeEnum(String) extern enum Context3DWrapMode { CLAMP; CLAMP_U_REPEAT_V; REPEAT; REPEAT_U_CLAMP_V; } haxe_3.4.4.orig/std/flash/display3D/IndexBuffer3D.hx0000664000175000017500000000046613166552354022076 0ustar andyandy00000000000000package flash.display3D; @:final extern class IndexBuffer3D { function dispose() : Void; function uploadFromByteArray(data : flash.utils.ByteArray, byteArrayOffset : Int, startOffset : Int, count : Int) : Void; function uploadFromVector(data : flash.Vector, startOffset : Int, count : Int) : Void; } haxe_3.4.4.orig/std/flash/display3D/Program3D.hx0000664000175000017500000000030213166552354021271 0ustar andyandy00000000000000package flash.display3D; @:final extern class Program3D { function dispose() : Void; function upload(vertexProgram : flash.utils.ByteArray, fragmentProgram : flash.utils.ByteArray) : Void; } haxe_3.4.4.orig/std/flash/display3D/VertexBuffer3D.hx0000664000175000017500000000047413166552354022303 0ustar andyandy00000000000000package flash.display3D; extern class VertexBuffer3D { function dispose() : Void; function uploadFromByteArray(data : flash.utils.ByteArray, byteArrayOffset : Int, startVertex : Int, numVertices : Int) : Void; function uploadFromVector(data : flash.Vector, startVertex : Int, numVertices : Int) : Void; } haxe_3.4.4.orig/std/flash/display3D/textures/CubeTexture.hx0000664000175000017500000000071113166552354023621 0ustar andyandy00000000000000package flash.display3D.textures; @:final extern class CubeTexture extends TextureBase { function uploadCompressedTextureFromByteArray(data : flash.utils.ByteArray, byteArrayOffset : UInt, async : Bool = false) : Void; function uploadFromBitmapData(source : flash.display.BitmapData, side : UInt, miplevel : UInt = 0) : Void; function uploadFromByteArray(data : flash.utils.ByteArray, byteArrayOffset : UInt, side : UInt, miplevel : UInt = 0) : Void; } haxe_3.4.4.orig/std/flash/display3D/textures/RectangleTexture.hx0000664000175000017500000000043713166552354024654 0ustar andyandy00000000000000package flash.display3D.textures; @:final extern class RectangleTexture extends TextureBase { function new() : Void; function uploadFromBitmapData(source : flash.display.BitmapData) : Void; function uploadFromByteArray(data : flash.utils.ByteArray, byteArrayOffset : UInt) : Void; } haxe_3.4.4.orig/std/flash/display3D/textures/Texture.hx0000664000175000017500000000065313166552354023027 0ustar andyandy00000000000000package flash.display3D.textures; @:final extern class Texture extends TextureBase { function uploadCompressedTextureFromByteArray(data : flash.utils.ByteArray, byteArrayOffset : UInt, async : Bool = false) : Void; function uploadFromBitmapData(source : flash.display.BitmapData, miplevel : UInt = 0) : Void; function uploadFromByteArray(data : flash.utils.ByteArray, byteArrayOffset : UInt, miplevel : UInt = 0) : Void; } haxe_3.4.4.orig/std/flash/display3D/textures/TextureBase.hx0000664000175000017500000000020113166552354023607 0ustar andyandy00000000000000package flash.display3D.textures; extern class TextureBase extends flash.events.EventDispatcher { function dispose() : Void; } haxe_3.4.4.orig/std/flash/display3D/textures/VideoTexture.hx0000664000175000017500000000050413166552354024011 0ustar andyandy00000000000000package flash.display3D.textures; @:final extern class VideoTexture extends TextureBase { var videoHeight(default,never) : Int; var videoWidth(default,never) : Int; function new() : Void; function attachCamera(theCamera : flash.media.Camera) : Void; function attachNetStream(netStream : flash.net.NetStream) : Void; } haxe_3.4.4.orig/std/flash/errors/ArgumentError.hx0000664000175000017500000000013613166552354021754 0ustar andyandy00000000000000package flash.errors; @:native("ArgumentError") extern class ArgumentError extends Error { } haxe_3.4.4.orig/std/flash/errors/DRMManagerError.hx0000664000175000017500000000034413166552354022110 0ustar andyandy00000000000000package flash.errors; @:require(flash10_1) extern class DRMManagerError extends Error { var subErrorID(default,never) : Int; function new(message : String, id : Int, subErrorID : Int) : Void; function toString() : String; } haxe_3.4.4.orig/std/flash/errors/DefinitionError.hx0000664000175000017500000000015713166552354022265 0ustar andyandy00000000000000package flash.errors; @:native("DefinitionError") extern class DefinitionError extends flash.errors.Error { } haxe_3.4.4.orig/std/flash/errors/EOFError.hx0000664000175000017500000000017013166552354020601 0ustar andyandy00000000000000package flash.errors; extern class EOFError extends IOError { function new(?message : String, id : Int = 0) : Void; } haxe_3.4.4.orig/std/flash/errors/Error.hx0000664000175000017500000000100013166552354020240 0ustar andyandy00000000000000package flash.errors; extern class Error #if !flash_strict implements Dynamic #end { var errorID(default,never) : Int; var message : Dynamic; var name : Dynamic; function new(?message : Dynamic, id : Dynamic = 0) : Void; function getStackTrace() : String; static var length(default,never) : Int; static function getErrorMessage(index : Int) : String; static function throwError(type : Class, index : UInt, ?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Dynamic; } haxe_3.4.4.orig/std/flash/errors/EvalError.hx0000664000175000017500000000014313166552354021057 0ustar andyandy00000000000000package flash.errors; @:native("EvalError") extern class EvalError extends flash.errors.Error { } haxe_3.4.4.orig/std/flash/errors/IOError.hx0000664000175000017500000000016513166552354020503 0ustar andyandy00000000000000package flash.errors; extern class IOError extends Error { function new(?message : String, id : Int = 0) : Void; } haxe_3.4.4.orig/std/flash/errors/IllegalOperationError.hx0000664000175000017500000000020313166552354023417 0ustar andyandy00000000000000package flash.errors; extern class IllegalOperationError extends Error { function new(?message : String, id : Int = 0) : Void; } haxe_3.4.4.orig/std/flash/errors/InvalidSWFError.hx0000664000175000017500000000017513166552354022143 0ustar andyandy00000000000000package flash.errors; extern class InvalidSWFError extends Error { function new(?message : String, id : Int = 0) : Void; } haxe_3.4.4.orig/std/flash/errors/MemoryError.hx0000664000175000017500000000017113166552354021441 0ustar andyandy00000000000000package flash.errors; extern class MemoryError extends Error { function new(?message : String, id : Int = 0) : Void; } haxe_3.4.4.orig/std/flash/errors/RangeError.hx0000664000175000017500000000014513166552354021226 0ustar andyandy00000000000000package flash.errors; @:native("RangeError") extern class RangeError extends flash.errors.Error { } haxe_3.4.4.orig/std/flash/errors/ReferenceError.hx0000664000175000017500000000015513166552354022071 0ustar andyandy00000000000000package flash.errors; @:native("ReferenceError") extern class ReferenceError extends flash.errors.Error { } haxe_3.4.4.orig/std/flash/errors/ScriptTimeoutError.hx0000664000175000017500000000020013166552354022775 0ustar andyandy00000000000000package flash.errors; extern class ScriptTimeoutError extends Error { function new(?message : String, id : Int = 0) : Void; } haxe_3.4.4.orig/std/flash/errors/SecurityError.hx0000664000175000017500000000013613166552354022001 0ustar andyandy00000000000000package flash.errors; @:native("SecurityError") extern class SecurityError extends Error { } haxe_3.4.4.orig/std/flash/errors/StackOverflowError.hx0000664000175000017500000000020013166552354022753 0ustar andyandy00000000000000package flash.errors; extern class StackOverflowError extends Error { function new(?message : String, id : Int = 0) : Void; } haxe_3.4.4.orig/std/flash/errors/SyntaxError.hx0000664000175000017500000000014713166552354021462 0ustar andyandy00000000000000package flash.errors; @:native("SyntaxError") extern class SyntaxError extends flash.errors.Error { } haxe_3.4.4.orig/std/flash/errors/TypeError.hx0000664000175000017500000000012613166552354021112 0ustar andyandy00000000000000package flash.errors; @:native("TypeError") extern class TypeError extends Error { } haxe_3.4.4.orig/std/flash/errors/URIError.hx0000664000175000017500000000014113166552354020625 0ustar andyandy00000000000000package flash.errors; @:native("URIError") extern class URIError extends flash.errors.Error { } haxe_3.4.4.orig/std/flash/errors/UninitializedError.hx0000664000175000017500000000016513166552354023004 0ustar andyandy00000000000000package flash.errors; @:native("UninitializedError") extern class UninitializedError extends flash.errors.Error { } haxe_3.4.4.orig/std/flash/errors/VerifyError.hx0000664000175000017500000000013213166552354021432 0ustar andyandy00000000000000package flash.errors; @:native("VerifyError") extern class VerifyError extends Error { } haxe_3.4.4.orig/std/flash/events/AVDictionaryDataEvent.hx0000664000175000017500000000057613166552354023310 0ustar andyandy00000000000000package flash.events; extern class AVDictionaryDataEvent extends Event { var dictionary(default,never) : flash.utils.Dictionary; var time(default,never) : Float; function new(?type : String, bubbles : Bool = false, cancelable : Bool = false, ?init_dictionary : flash.utils.Dictionary, init_dataTime : Float = 0) : Void; static var AV_DICTIONARY_DATA(default,never) : String; } haxe_3.4.4.orig/std/flash/events/AVHTTPStatusEvent.hx0000664000175000017500000000061513166552354022366 0ustar andyandy00000000000000package flash.events; extern class AVHTTPStatusEvent extends Event { var responseHeaders : Array; var responseURL : String; var status(default,never) : Int; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, status : Int = 0, ?responseUrl : String, ?responseHeaders : Array) : Void; static var AV_HTTP_RESPONSE_STATUS(default,never) : String; } haxe_3.4.4.orig/std/flash/events/AVLoadInfoEvent.hx0000664000175000017500000000045713166552354022102 0ustar andyandy00000000000000package flash.events; extern class AVLoadInfoEvent extends Event { var loadInfo(default,never) : flash.utils.Dictionary; function new(?type : String, bubbles : Bool = false, cancelable : Bool = false, ?inLoadInfo : flash.utils.Dictionary) : Void; static var AV_LOAD_INFO(default,never) : Dynamic; } haxe_3.4.4.orig/std/flash/events/AVManifestLoadEvent.hx0000664000175000017500000000071613166552354022753 0ustar andyandy00000000000000package flash.events; extern class AVManifestLoadEvent extends Event { var duration(default,never) : Float; var handle(default,never) : Int; var result(default,never) : flash.media.AVResult; var userData(default,never) : Int; function new(?type : String, bubbles : Bool = false, cancelable : Bool = false, inResult : Int = 0, inUserData : Int = 0, inHandle : Int = 0, inDuration : Float = 0) : Void; static var AV_MANIFEST_LOAD(default,never) : String; } haxe_3.4.4.orig/std/flash/events/AVPauseAtPeriodEndEvent.hx0000664000175000017500000000043313166552354023535 0ustar andyandy00000000000000package flash.events; extern class AVPauseAtPeriodEndEvent extends Event { var userData(default,never) : Int; function new(?type : String, bubbles : Bool = false, cancelable : Bool = false, userData : Int = 0) : Void; static var AV_PAUSE_AT_PERIOD_END(default,never) : String; } haxe_3.4.4.orig/std/flash/events/AVPlayStateEvent.hx0000664000175000017500000000043713166552354022313 0ustar andyandy00000000000000package flash.events; extern class AVPlayStateEvent extends Event { var playState(default,never) : flash.media.AVPlayState; function new(?type : String, bubbles : Bool = false, cancelable : Bool = false, inState : Int = 0) : Void; static var AV_PLAY_STATE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/AVStatusEvent.hx0000664000175000017500000000234413166552354021667 0ustar andyandy00000000000000package flash.events; extern class AVStatusEvent extends Event { var description(default,never) : String; var notificationType(default,never) : String; var result(default,never) : flash.media.AVResult; function new(?type : String, bubbles : Bool = false, cancelable : Bool = false, ?inNotificationType : String, inResult : Int = 0, ?inDescription : String) : Void; static var AV_STATUS(default,never) : String; static var BACKGROUND_MANIFEST_ERROR(default,never) : String; static var BACKGROUND_MANIFEST_WARNING(default,never) : String; static var BUFFER_STATE(default,never) : String; static var DECODER_TYPE(default,never) : String; static var DIMENSION_CHANGE(default,never) : String; static var ERROR(default,never) : String; static var INSERTION_COMPLETE(default,never) : String; static var LOAD_COMPLETE(default,never) : String; static var MANIFEST_UPDATE(default,never) : String; static var PLAY_STATE(default,never) : String; static var RENDER_TYPE(default,never) : String; static var SEEK_COMPLETE(default,never) : String; static var STEP_COMPLETE(default,never) : String; static var STREAM_SWITCH(default,never) : String; static var TRICKPLAY_ENDED(default,never) : String; static var WARNING(default,never) : String; } haxe_3.4.4.orig/std/flash/events/AVStreamSwitchEvent.hx0000664000175000017500000000112513166552354023015 0ustar andyandy00000000000000package flash.events; extern class AVStreamSwitchEvent extends Event { var bitrate(default,never) : Int; var description(default,never) : String; var switchType(default,never) : Int; var time(default,never) : Float; var userData(default,never) : Int; function new(?type : String, bubbles : Bool = false, cancelable : Bool = false, time : Float = 0, switchType : Int = 0, bitrate : Int = 0, ?description : String, userData : Int = 0) : Void; static var ABR_SWITCH(default,never) : Int; static var AV_STREAM_SWITCH(default,never) : String; static var PERIOD_SWITCH(default,never) : Int; } haxe_3.4.4.orig/std/flash/events/AccelerometerEvent.hx0000664000175000017500000000066613166552354022734 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class AccelerometerEvent extends Event { var accelerationX : Float; var accelerationY : Float; var accelerationZ : Float; var timestamp : Float; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, timestamp : Float = 0, accelerationX : Float = 0, accelerationY : Float = 0, accelerationZ : Float = 0) : Void; static var UPDATE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/ActivityEvent.hx0000664000175000017500000000037513166552354021753 0ustar andyandy00000000000000package flash.events; extern class ActivityEvent extends Event { var activating : Bool; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, activating : Bool = false) : Void; static var ACTIVITY(default,never) : String; } haxe_3.4.4.orig/std/flash/events/AsyncErrorEvent.hx0000664000175000017500000000044213166552354022241 0ustar andyandy00000000000000package flash.events; extern class AsyncErrorEvent extends ErrorEvent { var error : flash.errors.Error; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?text : String, ?error : flash.errors.Error) : Void; static var ASYNC_ERROR(default,never) : String; } haxe_3.4.4.orig/std/flash/events/ContextMenuEvent.hx0000664000175000017500000000102213166552354022416 0ustar andyandy00000000000000package flash.events; extern class ContextMenuEvent extends Event { var contextMenuOwner : flash.display.InteractiveObject; @:require(flash10) var isMouseTargetInaccessible : Bool; var mouseTarget : flash.display.InteractiveObject; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?mouseTarget : flash.display.InteractiveObject, ?contextMenuOwner : flash.display.InteractiveObject) : Void; static var MENU_ITEM_SELECT(default,never) : String; static var MENU_SELECT(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DRMAuthenticateEvent.hx0000664000175000017500000000141213166552354023131 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class DRMAuthenticateEvent extends Event { var authenticationType(default,never) : String; var header(default,never) : String; var netstream(default,never) : flash.net.NetStream; var passwordPrompt(default,never) : String; var urlPrompt(default,never) : String; var usernamePrompt(default,never) : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?header : String, ?userPrompt : String, ?passPrompt : String, ?urlPrompt : String, ?authenticationType : String, ?netstream : flash.net.NetStream) : Void; static var AUTHENTICATION_TYPE_DRM(default,never) : String; static var AUTHENTICATION_TYPE_PROXY(default,never) : String; static var DRM_AUTHENTICATE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DRMAuthenticationCompleteEvent.hx0000664000175000017500000000063713166552354025173 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class DRMAuthenticationCompleteEvent extends Event { var domain : String; var serverURL : String; var token : flash.utils.ByteArray; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?inServerURL : String, ?inDomain : String, ?inToken : flash.utils.ByteArray) : Void; static var AUTHENTICATION_COMPLETE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DRMAuthenticationErrorEvent.hx0000664000175000017500000000066013166552354024510 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class DRMAuthenticationErrorEvent extends ErrorEvent { var domain : String; var serverURL : String; var subErrorID : Int; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?inDetail : String, inErrorID : Int = 0, inSubErrorID : Int = 0, ?inServerURL : String, ?inDomain : String) : Void; static var AUTHENTICATION_ERROR(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DRMCustomProperties.hx0000664000175000017500000000015113166552354023037 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class DRMCustomProperties { function new() : Void; } haxe_3.4.4.orig/std/flash/events/DRMDeviceGroupErrorEvent.hx0000664000175000017500000000120413166552354023740 0ustar andyandy00000000000000package flash.events; extern class DRMDeviceGroupErrorEvent extends ErrorEvent { var deviceGroup : flash.net.drm.DRMDeviceGroup; var drmUpdateNeeded(default,never) : Bool; var subErrorID : Int; var systemUpdateNeeded(default,never) : Bool; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?errorDetail : String, errorCode : Int = 0, subErrorID : Int = 0, ?deviceGroup : flash.net.drm.DRMDeviceGroup, systemUpdateNeeded : Bool = false, drmUpdateNeeded : Bool = false) : Void; static var ADD_TO_DEVICE_GROUP_ERROR(default,never) : String; static var REMOVE_FROM_DEVICE_GROUP_ERROR(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DRMDeviceGroupEvent.hx0000664000175000017500000000061113166552354022727 0ustar andyandy00000000000000package flash.events; extern class DRMDeviceGroupEvent extends Event { var deviceGroup : flash.net.drm.DRMDeviceGroup; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?deviceGroup : flash.net.drm.DRMDeviceGroup) : Void; static var ADD_TO_DEVICE_GROUP_COMPLETE(default,never) : String; static var REMOVE_FROM_DEVICE_GROUP_COMPLETE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DRMErrorEvent.hx0000664000175000017500000000122013166552354021601 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class DRMErrorEvent extends ErrorEvent { var contentData : flash.net.drm.DRMContentData; var drmUpdateNeeded(default,never) : Bool; var subErrorID(default,never) : Int; var systemUpdateNeeded(default,never) : Bool; function new(?type : String, bubbles : Bool = false, cancelable : Bool = false, ?inErrorDetail : String, inErrorCode : Int = 0, insubErrorID : Int = 0, ?inMetadata : flash.net.drm.DRMContentData, inSystemUpdateNeeded : Bool = false, inDrmUpdateNeeded : Bool = false) : Void; static var DRM_ERROR(default,never) : String; static var DRM_LOAD_DEVICEID_ERROR(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DRMLicenseRequestEvent.hx0000664000175000017500000000041213166552354023445 0ustar andyandy00000000000000package flash.events; extern class DRMLicenseRequestEvent extends Event { var serverURL : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?inServerURL : String) : Void; static var LICENSE_REQUEST(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DRMMetadataEvent.hx0000664000175000017500000000056713166552354022245 0ustar andyandy00000000000000package flash.events; extern class DRMMetadataEvent extends Event { var drmMetadata(default,never) : flash.net.drm.DRMContentData; var timestamp(default,never) : Float; function new(?type : String, bubbles : Bool = false, cancelable : Bool = false, ?inMetadata : flash.utils.ByteArray, inTimestamp : Float = 0) : Void; static var DRM_METADATA(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DRMReturnVoucherCompleteEvent.hx0000664000175000017500000000070213166552354025020 0ustar andyandy00000000000000package flash.events; extern class DRMReturnVoucherCompleteEvent extends Event { var licenseID : String; var numberOfVouchersReturned : Int; var policyID : String; var serverURL : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?inServerURL : String, ?inLicenseID : String, ?inPolicyID : String, inNumberOfVouchersReturned : Int = 0) : Void; static var RETURN_VOUCHER_COMPLETE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DRMReturnVoucherErrorEvent.hx0000664000175000017500000000071613166552354024346 0ustar andyandy00000000000000package flash.events; extern class DRMReturnVoucherErrorEvent extends ErrorEvent { var licenseID : String; var policyID : String; var serverURL : String; var subErrorID : Int; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?inDetail : String, inErrorID : Int = 0, inSubErrorID : Int = 0, ?inServerURL : String, ?inLicenseID : String, ?inPolicyID : String) : Void; static var RETURN_VOUCHER_ERROR(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DRMStatusEvent.hx0000664000175000017500000000067513166552354022010 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class DRMStatusEvent extends Event { var contentData : flash.net.drm.DRMContentData; var isLocal : Bool; var voucher : flash.net.drm.DRMVoucher; function new(?type : String, bubbles : Bool = false, cancelable : Bool = false, ?inMetadata : flash.net.drm.DRMContentData, ?inVoucher : flash.net.drm.DRMVoucher, inLocal : Bool = false) : Void; static var DRM_STATUS(default,never) : String; } haxe_3.4.4.orig/std/flash/events/DataEvent.hx0000664000175000017500000000044413166552354021025 0ustar andyandy00000000000000package flash.events; extern class DataEvent extends TextEvent { var data : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?data : String) : Void; static var DATA(default,never) : String; static var UPLOAD_COMPLETE_DATA(default,never) : String; } haxe_3.4.4.orig/std/flash/events/ErrorEvent.hx0000664000175000017500000000043613166552354021246 0ustar andyandy00000000000000package flash.events; extern class ErrorEvent extends TextEvent { @:require(flash10_1) var errorID(default,never) : Int; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?text : String, id : Int = 0) : Void; static var ERROR(default,never) : String; } haxe_3.4.4.orig/std/flash/events/Event.hx0000664000175000017500000000571013166552354020234 0ustar andyandy00000000000000package flash.events; extern class Event { var bubbles(default,never) : Bool; var cancelable(default,never) : Bool; var currentTarget(default,never) : Dynamic; var eventPhase(default,never) : EventPhase; var target(default,never) : Dynamic; var type(default,never) : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false) : Void; function clone() : Event; function formatToString(className : String, ?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : String; function isDefaultPrevented() : Bool; function preventDefault() : Void; function stopImmediatePropagation() : Void; function stopPropagation() : Void; function toString() : String; static var ACTIVATE(default,never) : String; static var ADDED(default,never) : String; static var ADDED_TO_STAGE(default,never) : String; static var BROWSER_ZOOM_CHANGE(default,never) : String; static var CANCEL(default,never) : String; static var CHANGE(default,never) : String; static var CHANNEL_MESSAGE(default,never) : String; static var CHANNEL_STATE(default,never) : String; @:require(flash10) static var CLEAR(default,never) : String; static var CLOSE(default,never) : String; static var COMPLETE(default,never) : String; static var CONNECT(default,never) : String; @:require(flash11) static var CONTEXT3D_CREATE(default,never) : String; @:require(flash10) static var COPY(default,never) : String; @:require(flash10) static var CUT(default,never) : String; static var DEACTIVATE(default,never) : String; static var ENTER_FRAME(default,never) : String; @:require(flash10) static var EXIT_FRAME(default,never) : String; @:require(flash10) static var FRAME_CONSTRUCTED(default,never) : String; @:require(flash11_3) static var FRAME_LABEL(default,never) : String; static var FULLSCREEN(default,never) : String; static var ID3(default,never) : String; static var INIT(default,never) : String; static var MOUSE_LEAVE(default,never) : String; static var OPEN(default,never) : String; @:require(flash10) static var PASTE(default,never) : String; static var REMOVED(default,never) : String; static var REMOVED_FROM_STAGE(default,never) : String; static var RENDER(default,never) : String; static var RESIZE(default,never) : String; static var SCROLL(default,never) : String; static var SELECT(default,never) : String; @:require(flash10) static var SELECT_ALL(default,never) : String; static var SOUND_COMPLETE(default,never) : String; @:require(flash11_3) static var SUSPEND(default,never) : String; static var TAB_CHILDREN_CHANGE(default,never) : String; static var TAB_ENABLED_CHANGE(default,never) : String; static var TAB_INDEX_CHANGE(default,never) : String; @:require(flash11_3) static var TEXTURE_READY(default,never) : String; @:require(flash11) static var TEXT_INTERACTION_MODE_CHANGE(default,never) : String; static var UNLOAD(default,never) : String; static var VIDEO_FRAME(default,never) : String; static var WORKER_STATE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/EventDispatcher.hx0000664000175000017500000000107513166552354022243 0ustar andyandy00000000000000package flash.events; extern class EventDispatcher implements IEventDispatcher { function new(?target : IEventDispatcher) : Void; function addEventListener(type : String, listener : Dynamic -> Void, useCapture : Bool = false, priority : Int = 0, useWeakReference : Bool = false) : Void; function dispatchEvent(event : Event) : Bool; function hasEventListener(type : String) : Bool; function removeEventListener(type : String, listener : Dynamic -> Void, useCapture : Bool = false) : Void; function toString() : String; function willTrigger(type : String) : Bool; } haxe_3.4.4.orig/std/flash/events/EventPhase.hx0000664000175000017500000000016213166552354021211 0ustar andyandy00000000000000package flash.events; @:fakeEnum(UInt) extern enum EventPhase { AT_TARGET; BUBBLING_PHASE; CAPTURING_PHASE; } haxe_3.4.4.orig/std/flash/events/FocusEvent.hx0000664000175000017500000000113713166552354021233 0ustar andyandy00000000000000package flash.events; extern class FocusEvent extends Event { @:require(flash10) var isRelatedObjectInaccessible : Bool; var keyCode : UInt; var relatedObject : flash.display.InteractiveObject; var shiftKey : Bool; function new(type : String, bubbles : Bool = true, cancelable : Bool = false, ?relatedObject : flash.display.InteractiveObject, shiftKey : Bool = false, keyCode : UInt = 0) : Void; static var FOCUS_IN(default,never) : String; static var FOCUS_OUT(default,never) : String; static var KEY_FOCUS_CHANGE(default,never) : String; static var MOUSE_FOCUS_CHANGE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/FullScreenEvent.hx0000664000175000017500000000071513166552354022217 0ustar andyandy00000000000000package flash.events; extern class FullScreenEvent extends ActivityEvent { var fullScreen(default,never) : Bool; @:require(flash11_3) var interactive(default,never) : Bool; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, fullScreen : Bool = false, interactive : Bool = false) : Void; static var FULL_SCREEN(default,never) : String; @:require(flash11_3) static var FULL_SCREEN_INTERACTIVE_ACCEPTED(default,never) : String; } haxe_3.4.4.orig/std/flash/events/GameInputEvent.hx0000664000175000017500000000066013166552354022045 0ustar andyandy00000000000000package flash.events; @:final @:require(flash11_8) extern class GameInputEvent extends Event { var device(default,never) : flash.ui.GameInputDevice; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?device : flash.ui.GameInputDevice) : Void; static var DEVICE_ADDED(default,never) : String; static var DEVICE_REMOVED(default,never) : String; static var DEVICE_UNUSABLE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/GeolocationEvent.hx0000664000175000017500000000113013166552354022410 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class GeolocationEvent extends Event { var altitude : Float; var heading : Float; var horizontalAccuracy : Float; var latitude : Float; var longitude : Float; var speed : Float; var timestamp : Float; var verticalAccuracy : Float; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, latitude : Float = 0, longitude : Float = 0, altitude : Float = 0, hAccuracy : Float = 0, vAccuracy : Float = 0, speed : Float = 0, heading : Float = 0, timestamp : Float = 0) : Void; static var UPDATE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/GestureEvent.hx0000664000175000017500000000112713166552354021571 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class GestureEvent extends Event { var altKey : Bool; var ctrlKey : Bool; var localX : Float; var localY : Float; var phase : String; var shiftKey : Bool; var stageX(default,never) : Float; var stageY(default,never) : Float; function new(type : String, bubbles : Bool = true, cancelable : Bool = false, ?phase : String, localX : Float = 0, localY : Float = 0, ctrlKey : Bool = false, altKey : Bool = false, shiftKey : Bool = false) : Void; function updateAfterEvent() : Void; static var GESTURE_TWO_FINGER_TAP(default,never) : String; } haxe_3.4.4.orig/std/flash/events/GesturePhase.hx0000664000175000017500000000017113166552354021546 0ustar andyandy00000000000000package flash.events; @:fakeEnum(String) @:require(flash10_1) extern enum GesturePhase { ALL; BEGIN; END; UPDATE; } haxe_3.4.4.orig/std/flash/events/HTTPStatusEvent.hx0000664000175000017500000000076113166552354022141 0ustar andyandy00000000000000package flash.events; extern class HTTPStatusEvent extends Event { var redirected : Bool; @:require(flash10_1) var responseHeaders : Array; @:require(flash10_1) var responseURL : String; var status(default,never) : Int; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, status : Int = 0, redirected : Bool = false) : Void; @:require(flash10_1) static var HTTP_RESPONSE_STATUS(default,never) : String; static var HTTP_STATUS(default,never) : String; } haxe_3.4.4.orig/std/flash/events/IEventDispatcher.hx0000664000175000017500000000072513166552354022355 0ustar andyandy00000000000000package flash.events; extern interface IEventDispatcher { function addEventListener(type : String, listener : Dynamic -> Void, useCapture : Bool = false, priority : Int = 0, useWeakReference : Bool = false) : Void; function dispatchEvent(event : Event) : Bool; function hasEventListener(type : String) : Bool; function removeEventListener(type : String, listener : Dynamic -> Void, useCapture : Bool = false) : Void; function willTrigger(type : String) : Bool; } haxe_3.4.4.orig/std/flash/events/IMEEvent.hx0000664000175000017500000000063113166552354020564 0ustar andyandy00000000000000package flash.events; extern class IMEEvent extends TextEvent { @:require(flash10_1) var imeClient : flash.text.ime.IIMEClient; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?text : String, ?imeClient : flash.text.ime.IIMEClient) : Void; static var IME_COMPOSITION(default,never) : String; @:require(flash10_1) static var IME_START_COMPOSITION(default,never) : String; } haxe_3.4.4.orig/std/flash/events/IOErrorEvent.hx0000664000175000017500000000060113166552354021470 0ustar andyandy00000000000000package flash.events; extern class IOErrorEvent extends ErrorEvent { function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?text : String, id : Int = 0) : Void; static var DISK_ERROR(default,never) : String; static var IO_ERROR(default,never) : String; static var NETWORK_ERROR(default,never) : String; static var VERIFY_ERROR(default,never) : String; } haxe_3.4.4.orig/std/flash/events/KeyboardEvent.hx0000664000175000017500000000114413166552354021712 0ustar andyandy00000000000000package flash.events; extern class KeyboardEvent extends Event { var altKey : Bool; var charCode : UInt; var ctrlKey : Bool; var keyCode : UInt; var keyLocation : flash.ui.KeyLocation; var shiftKey : Bool; function new(type : String, bubbles : Bool = true, cancelable : Bool = false, charCodeValue : UInt = 0, keyCodeValue : UInt = 0, keyLocationValue : flash.ui.KeyLocation = 0, ctrlKeyValue : Bool = false, altKeyValue : Bool = false, shiftKeyValue : Bool = false) : Void; function updateAfterEvent() : Void; static var KEY_DOWN(default,never) : String; static var KEY_UP(default,never) : String; } haxe_3.4.4.orig/std/flash/events/MouseEvent.hx0000664000175000017500000000353613166552354021251 0ustar andyandy00000000000000package flash.events; extern class MouseEvent extends Event { var altKey : Bool; var buttonDown : Bool; var ctrlKey : Bool; var delta : Int; @:require(flash10) var isRelatedObjectInaccessible : Bool; var localX : Float; var localY : Float; @:require(flash11_2) var movementX : Float; @:require(flash11_2) var movementY : Float; var relatedObject : flash.display.InteractiveObject; var shiftKey : Bool; var stageX(default,never) : Float; var stageY(default,never) : Float; function new(type : String, bubbles : Bool = true, cancelable : Bool = false, localX : Null = 0, localY : Null = 0, ?relatedObject : flash.display.InteractiveObject, ctrlKey : Bool = false, altKey : Bool = false, shiftKey : Bool = false, buttonDown : Bool = false, delta : Int = 0) : Void; function updateAfterEvent() : Void; static var CLICK(default,never) : String; @:require(flash11_2) static var CONTEXT_MENU(default,never) : String; static var DOUBLE_CLICK(default,never) : String; @:require(flash11_2) static var MIDDLE_CLICK(default,never) : String; @:require(flash11_2) static var MIDDLE_MOUSE_DOWN(default,never) : String; @:require(flash11_2) static var MIDDLE_MOUSE_UP(default,never) : String; static var MOUSE_DOWN(default,never) : String; static var MOUSE_MOVE(default,never) : String; static var MOUSE_OUT(default,never) : String; static var MOUSE_OVER(default,never) : String; static var MOUSE_UP(default,never) : String; static var MOUSE_WHEEL(default,never) : String; @:require(flash11_3) static var RELEASE_OUTSIDE(default,never) : String; @:require(flash11_2) static var RIGHT_CLICK(default,never) : String; @:require(flash11_2) static var RIGHT_MOUSE_DOWN(default,never) : String; @:require(flash11_2) static var RIGHT_MOUSE_UP(default,never) : String; static var ROLL_OUT(default,never) : String; static var ROLL_OVER(default,never) : String; } haxe_3.4.4.orig/std/flash/events/NetDataEvent.hx0000664000175000017500000000050313166552354021470 0ustar andyandy00000000000000package flash.events; extern class NetDataEvent extends Event { var info(default,never) : Dynamic; var timestamp(default,never) : Float; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, timestamp : Float = 0, ?info : Dynamic) : Void; static var MEDIA_TYPE_DATA(default,never) : String; } haxe_3.4.4.orig/std/flash/events/NetFilterEvent.hx0000664000175000017500000000044513166552354022051 0ustar andyandy00000000000000package flash.events; extern class NetFilterEvent extends Event { var data : flash.utils.ByteArray; var header : flash.utils.ByteArray; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?header : flash.utils.ByteArray, ?data : flash.utils.ByteArray) : Void; } haxe_3.4.4.orig/std/flash/events/NetMonitorEvent.hx0000664000175000017500000000045413166552354022253 0ustar andyandy00000000000000package flash.events; extern class NetMonitorEvent extends Event { var netStream(default,never) : flash.net.NetStream; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?netStream : flash.net.NetStream) : Void; static var NET_STREAM_CREATE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/NetStatusEvent.hx0000664000175000017500000000036313166552354022106 0ustar andyandy00000000000000package flash.events; extern class NetStatusEvent extends Event { var info : Dynamic; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?info : Dynamic) : Void; static var NET_STATUS(default,never) : String; } haxe_3.4.4.orig/std/flash/events/OutputProgressEvent.hx0000664000175000017500000000047513166552354023205 0ustar andyandy00000000000000package flash.events; extern class OutputProgressEvent extends Event { var bytesPending : Float; var bytesTotal : Float; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, bytesPending : Float = 0, bytesTotal : Float = 0) : Void; static var OUTPUT_PROGRESS(default,never) : String; } haxe_3.4.4.orig/std/flash/events/PressAndTapGestureEvent.hx0000664000175000017500000000105113166552354023672 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class PressAndTapGestureEvent extends GestureEvent { var tapLocalX : Float; var tapLocalY : Float; var tapStageX(default,never) : Float; var tapStageY(default,never) : Float; function new(type : String, bubbles : Bool = true, cancelable : Bool = false, ?phase : String, localX : Float = 0, localY : Float = 0, tapLocalX : Float = 0, tapLocalY : Float = 0, ctrlKey : Bool = false, altKey : Bool = false, shiftKey : Bool = false) : Void; static var GESTURE_PRESS_AND_TAP(default,never) : String; } haxe_3.4.4.orig/std/flash/events/ProgressEvent.hx0000664000175000017500000000053713166552354021763 0ustar andyandy00000000000000package flash.events; extern class ProgressEvent extends Event { var bytesLoaded : Float; var bytesTotal : Float; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, bytesLoaded : Float = 0, bytesTotal : Float = 0) : Void; static var PROGRESS(default,never) : String; static var SOCKET_DATA(default,never) : String; } haxe_3.4.4.orig/std/flash/events/SampleDataEvent.hx0000664000175000017500000000050413166552354022164 0ustar andyandy00000000000000package flash.events; extern class SampleDataEvent extends Event { var data : flash.utils.ByteArray; var position : Float; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, theposition : Float = 0, ?thedata : flash.utils.ByteArray) : Void; static var SAMPLE_DATA(default,never) : String; } haxe_3.4.4.orig/std/flash/events/SecurityErrorEvent.hx0000664000175000017500000000037013166552354022773 0ustar andyandy00000000000000package flash.events; extern class SecurityErrorEvent extends ErrorEvent { function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?text : String, id : Int = 0) : Void; static var SECURITY_ERROR(default,never) : String; } haxe_3.4.4.orig/std/flash/events/ShaderEvent.hx0000664000175000017500000000064213166552354021362 0ustar andyandy00000000000000package flash.events; extern class ShaderEvent extends Event { var bitmapData : flash.display.BitmapData; var byteArray : flash.utils.ByteArray; var vector : flash.Vector; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?bitmap : flash.display.BitmapData, ?array : flash.utils.ByteArray, ?vector : flash.Vector) : Void; static var COMPLETE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/SoftKeyboardEvent.hx0000664000175000017500000000076513166552354022556 0ustar andyandy00000000000000package flash.events; extern class SoftKeyboardEvent extends Event { var relatedObject : flash.display.InteractiveObject; var triggerType(default,never) : String; function new(type : String, bubbles : Bool, cancelable : Bool, relatedObjectVal : flash.display.InteractiveObject, triggerTypeVal : String) : Void; static var SOFT_KEYBOARD_ACTIVATE(default,never) : String; static var SOFT_KEYBOARD_ACTIVATING(default,never) : String; static var SOFT_KEYBOARD_DEACTIVATE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/SoftKeyboardTrigger.hx0000664000175000017500000000027713166552354023076 0ustar andyandy00000000000000package flash.events; extern class SoftKeyboardTrigger { function new() : Void; static var CONTENT_TRIGGERED(default,never) : String; static var USER_TRIGGERED(default,never) : String; } haxe_3.4.4.orig/std/flash/events/StageVideoAvailabilityEvent.hx0000664000175000017500000000056513166552354024545 0ustar andyandy00000000000000package flash.events; extern class StageVideoAvailabilityEvent extends Event { var availability(default,never) : String; var driver(default,never) : String; var reason(default,never) : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?availability : String) : Void; static var STAGE_VIDEO_AVAILABILITY(default,never) : String; } haxe_3.4.4.orig/std/flash/events/StageVideoEvent.hx0000664000175000017500000000107513166552354022207 0ustar andyandy00000000000000package flash.events; @:require(flash10_2) extern class StageVideoEvent extends Event { var codecInfo(default,never) : String; var colorSpace(default,never) : String; var status(default,never) : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?status : String, ?colorSpace : String) : Void; static var RENDER_STATE(default,never) : String; static var RENDER_STATUS_ACCELERATED(default,never) : String; static var RENDER_STATUS_SOFTWARE(default,never) : String; static var RENDER_STATUS_UNAVAILABLE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/StatusEvent.hx0000664000175000017500000000042013166552354021431 0ustar andyandy00000000000000package flash.events; extern class StatusEvent extends Event { var code : String; var level : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?code : String, ?level : String) : Void; static var STATUS(default,never) : String; } haxe_3.4.4.orig/std/flash/events/SyncEvent.hx0000664000175000017500000000040213166552354021062 0ustar andyandy00000000000000package flash.events; extern class SyncEvent extends Event { var changeList : Array; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?changeList : Array) : Void; static var SYNC(default,never) : String; } haxe_3.4.4.orig/std/flash/events/TextEvent.hx0000664000175000017500000000042613166552354021100 0ustar andyandy00000000000000package flash.events; extern class TextEvent extends Event { var text : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?text : String) : Void; static var LINK(default,never) : String; static var TEXT_INPUT(default,never) : String; } haxe_3.4.4.orig/std/flash/events/ThrottleEvent.hx0000664000175000017500000000054413166552354021762 0ustar andyandy00000000000000package flash.events; @:require(flash11_2) extern class ThrottleEvent extends Event { var state(default,never) : String; var targetFrameRate(default,never) : Float; function new(type : ThrottleType, bubbles : Bool = false, cancelable : Bool = false, ?state : String, targetFrameRate : Float = 0) : Void; static var THROTTLE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/ThrottleType.hx0000664000175000017500000000014313166552354021615 0ustar andyandy00000000000000package flash.events; @:fakeEnum(String) extern enum ThrottleType { PAUSE; RESUME; THROTTLE; } haxe_3.4.4.orig/std/flash/events/TimerEvent.hx0000664000175000017500000000043513166552354021234 0ustar andyandy00000000000000package flash.events; extern class TimerEvent extends Event { function new(type : String, bubbles : Bool = false, cancelable : Bool = false) : Void; function updateAfterEvent() : Void; static var TIMER(default,never) : String; static var TIMER_COMPLETE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/TouchEvent.hx0000664000175000017500000000323013166552354021232 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class TouchEvent extends Event { var altKey : Bool; var ctrlKey : Bool; var isPrimaryTouchPoint : Bool; var isRelatedObjectInaccessible : Bool; var localX : Float; var localY : Float; var pressure : Float; var relatedObject : flash.display.InteractiveObject; var shiftKey : Bool; var sizeX : Float; var sizeY : Float; var stageX(default,never) : Float; var stageY(default,never) : Float; var touchPointID : Int; function new(type : String, bubbles : Bool = true, cancelable : Bool = false, touchPointID : Int = 0, isPrimaryTouchPoint : Bool = false, localX : Float = 0./*NaN*/, localY : Float = 0./*NaN*/, sizeX : Float = 0./*NaN*/, sizeY : Float = 0./*NaN*/, pressure : Float = 0./*NaN*/, ?relatedObject : flash.display.InteractiveObject, ctrlKey : Bool = false, altKey : Bool = false, shiftKey : Bool = false) : Void; function updateAfterEvent() : Void; static var PROXIMITY_BEGIN(default,never) : String; static var PROXIMITY_END(default,never) : String; static var PROXIMITY_MOVE(default,never) : String; static var PROXIMITY_OUT(default,never) : String; static var PROXIMITY_OVER(default,never) : String; static var PROXIMITY_ROLL_OUT(default,never) : String; static var PROXIMITY_ROLL_OVER(default,never) : String; static var TOUCH_BEGIN(default,never) : String; static var TOUCH_END(default,never) : String; static var TOUCH_MOVE(default,never) : String; static var TOUCH_OUT(default,never) : String; static var TOUCH_OVER(default,never) : String; static var TOUCH_ROLL_OUT(default,never) : String; static var TOUCH_ROLL_OVER(default,never) : String; static var TOUCH_TAP(default,never) : String; } haxe_3.4.4.orig/std/flash/events/TransformGestureEvent.hx0000664000175000017500000000133713166552354023470 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class TransformGestureEvent extends GestureEvent { var offsetX : Float; var offsetY : Float; var rotation : Float; var scaleX : Float; var scaleY : Float; function new(type : String, bubbles : Bool = true, cancelable : Bool = false, ?phase : String, localX : Float = 0, localY : Float = 0, scaleX : Float = 1, scaleY : Float = 1, rotation : Float = 0, offsetX : Float = 0, offsetY : Float = 0, ctrlKey : Bool = false, altKey : Bool = false, shiftKey : Bool = false) : Void; static var GESTURE_PAN(default,never) : String; static var GESTURE_ROTATE(default,never) : String; static var GESTURE_SWIPE(default,never) : String; static var GESTURE_ZOOM(default,never) : String; } haxe_3.4.4.orig/std/flash/events/UncaughtErrorEvent.hx0000664000175000017500000000045013166552354022741 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class UncaughtErrorEvent extends ErrorEvent { var error(default,never) : Dynamic; function new(?type : String, bubbles : Bool = true, cancelable : Bool = true, ?error_in : Dynamic) : Void; static var UNCAUGHT_ERROR(default,never) : String; } haxe_3.4.4.orig/std/flash/events/UncaughtErrorEvents.hx0000664000175000017500000000020113166552354023116 0ustar andyandy00000000000000package flash.events; @:require(flash10_1) extern class UncaughtErrorEvents extends EventDispatcher { function new() : Void; } haxe_3.4.4.orig/std/flash/events/VideoEvent.hx0000664000175000017500000000077113166552354021225 0ustar andyandy00000000000000package flash.events; @:require(flash10_2) extern class VideoEvent extends Event { var codecInfo(default,never) : String; var status(default,never) : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?status : String) : Void; static var RENDER_STATE(default,never) : String; static var RENDER_STATUS_ACCELERATED(default,never) : String; static var RENDER_STATUS_SOFTWARE(default,never) : String; static var RENDER_STATUS_UNAVAILABLE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/VideoTextureEvent.hx0000664000175000017500000000056013166552354022602 0ustar andyandy00000000000000package flash.events; extern class VideoTextureEvent extends Event { var codecInfo(default,never) : String; var colorSpace(default,never) : String; var status(default,never) : String; function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?status : String, ?colorSpace : String) : Void; static var RENDER_STATE(default,never) : String; } haxe_3.4.4.orig/std/flash/events/WeakFunctionClosure.hx0000664000175000017500000000007413166552354023103 0ustar andyandy00000000000000package flash.events; extern class WeakFunctionClosure { } haxe_3.4.4.orig/std/flash/events/WeakMethodClosure.hx0000664000175000017500000000012213166552354022530 0ustar andyandy00000000000000package flash.events; extern class WeakMethodClosure { function new() : Void; } haxe_3.4.4.orig/std/flash/external/ExternalInterface.hx0000664000175000017500000000062013166552354023067 0ustar andyandy00000000000000package flash.external; extern class ExternalInterface { static var available(default,never) : Bool; static var marshallExceptions : Bool; static var objectID(default,never) : String; static function addCallback(functionName : String, closure : Dynamic) : Void; static function call(functionName : String, ?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Dynamic; } haxe_3.4.4.orig/std/flash/filters/BevelFilter.hx0000664000175000017500000000124113166552354021515 0ustar andyandy00000000000000package flash.filters; @:final extern class BevelFilter extends BitmapFilter { var angle : Float; var blurX : Float; var blurY : Float; var distance : Float; var highlightAlpha : Float; var highlightColor : UInt; var knockout : Bool; var quality : Int; var shadowAlpha : Float; var shadowColor : UInt; var strength : Float; var type : BitmapFilterType; function new(distance : Float = 4, angle : Float = 45, highlightColor : UInt = 0xFFFFFF, highlightAlpha : Float = 1, shadowColor : UInt = 0, shadowAlpha : Float = 1, blurX : Float = 4, blurY : Float = 4, strength : Float = 1, quality : Int = 1, ?type : BitmapFilterType, knockout : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/filters/BitmapFilter.hx0000664000175000017500000000016013166552354021673 0ustar andyandy00000000000000package flash.filters; extern class BitmapFilter { function new() : Void; function clone() : BitmapFilter; } haxe_3.4.4.orig/std/flash/filters/BitmapFilterQuality.hx0000664000175000017500000000024713166552354023252 0ustar andyandy00000000000000package flash.filters; extern class BitmapFilterQuality { static inline var HIGH : Int = 3; static inline var LOW : Int = 1; static inline var MEDIUM : Int = 2; } haxe_3.4.4.orig/std/flash/filters/BitmapFilterType.hx0000664000175000017500000000014313166552354022536 0ustar andyandy00000000000000package flash.filters; @:fakeEnum(String) extern enum BitmapFilterType { FULL; INNER; OUTER; } haxe_3.4.4.orig/std/flash/filters/BlurFilter.hx0000664000175000017500000000033413166552354021366 0ustar andyandy00000000000000package flash.filters; @:final extern class BlurFilter extends BitmapFilter { var blurX : Float; var blurY : Float; var quality : Int; function new(blurX : Float = 4, blurY : Float = 4, quality : Int = 1) : Void; } haxe_3.4.4.orig/std/flash/filters/ColorMatrixFilter.hx0000664000175000017500000000024613166552354022727 0ustar andyandy00000000000000package flash.filters; @:final extern class ColorMatrixFilter extends BitmapFilter { var matrix : Array; function new(?matrix : Array) : Void; } haxe_3.4.4.orig/std/flash/filters/ConvolutionFilter.hx0000664000175000017500000000076013166552354023004 0ustar andyandy00000000000000package flash.filters; extern class ConvolutionFilter extends BitmapFilter { var alpha : Float; var bias : Float; var clamp : Bool; var color : UInt; var divisor : Float; var matrix : Array; var matrixX : Float; var matrixY : Float; var preserveAlpha : Bool; function new(matrixX : Float = 0, matrixY : Float = 0, ?matrix : Array, divisor : Float = 1, bias : Float = 0, preserveAlpha : Bool = true, clamp : Bool = true, color : UInt = 0, alpha : Float = 0) : Void; } haxe_3.4.4.orig/std/flash/filters/DisplacementMapFilter.hx0000664000175000017500000000111213166552354023523 0ustar andyandy00000000000000package flash.filters; @:final extern class DisplacementMapFilter extends BitmapFilter { var alpha : Float; var color : UInt; var componentX : UInt; var componentY : UInt; var mapBitmap : flash.display.BitmapData; var mapPoint : flash.geom.Point; var mode : DisplacementMapFilterMode; var scaleX : Float; var scaleY : Float; function new(?mapBitmap : flash.display.BitmapData, ?mapPoint : flash.geom.Point, componentX : UInt = 0, componentY : UInt = 0, scaleX : Float = 0, scaleY : Float = 0, ?mode : DisplacementMapFilterMode, color : UInt = 0, alpha : Float = 0) : Void; } haxe_3.4.4.orig/std/flash/filters/DisplacementMapFilterMode.hx0000664000175000017500000000016513166552354024337 0ustar andyandy00000000000000package flash.filters; @:fakeEnum(String) extern enum DisplacementMapFilterMode { CLAMP; COLOR; IGNORE; WRAP; } haxe_3.4.4.orig/std/flash/filters/DropShadowFilter.hx0000664000175000017500000000107313166552354022535 0ustar andyandy00000000000000package flash.filters; @:final extern class DropShadowFilter extends BitmapFilter { var alpha : Float; var angle : Float; var blurX : Float; var blurY : Float; var color : UInt; var distance : Float; var hideObject : Bool; var inner : Bool; var knockout : Bool; var quality : Int; var strength : Float; function new(distance : Float = 4, angle : Float = 45, color : UInt = 0, alpha : Float = 1, blurX : Float = 4, blurY : Float = 4, strength : Float = 1, quality : Int = 1, inner : Bool = false, knockout : Bool = false, hideObject : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/filters/GlowFilter.hx0000664000175000017500000000066413166552354021400 0ustar andyandy00000000000000package flash.filters; @:final extern class GlowFilter extends BitmapFilter { var alpha : Float; var blurX : Float; var blurY : Float; var color : UInt; var inner : Bool; var knockout : Bool; var quality : Int; var strength : Float; function new(color : UInt = 16711680, alpha : Float = 1, blurX : Float = 6, blurY : Float = 6, strength : Float = 2, quality : Int = 1, inner : Bool = false, knockout : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/filters/GradientBevelFilter.hx0000664000175000017500000000114213166552354023173 0ustar andyandy00000000000000package flash.filters; @:final extern class GradientBevelFilter extends BitmapFilter { var alphas : Array; var angle : Float; var blurX : Float; var blurY : Float; var colors : Array; var distance : Float; var knockout : Bool; var quality : Int; var ratios : Array; var strength : Float; var type : String; function new(distance : Float = 4, angle : Float = 45, ?colors : Array, ?alphas : Array, ?ratios : Array, blurX : Float = 4, blurY : Float = 4, strength : Float = 1, quality : Int = 1, ?type : String, knockout : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/filters/GradientGlowFilter.hx0000664000175000017500000000116513166552354023053 0ustar andyandy00000000000000package flash.filters; @:final extern class GradientGlowFilter extends BitmapFilter { var alphas : Array; var angle : Float; var blurX : Float; var blurY : Float; var colors : Array; var distance : Float; var knockout : Bool; var quality : Int; var ratios : Array; var strength : Float; var type : BitmapFilterType; function new(distance : Float = 4, angle : Float = 45, ?colors : Array, ?alphas : Array, ?ratios : Array, blurX : Float = 4, blurY : Float = 4, strength : Float = 1, quality : Int = 1, ?type : BitmapFilterType, knockout : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/filters/ShaderFilter.hx0000664000175000017500000000041713166552354021672 0ustar andyandy00000000000000package flash.filters; extern class ShaderFilter extends BitmapFilter { var bottomExtension : Int; var leftExtension : Int; var rightExtension : Int; var shader : flash.display.Shader; var topExtension : Int; function new(?shader : flash.display.Shader) : Void; } haxe_3.4.4.orig/std/flash/geom/ColorTransform.hx0000664000175000017500000000113313166552354021543 0ustar andyandy00000000000000package flash.geom; extern class ColorTransform { var alphaMultiplier : Float; var alphaOffset : Float; var blueMultiplier : Float; var blueOffset : Float; var color : UInt; var greenMultiplier : Float; var greenOffset : Float; var redMultiplier : Float; var redOffset : Float; function new(redMultiplier : Float = 1, greenMultiplier : Float = 1, blueMultiplier : Float = 1, alphaMultiplier : Float = 1, redOffset : Float = 0, greenOffset : Float = 0, blueOffset : Float = 0, alphaOffset : Float = 0) : Void; function concat(second : ColorTransform) : Void; function toString() : String; } haxe_3.4.4.orig/std/flash/geom/Matrix.hx0000664000175000017500000000260113166552354020036 0ustar andyandy00000000000000package flash.geom; extern class Matrix { var a : Float; var b : Float; var c : Float; var d : Float; var tx : Float; var ty : Float; function new(a : Float = 1, b : Float = 0, c : Float = 0, d : Float = 1, tx : Float = 0, ty : Float = 0) : Void; function clone() : Matrix; function concat(m : Matrix) : Void; @:require(flash11) function copyColumnFrom(column : UInt, vector3D : Vector3D) : Void; @:require(flash11) function copyColumnTo(column : UInt, vector3D : Vector3D) : Void; @:require(flash11) function copyFrom(sourceMatrix : Matrix) : Void; @:require(flash11) function copyRowFrom(row : UInt, vector3D : Vector3D) : Void; @:require(flash11) function copyRowTo(row : UInt, vector3D : Vector3D) : Void; function createBox(scaleX : Float, scaleY : Float, rotation : Float = 0, tx : Float = 0, ty : Float = 0) : Void; function createGradientBox(width : Float, height : Float, rotation : Float = 0, tx : Float = 0, ty : Float = 0) : Void; function deltaTransformPoint(point : Point) : Point; function identity() : Void; function invert() : Void; function rotate(angle : Float) : Void; function scale(sx : Float, sy : Float) : Void; @:require(flash11) function setTo(aa : Float, ba : Float, ca : Float, da : Float, txa : Float, tya : Float) : Void; function toString() : String; function transformPoint(point : Point) : Point; function translate(dx : Float, dy : Float) : Void; } haxe_3.4.4.orig/std/flash/geom/Matrix3D.hx0000664000175000017500000000430213166552354020225 0ustar andyandy00000000000000package flash.geom; @:require(flash10) extern class Matrix3D { var determinant(default,never) : Float; var position : Vector3D; var rawData : flash.Vector; function new(?v : flash.Vector) : Void; function append(lhs : Matrix3D) : Void; function appendRotation(degrees : Float, axis : Vector3D, ?pivotPoint : Vector3D) : Void; function appendScale(xScale : Float, yScale : Float, zScale : Float) : Void; function appendTranslation(x : Float, y : Float, z : Float) : Void; function clone() : Matrix3D; @:require(flash11) function copyColumnFrom(column : UInt, vector3D : Vector3D) : Void; @:require(flash11) function copyColumnTo(column : UInt, vector3D : Vector3D) : Void; @:require(flash11) function copyFrom(sourceMatrix3D : Matrix3D) : Void; @:require(flash11) function copyRawDataFrom(vector : flash.Vector, index : UInt = 0, transpose : Bool = false) : Void; @:require(flash11) function copyRawDataTo(vector : flash.Vector, index : UInt = 0, transpose : Bool = false) : Void; @:require(flash11) function copyRowFrom(row : UInt, vector3D : Vector3D) : Void; @:require(flash11) function copyRowTo(row : UInt, vector3D : Vector3D) : Void; @:require(flash11) function copyToMatrix3D(dest : Matrix3D) : Void; function decompose(?orientationStyle : Orientation3D) : flash.Vector; function deltaTransformVector(v : Vector3D) : Vector3D; function identity() : Void; function interpolateTo(toMat : Matrix3D, percent : Float) : Void; function invert() : Bool; function pointAt(pos : Vector3D, ?at : Vector3D, ?up : Vector3D) : Void; function prepend(rhs : Matrix3D) : Void; function prependRotation(degrees : Float, axis : Vector3D, ?pivotPoint : Vector3D) : Void; function prependScale(xScale : Float, yScale : Float, zScale : Float) : Void; function prependTranslation(x : Float, y : Float, z : Float) : Void; function recompose(components : flash.Vector, ?orientationStyle : Orientation3D) : Bool; function transformVector(v : Vector3D) : Vector3D; function transformVectors(vin : flash.Vector, vout : flash.Vector) : Void; function transpose() : Void; static function interpolate(thisMat : Matrix3D, toMat : Matrix3D, percent : Float) : Matrix3D; } haxe_3.4.4.orig/std/flash/geom/Orientation3D.hx0000664000175000017500000000015713166552354021260 0ustar andyandy00000000000000package flash.geom; @:fakeEnum(String) extern enum Orientation3D { AXIS_ANGLE; EULER_ANGLES; QUATERNION; } haxe_3.4.4.orig/std/flash/geom/PerspectiveProjection.hx0000664000175000017500000000033513166552354023122 0ustar andyandy00000000000000package flash.geom; @:require(flash10) extern class PerspectiveProjection { var fieldOfView : Float; var focalLength : Float; var projectionCenter : Point; function new() : Void; function toMatrix3D() : Matrix3D; } haxe_3.4.4.orig/std/flash/geom/Point.hx0000664000175000017500000000137513166552354017672 0ustar andyandy00000000000000package flash.geom; extern class Point { var length(default,never) : Float; var x : Float; var y : Float; function new(x : Float = 0, y : Float = 0) : Void; function add(v : Point) : Point; function clone() : Point; @:require(flash11) function copyFrom(sourcePoint : Point) : Void; function equals(toCompare : Point) : Bool; function normalize(thickness : Float) : Void; function offset(dx : Float, dy : Float) : Void; @:require(flash11) function setTo(xa : Float, ya : Float) : Void; function subtract(v : Point) : Point; function toString() : String; static function distance(pt1 : Point, pt2 : Point) : Float; static function interpolate(pt1 : Point, pt2 : Point, f : Float) : Point; static function polar(len : Float, angle : Float) : Point; } haxe_3.4.4.orig/std/flash/geom/Rectangle.hx0000664000175000017500000000225213166552354020500 0ustar andyandy00000000000000package flash.geom; extern class Rectangle { var bottom : Float; var bottomRight : Point; var height : Float; var left : Float; var right : Float; var size : Point; var top : Float; var topLeft : Point; var width : Float; var x : Float; var y : Float; function new(x : Float = 0, y : Float = 0, width : Float = 0, height : Float = 0) : Void; function clone() : Rectangle; function contains(x : Float, y : Float) : Bool; function containsPoint(point : Point) : Bool; function containsRect(rect : Rectangle) : Bool; @:require(flash11) function copyFrom(sourceRect : Rectangle) : Void; function equals(toCompare : Rectangle) : Bool; function inflate(dx : Float, dy : Float) : Void; function inflatePoint(point : Point) : Void; function intersection(toIntersect : Rectangle) : Rectangle; function intersects(toIntersect : Rectangle) : Bool; function isEmpty() : Bool; function offset(dx : Float, dy : Float) : Void; function offsetPoint(point : Point) : Void; function setEmpty() : Void; @:require(flash11) function setTo(xa : Float, ya : Float, widtha : Float, heighta : Float) : Void; function toString() : String; function union(toUnion : Rectangle) : Rectangle; } haxe_3.4.4.orig/std/flash/geom/Transform.hx0000664000175000017500000000105113166552354020543 0ustar andyandy00000000000000package flash.geom; extern class Transform { var colorTransform : ColorTransform; var concatenatedColorTransform(default,never) : ColorTransform; var concatenatedMatrix(default,never) : Matrix; var matrix : Matrix; @:require(flash10) var matrix3D : Matrix3D; @:require(flash10) var perspectiveProjection : PerspectiveProjection; var pixelBounds(default,never) : Rectangle; function new(displayObject : flash.display.DisplayObject) : Void; @:require(flash10) function getRelativeMatrix3D(relativeTo : flash.display.DisplayObject) : Matrix3D; } haxe_3.4.4.orig/std/flash/geom/Utils3D.hx0000664000175000017500000000063013166552354020061 0ustar andyandy00000000000000package flash.geom; @:require(flash10) extern class Utils3D { static function pointTowards(percent : Float, mat : Matrix3D, pos : Vector3D, ?at : Vector3D, ?up : Vector3D) : Matrix3D; static function projectVector(m : Matrix3D, v : Vector3D) : Vector3D; static function projectVectors(m : Matrix3D, verts : flash.Vector, projectedVerts : flash.Vector, uvts : flash.Vector) : Void; } haxe_3.4.4.orig/std/flash/geom/Vector3D.hx0000664000175000017500000000246213166552354020230 0ustar andyandy00000000000000package flash.geom; @:require(flash10) extern class Vector3D { var length(default,never) : Float; var lengthSquared(default,never) : Float; var w : Float; var x : Float; var y : Float; var z : Float; function new(x : Float = 0, y : Float = 0, z : Float = 0, w : Float = 0) : Void; function add(a : Vector3D) : Vector3D; function clone() : Vector3D; @:require(flash11) function copyFrom(sourceVector3D : Vector3D) : Void; function crossProduct(a : Vector3D) : Vector3D; function decrementBy(a : Vector3D) : Void; function dotProduct(a : Vector3D) : Float; function equals(toCompare : Vector3D, allFour : Bool = false) : Bool; function incrementBy(a : Vector3D) : Void; function nearEquals(toCompare : Vector3D, tolerance : Float, allFour : Bool = false) : Bool; function negate() : Void; function normalize() : Float; function project() : Void; function scaleBy(s : Float) : Void; @:require(flash11) function setTo(xa : Float, ya : Float, za : Float) : Void; function subtract(a : Vector3D) : Vector3D; function toString() : String; static var X_AXIS(default,never) : Vector3D; static var Y_AXIS(default,never) : Vector3D; static var Z_AXIS(default,never) : Vector3D; static function angleBetween(a : Vector3D, b : Vector3D) : Float; static function distance(pt1 : Vector3D, pt2 : Vector3D) : Float; } haxe_3.4.4.orig/std/flash/globalization/Collator.hx0000664000175000017500000000127113166552354022262 0ustar andyandy00000000000000package flash.globalization; @:final @:require(flash10_1) extern class Collator { var actualLocaleIDName(default,never) : String; var ignoreCase : Bool; var ignoreCharacterWidth : Bool; var ignoreDiacritics : Bool; var ignoreKanaType : Bool; var ignoreSymbols : Bool; var lastOperationStatus(default,never) : LastOperationStatus; var numericComparison : Bool; var requestedLocaleIDName(default,never) : String; function new(requestedLocaleIDName : String, ?initialMode : CollatorMode) : Void; function compare(string1 : String, string2 : String) : Int; function equals(string1 : String, string2 : String) : Bool; static function getAvailableLocaleIDNames() : flash.Vector; } haxe_3.4.4.orig/std/flash/globalization/CollatorMode.hx0000664000175000017500000000014313166552354023064 0ustar andyandy00000000000000package flash.globalization; @:fakeEnum(String) extern enum CollatorMode { MATCHING; SORTING; } haxe_3.4.4.orig/std/flash/globalization/CurrencyFormatter.hx0000664000175000017500000000211313166552354024155 0ustar andyandy00000000000000package flash.globalization; @:final @:require(flash10_1) extern class CurrencyFormatter { var actualLocaleIDName(default,never) : String; var currencyISOCode(default,never) : String; var currencySymbol(default,never) : String; var decimalSeparator : String; var digitsType : UInt; var fractionalDigits : Int; var groupingPattern : String; var groupingSeparator : String; var lastOperationStatus(default,never) : LastOperationStatus; var leadingZero : Bool; var negativeCurrencyFormat : UInt; var negativeSymbol : String; var positiveCurrencyFormat : UInt; var requestedLocaleIDName(default,never) : String; var trailingZeros : Bool; var useGrouping : Bool; function new(requestedLocaleIDName : String) : Void; function format(value : Float, withCurrencySymbol : Bool = false) : String; function formattingWithCurrencySymbolIsSafe(requestedISOCode : String) : Bool; function parse(inputString : String) : CurrencyParseResult; function setCurrency(currencyISOCode : String, currencySymbol : String) : Void; static function getAvailableLocaleIDNames() : flash.Vector; } haxe_3.4.4.orig/std/flash/globalization/CurrencyParseResult.hx0000664000175000017500000000033613166552354024470 0ustar andyandy00000000000000package flash.globalization; @:final extern class CurrencyParseResult { var currencyString(default,never) : String; var value(default,never) : Float; function new(value : Float = 0./*NaN*/, ?symbol : String) : Void; } haxe_3.4.4.orig/std/flash/globalization/DateTimeFormatter.hx0000664000175000017500000000205213166552354024061 0ustar andyandy00000000000000package flash.globalization; @:final @:require(flash10_1) extern class DateTimeFormatter { var actualLocaleIDName(default,never) : String; var lastOperationStatus(default,never) : LastOperationStatus; var requestedLocaleIDName(default,never) : String; function new(requestedLocaleIDName : String, ?dateStyle : DateTimeStyle, ?timeStyle : DateTimeStyle) : Void; function format(dateTime : Date) : String; function formatUTC(dateTime : Date) : String; function getDateStyle() : DateTimeStyle; function getDateTimePattern() : DateTimeStyle; function getFirstWeekday() : Int; function getMonthNames(?nameStyle : DateTimeNameStyle, ?context : DateTimeNameContext) : flash.Vector; function getTimeStyle() : DateTimeStyle; function getWeekdayNames(?nameStyle : DateTimeNameStyle, ?context : DateTimeNameContext) : flash.Vector; function setDateTimePattern(pattern : String) : Void; function setDateTimeStyles(dateStyle : DateTimeStyle, timeStyle : DateTimeStyle) : Void; static function getAvailableLocaleIDNames() : flash.Vector; } haxe_3.4.4.orig/std/flash/globalization/DateTimeNameContext.hx0000664000175000017500000000015313166552354024343 0ustar andyandy00000000000000package flash.globalization; @:fakeEnum(String) extern enum DateTimeNameContext { FORMAT; STANDALONE; } haxe_3.4.4.orig/std/flash/globalization/DateTimeNameStyle.hx0000664000175000017500000000020313166552354024013 0ustar andyandy00000000000000package flash.globalization; @:fakeEnum(String) extern enum DateTimeNameStyle { FULL; LONG_ABBREVIATION; SHORT_ABBREVIATION; } haxe_3.4.4.orig/std/flash/globalization/DateTimeStyle.hx0000664000175000017500000000016713166552354023223 0ustar andyandy00000000000000package flash.globalization; @:fakeEnum(String) extern enum DateTimeStyle { CUSTOM; LONG; MEDIUM; NONE; SHORT; } haxe_3.4.4.orig/std/flash/globalization/LastOperationStatus.hx0000664000175000017500000000071013166552354024470 0ustar andyandy00000000000000package flash.globalization; @:fakeEnum(String) extern enum LastOperationStatus { BUFFER_OVERFLOW_ERROR; ERROR_CODE_UNKNOWN; ILLEGAL_ARGUMENT_ERROR; INDEX_OUT_OF_BOUNDS_ERROR; INVALID_ATTR_VALUE; INVALID_CHAR_FOUND; MEMORY_ALLOCATION_ERROR; NO_ERROR; NUMBER_OVERFLOW_ERROR; PARSE_ERROR; PATTERN_SYNTAX_ERROR; PLATFORM_API_FAILED; TRUNCATED_CHAR_FOUND; UNEXPECTED_TOKEN; UNSUPPORTED_ERROR; USING_DEFAULT_WARNING; USING_FALLBACK_WARNING; } haxe_3.4.4.orig/std/flash/globalization/LocaleID.hx0000664000175000017500000000116113166552354022115 0ustar andyandy00000000000000package flash.globalization; @:final @:require(flash10_1) extern class LocaleID { var lastOperationStatus(default,never) : LastOperationStatus; var name(default,never) : String; function new(name : String) : Void; function getKeysAndValues() : flash.utils.Object; function getLanguage() : String; function getRegion() : String; function getScript() : String; function getVariant() : String; function isRightToLeft() : Bool; static var DEFAULT(default,never) : String; static function determinePreferredLocales(want : flash.Vector, have : flash.Vector, ?keyword : String) : flash.Vector; } haxe_3.4.4.orig/std/flash/globalization/NationalDigitsType.hx0000664000175000017500000000064713166552354024264 0ustar andyandy00000000000000package flash.globalization; @:fakeEnum(UInt) extern enum NationalDigitsType { ARABIC_INDIC; BALINESE; BENGALI; CHAM; DEVANAGARI; EUROPEAN; EXTENDED_ARABIC_INDIC; FULL_WIDTH; GUJARATI; GURMUKHI; KANNADA; KAYAH_LI; KHMER; LAO; LEPCHA; LIMBU; MALAYALAM; MONGOLIAN; MYANMAR; MYANMAR_SHAN; NEW_TAI_LUE; NKO; OL_CHIKI; ORIYA; OSMANYA; SAURASHTRA; SUNDANESE; TAMIL; TELUGU; THAI; TIBETAN; VAI; } haxe_3.4.4.orig/std/flash/globalization/NumberFormatter.hx0000664000175000017500000000164313166552354023622 0ustar andyandy00000000000000package flash.globalization; @:final @:require(flash10_1) extern class NumberFormatter { var actualLocaleIDName(default,never) : String; var decimalSeparator : String; var digitsType : NationalDigitsType; var fractionalDigits : Int; var groupingPattern : String; var groupingSeparator : String; var lastOperationStatus(default,never) : LastOperationStatus; var leadingZero : Bool; var negativeNumberFormat : UInt; var negativeSymbol : String; var requestedLocaleIDName(default,never) : String; var trailingZeros : Bool; var useGrouping : Bool; function new(requestedLocaleIDName : String) : Void; function formatInt(value : Int) : String; function formatNumber(value : Float) : String; function formatUint(value : UInt) : String; function parse(parseString : String) : NumberParseResult; function parseNumber(parseString : String) : Float; static function getAvailableLocaleIDNames() : flash.Vector; } haxe_3.4.4.orig/std/flash/globalization/NumberParseResult.hx0000664000175000017500000000047013166552354024125 0ustar andyandy00000000000000package flash.globalization; @:final @:require(flash10_1) extern class NumberParseResult { var endIndex(default,never) : Int; var startIndex(default,never) : Int; var value(default,never) : Float; function new(value : Float = 0./*NaN*/, startIndex : Int = 2147483647, endIndex : Int = 2147483647) : Void; } haxe_3.4.4.orig/std/flash/globalization/StringTools.hx0000664000175000017500000000071713166552354022776 0ustar andyandy00000000000000package flash.globalization; @:final @:require(flash10_1) extern class StringTools { var actualLocaleIDName(default,never) : String; var lastOperationStatus(default,never) : LastOperationStatus; var requestedLocaleIDName(default,never) : String; function new(requestedLocaleIDName : String) : Void; function toLowerCase(s : String) : String; function toUpperCase(s : String) : String; static function getAvailableLocaleIDNames() : flash.Vector; } haxe_3.4.4.orig/std/flash/media/AVABRParameters.hx0000664000175000017500000000067613166552354021613 0ustar andyandy00000000000000package flash.media; extern class AVABRParameters { var maxBitsPerSecond : Int; var minBitsPerSecond : Int; var policy : String; var startBitsPerSecond : Int; function new(init_policy : String, init_startBitsPerSecond : UInt, init_minBitsPerSecond : UInt, init_maxBitsPerSecond : UInt) : Void; static var AGGRESSIVE(default,never) : String; static var CONSERVATIVE(default,never) : String; static var MODERATE(default,never) : String; } haxe_3.4.4.orig/std/flash/media/AVABRProfileInfo.hx0000664000175000017500000000037113166552354021714 0ustar andyandy00000000000000package flash.media; extern class AVABRProfileInfo { var bitsPerSecond(default,never) : Int; var height(default,never) : Int; var width(default,never) : Int; function new(init_bitsPerSecond : Int, init_width : Int, init_height : Int) : Void; } haxe_3.4.4.orig/std/flash/media/AVCaptionStyle.hx0000664000175000017500000000427313166552354021576 0ustar andyandy00000000000000package flash.media; extern class AVCaptionStyle { var backgroundColor : String; var backgroundOpacity : String; var bottomInset : String; var edgeColor : String; var fillColor : String; var fillOpacity : String; var font : String; var fontColor : String; var fontEdge : String; var fontOpacity : String; var size : String; function new() : Void; static var BLACK(default,never) : String; static var BLUE(default,never) : String; static var BRIGHT_BLUE(default,never) : String; static var BRIGHT_CYAN(default,never) : String; static var BRIGHT_GREEN(default,never) : String; static var BRIGHT_MAGENTA(default,never) : String; static var BRIGHT_RED(default,never) : String; static var BRIGHT_WHITE(default,never) : String; static var BRIGHT_YELLOW(default,never) : String; static var CASUAL(default,never) : String; static var CURSIVE(default,never) : String; static var CYAN(default,never) : String; static var DARK_BLUE(default,never) : String; static var DARK_CYAN(default,never) : String; static var DARK_GREEN(default,never) : String; static var DARK_MAGENTA(default,never) : String; static var DARK_RED(default,never) : String; static var DARK_YELLOW(default,never) : String; static var DEFAULT(default,never) : String; static var DEPRESSED(default,never) : String; static var GRAY(default,never) : String; static var GREEN(default,never) : String; static var LARGE(default,never) : String; static var LEFT_DROP_SHADOW(default,never) : String; static var MAGENTA(default,never) : String; static var MEDIUM(default,never) : String; static var MONOSPACED_WITHOUT_SERIFS(default,never) : String; static var MONOSPACE_WITH_SERIFS(default,never) : String; static var NONE(default,never) : String; static var PROPORTIONAL_WITHOUT_SERIFS(default,never) : String; static var PROPORTIONAL_WITH_SERIFS(default,never) : String; static var RAISED(default,never) : String; static var RED(default,never) : String; static var RIGHT_DROP_SHADOW(default,never) : String; static var SMALL(default,never) : String; static var SMALL_CAPITALS(default,never) : String; static var UNIFORM(default,never) : String; static var WHITE(default,never) : String; static var YELLOW(default,never) : String; } haxe_3.4.4.orig/std/flash/media/AVCuePoint.hx0000664000175000017500000000035213166552354020700 0ustar andyandy00000000000000package flash.media; extern class AVCuePoint { var dictionary(default,never) : flash.utils.Dictionary; var localTime(default,never) : Float; function new(init_dictionary : flash.utils.Dictionary, init_localTime : Float) : Void; } haxe_3.4.4.orig/std/flash/media/AVInsertionResult.hx0000664000175000017500000000037213166552354022325 0ustar andyandy00000000000000package flash.media; extern class AVInsertionResult extends AVResult { var insertedBeforeReadHead(default,never) : Bool; var periodIndex(default,never) : Int; function new(result : Int, periodIndex : Int, insertedBeforeReadHead : Bool) : Void; } haxe_3.4.4.orig/std/flash/media/AVNetworkingParams.hx0000664000175000017500000000050513166552354022445 0ustar andyandy00000000000000package flash.media; extern class AVNetworkingParams { var forceNativeNetworking : Bool; var readSetCookieHeader : Bool; var useCookieHeaderForAllRequests : Bool; function new(init_forceNativeNetworking : Bool = false, init_readSetCookieHeader : Bool = true, init_useCookieHeaderForAllRequests : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/media/AVPeriodInfo.hx0000664000175000017500000000146013166552354021211 0ustar andyandy00000000000000package flash.media; extern class AVPeriodInfo { var duration(default,never) : Float; var firstCuePointIndex(default,never) : Int; var firstSubscribedTagIndex(default,never) : Int; var lastCuePointIndex(default,never) : Int; var lastSubscribedTagIndex(default,never) : Int; var localStartTime(default,never) : Float; var supportsTrickPlay(default,never) : Bool; var targetDuration(default,never) : Float; var userData(default,never) : Int; var virtualStartTime(default,never) : Float; function new(init_localStartTime : Float, init_virtualStartTime : Float, init_duration : Float, init_firstCuePointIndex : Int, init_lastCuePointIndex : Int, init_firstSubscribedTagIndex : Int, init_lastSubscribedTagIndex : Int, init_userData : Int, init_supportsTrickPlay : Bool, init_targetDuration : Float) : Void; } haxe_3.4.4.orig/std/flash/media/AVPlayState.hx0000664000175000017500000000100413166552354021053 0ustar andyandy00000000000000package flash.media; extern class AVPlayState { var state(default,never) : Int; function new(state : UInt) : Void; static var BUFFERING(default,never) : Int; static var EOF(default,never) : Int; static var PAUSED(default,never) : Int; static var PLAYING(default,never) : Int; static var READY(default,never) : Int; static var SUSPENDED(default,never) : Int; static var TRICK_PLAY(default,never) : Int; static var UNINITIALIZED(default,never) : Int; static var UNRECOVERABLE_ERROR(default,never) : Int; } haxe_3.4.4.orig/std/flash/media/AVResult.hx0000664000175000017500000001300613166552354020430 0ustar andyandy00000000000000package flash.media; extern class AVResult { var result(default,never) : Int; function new(inResult : Int) : Void; static var ASYNC_OPERATION_IN_PROGRESS(default,never) : Int; static var AUDIO_ONLY_STREAM_END(default,never) : Int; static var AUDIO_ONLY_STREAM_START(default,never) : Int; static var AUDIO_START_ERROR(default,never) : Int; static var BAD_MANIFEST_SIGNATURE(default,never) : Int; static var BAD_MEDIASAMPLE_FOUND(default,never) : Int; static var BAD_MEDIA_INTERLEAVING(default,never) : Int; static var CALLED_FROM_WRONG_THREAD(default,never) : Int; static var CANNOT_ERASE_TIMELINE(default,never) : Int; static var CANNOT_FAIL_OVER(default,never) : Int; static var CANNOT_HANDLE_MAIN_MANIFEST_UPDATE(default,never) : Int; static var CANNOT_LOAD_PLAY_LIST(default,never) : Int; static var CANNOT_SPLIT_TIMELINE(default,never) : Int; static var CODEC_NOT_SUPPORTED(default,never) : Int; static var COMPONENT_CREATION_FAILURE(default,never) : Int; static var CONTAINER_NOT_SUPPORTED(default,never) : Int; static var CONTENT_LENGTH_MISMATCH(default,never) : Int; static var CRYPTO_ALGORITHM_NOT_SUPPORTED(default,never) : Int; static var CRYPTO_ERROR_BAD_CERTIFICATE(default,never) : Int; static var CRYPTO_ERROR_BAD_PARAMETER(default,never) : Int; static var CRYPTO_ERROR_BUFFER_TOO_SMALL(default,never) : Int; static var CRYPTO_ERROR_CORRUPTED_DATA(default,never) : Int; static var CRYPTO_ERROR_DIGEST_FINISH(default,never) : Int; static var CRYPTO_ERROR_DIGEST_UPDATE(default,never) : Int; static var CRYPTO_ERROR_UNKNOWN(default,never) : Int; static var CURRENT_PERIOD_EXPIRED(default,never) : Int; static var DECODER_FAILED(default,never) : Int; static var DEVICE_OPEN_ERROR(default,never) : Int; static var DID_NOT_GET_NEXT_FRAGMENT(default,never) : Int; static var DRM_INIT_ERROR(default,never) : Int; static var DRM_NOT_AVAILABLE(default,never) : Int; static var END_OF_PERIOD(default,never) : Int; static var EOF(default,never) : Int; static var FILE_NOT_FOUND(default,never) : Int; static var FILE_OPEN_ERROR(default,never) : Int; static var FILE_READ_ERROR(default,never) : Int; static var FILE_STRUCTURE_INVALID(default,never) : Int; static var FILE_WRITE_ERROR(default,never) : Int; static var FRAGMENT_READ_ERROR(default,never) : Int; static var GENERIC_ERROR(default,never) : Int; static var HTTP_TIME_OUT(default,never) : Int; static var ID3_PARSE_ERROR(default,never) : Int; static var INCOMPATIBLE_RENDER_MODE(default,never) : Int; static var INCOMPATIBLE_VERSION(default,never) : Int; static var INTERNAL_ERROR(default,never) : Int; static var INVALID_KEY(default,never) : Int; static var INVALID_OPERATION(default,never) : Int; static var INVALID_PARAMETER(default,never) : Int; static var INVALID_REPLACE_DURATION(default,never) : Int; static var INVALID_SEEK_TIME(default,never) : Int; static var INVALID_WITH_AUDIO_ONLY_FILE(default,never) : Int; static var IRRECOVERABLE_ERROR(default,never) : Int; static var KEY_NOT_FOUND(default,never) : Int; static var KEY_SERVER_NOT_FOUND(default,never) : Int; static var LISTENER_NOT_FOUND(default,never) : Int; static var LIVE_HOLD(default,never) : Int; static var LIVE_WINDOW_MOVED_BACKWARD(default,never) : Int; static var LOST_CONNECTION_RECOVERABLE(default,never) : Int; static var MAIN_MANIFEST_UPDATE_TO_BE_HANDLED(default,never) : Int; static var MANIFEST_FILE_UNEXPECTEDLY_CHANGED(default,never) : Int; static var NETWORK_DOWN(default,never) : Int; static var NETWORK_ERROR(default,never) : Int; static var NETWORK_UNAVAILABLE(default,never) : Int; static var NOT_IMPLEMENTED(default,never) : Int; static var NO_AUDIO_SINK(default,never) : Int; static var NO_FIXED_SIZE(default,never) : Int; static var NO_TIMELINE(default,never) : Int; static var NO_USEABLE_BITRATE_PROFILE(default,never) : Int; static var NULL_OPERATION(default,never) : Int; static var ONLY_ALLOWED_IN_PAUSED_STATE(default,never) : Int; static var OPERATION_ABORTED(default,never) : Int; static var OUT_OF_MEMORY(default,never) : Int; static var OVERFLOW(default,never) : Int; static var PARSE_ERROR(default,never) : Int; static var PARTIAL_REPLACEMENT(default,never) : Int; static var PERIOD_HOLD(default,never) : Int; static var PERIOD_NOT_LOADED(default,never) : Int; static var PLAYBACK_NOT_ENABLED(default,never) : Int; static var POSTROLL_WITH_LIVE_NOT_ALLOWED(default,never) : Int; static var PREVIOUS_STEP_SEEK_IN_PROGRESS(default,never) : Int; static var PROTOCOL_NOT_SUPPORTED(default,never) : Int; static var RANGE_ERROR(default,never) : Int; static var RANGE_SPANS_READHEAD(default,never) : Int; static var RENDITION_M3U8_ERROR(default,never) : Int; static var REPLACEMENT_FAILED(default,never) : Int; static var RESOURCE_NOT_SPECIFIED(default,never) : Int; static var SECURITY_ERROR(default,never) : Int; static var SEEK_FAILED(default,never) : Int; static var SEGMENT_SKIPPED_ON_FAILURE(default,never) : Int; static var SIZE_UNKNOWN(default,never) : Int; static var SPS_PPS_FOUND_OUTSIDE_AVCC(default,never) : Int; static var SUCCESS(default,never) : Int; static var SWITCH_TO_ASYMMETRIC_PROFILE(default,never) : Int; static var TIMELINE_TOO_SHORT(default,never) : Int; static var UNDERFLOW(default,never) : Int; static var UNREPORTED_TIME_DISCONTINUITY_FOUND(default,never) : Int; static var UNSUPPORTED_CONFIGURATION(default,never) : Int; static var UNSUPPORTED_HLS_VERSION(default,never) : Int; static var UNSUPPORTED_OPERATION(default,never) : Int; static var VIDEO_PROFILE_NOT_SUPPORTED(default,never) : Int; static var WAITING_FOR_INIT(default,never) : Int; } haxe_3.4.4.orig/std/flash/media/AVSegmentedSource.hx0000664000175000017500000000653713166552354022261 0ustar andyandy00000000000000package flash.media; extern class AVSegmentedSource extends AVSource { var cookieHeader(never,default) : String; var masterUpdateInterval(never,default) : Int; var networkingParams : AVNetworkingParams; var useRedirectedUrl(never,default) : Bool; function new() : Void; function addCustomHeader(headerName : String, args : flash.Vector) : Void; function clearPauseAtPeriodEnd(periodIndex : Int) : AVResult; function getABRProfileCount(periodIndex : Int) : Int; function getABRProfileInfoAtIndex(periodIndex : Int, abrProfileIndex : Int) : AVABRProfileInfo; function getBackgroundPeriodInfo(periodIndex : Int) : AVPeriodInfo; function getBackgroundTimeline() : AVTimeline; function getCuePoint(periodIndex : Int, cuePointIndex : Int) : AVCuePoint; function getPerceivedBandwidth() : UInt; function getPeriodInfo(periodIndex : Int) : AVPeriodInfo; function getSubscribedTag(periodIndex : Int, tagDataIndex : Int) : AVTagData; function getSubscribedTagForBackgroundManifest(periodIndex : Int, tagDataIndex : Int) : AVTagData; function getTimeline() : AVTimeline; function getTimelineSubscribedTag(tagDataIndex : Int) : AVTagData; function getTimelineSubscribedTagForBackgroundManifest(tagDataIndex : Int) : AVTagData; function getTrackCount(periodIndex : Int, payloadType : String) : Int; function getTrackInfo(periodIndex : Int, payloadType : String, trackIndex : Int) : AVTrackInfo; function insertByLocalTime(periodIndex : Int, insertionTime : Float, handle : Int, userData : Int = 0, replaceDuration : Float = 0) : AVInsertionResult; function insertByVirtualTime(insertionTime : Float, handle : Int, userData : Int = 0, replaceDuration : Float = 0) : AVInsertionResult; function load(url : String, ?containerType : String, userData : Int = 0) : AVResult; function loadManifest(uri : String, userData : Int = 0, ?containerType : String) : AVResult; function loadWithBackgroundManifest(url : String, containerType : String, userData : Int, backgroundManifest : String) : AVResult; function releaseManifest(handle : Int) : AVResult; function removeByLocalTime(periodIndex : Int, timeStart : Float, timeEnd : Float, replaceWithMainMedia : Bool) : AVResult; function removeByVirtualTime(virtualTimeStart : Float, virtualTimeEnd : Float) : AVResult; function selectTrack(periodIndex : Int, payloadType : String, trackIndex : Int) : AVResult; function selectTrackString(periodIndex : Int, payloadType : String, trackString : String) : AVResult; function setABRParameters(params : AVABRParameters) : AVResult; function setBandwidth(bitsPerSecond : Int) : AVResult; function setCuePointTags(tagArray : Array) : AVResult; function setHoldAt(time : Float) : AVResult; function setPauseAtPeriodEnd(periodIndex : Int, userData : Int = 0) : AVResult; function setSubscribedTags(tagArray : Array) : AVResult; function setSubscribedTagsForBackgroundManifest(tagArray : Array) : AVResult; static var AUDIO(default,never) : String; static var AUDIO_DESCRIPTION(default,never) : String; static var AUDIO_LANGUAGE(default,never) : String; static var AUDIO_PID(default,never) : String; static var DASH(default,never) : String; static var DATA(default,never) : String; static var DATA_DESCRIPTION(default,never) : String; static var HLS(default,never) : String; static var VIDEO(default,never) : String; static var VIDEO_DESCRIPTION(default,never) : String; } haxe_3.4.4.orig/std/flash/media/AVSource.hx0000664000175000017500000000021113166552354020404 0ustar andyandy00000000000000package flash.media; extern class AVSource extends flash.events.EventDispatcher { function new() : Void; function dispose() : Void; } haxe_3.4.4.orig/std/flash/media/AVStream.hx0000664000175000017500000000275513166552354020416 0ustar andyandy00000000000000package flash.media; extern class AVStream extends flash.events.EventDispatcher { var backBufferLength(default,never) : Float; var backBufferTime(never,default) : Float; var bufferLength(default,never) : Float; var bufferTime(never,default) : Float; var captionStyle(never,default) : AVCaptionStyle; var captionsEnabled : Bool; var clientLivePoint(default,never) : Float; var currentFPS(default,never) : Float; var decoderType(default,never) : String; var droppedFrames(default,never) : Int; var frameTime(default,never) : Float; var initialBufferTime(never,default) : Float; var playState(default,never) : AVPlayState; var renderType(default,never) : String; var time(default,never) : Float; var useHardwareDecoder : Bool; var volume : Float; function new(source : AVSource) : Void; function dispose() : Void; function fastForward(rate : Float) : AVResult; function pause() : AVResult; function play() : AVResult; function resume() : Bool; function rewind(rate : Float) : AVResult; function seek(offset : Float, inBufferSeek : Bool = true) : AVResult; function seekToKeyFrame(offset : Float, inBufferSeek : Bool = true) : AVResult; function seekToLivePoint() : AVResult; function seekToLocalTime(periodIndex : Int, time : Float) : AVResult; function setPlaySpeed(speed : Float, reserved : Float) : Void; function step(frames : Int) : AVResult; static var HARDWARE(default,never) : String; static var SOFTWARE(default,never) : String; static var UNDEFINED(default,never) : String; } haxe_3.4.4.orig/std/flash/media/AVTagData.hx0000664000175000017500000000027513166552354020463 0ustar andyandy00000000000000package flash.media; extern class AVTagData { var data(default,never) : String; var localTime(default,never) : Float; function new(init_data : String, init_localTime : Float) : Void; } haxe_3.4.4.orig/std/flash/media/AVTimeline.hx0000664000175000017500000000121013166552354020712 0ustar andyandy00000000000000package flash.media; extern class AVTimeline { var complete(default,never) : Bool; var firstPeriodIndex(default,never) : Int; var firstSubscribedTagIndex(default,never) : Int; var lastPeriodIndex(default,never) : Int; var lastSubscribedTagIndex(default,never) : Int; var type(default,never) : String; var virtualDuration(default,never) : Float; var virtualStartTime(default,never) : Float; function new(init_type : String, init_virtualStartTime : Float, init_virtualDuration : Float, init_firstPeriodIndex : Int, init_lastPeriodIndex : Int, init_firstSubscribedIndex : Int, init_lastSubscribedIndex : Int, init_complete : Bool) : Void; } haxe_3.4.4.orig/std/flash/media/AVTrackInfo.hx0000664000175000017500000000136413166552354021036 0ustar andyandy00000000000000package flash.media; extern class AVTrackInfo { var activity(default,never) : Bool; var autoSelect(default,never) : Bool; var dataTrackInfoServiceType(default,never) : String; var defaultTrack(default,never) : Bool; var description(default,never) : String; var forced(default,never) : Bool; var language(default,never) : String; var pid(default,never) : Int; function new(init_description : String, init_language : String, init_defaultTrack : Bool, init_autoSelect : Bool, init_forced : Bool, init_activity : Bool, init_dataTrackInfoServiceType : String, init_pid : Int) : Void; static var DTI_608_CAPTIONS(default,never) : String; static var DTI_708_CAPTIONS(default,never) : String; static var DTI_WEBVTT_CAPTIONS(default,never) : String; } haxe_3.4.4.orig/std/flash/media/AVURLLoader.hx0000664000175000017500000000031413166552354020741 0ustar andyandy00000000000000package flash.media; extern class AVURLLoader extends flash.net.URLLoader { var cookieHeader(never,default) : String; var stream : AVURLStream; function new(?request : flash.net.URLRequest) : Void; } haxe_3.4.4.orig/std/flash/media/AVURLStream.hx0000664000175000017500000000022213166552354020764 0ustar andyandy00000000000000package flash.media; extern class AVURLStream extends flash.net.URLStream { var cookieHeader(never,default) : String; function new() : Void; } haxe_3.4.4.orig/std/flash/media/AudioDecoder.hx0000664000175000017500000000061413166552354021253 0ustar andyandy00000000000000package flash.media; extern class AudioDecoder { function new() : Void; static var DOLBY_DIGITAL(default,never) : String; static var DOLBY_DIGITAL_PLUS(default,never) : String; static var DTS(default,never) : String; static var DTS_EXPRESS(default,never) : String; static var DTS_HD_HIGH_RESOLUTION_AUDIO(default,never) : String; static var DTS_HD_MASTER_AUDIO(default,never) : String; } haxe_3.4.4.orig/std/flash/media/Camera.hx0000664000175000017500000000315413166552354020116 0ustar andyandy00000000000000package flash.media; @:final extern class Camera extends flash.events.EventDispatcher { var activityLevel(default,never) : Float; var bandwidth(default,never) : Int; var currentFPS(default,never) : Float; var fps(default,never) : Float; var height(default,never) : Int; var index(default,never) : Int; var keyFrameInterval(default,never) : Int; var loopback(default,never) : Bool; var motionLevel(default,never) : Int; var motionTimeout(default,never) : Int; var muted(default,never) : Bool; var name(default,never) : String; @:require(flash11_2) var position(default,never) : String; var quality(default,never) : Int; var width(default,never) : Int; function new() : Void; @:require(flash11_4) function copyToByteArray(rect : flash.geom.Rectangle, destination : flash.utils.ByteArray) : Void; @:require(flash11_4) function copyToVector(rect : flash.geom.Rectangle, destination : flash.Vector) : Void; @:require(flash11_4) function drawToBitmapData(destination : flash.display.BitmapData) : Void; function setCursor(value : Bool) : Void; function setKeyFrameInterval(keyFrameInterval : Int) : Void; function setLoopback(compress : Bool = false) : Void; function setMode(width : Int, height : Int, fps : Float, favorArea : Bool = true) : Void; function setMotionLevel(motionLevel : Int, timeout : Int = 2000) : Void; function setQuality(bandwidth : Int, quality : Int) : Void; @:require(flash10_1) static var isSupported(default,never) : Bool; static var names(default,never) : Array; @:require(flash10_1) static function _scanHardware() : Void; static function getCamera(?name : String) : Camera; } haxe_3.4.4.orig/std/flash/media/H264Level.hx0000664000175000017500000000145613166552354020344 0ustar andyandy00000000000000package flash.media; extern class H264Level { function new() : Void; static var LEVEL_1(default,never) : String; static var LEVEL_1B(default,never) : String; static var LEVEL_1_1(default,never) : String; static var LEVEL_1_2(default,never) : String; static var LEVEL_1_3(default,never) : String; static var LEVEL_2(default,never) : String; static var LEVEL_2_1(default,never) : String; static var LEVEL_2_2(default,never) : String; static var LEVEL_3(default,never) : String; static var LEVEL_3_1(default,never) : String; static var LEVEL_3_2(default,never) : String; static var LEVEL_4(default,never) : String; static var LEVEL_4_1(default,never) : String; static var LEVEL_4_2(default,never) : String; static var LEVEL_5(default,never) : String; static var LEVEL_5_1(default,never) : String; } haxe_3.4.4.orig/std/flash/media/H264Profile.hx0000664000175000017500000000024313166552354020666 0ustar andyandy00000000000000package flash.media; extern class H264Profile { function new() : Void; static var BASELINE(default,never) : String; static var MAIN(default,never) : String; } haxe_3.4.4.orig/std/flash/media/H264VideoStreamSettings.hx0000664000175000017500000000040113166552354023225 0ustar andyandy00000000000000package flash.media; extern class H264VideoStreamSettings extends VideoStreamSettings { var level(default,never) : String; var profile(default,never) : String; function new() : Void; function setProfileLevel(profile : String, level : String) : Void; } haxe_3.4.4.orig/std/flash/media/ID3Info.hx0000664000175000017500000000037213166552354020120 0ustar andyandy00000000000000package flash.media; @:final extern class ID3Info implements Dynamic { var album : String; var artist : String; var comment : String; var genre : String; var songName : String; var track : String; var year : String; function new() : Void; } haxe_3.4.4.orig/std/flash/media/Microphone.hx0000664000175000017500000000233313166552354021027 0ustar andyandy00000000000000package flash.media; @:final extern class Microphone extends flash.events.EventDispatcher { var activityLevel(default,never) : Float; @:require(flash10) var codec : SoundCodec; @:require(flash10_1) var enableVAD : Bool; @:require(flash10) var encodeQuality : Int; @:require(flash10_2) var enhancedOptions : MicrophoneEnhancedOptions; @:require(flash10) var framesPerPacket : Int; var gain : Float; var index(default,never) : Int; var muted(default,never) : Bool; var name(default,never) : String; @:require(flash10_1) var noiseSuppressionLevel : Int; var rate : Int; var silenceLevel(default,never) : Float; var silenceTimeout(default,never) : Int; var soundTransform : SoundTransform; var useEchoSuppression(default,never) : Bool; function new() : Void; function setLoopBack(state : Bool = true) : Void; function setSilenceLevel(silenceLevel : Float, timeout : Int = -1) : Void; function setUseEchoSuppression(useEchoSuppression : Bool) : Void; @:require(flash10_1) static var isSupported(default,never) : Bool; static var names(default,never) : Array; @:require(flash10_2) static function getEnhancedMicrophone(index : Int = -1) : Microphone; static function getMicrophone(index : Int = -1) : Microphone; } haxe_3.4.4.orig/std/flash/media/MicrophoneEnhancedMode.hx0000664000175000017500000000024013166552354023255 0ustar andyandy00000000000000package flash.media; @:fakeEnum(String) @:require(flash10_2) extern enum MicrophoneEnhancedMode { FULL_DUPLEX; HALF_DUPLEX; HEADSET; OFF; SPEAKER_MUTE; } haxe_3.4.4.orig/std/flash/media/MicrophoneEnhancedOptions.hx0000664000175000017500000000040213166552354024024 0ustar andyandy00000000000000package flash.media; @:final @:require(flash10_2) extern class MicrophoneEnhancedOptions { var autoGain : Bool; var echoPath : Int; var isVoiceDetected : Int; var mode : MicrophoneEnhancedMode; var nonLinearProcessing : Bool; function new() : Void; } haxe_3.4.4.orig/std/flash/media/Sound.hx0000664000175000017500000000207613166552354020020 0ustar andyandy00000000000000package flash.media; extern class Sound extends flash.events.EventDispatcher { var bytesLoaded(default,never) : UInt; var bytesTotal(default,never) : Int; var id3(default,never) : ID3Info; var isBuffering(default,never) : Bool; @:require(flash10_1) var isURLInaccessible(default,never) : Bool; var length(default,never) : Float; var url(default,never) : String; function new(?stream : flash.net.URLRequest, ?context : SoundLoaderContext) : Void; function close() : Void; @:require(flash10) function extract(target : flash.utils.ByteArray, length : Float, startPosition : Float = -1) : Float; function load(stream : flash.net.URLRequest, ?context : SoundLoaderContext) : Void; @:require(flash11) function loadCompressedDataFromByteArray(bytes : flash.utils.ByteArray, bytesLength : UInt) : Void; @:require(flash11) function loadPCMFromByteArray(bytes : flash.utils.ByteArray, samples : UInt, ?format : String, stereo : Bool = true, sampleRate : Float = 44100) : Void; function play(startTime : Float = 0, loops : Int = 0, ?sndTransform : SoundTransform) : SoundChannel; } haxe_3.4.4.orig/std/flash/media/SoundChannel.hx0000664000175000017500000000045313166552354021306 0ustar andyandy00000000000000package flash.media; @:final extern class SoundChannel extends flash.events.EventDispatcher { var leftPeak(default,never) : Float; var position(default,never) : Float; var rightPeak(default,never) : Float; var soundTransform : SoundTransform; function new() : Void; function stop() : Void; } haxe_3.4.4.orig/std/flash/media/SoundCodec.hx0000664000175000017500000000014713166552354020753 0ustar andyandy00000000000000package flash.media; @:fakeEnum(String) extern enum SoundCodec { NELLYMOSER; PCMA; PCMU; SPEEX; } haxe_3.4.4.orig/std/flash/media/SoundLoaderContext.hx0000664000175000017500000000030113166552354022501 0ustar andyandy00000000000000package flash.media; extern class SoundLoaderContext { var bufferTime : Float; var checkPolicyFile : Bool; function new(bufferTime : Float = 1000, checkPolicyFile : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/media/SoundMixer.hx0000664000175000017500000000064413166552354021024 0ustar andyandy00000000000000package flash.media; extern class SoundMixer { static var audioPlaybackMode : String; static var bufferTime : Int; static var soundTransform : SoundTransform; static var useSpeakerphoneForVoice : Bool; static function areSoundsInaccessible() : Bool; static function computeSpectrum(outputArray : flash.utils.ByteArray, FFTMode : Bool = false, stretchFactor : Int = 0) : Void; static function stopAll() : Void; } haxe_3.4.4.orig/std/flash/media/SoundTransform.hx0000664000175000017500000000041113166552354021703 0ustar andyandy00000000000000package flash.media; @:final extern class SoundTransform { var leftToLeft : Float; var leftToRight : Float; var pan : Float; var rightToLeft : Float; var rightToRight : Float; var volume : Float; function new(vol : Float = 1, panning : Float = 0) : Void; } haxe_3.4.4.orig/std/flash/media/StageVideo.hx0000664000175000017500000000112213166552354020751 0ustar andyandy00000000000000package flash.media; @:require(flash10_2) extern class StageVideo extends flash.events.EventDispatcher { var colorSpaces(default,never) : flash.Vector; var depth : Int; var pan : flash.geom.Point; var videoHeight(default,never) : Int; var videoWidth(default,never) : Int; var viewPort : flash.geom.Rectangle; var zoom : flash.geom.Point; function new() : Void; @:require(flash11_7) function attachAVStream(avStream : AVStream) : Void; @:require(flash11_4) function attachCamera(theCamera : Camera) : Void; function attachNetStream(netStream : flash.net.NetStream) : Void; } haxe_3.4.4.orig/std/flash/media/StageVideoAvailability.hx0000664000175000017500000000026613166552354023314 0ustar andyandy00000000000000package flash.media; extern class StageVideoAvailability { function new() : Void; static var AVAILABLE(default,never) : String; static var UNAVAILABLE(default,never) : String; } haxe_3.4.4.orig/std/flash/media/StageVideoAvailabilityReason.hx0000664000175000017500000000053213166552354024460 0ustar andyandy00000000000000package flash.media; extern class StageVideoAvailabilityReason { function new() : Void; static var DRIVER_TOO_OLD(default,never) : String; static var NO_ERROR(default,never) : String; static var UNAVAILABLE(default,never) : String; static var USER_DISABLED(default,never) : String; static var WMODE_INCOMPATIBLE(default,never) : String; } haxe_3.4.4.orig/std/flash/media/Video.hx0000664000175000017500000000062613166552354017775 0ustar andyandy00000000000000package flash.media; extern class Video extends flash.display.DisplayObject { var deblocking : Int; var smoothing : Bool; var videoHeight(default,never) : Int; var videoWidth(default,never) : Int; function new(width : Int = 320, height : Int = 240) : Void; function attachCamera(camera : Camera) : Void; function attachNetStream(netStream : flash.net.NetStream) : Void; function clear() : Void; } haxe_3.4.4.orig/std/flash/media/VideoCodec.hx0000664000175000017500000000031613166552354020727 0ustar andyandy00000000000000package flash.media; extern class VideoCodec { function new() : Void; static var H264AVC(default,never) : String; static var SORENSON(default,never) : String; static var VP6(default,never) : String; } haxe_3.4.4.orig/std/flash/media/VideoStatus.hx0000664000175000017500000000033313166552354021174 0ustar andyandy00000000000000package flash.media; extern class VideoStatus { function new() : Void; static var ACCELERATED(default,never) : String; static var SOFTWARE(default,never) : String; static var UNAVAILABLE(default,never) : String; } haxe_3.4.4.orig/std/flash/media/VideoStreamSettings.hx0000664000175000017500000000101413166552354022662 0ustar andyandy00000000000000package flash.media; extern class VideoStreamSettings { var bandwidth(default,never) : Int; var codec(default,never) : String; var fps(default,never) : Float; var height(default,never) : Int; var keyFrameInterval(default,never) : Int; var quality(default,never) : Int; var width(default,never) : Int; function new() : Void; function setKeyFrameInterval(keyFrameInterval : Int) : Void; function setMode(width : Int, height : Int, fps : Float) : Void; function setQuality(bandwidth : Int, quality : Int) : Void; } haxe_3.4.4.orig/std/flash/net/DynamicPropertyOutput.hx0000664000175000017500000000027413166552354023007 0ustar andyandy00000000000000package flash.net; extern class DynamicPropertyOutput implements IDynamicPropertyOutput { function new() : Void; function writeDynamicProperty(name : String, value : Dynamic) : Void; } haxe_3.4.4.orig/std/flash/net/FileFilter.hx0000664000175000017500000000032613166552354020460 0ustar andyandy00000000000000package flash.net; @:final extern class FileFilter { var description : String; var extension : String; var macType : String; function new(description : String, extension : String, ?macType : String) : Void; } haxe_3.4.4.orig/std/flash/net/FileReference.hx0000664000175000017500000000144413166552354021133 0ustar andyandy00000000000000package flash.net; extern class FileReference extends flash.events.EventDispatcher { var creationDate(default,never) : Date; var creator(default,never) : String; @:require(flash10) var data(default,never) : flash.utils.ByteArray; var modificationDate(default,never) : Date; var name(default,never) : String; var size(default,never) : Float; var type(default,never) : String; function new() : Void; function browse(?typeFilter : Array) : Bool; function cancel() : Void; function download(request : URLRequest, ?defaultFileName : String) : Void; @:require(flash10) function load() : Void; @:require(flash10) function save(data : Dynamic, ?defaultFileName : String) : Void; function upload(request : URLRequest, ?uploadDataFieldName : String, testUpload : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/net/FileReferenceList.hx0000664000175000017500000000034313166552354021764 0ustar andyandy00000000000000package flash.net; extern class FileReferenceList extends flash.events.EventDispatcher { var fileList(default,never) : Array; function new() : Void; function browse(?typeFilter : Array) : Bool; } haxe_3.4.4.orig/std/flash/net/GroupSpecifier.hx0000664000175000017500000000235213166552354021362 0ustar andyandy00000000000000package flash.net; @:require(flash10_1) extern class GroupSpecifier { var ipMulticastMemberUpdatesEnabled : Bool; var minGroupspecVersion : Int; var multicastEnabled : Bool; var objectReplicationEnabled : Bool; var peerToPeerDisabled : Bool; var postingEnabled : Bool; var routingEnabled : Bool; var serverChannelEnabled : Bool; function new(name : String) : Void; function addBootstrapPeer(peerID : String) : Void; function addIPMulticastAddress(address : String, ?port : Dynamic, ?source : String) : Void; function authorizations() : String; function groupspecWithAuthorizations() : String; function groupspecWithoutAuthorizations() : String; function makeUnique() : Void; function setPostingPassword(?password : String, ?salt : String) : Void; function setPublishPassword(?password : String, ?salt : String) : Void; function toString() : String; static var maxSupportedGroupspecVersion(default,never) : Int; static function encodeBootstrapPeerIDSpec(peerID : String) : String; static function encodeIPMulticastAddressSpec(address : String, ?port : Dynamic, ?source : String) : String; static function encodePostingAuthorization(password : String) : String; static function encodePublishAuthorization(password : String) : String; } haxe_3.4.4.orig/std/flash/net/IDynamicPropertyOutput.hx0000664000175000017500000000020713166552354023114 0ustar andyandy00000000000000package flash.net; extern interface IDynamicPropertyOutput { function writeDynamicProperty(name : String, value : Dynamic) : Void; } haxe_3.4.4.orig/std/flash/net/IDynamicPropertyWriter.hx0000664000175000017500000000024413166552354023071 0ustar andyandy00000000000000package flash.net; extern interface IDynamicPropertyWriter { function writeDynamicProperties(obj : flash.utils.Object, output : IDynamicPropertyOutput) : Void; } haxe_3.4.4.orig/std/flash/net/LocalConnection.hx0000664000175000017500000000132513166552354021505 0ustar andyandy00000000000000package flash.net; extern class LocalConnection extends flash.events.EventDispatcher { var client : Dynamic; var domain(default,never) : String; @:require(flash10_1) var isPerUser : Bool; function new() : Void; function allowDomain(?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void; function allowInsecureDomain(?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void; function close() : Void; function connect(connectionName : String) : Void; function send(connectionName : String, methodName : String, ?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void; @:require(flash10_1) static var isSupported(default,never) : Bool; } haxe_3.4.4.orig/std/flash/net/NetConnection.hx0000664000175000017500000000225513166552354021204 0ustar andyandy00000000000000package flash.net; extern class NetConnection extends flash.events.EventDispatcher { var client : Dynamic; var connected(default,never) : Bool; var connectedProxyType(default,never) : String; @:require(flash10) var farID(default,never) : String; @:require(flash10) var farNonce(default,never) : String; @:require(flash10) var maxPeerConnections : UInt; @:require(flash10) var nearID(default,never) : String; @:require(flash10) var nearNonce(default,never) : String; var objectEncoding : UInt; @:require(flash10) var protocol(default,never) : String; var proxyType : String; @:require(flash10) var unconnectedPeerStreams(default,never) : Array; var uri(default,never) : String; var usingTLS(default,never) : Bool; function new() : Void; function addHeader(operation : String, mustUnderstand : Bool = false, ?param : flash.utils.Object) : Void; function call(command : String, responder : Responder, ?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void; function close() : Void; function connect(command : String, ?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void; static var defaultObjectEncoding : UInt; } haxe_3.4.4.orig/std/flash/net/NetGroup.hx0000664000175000017500000000254013166552354020176 0ustar andyandy00000000000000package flash.net; @:require(flash10_1) extern class NetGroup extends flash.events.EventDispatcher { var estimatedMemberCount(default,never) : Float; var info(default,never) : NetGroupInfo; var localCoverageFrom(default,never) : String; var localCoverageTo(default,never) : String; var neighborCount(default,never) : Float; var receiveMode : String; var replicationStrategy : String; function new(connection : NetConnection, groupspec : String) : Void; function addHaveObjects(startIndex : Float, endIndex : Float) : Void; function addMemberHint(peerID : String) : Bool; function addNeighbor(peerID : String) : Bool; function addWantObjects(startIndex : Float, endIndex : Float) : Void; function close() : Void; function convertPeerIDToGroupAddress(peerID : String) : String; function denyRequestedObject(requestID : Int) : Void; function post(message : flash.utils.Object) : String; function removeHaveObjects(startIndex : Float, endIndex : Float) : Void; function removeWantObjects(startIndex : Float, endIndex : Float) : Void; function sendToAllNeighbors(message : flash.utils.Object) : String; function sendToNearest(message : flash.utils.Object, groupAddress : String) : String; function sendToNeighbor(message : flash.utils.Object, sendMode : String) : String; function writeRequestedObject(requestID : Int, object : flash.utils.Object) : Void; } haxe_3.4.4.orig/std/flash/net/NetGroupInfo.hx0000664000175000017500000000170013166552354021007 0ustar andyandy00000000000000package flash.net; @:final @:require(flash10_1) extern class NetGroupInfo { var objectReplicationReceiveBytesPerSecond(default,never) : Float; var objectReplicationSendBytesPerSecond(default,never) : Float; var postingReceiveControlBytesPerSecond(default,never) : Float; var postingReceiveDataBytesPerSecond(default,never) : Float; var postingSendControlBytesPerSecond(default,never) : Float; var postingSendDataBytesPerSecond(default,never) : Float; var routingReceiveBytesPerSecond(default,never) : Float; var routingSendBytesPerSecond(default,never) : Float; function new(postingSendDataBytesPerSecond : Float, postingSendControlBytesPerSecond : Float, postingReceiveDataBytesPerSecond : Float, postingReceiveControlBytesPerSecond : Float, routingSendBytesPerSecond : Float, routingReceiveBytesPerSecond : Float, objectReplicationSendBytesPerSecond : Float, objectReplicationReceiveBytesPerSecond : Float) : Void; function toString() : String; } haxe_3.4.4.orig/std/flash/net/NetGroupReceiveMode.hx0000664000175000017500000000025113166552354022303 0ustar andyandy00000000000000package flash.net; extern class NetGroupReceiveMode { function new() : Void; static var EXACT(default,never) : String; static var NEAREST(default,never) : String; } haxe_3.4.4.orig/std/flash/net/NetGroupReplicationStrategy.hx0000664000175000017500000000027513166552354024116 0ustar andyandy00000000000000package flash.net; extern class NetGroupReplicationStrategy { function new() : Void; static var LOWEST_FIRST(default,never) : String; static var RAREST_FIRST(default,never) : String; } haxe_3.4.4.orig/std/flash/net/NetGroupSendMode.hx0000664000175000017500000000027013166552354021613 0ustar andyandy00000000000000package flash.net; extern class NetGroupSendMode { function new() : Void; static var NEXT_DECREASING(default,never) : String; static var NEXT_INCREASING(default,never) : String; } haxe_3.4.4.orig/std/flash/net/NetGroupSendResult.hx0000664000175000017500000000032313166552354022204 0ustar andyandy00000000000000package flash.net; extern class NetGroupSendResult { function new() : Void; static var ERROR(default,never) : String; static var NO_ROUTE(default,never) : String; static var SENT(default,never) : String; } haxe_3.4.4.orig/std/flash/net/NetMonitor.hx0000664000175000017500000000026313166552354020531 0ustar andyandy00000000000000package flash.net; @:require(flash11) extern class NetMonitor extends flash.events.EventDispatcher { function new() : Void; function listStreams() : flash.Vector; } haxe_3.4.4.orig/std/flash/net/NetStream.hx0000664000175000017500000000673113166552354020343 0ustar andyandy00000000000000package flash.net; extern class NetStream extends flash.events.EventDispatcher { var audioCodec(default,never) : UInt; @:require(flash10_1) var audioReliable : Bool; @:require(flash10_1) var audioSampleAccess : Bool; @:require(flash10_1) var backBufferLength(default,never) : Float; @:require(flash10_1) var backBufferTime : Float; var bufferLength(default,never) : Float; var bufferTime : Float; @:require(flash10_1) var bufferTimeMax : Float; var bytesLoaded(default,never) : UInt; var bytesTotal(default,never) : UInt; var checkPolicyFile : Bool; var client : Dynamic; var currentFPS(default,never) : Float; @:require(flash10_1) var dataReliable : Bool; var decodedFrames(default,never) : UInt; @:require(flash10) var farID(default,never) : String; @:require(flash10) var farNonce(default,never) : String; @:require(flash10_1) var inBufferSeek : Bool; @:require(flash10) var info(default,never) : NetStreamInfo; var liveDelay(default,never) : Float; @:require(flash10) var maxPauseBufferTime : Float; @:require(flash10_1) var multicastAvailabilitySendToAll : Bool; @:require(flash10_1) var multicastAvailabilityUpdatePeriod : Float; @:require(flash10_1) var multicastFetchPeriod : Float; @:require(flash10_1) var multicastInfo(default,never) : NetStreamMulticastInfo; @:require(flash10_1) var multicastPushNeighborLimit : Float; @:require(flash10_1) var multicastRelayMarginDuration : Float; @:require(flash10_1) var multicastWindowDuration : Float; @:require(flash10) var nearNonce(default,never) : String; var objectEncoding(default,never) : UInt; @:require(flash10) var peerStreams(default,never) : Array; var soundTransform : flash.media.SoundTransform; var time(default,never) : Float; @:require(flash11) var useHardwareDecoder : Bool; @:require(flash11_3) var useJitterBuffer : Bool; var videoCodec(default,never) : UInt; @:require(flash10_1) var videoReliable : Bool; @:require(flash10_1) var videoSampleAccess : Bool; @:require(flash11) var videoStreamSettings : flash.media.VideoStreamSettings; function new(connection : NetConnection, ?peerID : String) : Void; @:require(flash10_1) function appendBytes(bytes : flash.utils.ByteArray) : Void; @:require(flash10_1) function appendBytesAction(netStreamAppendBytesAction : String) : Void; @:require(flash10_1) function attach(connection : NetConnection) : Void; function attachAudio(microphone : flash.media.Microphone) : Void; function attachCamera(theCamera : flash.media.Camera, snapshotMilliseconds : Int = -1) : Void; function close() : Void; @:require(flash11_2) function dispose() : Void; @:require(flash10) function onPeerConnect(subscriber : NetStream) : Bool; function pause() : Void; function play(?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void; @:require(flash10) function play2(param : NetStreamPlayOptions) : Void; function publish(?name : String, ?type : String) : Void; function receiveAudio(flag : Bool) : Void; function receiveVideo(flag : Bool) : Void; function receiveVideoFPS(FPS : Float) : Void; function resume() : Void; function seek(offset : Float) : Void; function send(handlerName : String, ?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void; @:require(flash10_1) function step(frames : Int) : Void; function togglePause() : Void; @:require(flash10) static var CONNECT_TO_FMS(default,never) : String; @:require(flash10) static var DIRECT_CONNECTIONS(default,never) : String; static function resetDRMVouchers() : Void; } haxe_3.4.4.orig/std/flash/net/NetStreamAppendBytesAction.hx0000664000175000017500000000035313166552354023632 0ustar andyandy00000000000000package flash.net; extern class NetStreamAppendBytesAction { function new() : Void; static var END_SEQUENCE(default,never) : String; static var RESET_BEGIN(default,never) : String; static var RESET_SEEK(default,never) : String; } haxe_3.4.4.orig/std/flash/net/NetStreamInfo.hx0000664000175000017500000000340613166552354021153 0ustar andyandy00000000000000package flash.net; @:final extern class NetStreamInfo { var SRTT(default,never) : Float; var audioBufferByteLength(default,never) : Float; var audioBufferLength(default,never) : Float; var audioByteCount(default,never) : Float; var audioBytesPerSecond(default,never) : Float; var audioLossRate(default,never) : Float; var byteCount(default,never) : Float; var currentBytesPerSecond(default,never) : Float; var dataBufferByteLength(default,never) : Float; var dataBufferLength(default,never) : Float; var dataByteCount(default,never) : Float; var dataBytesPerSecond(default,never) : Float; var droppedFrames(default,never) : Float; var isLive(default,never) : Bool; var maxBytesPerSecond(default,never) : Float; var metaData(default,never) : Dynamic; var playbackBytesPerSecond(default,never) : Float; var resourceName(default,never) : String; var uri(default,never) : String; var videoBufferByteLength(default,never) : Float; var videoBufferLength(default,never) : Float; var videoByteCount(default,never) : Float; var videoBytesPerSecond(default,never) : Float; @:require(flash10_1) var videoLossRate(default,never) : Float; var xmpData(default,never) : Dynamic; function new(curBPS : Float, byteCount : Float, maxBPS : Float, audioBPS : Float, audioByteCount : Float, videoBPS : Float, videoByteCount : Float, dataBPS : Float, dataByteCount : Float, playbackBPS : Float, droppedFrames : Float, audioBufferByteLength : Float, videoBufferByteLength : Float, dataBufferByteLength : Float, audioBufferLength : Float, videoBufferLength : Float, dataBufferLength : Float, srtt : Float, audioLossRate : Float, videoLossRate : Float, ?metaData : Dynamic, ?xmpData : Dynamic, ?uri : String, ?resourceName : String, isLive : Bool = true) : Void; function toString() : String; } haxe_3.4.4.orig/std/flash/net/NetStreamMulticastInfo.hx0000664000175000017500000000355213166552354023043 0ustar andyandy00000000000000package flash.net; @:final @:require(flash10_1) extern class NetStreamMulticastInfo { var bytesPushedFromPeers(default,never) : Float; var bytesPushedToPeers(default,never) : Float; var bytesReceivedFromIPMulticast(default,never) : Float; var bytesReceivedFromServer(default,never) : Float; var bytesRequestedByPeers(default,never) : Float; var bytesRequestedFromPeers(default,never) : Float; var fragmentsPushedFromPeers(default,never) : Float; var fragmentsPushedToPeers(default,never) : Float; var fragmentsReceivedFromIPMulticast(default,never) : Float; var fragmentsReceivedFromServer(default,never) : Float; var fragmentsRequestedByPeers(default,never) : Float; var fragmentsRequestedFromPeers(default,never) : Float; var receiveControlBytesPerSecond(default,never) : Float; var receiveDataBytesPerSecond(default,never) : Float; var receiveDataBytesPerSecondFromIPMulticast(default,never) : Float; var receiveDataBytesPerSecondFromServer(default,never) : Float; var sendControlBytesPerSecond(default,never) : Float; var sendControlBytesPerSecondToServer(default,never) : Float; var sendDataBytesPerSecond(default,never) : Float; function new(sendDataBytesPerSecond : Float, sendControlBytesPerSecond : Float, receiveDataBytesPerSecond : Float, receiveControlBytesPerSecond : Float, bytesPushedToPeers : Float, fragmentsPushedToPeers : Float, bytesRequestedByPeers : Float, fragmentsRequestedByPeers : Float, bytesPushedFromPeers : Float, fragmentsPushedFromPeers : Float, bytesRequestedFromPeers : Float, fragmentsRequestedFromPeers : Float, sendControlBytesPerSecondToServer : Float, receiveDataBytesPerSecondFromServer : Float, bytesReceivedFromServer : Float, fragmentsReceivedFromServer : Float, receiveDataBytesPerSecondFromIPMulticast : Float, bytesReceivedFromIPMulticast : Float, fragmentsReceivedFromIPMulticast : Float) : Void; function toString() : String; } haxe_3.4.4.orig/std/flash/net/NetStreamPlayOptions.hx0000664000175000017500000000045313166552354022540 0ustar andyandy00000000000000package flash.net; extern class NetStreamPlayOptions extends flash.events.EventDispatcher implements Dynamic { var len : Float; @:require(flash10_1) var offset : Float; var oldStreamName : String; var start : Float; var streamName : String; var transition : String; function new() : Void; } haxe_3.4.4.orig/std/flash/net/NetStreamPlayTransitions.hx0000664000175000017500000000014513166552354023420 0ustar andyandy00000000000000package flash.net; extern enum NetStreamPlayTransitions { SWAP; SWITCH; STOP; APPEND; RESET; } haxe_3.4.4.orig/std/flash/net/ObjectEncoding.hx0000664000175000017500000000035313166552354021310 0ustar andyandy00000000000000package flash.net; extern class ObjectEncoding { static var AMF0(default,never) : UInt; static var AMF3(default,never) : UInt; static var DEFAULT(default,never) : UInt; static var dynamicPropertyWriter : IDynamicPropertyWriter; } haxe_3.4.4.orig/std/flash/net/Responder.hx0000664000175000017500000000015213166552354020371 0ustar andyandy00000000000000package flash.net; extern class Responder { function new(result : Dynamic, ?status : Dynamic) : Void; } haxe_3.4.4.orig/std/flash/net/SecureSocket.hx0000664000175000017500000000060213166552354021027 0ustar andyandy00000000000000package flash.net; @:require(flash11) extern class SecureSocket extends Socket { var serverCertificate(default,never) : flash.security.X509Certificate; var serverCertificateStatus(default,never) : String; function new() : Void; function addBinaryChainBuildingCertificate(certificate : flash.utils.ByteArray, trusted : Bool) : Void; static var isSupported(default,never) : Bool; } haxe_3.4.4.orig/std/flash/net/SharedObject.hx0000664000175000017500000000211513166552354020766 0ustar andyandy00000000000000package flash.net; extern class SharedObject extends flash.events.EventDispatcher { var client : Dynamic; var data(default,never) : Dynamic; var fps(never,default) : Float; var objectEncoding : UInt; var size(default,never) : UInt; function new() : Void; function clear() : Void; function close() : Void; function connect(myConnection : NetConnection, ?params : String) : Void; function flush(minDiskSpace : Int = 0) : String; function send(?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void; function setDirty(propertyName : String) : Void; function setProperty(propertyName : String, ?value : flash.utils.Object) : Void; static var defaultObjectEncoding : UInt; @:require(flash11_7) static var preventBackup : Bool; static function deleteAll(url : String) : Int; static function getDiskUsage(url : String) : Int; static function getLocal(name : String, ?localPath : String, secure : Bool = false) : SharedObject; static function getRemote(name : String, ?remotePath : String, persistence : Dynamic = false, secure : Bool = false) : SharedObject; } haxe_3.4.4.orig/std/flash/net/SharedObjectFlushStatus.hx0000664000175000017500000000025713166552354023201 0ustar andyandy00000000000000package flash.net; extern class SharedObjectFlushStatus { function new() : Void; static var FLUSHED(default,never) : String; static var PENDING(default,never) : String; } haxe_3.4.4.orig/std/flash/net/Socket.hx0000664000175000017500000000330013166552354017656 0ustar andyandy00000000000000package flash.net; extern class Socket extends flash.events.EventDispatcher implements flash.utils.IDataOutput implements flash.utils.IDataInput { var bytesAvailable(default,never) : UInt; @:require(flash11) var bytesPending(default,never) : UInt; var connected(default,never) : Bool; var endian : flash.utils.Endian; var objectEncoding : UInt; @:require(flash10) var timeout : UInt; function new(?host : String, port : Int = 0) : Void; function close() : Void; function connect(host : String, port : Int) : Void; function flush() : Void; function readBoolean() : Bool; function readByte() : Int; function readBytes(bytes : flash.utils.ByteArray, offset : UInt = 0, length : UInt = 0) : Void; function readDouble() : Float; function readFloat() : Float; function readInt() : Int; function readMultiByte(length : UInt, charSet : String) : String; function readObject() : Dynamic; function readShort() : Int; function readUTF() : String; function readUTFBytes(length : UInt) : String; function readUnsignedByte() : UInt; function readUnsignedInt() : UInt; function readUnsignedShort() : UInt; function writeBoolean(value : Bool) : Void; function writeByte(value : Int) : Void; function writeBytes(bytes : flash.utils.ByteArray, offset : UInt = 0, length : UInt = 0) : Void; function writeDouble(value : Float) : Void; function writeFloat(value : Float) : Void; function writeInt(value : Int) : Void; function writeMultiByte(value : String, charSet : String) : Void; function writeObject(object : Dynamic) : Void; function writeShort(value : Int) : Void; function writeUTF(value : String) : Void; function writeUTFBytes(value : String) : Void; function writeUnsignedInt(value : UInt) : Void; } haxe_3.4.4.orig/std/flash/net/URLLoader.hx0000664000175000017500000000046513166552354020230 0ustar andyandy00000000000000package flash.net; extern class URLLoader extends flash.events.EventDispatcher { var bytesLoaded : UInt; var bytesTotal : UInt; var data : Dynamic; var dataFormat : URLLoaderDataFormat; function new(?request : URLRequest) : Void; function close() : Void; function load(request : URLRequest) : Void; } haxe_3.4.4.orig/std/flash/net/URLLoaderDataFormat.hx0000664000175000017500000000014713166552354022170 0ustar andyandy00000000000000package flash.net; @:fakeEnum(String) extern enum URLLoaderDataFormat { BINARY; TEXT; VARIABLES; } haxe_3.4.4.orig/std/flash/net/URLRequest.hx0000664000175000017500000000057213166552354020451 0ustar andyandy00000000000000package flash.net; @:final extern class URLRequest { var contentType : String; var data : Dynamic; var digest : String; var method : String; var requestHeaders : Array; var url : String; function new(?url : String) : Void; function useRedirectedURL(sourceRequest : URLRequest, wholeURL : Bool = false, ?pattern : Dynamic, ?replace : String) : Void; } haxe_3.4.4.orig/std/flash/net/URLRequestHeader.hx0000664000175000017500000000023613166552354021557 0ustar andyandy00000000000000package flash.net; @:final extern class URLRequestHeader { var name : String; var value : String; function new(?name : String, ?value : String) : Void; } haxe_3.4.4.orig/std/flash/net/URLRequestMethod.hx0000664000175000017500000000061113166552354021604 0ustar andyandy00000000000000package flash.net; extern class URLRequestMethod { @:require(flash10_1) static var DELETE(default,never) : String; static var GET(default,never) : String; @:require(flash10_1) static var HEAD(default,never) : String; @:require(flash10_1) static var OPTIONS(default,never) : String; static var POST(default,never) : String; @:require(flash10_1) static var PUT(default,never) : String; } haxe_3.4.4.orig/std/flash/net/URLStream.hx0000664000175000017500000000215713166552354020255 0ustar andyandy00000000000000package flash.net; extern class URLStream extends flash.events.EventDispatcher implements flash.utils.IDataInput { var bytesAvailable(default,never) : UInt; var connected(default,never) : Bool; @:require(flash11_4) var diskCacheEnabled(default,never) : Bool; var endian : flash.utils.Endian; @:require(flash11_4) var length(default,never) : Float; var objectEncoding : UInt; @:require(flash11_4) var position : Float; function new() : Void; function close() : Void; function load(request : URLRequest) : Void; function readBoolean() : Bool; function readByte() : Int; function readBytes(bytes : flash.utils.ByteArray, offset : UInt = 0, length : UInt = 0) : Void; function readDouble() : Float; function readFloat() : Float; function readInt() : Int; function readMultiByte(length : UInt, charSet : String) : String; function readObject() : Dynamic; function readShort() : Int; function readUTF() : String; function readUTFBytes(length : UInt) : String; function readUnsignedByte() : UInt; function readUnsignedInt() : UInt; function readUnsignedShort() : UInt; @:require(flash11_4) function stop() : Void; } haxe_3.4.4.orig/std/flash/net/URLVariables.hx0000664000175000017500000000026613166552354020731 0ustar andyandy00000000000000package flash.net; extern class URLVariables implements Dynamic { function new(?source : String) : Void; function decode(source : String) : Void; function toString() : String; } haxe_3.4.4.orig/std/flash/net/XMLSocket.hx0000664000175000017500000000051713166552354020246 0ustar andyandy00000000000000package flash.net; extern class XMLSocket extends flash.events.EventDispatcher { var connected(default,never) : Bool; @:require(flash10) var timeout : Int; function new(?host : String, port : Int = 0) : Void; function close() : Void; function connect(host : String, port : Int) : Void; function send(object : Dynamic) : Void; } haxe_3.4.4.orig/std/flash/net/drm/AddToDeviceGroupSetting.hx0000664000175000017500000000035613166552354023706 0ustar andyandy00000000000000package flash.net.drm; extern class AddToDeviceGroupSetting { function new() : Void; static var ALLOW_SERVER(default,never) : String; static var FORCE_REFRESH(default,never) : String; static var LOCAL_ONLY(default,never) : String; } haxe_3.4.4.orig/std/flash/net/drm/AuthenticationMethod.hx0000664000175000017500000000030013166552354023325 0ustar andyandy00000000000000package flash.net.drm; extern class AuthenticationMethod { function new() : Void; static var ANONYMOUS(default,never) : String; static var USERNAME_AND_PASSWORD(default,never) : String; } haxe_3.4.4.orig/std/flash/net/drm/DRMAddToDeviceGroupContext.hx0000664000175000017500000000031413166552354024252 0ustar andyandy00000000000000package flash.net.drm; extern class DRMAddToDeviceGroupContext extends DRMManagerSession { function new() : Void; function addToDeviceGroup(deviceGroup : DRMDeviceGroup, forceRefresh : Bool) : Void; } haxe_3.4.4.orig/std/flash/net/drm/DRMAuthenticationContext.hx0000664000175000017500000000043113166552354024101 0ustar andyandy00000000000000package flash.net.drm; extern class DRMAuthenticationContext extends DRMManagerSession { var authenticationToken(default,never) : flash.utils.ByteArray; function new() : Void; function authenticate(url : String, domain : String, username : String, password : String) : Void; } haxe_3.4.4.orig/std/flash/net/drm/DRMContentData.hx0000664000175000017500000000053413166552354021765 0ustar andyandy00000000000000package flash.net.drm; extern class DRMContentData { var authenticationMethod(default,never) : String; var domain(default,never) : String; var licenseID(default,never) : String; var serverURL(default,never) : String; function new(?rawData : flash.utils.ByteArray) : Void; function getVoucherAccessInfo() : flash.Vector; } haxe_3.4.4.orig/std/flash/net/drm/DRMDeviceGroup.hx0000664000175000017500000000035413166552354021775 0ustar andyandy00000000000000package flash.net.drm; @:final extern class DRMDeviceGroup { var authenticationMethod(default,never) : String; var domain(default,never) : String; var name : String; var serverURL(default,never) : String; function new() : Void; } haxe_3.4.4.orig/std/flash/net/drm/DRMManager.hx0000664000175000017500000000212313166552354021127 0ustar andyandy00000000000000package flash.net.drm; extern class DRMManager extends flash.events.EventDispatcher { function new() : Void; function addToDeviceGroup(deviceGroup : DRMDeviceGroup, forceRefresh : Bool = false) : Void; function authenticate(serverURL : String, domain : String, username : String, password : String) : Void; function loadPreviewVoucher(contentData : DRMContentData) : Void; function loadVoucher(contentData : DRMContentData, setting : String) : Void; function removeFromDeviceGroup(deviceGroup : DRMDeviceGroup) : Void; function resetDRMVouchers() : Void; function resetDRMVouchersInternal(isAutoReset : Bool) : Void; function returnVoucher(inServerURL : String, immediateCommit : Bool, licenseID : String, policyID : String) : Void; function setAuthenticationToken(serverUrl : String, domain : String, token : flash.utils.ByteArray) : Void; function storeVoucher(voucher : flash.utils.ByteArray) : Void; static var isSupported(default,never) : Bool; static var networkIdleTimeout : Float; static function getDRMManager() : DRMManager; static function getDRMManagerInternal() : DRMManager; } haxe_3.4.4.orig/std/flash/net/drm/DRMManagerSession.hx0000664000175000017500000000160513166552354022477 0ustar andyandy00000000000000package flash.net.drm; extern class DRMManagerSession extends flash.events.EventDispatcher { var m_isInSession : Bool; var metadata : DRMContentData; function new() : Void; function checkStatus() : UInt; function errorCodeToThrow(errorCode : UInt) : Void; function getLastError() : UInt; function getLastServerErrorString() : String; function getLastSubErrorID() : UInt; function issueDRMErrorEvent(metadata : DRMContentData, errorID : Int, subErrorID : Int, serverErrorString : String) : Void; function issueDRMStatusEvent(inMetadata : DRMContentData, voucher : DRMVoucher) : Dynamic; function onSessionComplete() : Void; function onSessionError() : Void; function setTimerUp() : Void; static var STATUS_FAILED(default,never) : UInt; static var STATUS_NOTREADY(default,never) : UInt; static var STATUS_READY(default,never) : UInt; static var STATUS_UNKNOWN(default,never) : UInt; } haxe_3.4.4.orig/std/flash/net/drm/DRMModuleCycleProvider.hx0000664000175000017500000000013013166552354023471 0ustar andyandy00000000000000package flash.net.drm; extern class DRMModuleCycleProvider { function new() : Void; } haxe_3.4.4.orig/std/flash/net/drm/DRMPlaybackTimeWindow.hx0000664000175000017500000000030413166552354023311 0ustar andyandy00000000000000package flash.net.drm; extern class DRMPlaybackTimeWindow { var endDate(default,never) : Date; var period(default,never) : UInt; var startDate(default,never) : Date; function new() : Void; } haxe_3.4.4.orig/std/flash/net/drm/DRMRemoveFromDeviceGroupContext.hx0000664000175000017500000000030113166552354025334 0ustar andyandy00000000000000package flash.net.drm; extern class DRMRemoveFromDeviceGroupContext extends DRMManagerSession { function new() : Void; function removeFromDeviceGroup(deviceGroup : DRMDeviceGroup) : Void; } haxe_3.4.4.orig/std/flash/net/drm/DRMResetContext.hx0000664000175000017500000000026413166552354022210 0ustar andyandy00000000000000package flash.net.drm; extern class DRMResetContext extends DRMManagerSession { var m_isAutoReset : Bool; function new(isAutoReset : Bool) : Void; function doReset() : Void; } haxe_3.4.4.orig/std/flash/net/drm/DRMReturnVoucherContext.hx0000664000175000017500000000035013166552354023735 0ustar andyandy00000000000000package flash.net.drm; extern class DRMReturnVoucherContext extends DRMManagerSession { function new() : Void; function returnVoucher(inServerURL : String, immediateCommit : Bool, licenseID : String, policyID : String) : Void; } haxe_3.4.4.orig/std/flash/net/drm/DRMStoreVoucherContext.hx0000664000175000017500000000026413166552354023556 0ustar andyandy00000000000000package flash.net.drm; extern class DRMStoreVoucherContext extends DRMManagerSession { function new(voucher : flash.utils.ByteArray) : Void; function doStoreVoucher() : Void; } haxe_3.4.4.orig/std/flash/net/drm/DRMURLDownloadContext.hx0000664000175000017500000000047513166552354023264 0ustar andyandy00000000000000package flash.net.drm; extern class DRMURLDownloadContext extends flash.events.EventDispatcher { function new() : Void; function httpGetASync(url : String) : Void; function httpPostAndReceiveASync(url : String, headerName : String, headerValue : String, data : flash.utils.ByteArray, serverType : UInt) : Void; } haxe_3.4.4.orig/std/flash/net/drm/DRMVoucher.hx0000664000175000017500000000102613166552354021171 0ustar andyandy00000000000000package flash.net.drm; extern class DRMVoucher { var licenseID(default,never) : String; var offlineLeaseEndDate(default,never) : Date; var offlineLeaseStartDate(default,never) : Date; var playbackTimeWindow(default,never) : DRMPlaybackTimeWindow; var policies(default,never) : Dynamic; var policyID(default,never) : String; var serverURL(default,never) : String; var voucherEndDate(default,never) : Date; var voucherStartDate(default,never) : Date; function new() : Void; function toByteArray() : flash.utils.ByteArray; } haxe_3.4.4.orig/std/flash/net/drm/DRMVoucherDownloadContext.hx0000664000175000017500000000036613166552354024234 0ustar andyandy00000000000000package flash.net.drm; extern class DRMVoucherDownloadContext extends DRMManagerSession { var voucher(default,never) : DRMVoucher; function new() : Void; function download(inMetadata : DRMContentData, previewVoucher : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/net/drm/DRMVoucherStoreContext.hx0000664000175000017500000000033713166552354023557 0ustar andyandy00000000000000package flash.net.drm; extern class DRMVoucherStoreContext extends DRMManagerSession { var voucher(default,never) : DRMVoucher; function new() : Void; function getVoucherFromStore(inMetadata : DRMContentData) : Void; } haxe_3.4.4.orig/std/flash/net/drm/LoadVoucherSetting.hx0000664000175000017500000000035113166552354022764 0ustar andyandy00000000000000package flash.net.drm; extern class LoadVoucherSetting { function new() : Void; static var ALLOW_SERVER(default,never) : String; static var FORCE_REFRESH(default,never) : String; static var LOCAL_ONLY(default,never) : String; } haxe_3.4.4.orig/std/flash/net/drm/VoucherAccessInfo.hx0000664000175000017500000000046613166552354022573 0ustar andyandy00000000000000package flash.net.drm; @:final extern class VoucherAccessInfo { var authenticationMethod(default,never) : String; var deviceGroup(default,never) : DRMDeviceGroup; var displayName(default,never) : String; var domain(default,never) : String; var policyID(default,never) : String; function new() : Void; } haxe_3.4.4.orig/std/flash/printing/PrintJob.hx0000664000175000017500000000110213166552354021217 0ustar andyandy00000000000000package flash.printing; extern class PrintJob extends flash.events.EventDispatcher { var orientation(default,never) : PrintJobOrientation; var pageHeight(default,never) : Int; var pageWidth(default,never) : Int; var paperHeight(default,never) : Int; var paperWidth(default,never) : Int; function new() : Void; function addPage(sprite : flash.display.Sprite, ?printArea : flash.geom.Rectangle, ?options : PrintJobOptions, frameNum : Int = 0) : Void; function send() : Void; function start() : Bool; @:require(flash10_1) static var isSupported(default,never) : Bool; } haxe_3.4.4.orig/std/flash/printing/PrintJobOptions.hx0000664000175000017500000000021113166552354022573 0ustar andyandy00000000000000package flash.printing; extern class PrintJobOptions { var printAsBitmap : Bool; function new(printAsBitmap : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/printing/PrintJobOrientation.hx0000664000175000017500000000014713166552354023443 0ustar andyandy00000000000000package flash.printing; @:fakeEnum(String) extern enum PrintJobOrientation { LANDSCAPE; PORTRAIT; } haxe_3.4.4.orig/std/flash/profiler/Telemetry.hx0000664000175000017500000000076313166552354021446 0ustar andyandy00000000000000package flash.profiler; extern class Telemetry { function new() : Void; static var connected(default,never) : Bool; static var spanMarker(default,never) : Float; static function registerCommandHandler(commandName : String, handler : Dynamic) : Bool; static function sendMetric(metric : String, value : Dynamic) : Void; static function sendSpanMetric(metric : String, startSpanMarker : Float, ?value : Dynamic) : Void; static function unregisterCommandHandler(commandName : String) : Bool; } haxe_3.4.4.orig/std/flash/sampler/Api.hx0000664000175000017500000000503713166552354020025 0ustar andyandy00000000000000package flash.sampler; extern class Api { public inline static function clearSamples() : Void { untyped __global__["flash.sampler.clearSamples"](); } public inline static function getGetterInvocationCount( obj : Dynamic, qname : flash.utils.QName ) : Float { return untyped __global__["flash.sampler.getGetterInvocationCount"](obj,qname); } public inline static function getSetterInvocationCount( obj : Dynamic, qname : flash.utils.QName ) : Float { return untyped __global__["flash.sampler.getSetterInvocationCount"](obj,qname); } public inline static function getInvocationCount( obj : Dynamic, qname : flash.utils.QName ) : Float { return untyped __global__["flash.sampler.getInvocationCount"](obj,qname); } public inline static function getMemberNames( obj : Dynamic, instanceNames : Bool = false ) : Dynamic { return untyped __global__["flash.sampler.getMemberNames"](obj,instanceNames); } public inline static function getSampleCount() : Float { return untyped __global__["flash.sampler.getSampleCount"](); } public inline static function getSamples() : Array { return untyped __foreach__(__global__["flash.sampler.getSamples"]()); } public inline static function getSize( obj : Dynamic ) : Float { return untyped __global__["flash.sampler.getSize"](obj); } public inline static function isGetterSetter( obj : Dynamic, qname : flash.utils.QName ) : Bool { return untyped __global__["flash.sampler.isGetterSetter"](obj,qname); } public inline static function pauseSampling() : Void { untyped __global__["flash.sampler.pauseSampling"](); } public inline static function startSampling() : Void { untyped __global__["flash.sampler.startSampling"](); } public inline static function stopSampling() : Void { untyped __global__["flash.sampler.stopSampling"](); } public inline static function getLexicalScopes( fun : Dynamic ) : Array { return untyped __global__["flash.sampler.getLexicalScopes"](fun); } public inline static function getMasterString( s : String ) : String { return untyped __global__["flash.sampler.getMasterString"](s); } public inline static function getSavedThis( fun : Dynamic ) : Dynamic { return untyped __global__["flash.sampler.getSavedThis"](fun); } public inline static function sampleInternalAllocs( b : Bool ) : Void { untyped __global__["flash.sampler.sampleInternalAllocs"](b); } public inline static function setSamplerCallback( callb : Dynamic ) : Void { untyped __global__["flash.sampler.setSamplerCallback"](callb); } }haxe_3.4.4.orig/std/flash/sampler/ClassFactory.hx0000664000175000017500000000051313166552354021703 0ustar andyandy00000000000000package flash.sampler; extern class ClassFactory { function new() : Void; static var DeleteObjectSampleClass(default,never) : Class; static var NewObjectSampleClass(default,never) : Class; static var SampleClass(default,never) : Class; static var StackFrameClass(default,never) : Class; } haxe_3.4.4.orig/std/flash/sampler/DeleteObjectSample.hx0000664000175000017500000000022513166552354023001 0ustar andyandy00000000000000package flash.sampler; @:final extern class DeleteObjectSample extends Sample { var id(default,never) : Float; var size(default,never) : Float; } haxe_3.4.4.orig/std/flash/sampler/NewObjectSample.hx0000664000175000017500000000037013166552354022331 0ustar andyandy00000000000000package flash.sampler; @:final extern class NewObjectSample extends Sample { var id(default,never) : Float; var object(default,never) : Dynamic; @:require(flash10_1) var size(default,never) : Float; var type(default,never) : Class; } haxe_3.4.4.orig/std/flash/sampler/Sample.hx0000664000175000017500000000020113166552354020521 0ustar andyandy00000000000000package flash.sampler; extern class Sample { var stack(default,never) : Array; var time(default,never) : Float; } haxe_3.4.4.orig/std/flash/sampler/StackFrame.hx0000664000175000017500000000037513166552354021334 0ustar andyandy00000000000000package flash.sampler; @:final extern class StackFrame { var file(default,never) : String; var line(default,never) : UInt; var name(default,never) : String; @:require(flash10_1) var scriptID(default,never) : Float; function toString() : String; } haxe_3.4.4.orig/std/flash/security/CertificateStatus.hx0000664000175000017500000000101213166552354023133 0ustar andyandy00000000000000package flash.security; extern class CertificateStatus { function new() : Void; static var EXPIRED(default,never) : String; static var INVALID(default,never) : String; static var INVALID_CHAIN(default,never) : String; static var NOT_YET_VALID(default,never) : String; static var PRINCIPAL_MISMATCH(default,never) : String; static var REVOKED(default,never) : String; static var TRUSTED(default,never) : String; static var UNKNOWN(default,never) : String; static var UNTRUSTED_SIGNERS(default,never) : String; } haxe_3.4.4.orig/std/flash/security/X500DistinguishedName.hx0000664000175000017500000000061313166552354023474 0ustar andyandy00000000000000package flash.security; extern class X500DistinguishedName { var commonName(default,never) : String; var countryName(default,never) : String; var localityName(default,never) : String; var organizationName(default,never) : String; var organizationalUnitName(default,never) : String; var stateOrProvinceName(default,never) : String; function new() : Void; function toString() : String; } haxe_3.4.4.orig/std/flash/security/X509Certificate.hx0000664000175000017500000000132313166552354022322 0ustar andyandy00000000000000package flash.security; extern class X509Certificate { var encoded(default,never) : flash.utils.ByteArray; var issuer(default,never) : X500DistinguishedName; var issuerUniqueID(default,never) : String; var serialNumber(default,never) : String; var signatureAlgorithmOID(default,never) : String; var signatureAlgorithmParams(default,never) : flash.utils.ByteArray; var subject(default,never) : X500DistinguishedName; var subjectPublicKey(default,never) : String; var subjectPublicKeyAlgorithmOID(default,never) : String; var subjectUniqueID(default,never) : String; var validNotAfter(default,never) : Date; var validNotBefore(default,never) : Date; var version(default,never) : UInt; function new() : Void; } haxe_3.4.4.orig/std/flash/sensors/Accelerometer.hx0000664000175000017500000000043113166552354022110 0ustar andyandy00000000000000package flash.sensors; @:require(flash10_1) extern class Accelerometer extends flash.events.EventDispatcher { var muted(default,never) : Bool; function new() : Void; function setRequestedUpdateInterval(interval : Float) : Void; static var isSupported(default,never) : Bool; } haxe_3.4.4.orig/std/flash/sensors/Geolocation.hx0000664000175000017500000000042713166552354021606 0ustar andyandy00000000000000package flash.sensors; @:require(flash10_1) extern class Geolocation extends flash.events.EventDispatcher { var muted(default,never) : Bool; function new() : Void; function setRequestedUpdateInterval(interval : Float) : Void; static var isSupported(default,never) : Bool; } haxe_3.4.4.orig/std/flash/system/ApplicationDomain.hx0000664000175000017500000000107513166552354022566 0ustar andyandy00000000000000package flash.system; @:final extern class ApplicationDomain { @:require(flash10) var domainMemory : flash.utils.ByteArray; var parentDomain(default,never) : ApplicationDomain; function new(?parentDomain : ApplicationDomain) : Void; function getDefinition(name : String) : flash.utils.Object; @:require(flash11_3) function getQualifiedDefinitionNames() : flash.Vector; function hasDefinition(name : String) : Bool; @:require(flash10) static var MIN_DOMAIN_MEMORY_LENGTH(default,never) : UInt; static var currentDomain(default,never) : ApplicationDomain; } haxe_3.4.4.orig/std/flash/system/ApplicationInstaller.hx0000664000175000017500000000055713166552354023320 0ustar andyandy00000000000000package flash.system; @:final @:require(flash11_3) extern class ApplicationInstaller extends flash.events.EventDispatcher { var isInstalled(default,never) : Bool; function new() : Void; function install(?mode : String) : Void; static function iconDigest(icon : flash.utils.ByteArray) : String; static function stringsDigest(strings : flash.xml.XML) : String; } haxe_3.4.4.orig/std/flash/system/ApplicationInstallerMode.hx0000664000175000017500000000021413166552354024113 0ustar andyandy00000000000000package flash.system; @:fakeEnum(String) extern enum ApplicationInstallerMode { INSTALL_ONLY; INSTALL_WITH_SHORTCUTS; SHORTCUTS_ONLY; } haxe_3.4.4.orig/std/flash/system/AuthorizedFeatures.hx0000664000175000017500000000146313166552354023011 0ustar andyandy00000000000000package flash.system; @:final @:require(flash11_3) extern class AuthorizedFeatures { function new() : Void; function createApplicationInstaller(strings : flash.xml.XML, icon : flash.utils.ByteArray) : ApplicationInstaller; function enableAVLoader(loader : flash.display.AVLoader) : Bool; function enableAVURLLoader(loader : flash.media.AVURLLoader) : Bool; function enableAVURLStream(stream : flash.media.AVURLStream) : Bool; @:require(flash11_4) function enableDiskCache(stream : flash.net.URLStream) : Bool; @:require(flash11_7) function enableHLSPlayback(stream : flash.media.AVStream) : Bool; function enableMediaPlayerHLSPlayback(player : Dynamic) : Bool; @:require(flash11_4) function isFeatureEnabled(feature : String, ?data : String) : Bool; @:require(flash11_4) function isNegativeToken() : Bool; } haxe_3.4.4.orig/std/flash/system/AuthorizedFeaturesLoader.hx0000664000175000017500000000063313166552354024136 0ustar andyandy00000000000000package flash.system; @:final @:require(flash11_3) extern class AuthorizedFeaturesLoader extends flash.events.EventDispatcher { var authorizedFeatures(default,never) : AuthorizedFeatures; function new() : Void; function loadAuthorizedFeatures() : Void; @:require(flash11_7) function loadAuthorizedFeaturesFromData(data : flash.utils.ByteArray) : Void; @:require(flash11_4) function makeGlobal() : Void; } haxe_3.4.4.orig/std/flash/system/Capabilities.hx0000664000175000017500000000365113166552354021566 0ustar andyandy00000000000000package flash.system; extern class Capabilities { static var _internal(default,never) : UInt; static var avHardwareDisable(default,never) : Bool; @:require(flash10_1) static var cpuArchitecture(default,never) : String; static var hasAccessibility(default,never) : Bool; static var hasAudio(default,never) : Bool; static var hasAudioEncoder(default,never) : Bool; static var hasEmbeddedVideo(default,never) : Bool; static var hasIME(default,never) : Bool; static var hasMP3(default,never) : Bool; static var hasPrinting(default,never) : Bool; static var hasScreenBroadcast(default,never) : Bool; static var hasScreenPlayback(default,never) : Bool; static var hasStreamingAudio(default,never) : Bool; static var hasStreamingVideo(default,never) : Bool; static var hasTLS(default,never) : Bool; static var hasVideoEncoder(default,never) : Bool; static var isDebugger(default,never) : Bool; @:require(flash10) static var isEmbeddedInAcrobat(default,never) : Bool; static var language(default,never) : String; static var localFileReadDisable(default,never) : Bool; static var manufacturer(default,never) : String; @:require(flash10) static var maxLevelIDC(default,never) : String; static var os(default,never) : String; static var pixelAspectRatio(default,never) : Float; static var playerType(default,never) : String; static var screenColor(default,never) : String; static var screenDPI(default,never) : Float; static var screenResolutionX(default,never) : Float; static var screenResolutionY(default,never) : Float; static var serverString(default,never) : String; @:require(flash10_1) static var supports32BitProcesses(default,never) : Bool; @:require(flash10_1) static var supports64BitProcesses(default,never) : Bool; @:require(flash10_1) static var touchscreenType(default,never) : TouchscreenType; static var version(default,never) : String; @:require(flash11) static function hasMultiChannelAudio(type : String) : Bool; } haxe_3.4.4.orig/std/flash/system/ConnexionsClient.hx0000664000175000017500000000054513166552354022456 0ustar andyandy00000000000000package flash.system; @:final extern class ConnexionsClient { function new() : Void; function Connexions() : Dynamic; function _init(topLocation : String, documentReferrer : String, windowLocation : String, movie : String, userAgent : String, timeout : UInt) : Void; function autoAdd(port : Int) : Dynamic; function manualAdd(port : Int) : Dynamic; } haxe_3.4.4.orig/std/flash/system/DomainMemoryWithStage3D.hx0000664000175000017500000000013013166552354023571 0ustar andyandy00000000000000package flash.system; extern class DomainMemoryWithStage3D { function new() : Void; } haxe_3.4.4.orig/std/flash/system/FSCommand.hx0000664000175000017500000000016713166552354021003 0ustar andyandy00000000000000package flash.system; extern class FSCommand { static function _fscommand(command : String, args : String) : Void; } haxe_3.4.4.orig/std/flash/system/IME.hx0000664000175000017500000000076413166552354017611 0ustar andyandy00000000000000package flash.system; extern class IME extends flash.events.EventDispatcher { static var conversionMode : IMEConversionMode; static var enabled : Bool; @:require(flash10_1) static var isSupported(default,never) : Bool; @:require(flash10_1) static function compositionAbandoned() : Void; @:require(flash10_1) static function compositionSelectionChanged(start : Int, end : Int) : Void; static function doConversion() : Void; static function setCompositionString(composition : String) : Void; } haxe_3.4.4.orig/std/flash/system/IMEConversionMode.hx0000664000175000017500000000032713166552354022457 0ustar andyandy00000000000000package flash.system; @:fakeEnum(String) extern enum IMEConversionMode { ALPHANUMERIC_FULL; ALPHANUMERIC_HALF; CHINESE; JAPANESE_HIRAGANA; JAPANESE_KATAKANA_FULL; JAPANESE_KATAKANA_HALF; KOREAN; UNKNOWN; } haxe_3.4.4.orig/std/flash/system/ImageDecodingPolicy.hx0000664000175000017500000000014413166552354023026 0ustar andyandy00000000000000package flash.system; @:fakeEnum(String) extern enum ImageDecodingPolicy { ON_DEMAND; ON_LOAD; } haxe_3.4.4.orig/std/flash/system/JPEGLoaderContext.hx0000664000175000017500000000044013166552354022407 0ustar andyandy00000000000000package flash.system; @:require(flash10) extern class JPEGLoaderContext extends LoaderContext { var deblockingFilter : Float; function new(deblockingFilter : Float = 0, checkPolicyFile : Bool = false, ?applicationDomain : ApplicationDomain, ?securityDomain : SecurityDomain) : Void; } haxe_3.4.4.orig/std/flash/system/LoaderContext.hx0000664000175000017500000000113513166552354021743 0ustar andyandy00000000000000package flash.system; extern class LoaderContext { @:require(flash10_1) var allowCodeImport : Bool; @:require(flash10_1) var allowLoadBytesCodeExecution : Bool; var applicationDomain : ApplicationDomain; var checkPolicyFile : Bool; @:require(flash11) var imageDecodingPolicy : ImageDecodingPolicy; @:require(flash11) var parameters : Dynamic; @:require(flash11) var requestedContentParent : flash.display.DisplayObjectContainer; var securityDomain : SecurityDomain; function new(checkPolicyFile : Bool = false, ?applicationDomain : ApplicationDomain, ?securityDomain : SecurityDomain) : Void; } haxe_3.4.4.orig/std/flash/system/MessageChannel.hx0000664000175000017500000000055613166552354022053 0ustar andyandy00000000000000package flash.system; @:final @:require(flash11_4) extern class MessageChannel extends flash.events.EventDispatcher { var messageAvailable(default,never) : Bool; var state(default,never) : MessageChannelState; function close() : Void; function receive(blockUntilReceived : Bool = false) : Dynamic; function send(arg : Dynamic, queueLimit : Int = -1) : Void; } haxe_3.4.4.orig/std/flash/system/MessageChannelState.hx0000664000175000017500000000032713166552354023050 0ustar andyandy00000000000000package flash.system; extern class MessageChannelState { function new() : Void; static var CLOSED(default,never) : String; static var CLOSING(default,never) : String; static var OPEN(default,never) : String; } haxe_3.4.4.orig/std/flash/system/Security.hx0000664000175000017500000000213513166552354021000 0ustar andyandy00000000000000package flash.system; extern class Security { @:require(flash10_1) static var APPLICATION(default,never) : String; static var LOCAL_TRUSTED(default,never) : String; static var LOCAL_WITH_FILE(default,never) : String; static var LOCAL_WITH_NETWORK(default,never) : String; static var REMOTE(default,never) : String; static var disableAVM1Loading : Bool; static var exactSettings : Bool; @:require(flash11) static var pageDomain(default,never) : String; static var sandboxType(default,never) : String; static function allowDomain(?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void; static function allowInsecureDomain(?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Void; @:require(flash10_1) static function duplicateSandboxBridgeInputArguments(toplevel : Dynamic, args : Array) : Array; @:require(flash10_1) static function duplicateSandboxBridgeOutputArgument(toplevel : Dynamic, arg : Dynamic) : Dynamic; static function loadPolicyFile(url : String) : Void; static function showSettings(?panel : SecurityPanel) : Void; } haxe_3.4.4.orig/std/flash/system/SecurityDomain.hx0000664000175000017500000000025613166552354022132 0ustar andyandy00000000000000package flash.system; extern class SecurityDomain { @:require(flash11_3) var domainID(default,never) : String; static var currentDomain(default,never) : SecurityDomain; } haxe_3.4.4.orig/std/flash/system/SecurityPanel.hx0000664000175000017500000000023713166552354021761 0ustar andyandy00000000000000package flash.system; @:fakeEnum(String) extern enum SecurityPanel { CAMERA; DEFAULT; DISPLAY; LOCAL_STORAGE; MICROPHONE; PRIVACY; SETTINGS_MANAGER; } haxe_3.4.4.orig/std/flash/system/System.hx0000664000175000017500000000154713166552354020463 0ustar andyandy00000000000000package flash.system; extern class System { @:require(flash10_1) static var freeMemory(default,never) : Float; static var ime(default,never) : IME; @:require(flash10_1) static var privateMemory(default,never) : Float; @:require(flash11) static var processCPUUsage(default,never) : Float; static var totalMemory(default,never) : UInt; @:require(flash10_1) static var totalMemoryNumber(default,never) : Float; static var useCodePage : Bool; static var vmVersion(default,never) : String; @:require(flash10_1) static function disposeXML(node : flash.xml.XML) : Void; static function exit(code : UInt) : Void; static function gc() : Void; static function pause() : Void; @:require(flash11) static function pauseForGCIfCollectionImminent(imminence : Float = 0.75) : Void; static function resume() : Void; static function setClipboard(string : String) : Void; } haxe_3.4.4.orig/std/flash/system/SystemUpdater.hx0000664000175000017500000000032613166552354022002 0ustar andyandy00000000000000package flash.system; @:require(flash10_1) extern class SystemUpdater extends flash.events.EventDispatcher { function new() : Void; function cancel() : Void; function update(type : SystemUpdaterType) : Void; } haxe_3.4.4.orig/std/flash/system/SystemUpdaterType.hx0000664000175000017500000000013313166552354022640 0ustar andyandy00000000000000package flash.system; @:fakeEnum(String) extern enum SystemUpdaterType { DRM; SYSTEM; } haxe_3.4.4.orig/std/flash/system/TouchscreenType.hx0000664000175000017500000000014313166552354022312 0ustar andyandy00000000000000package flash.system; @:fakeEnum(String) extern enum TouchscreenType { FINGER; NONE; STYLUS; } haxe_3.4.4.orig/std/flash/system/Worker.hx0000664000175000017500000000102313166552354020435 0ustar andyandy00000000000000package flash.system; @:final @:require(flash11_4) extern class Worker extends flash.events.EventDispatcher { var isPrimordial(default,never) : Bool; var state(default,never) : WorkerState; function createMessageChannel(receiver : Worker) : MessageChannel; function getSharedProperty(key : String) : Dynamic; function setSharedProperty(key : String, value : Dynamic) : Void; function start() : Void; function terminate() : Bool; static var current(default,never) : Worker; static var isSupported(default,never) : Bool; } haxe_3.4.4.orig/std/flash/system/WorkerDomain.hx0000664000175000017500000000053413166552354021573 0ustar andyandy00000000000000package flash.system; @:final @:require(flash11_4) extern class WorkerDomain { function new() : Void; function createWorker(swf : flash.utils.ByteArray, giveAppPrivileges : Bool = false) : Worker; function listWorkers() : flash.Vector; static var current(default,never) : WorkerDomain; static var isSupported(default,never) : Bool; } haxe_3.4.4.orig/std/flash/system/WorkerState.hx0000664000175000017500000000014313166552354021440 0ustar andyandy00000000000000package flash.system; @:fakeEnum(String) extern enum WorkerState { NEW; RUNNING; TERMINATED; } haxe_3.4.4.orig/std/flash/text/AntiAliasType.hx0000664000175000017500000000013213166552354021333 0ustar andyandy00000000000000package flash.text; @:fakeEnum(String) extern enum AntiAliasType { ADVANCED; NORMAL; } haxe_3.4.4.orig/std/flash/text/CSMSettings.hx0000664000175000017500000000033513166552354020774 0ustar andyandy00000000000000package flash.text; @:final extern class CSMSettings { var fontSize : Float; var insideCutoff : Float; var outsideCutoff : Float; function new(fontSize : Float, insideCutoff : Float, outsideCutoff : Float) : Void; } haxe_3.4.4.orig/std/flash/text/Font.hx0000664000175000017500000000057113166552354017541 0ustar andyandy00000000000000package flash.text; extern class Font { var fontName(default,never) : String; var fontStyle(default,never) : FontStyle; var fontType(default,never) : FontType; function new() : Void; function hasGlyphs(str : String) : Bool; static function enumerateFonts(enumerateDeviceFonts : Bool = false) : Array; static function registerFont(font : Class) : Void; } haxe_3.4.4.orig/std/flash/text/FontStyle.hx0000664000175000017500000000015213166552354020555 0ustar andyandy00000000000000package flash.text; @:fakeEnum(String) extern enum FontStyle { BOLD; BOLD_ITALIC; ITALIC; REGULAR; } haxe_3.4.4.orig/std/flash/text/FontType.hx0000664000175000017500000000014413166552354020377 0ustar andyandy00000000000000package flash.text; @:fakeEnum(String) extern enum FontType { DEVICE; EMBEDDED; EMBEDDED_CFF; } haxe_3.4.4.orig/std/flash/text/GridFitType.hx0000664000175000017500000000013613166552354021022 0ustar andyandy00000000000000package flash.text; @:fakeEnum(String) extern enum GridFitType { NONE; PIXEL; SUBPIXEL; } haxe_3.4.4.orig/std/flash/text/StaticText.hx0000664000175000017500000000023013166552354020717 0ustar andyandy00000000000000package flash.text; @:final extern class StaticText extends flash.display.DisplayObject { var text(default,never) : String; function new() : Void; } haxe_3.4.4.orig/std/flash/text/StyleSheet.hx0000664000175000017500000000071413166552354020723 0ustar andyandy00000000000000package flash.text; extern class StyleSheet extends flash.events.EventDispatcher implements Dynamic { var styleNames(default,never) : Array; function new() : Void; function clear() : Void; function getStyle(styleName : String) : flash.utils.Object; function parseCSS(CSSText : String) : Void; function setStyle(styleName : String, styleObject : flash.utils.Object) : Void; function transform(formatObject : flash.utils.Object) : TextFormat; } haxe_3.4.4.orig/std/flash/text/TextColorType.hx0000664000175000017500000000014113166552354021411 0ustar andyandy00000000000000package flash.text; @:fakeEnum(String) extern enum TextColorType { DARK_COLOR; LIGHT_COLOR; } haxe_3.4.4.orig/std/flash/text/TextDisplayMode.hx0000664000175000017500000000013613166552354021707 0ustar andyandy00000000000000package flash.text; @:fakeEnum(String) extern enum TextDisplayMode { CRT; DEFAULT; LCD; } haxe_3.4.4.orig/std/flash/text/TextExtent.hx0000664000175000017500000000050713166552354020746 0ustar andyandy00000000000000package flash.text; extern class TextExtent { var ascent : Float; var descent : Float; var height : Float; var textFieldHeight : Float; var textFieldWidth : Float; var width : Float; function new(width : Float, height : Float, textFieldWidth : Float, textFieldHeight : Float, ascent : Float, descent : Float) : Void; } haxe_3.4.4.orig/std/flash/text/TextField.hx0000664000175000017500000000556613166552354020534 0ustar andyandy00000000000000package flash.text; extern class TextField extends flash.display.InteractiveObject { var alwaysShowSelection : Bool; var antiAliasType : AntiAliasType; var autoSize : TextFieldAutoSize; var background : Bool; var backgroundColor : UInt; var border : Bool; var borderColor : UInt; var bottomScrollV(default,never) : Int; var caretIndex(default,never) : Int; var condenseWhite : Bool; var defaultTextFormat : TextFormat; var displayAsPassword : Bool; var embedFonts : Bool; var gridFitType : GridFitType; var htmlText : String; var length(default,never) : Int; var maxChars : Int; var maxScrollH(default,never) : Int; var maxScrollV(default,never) : Int; var mouseWheelEnabled : Bool; var multiline : Bool; var numLines(default,never) : Int; var restrict : String; var scrollH : Int; var scrollV : Int; var selectable : Bool; var selectedText(default,never) : String; var selectionBeginIndex(default,never) : Int; var selectionEndIndex(default,never) : Int; var sharpness : Float; var styleSheet : StyleSheet; var text : String; var textColor : UInt; var textHeight(default,never) : Float; @:require(flash11) var textInteractionMode(default,never) : TextInteractionMode; var textWidth(default,never) : Float; var thickness : Float; var type : TextFieldType; var useRichTextClipboard : Bool; var wordWrap : Bool; function new() : Void; function appendText(newText : String) : Void; function copyRichText() : String; function getCharBoundaries(charIndex : Int) : flash.geom.Rectangle; function getCharIndexAtPoint(x : Float, y : Float) : Int; function getFirstCharInParagraph(charIndex : Int) : Int; function getImageReference(id : String) : flash.display.DisplayObject; function getLineIndexAtPoint(x : Float, y : Float) : Int; function getLineIndexOfChar(charIndex : Int) : Int; function getLineLength(lineIndex : Int) : Int; function getLineMetrics(lineIndex : Int) : TextLineMetrics; function getLineOffset(lineIndex : Int) : Int; function getLineText(lineIndex : Int) : String; function getParagraphLength(charIndex : Int) : Int; function getRawText() : String; function getTextFormat(beginIndex : Int = -1, endIndex : Int = -1) : TextFormat; function getTextRuns(beginIndex : Int = 0, endIndex : Int = 2147483647) : Array; function getXMLText(beginIndex : Int = 0, endIndex : Int = 2147483647) : String; function insertXMLText(beginIndex : Int, endIndex : Int, richText : String, pasting : Bool = false) : Void; function pasteRichText(richText : String) : Bool; function replaceSelectedText(value : String) : Void; function replaceText(beginIndex : Int, endIndex : Int, newText : String) : Void; function setSelection(beginIndex : Int, endIndex : Int) : Void; function setTextFormat(format : TextFormat, beginIndex : Int = -1, endIndex : Int = -1) : Void; @:require(flash10) static function isFontCompatible(fontName : String, fontStyle : String) : Bool; } haxe_3.4.4.orig/std/flash/text/TextFieldAutoSize.hx0000664000175000017500000000015113166552354022201 0ustar andyandy00000000000000package flash.text; @:fakeEnum(String) extern enum TextFieldAutoSize { CENTER; LEFT; NONE; RIGHT; } haxe_3.4.4.orig/std/flash/text/TextFieldType.hx0000664000175000017500000000013013166552354021354 0ustar andyandy00000000000000package flash.text; @:fakeEnum(String) extern enum TextFieldType { DYNAMIC; INPUT; } haxe_3.4.4.orig/std/flash/text/TextFormat.hx0000664000175000017500000000162413166552354020730 0ustar andyandy00000000000000package flash.text; extern class TextFormat { var align : TextFormatAlign; var blockIndent : Null; var bold : Null; var bullet : Null; var color : Null; var display : TextFormatDisplay; var font : String; var indent : Null; var italic : Null; var kerning : Null; var leading : Null; var leftMargin : Null; var letterSpacing : Null; var rightMargin : Null; var size : Null; var tabStops : Array; var target : String; var underline : Null; var url : String; function new(?font : String, size : Null = 0, color : Null = 0, bold : Null = false, italic : Null = false, underline : Null = false, ?url : String, ?target : String, ?align : TextFormatAlign, leftMargin : Null = 0, rightMargin : Null = 0, indent : Null = 0, leading : Null = 0) : Void; } haxe_3.4.4.orig/std/flash/text/TextFormatAlign.hx0000664000175000017500000000017013166552354021676 0ustar andyandy00000000000000package flash.text; @:fakeEnum(String) extern enum TextFormatAlign { CENTER; END; JUSTIFY; LEFT; RIGHT; START; } haxe_3.4.4.orig/std/flash/text/TextFormatDisplay.hx0000664000175000017500000000013313166552354022250 0ustar andyandy00000000000000package flash.text; @:fakeEnum(String) extern enum TextFormatDisplay { BLOCK; INLINE; } haxe_3.4.4.orig/std/flash/text/TextInteractionMode.hx0000664000175000017500000000014113166552354022555 0ustar andyandy00000000000000package flash.text; @:fakeEnum(String) extern enum TextInteractionMode { NORMAL; SELECTION; } haxe_3.4.4.orig/std/flash/text/TextLineMetrics.hx0000664000175000017500000000044213166552354021713 0ustar andyandy00000000000000package flash.text; extern class TextLineMetrics { var ascent : Float; var descent : Float; var height : Float; var leading : Float; var width : Float; var x : Float; function new(x : Float, width : Float, height : Float, ascent : Float, descent : Float, leading : Float) : Void; } haxe_3.4.4.orig/std/flash/text/TextRenderer.hx0000664000175000017500000000051413166552354021243 0ustar andyandy00000000000000package flash.text; extern class TextRenderer { static var antiAliasType : AntiAliasType; static var displayMode : TextDisplayMode; static var maxLevel : Int; static function setAdvancedAntiAliasingTable(fontName : String, fontStyle : FontStyle, colorType : TextColorType, advancedAntiAliasingTable : Array) : Void; } haxe_3.4.4.orig/std/flash/text/TextRun.hx0000664000175000017500000000031113166552354020234 0ustar andyandy00000000000000package flash.text; extern class TextRun { var beginIndex : Int; var endIndex : Int; var textFormat : TextFormat; function new(beginIndex : Int, endIndex : Int, textFormat : TextFormat) : Void; } haxe_3.4.4.orig/std/flash/text/TextSnapshot.hx0000664000175000017500000000133513166552354021276 0ustar andyandy00000000000000package flash.text; extern class TextSnapshot { var charCount(default,never) : Int; function new() : Void; function findText(beginIndex : Int, textToFind : String, caseSensitive : Bool) : Int; function getSelected(beginIndex : Int, endIndex : Int) : Bool; function getSelectedText(includeLineEndings : Bool = false) : String; function getText(beginIndex : Int, endIndex : Int, includeLineEndings : Bool = false) : String; function getTextRunInfo(beginIndex : Int, endIndex : Int) : Array; function hitTestTextNearPos(x : Float, y : Float, maxDistance : Float = 0) : Float; function setSelectColor(hexColor : UInt = 16776960) : Void; function setSelected(beginIndex : Int, endIndex : Int, select : Bool) : Void; } haxe_3.4.4.orig/std/flash/text/engine/BreakOpportunity.hx0000664000175000017500000000015213166552354023414 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum BreakOpportunity { ALL; ANY; AUTO; NONE; } haxe_3.4.4.orig/std/flash/text/engine/CFFHinting.hx0000664000175000017500000000014313166552354022012 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum CFFHinting { HORIZONTAL_STEM; NONE; } haxe_3.4.4.orig/std/flash/text/engine/ContentElement.hx0000664000175000017500000000112413166552354023017 0ustar andyandy00000000000000package flash.text.engine; extern class ContentElement { var elementFormat : ElementFormat; var eventMirror : flash.events.EventDispatcher; var groupElement(default,never) : GroupElement; var rawText(default,never) : String; var text(default,never) : String; var textBlock(default,never) : TextBlock; var textBlockBeginIndex(default,never) : Int; var textRotation : TextRotation; var userData : Dynamic; function new(?elementFormat : ElementFormat, ?eventMirror : flash.events.EventDispatcher, ?textRotation : TextRotation) : Void; static var GRAPHIC_ELEMENT(default,never) : UInt; } haxe_3.4.4.orig/std/flash/text/engine/DigitCase.hx0000664000175000017500000000015013166552354021725 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum DigitCase { DEFAULT; LINING; OLD_STYLE; } haxe_3.4.4.orig/std/flash/text/engine/DigitWidth.hx0000664000175000017500000000015513166552354022136 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum DigitWidth { DEFAULT; PROPORTIONAL; TABULAR; } haxe_3.4.4.orig/std/flash/text/engine/EastAsianJustifier.hx0000664000175000017500000000046413166552354023636 0ustar andyandy00000000000000package flash.text.engine; @:final extern class EastAsianJustifier extends TextJustifier { var composeTrailingIdeographicSpaces : Bool; var justificationStyle : JustificationStyle; function new(?locale : String, ?lineJustification : LineJustification, ?justificationStyle : JustificationStyle) : Void; } haxe_3.4.4.orig/std/flash/text/engine/ElementFormat.hx0000664000175000017500000000222513166552354022640 0ustar andyandy00000000000000package flash.text.engine; @:final extern class ElementFormat { var alignmentBaseline : TextBaseline; var alpha : Float; var baselineShift : Float; var breakOpportunity : BreakOpportunity; var color : UInt; var digitCase : DigitCase; var digitWidth : DigitWidth; var dominantBaseline : TextBaseline; var fontDescription : FontDescription; var fontSize : Float; var kerning : Kerning; var ligatureLevel : LigatureLevel; var locale : String; var locked : Bool; var textRotation : TextRotation; var trackingLeft : Float; var trackingRight : Float; var typographicCase : TypographicCase; function new(?fontDescription : FontDescription, fontSize : Float = 12, color : UInt = 0, alpha : Float = 1, ?textRotation : TextRotation, ?dominantBaseline : TextBaseline, ?alignmentBaseline : TextBaseline, baselineShift : Float = 0, ?kerning : Kerning, trackingRight : Float = 0, trackingLeft : Float = 0, ?locale : String, ?breakOpportunity : BreakOpportunity, ?digitCase : DigitCase, ?digitWidth : DigitWidth, ?ligatureLevel : LigatureLevel, ?typographicCase : TypographicCase) : Void; function clone() : ElementFormat; function getFontMetrics() : FontMetrics; } haxe_3.4.4.orig/std/flash/text/engine/FontDescription.hx0000664000175000017500000000134513166552354023212 0ustar andyandy00000000000000package flash.text.engine; @:final extern class FontDescription { var cffHinting : CFFHinting; var fontLookup : FontLookup; var fontName : String; var fontPosture : FontPosture; var fontWeight : FontWeight; var locked : Bool; var renderingMode : RenderingMode; function new(?fontName : String, ?fontWeight : FontWeight, ?fontPosture : FontPosture, ?fontLookup : FontLookup, ?renderingMode : RenderingMode, ?cffHinting : CFFHinting) : Void; function clone() : FontDescription; @:require(flash10_1) static function isDeviceFontCompatible(fontName : String, fontWeight : FontWeight, fontPosture : FontPosture) : Bool; static function isFontCompatible(fontName : String, fontWeight : FontWeight, fontPosture : FontPosture) : Bool; } haxe_3.4.4.orig/std/flash/text/engine/FontLookup.hx0000664000175000017500000000014213166552354022172 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum FontLookup { DEVICE; EMBEDDED_CFF; } haxe_3.4.4.orig/std/flash/text/engine/FontMetrics.hx0000664000175000017500000000123313166552354022331 0ustar andyandy00000000000000package flash.text.engine; @:final extern class FontMetrics { var emBox : flash.geom.Rectangle; var lineGap : Float; var strikethroughOffset : Float; var strikethroughThickness : Float; var subscriptOffset : Float; var subscriptScale : Float; var superscriptOffset : Float; var superscriptScale : Float; var underlineOffset : Float; var underlineThickness : Float; function new(emBox : flash.geom.Rectangle, strikethroughOffset : Float, strikethroughThickness : Float, underlineOffset : Float, underlineThickness : Float, subscriptOffset : Float, subscriptScale : Float, superscriptOffset : Float, superscriptScale : Float, lineGap : Float = 0) : Void; } haxe_3.4.4.orig/std/flash/text/engine/FontPosture.hx0000664000175000017500000000013513166552354022364 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum FontPosture { ITALIC; NORMAL; } haxe_3.4.4.orig/std/flash/text/engine/FontWeight.hx0000664000175000017500000000013213166552354022147 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum FontWeight { BOLD; NORMAL; } haxe_3.4.4.orig/std/flash/text/engine/GraphicElement.hx0000664000175000017500000000063613166552354022771 0ustar andyandy00000000000000package flash.text.engine; @:final extern class GraphicElement extends ContentElement { var elementHeight : Float; var elementWidth : Float; var graphic : flash.display.DisplayObject; function new(?graphic : flash.display.DisplayObject, elementWidth : Float = 15, elementHeight : Float = 15, ?elementFormat : ElementFormat, ?eventMirror : flash.events.EventDispatcher, ?textRotation : TextRotation) : Void; } haxe_3.4.4.orig/std/flash/text/engine/GroupElement.hx0000664000175000017500000000170713166552354022510 0ustar andyandy00000000000000package flash.text.engine; @:final extern class GroupElement extends ContentElement { var elementCount(default,never) : Int; function new(?elements : flash.Vector, ?elementFormat : ElementFormat, ?eventMirror : flash.events.EventDispatcher, ?textRotation : TextRotation) : Void; function getElementAt(index : Int) : ContentElement; function getElementAtCharIndex(charIndex : Int) : ContentElement; function getElementIndex(element : ContentElement) : Int; function groupElements(beginIndex : Int, endIndex : Int) : GroupElement; function mergeTextElements(beginIndex : Int, endIndex : Int) : TextElement; function replaceElements(beginIndex : Int, endIndex : Int, newElements : flash.Vector) : flash.Vector; function setElements(value : flash.Vector) : Void; function splitTextElement(elementIndex : Int, splitIndex : Int) : TextElement; function ungroupElements(groupIndex : Int) : Void; } haxe_3.4.4.orig/std/flash/text/engine/JustificationStyle.hx0000664000175000017500000000022213166552354023725 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum JustificationStyle { PRIORITIZE_LEAST_ADJUSTMENT; PUSH_IN_KINSOKU; PUSH_OUT_ONLY; } haxe_3.4.4.orig/std/flash/text/engine/Kerning.hx0000664000175000017500000000013113166552354021465 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum Kerning { AUTO; OFF; ON; } haxe_3.4.4.orig/std/flash/text/engine/LigatureLevel.hx0000664000175000017500000000017313166552354022642 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum LigatureLevel { COMMON; EXOTIC; MINIMUM; NONE; UNCOMMON; } haxe_3.4.4.orig/std/flash/text/engine/LineJustification.hx0000664000175000017500000000023513166552354023520 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum LineJustification { ALL_BUT_LAST; ALL_BUT_MANDATORY_BREAK; ALL_INCLUDING_LAST; UNJUSTIFIED; } haxe_3.4.4.orig/std/flash/text/engine/RenderingMode.hx0000664000175000017500000000013413166552354022615 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum RenderingMode { CFF; NORMAL; } haxe_3.4.4.orig/std/flash/text/engine/SpaceJustifier.hx0000664000175000017500000000057113166552354023020 0ustar andyandy00000000000000package flash.text.engine; @:final extern class SpaceJustifier extends TextJustifier { var letterSpacing : Bool; @:require(flash10_1) var maximumSpacing : Float; @:require(flash10_1) var minimumSpacing : Float; @:require(flash10_1) var optimumSpacing : Float; function new(?locale : String, ?lineJustification : LineJustification, letterSpacing : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/text/engine/TabAlignment.hx0000664000175000017500000000015513166552354022443 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum TabAlignment { CENTER; DECIMAL; END; START; } haxe_3.4.4.orig/std/flash/text/engine/TabStop.hx0000664000175000017500000000040013166552354021443 0ustar andyandy00000000000000package flash.text.engine; @:final extern class TabStop { var alignment : TabAlignment; var decimalAlignmentToken : String; var position : Float; function new(?alignment : TabAlignment, position : Float = 0, ?decimalAlignmentToken : String) : Void; } haxe_3.4.4.orig/std/flash/text/engine/TextBaseline.hx0000664000175000017500000000027313166552354022466 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum TextBaseline { ASCENT; DESCENT; IDEOGRAPHIC_BOTTOM; IDEOGRAPHIC_CENTER; IDEOGRAPHIC_TOP; ROMAN; USE_DOMINANT_BASELINE; } haxe_3.4.4.orig/std/flash/text/engine/TextBlock.hx0000664000175000017500000000327013166552354021776 0ustar andyandy00000000000000package flash.text.engine; @:final extern class TextBlock { var applyNonLinearFontScaling : Bool; var baselineFontDescription : FontDescription; var baselineFontSize : Float; var baselineZero : TextBaseline; var bidiLevel : Int; var content : ContentElement; var firstInvalidLine(default,never) : TextLine; var firstLine(default,never) : TextLine; var lastLine(default,never) : TextLine; var lineRotation : TextRotation; var tabStops : flash.Vector; var textJustifier : TextJustifier; var textLineCreationResult(default,never) : TextLineCreationResult; var userData : Dynamic; function new(?content : ContentElement, ?tabStops : flash.Vector, ?textJustifier : TextJustifier, ?lineRotation : TextRotation, ?baselineZero : TextBaseline, bidiLevel : Int = 0, applyNonLinearFontScaling : Bool = true, ?baselineFontDescription : FontDescription, baselineFontSize : Float = 12) : Void; function createTextLine(?previousLine : TextLine, width : Float = 1000000, lineOffset : Float = 0, fitSomething : Bool = false) : TextLine; function dump() : String; function findNextAtomBoundary(afterCharIndex : Int) : Int; function findNextWordBoundary(afterCharIndex : Int) : Int; function findPreviousAtomBoundary(beforeCharIndex : Int) : Int; function findPreviousWordBoundary(beforeCharIndex : Int) : Int; function getTextLineAtCharIndex(charIndex : Int) : TextLine; @:require(flash10_1) function recreateTextLine(textLine : TextLine, ?previousLine : TextLine, width : Float = 1000000, lineOffset : Float = 0, fitSomething : Bool = false) : TextLine; @:require(flash10_1) function releaseLineCreationData() : Void; function releaseLines(firstLine : TextLine, lastLine : TextLine) : Void; } haxe_3.4.4.orig/std/flash/text/engine/TextElement.hx0000664000175000017500000000047313166552354022337 0ustar andyandy00000000000000package flash.text.engine; @:final extern class TextElement extends ContentElement { function new(?text : String, ?elementFormat : ElementFormat, ?eventMirror : flash.events.EventDispatcher, ?textRotation : TextRotation) : Void; function replaceText(beginIndex : Int, endIndex : Int, newText : String) : Void; } haxe_3.4.4.orig/std/flash/text/engine/TextJustifier.hx0000664000175000017500000000050613166552354022707 0ustar andyandy00000000000000package flash.text.engine; extern class TextJustifier { var lineJustification : LineJustification; var locale(default,never) : String; function new(locale : String, lineJustification : LineJustification) : Void; function clone() : TextJustifier; static function getJustifierForLocale(locale : String) : TextJustifier; } haxe_3.4.4.orig/std/flash/text/engine/TextLine.hx0000664000175000017500000000346013166552354021634 0ustar andyandy00000000000000package flash.text.engine; @:final extern class TextLine extends flash.display.DisplayObjectContainer { var ascent(default,never) : Float; var atomCount(default,never) : Int; var descent(default,never) : Float; var hasGraphicElement(default,never) : Bool; @:require(flash10_1) var hasTabs(default,never) : Bool; var mirrorRegions(default,never) : flash.Vector; var nextLine(default,never) : TextLine; var previousLine(default,never) : TextLine; var rawTextLength(default,never) : Int; var specifiedWidth(default,never) : Float; var textBlock(default,never) : TextBlock; var textBlockBeginIndex(default,never) : Int; var textHeight(default,never) : Float; var textWidth(default,never) : Float; var totalAscent(default,never) : Float; var totalDescent(default,never) : Float; var totalHeight(default,never) : Float; var unjustifiedTextWidth(default,never) : Float; var userData : Dynamic; var validity : String; function new() : Void; function dump() : String; function flushAtomData() : Void; function getAtomBidiLevel(atomIndex : Int) : Int; function getAtomBounds(atomIndex : Int) : flash.geom.Rectangle; function getAtomCenter(atomIndex : Int) : Float; function getAtomGraphic(atomIndex : Int) : flash.display.DisplayObject; function getAtomIndexAtCharIndex(charIndex : Int) : Int; function getAtomIndexAtPoint(stageX : Float, stageY : Float) : Int; function getAtomTextBlockBeginIndex(atomIndex : Int) : Int; function getAtomTextBlockEndIndex(atomIndex : Int) : Int; function getAtomTextRotation(atomIndex : Int) : String; function getAtomWordBoundaryOnLeft(atomIndex : Int) : Bool; function getBaselinePosition(baseline : String) : Float; function getMirrorRegion(mirror : flash.events.EventDispatcher) : TextLineMirrorRegion; static var MAX_LINE_WIDTH(default,never) : Int; } haxe_3.4.4.orig/std/flash/text/engine/TextLineCreationResult.hx0000664000175000017500000000021413166552354024512 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum TextLineCreationResult { COMPLETE; EMERGENCY; INSUFFICIENT_WIDTH; SUCCESS; } haxe_3.4.4.orig/std/flash/text/engine/TextLineMirrorRegion.hx0000664000175000017500000000063113166552354024170 0ustar andyandy00000000000000package flash.text.engine; @:final extern class TextLineMirrorRegion { var bounds(default,never) : flash.geom.Rectangle; var element(default,never) : ContentElement; var mirror(default,never) : flash.events.EventDispatcher; var nextRegion(default,never) : TextLineMirrorRegion; var previousRegion(default,never) : TextLineMirrorRegion; var textLine(default,never) : TextLine; function new() : Void; } haxe_3.4.4.orig/std/flash/text/engine/TextLineValidity.hx0000664000175000017500000000017613166552354023343 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum TextLineValidity { INVALID; POSSIBLY_INVALID; STATIC; VALID; } haxe_3.4.4.orig/std/flash/text/engine/TextRotation.hx0000664000175000017500000000020413166552354022535 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum TextRotation { AUTO; ROTATE_0; ROTATE_180; ROTATE_270; ROTATE_90; } haxe_3.4.4.orig/std/flash/text/engine/TypographicCase.hx0000664000175000017500000000024313166552354023161 0ustar andyandy00000000000000package flash.text.engine; @:fakeEnum(String) extern enum TypographicCase { CAPS; CAPS_AND_SMALL_CAPS; DEFAULT; LOWERCASE; SMALL_CAPS; TITLE; UPPERCASE; } haxe_3.4.4.orig/std/flash/text/ime/CompositionAttributeRange.hx0000664000175000017500000000041413166552354024545 0ustar andyandy00000000000000package flash.text.ime; @:final extern class CompositionAttributeRange { var converted : Bool; var relativeEnd : Int; var relativeStart : Int; var selected : Bool; function new(relativeStart : Int, relativeEnd : Int, selected : Bool, converted : Bool) : Void; } haxe_3.4.4.orig/std/flash/text/ime/IIMEClient.hx0000664000175000017500000000137313166552354021270 0ustar andyandy00000000000000package flash.text.ime; extern interface IIMEClient { var compositionEndIndex(default,never) : Int; var compositionStartIndex(default,never) : Int; var selectionActiveIndex(default,never) : Int; var selectionAnchorIndex(default,never) : Int; var verticalTextLayout(default,never) : Bool; function confirmComposition(?text : String, preserveSelection : Bool = false) : Void; function getTextBounds(startIndex : Int, endIndex : Int) : flash.geom.Rectangle; function getTextInRange(startIndex : Int, endIndex : Int) : String; function selectRange(anchorIndex : Int, activeIndex : Int) : Void; function updateComposition(text : String, attributes : flash.Vector, compositionStartIndex : Int, compositionEndIndex : Int) : Void; } haxe_3.4.4.orig/std/flash/trace/Trace.hx0000664000175000017500000000111713166552354020000 0ustar andyandy00000000000000package flash.trace; extern class Trace { static var FILE(default,never) : Dynamic; static var LISTENER(default,never) : Dynamic; static var METHODS(default,never) : Int; static var METHODS_AND_LINES(default,never) : Int; static var METHODS_AND_LINES_WITH_ARGS(default,never) : Int; static var METHODS_WITH_ARGS(default,never) : Int; static var OFF(default,never) : Int; static function getLevel(target : Int = 2) : Int; static function getListener() : Dynamic; static function setLevel(l : Int, target : Int = 2) : Dynamic; static function setListener(f : Dynamic) : Dynamic; } haxe_3.4.4.orig/std/flash/ui/ContextMenu.hx0000664000175000017500000000076213166552354020537 0ustar andyandy00000000000000package flash.ui; @:final extern class ContextMenu extends flash.display.NativeMenu { var builtInItems : ContextMenuBuiltInItems; @:require(flash10) var clipboardItems : ContextMenuClipboardItems; @:require(flash10) var clipboardMenu : Bool; var customItems : Array; @:require(flash10) var link : flash.net.URLRequest; function new() : Void; function clone() : ContextMenu; function hideBuiltInItems() : Void; @:require(flash10_1) static var isSupported(default,never) : Bool; } haxe_3.4.4.orig/std/flash/ui/ContextMenuBuiltInItems.hx0000664000175000017500000000045113166552354023023 0ustar andyandy00000000000000package flash.ui; @:final extern class ContextMenuBuiltInItems { var forwardAndBack : Bool; var loop : Bool; var play : Bool; var print : Bool; var quality : Bool; var rewind : Bool; var save : Bool; var zoom : Bool; function new() : Void; function clone() : ContextMenuBuiltInItems; } haxe_3.4.4.orig/std/flash/ui/ContextMenuClipboardItems.hx0000664000175000017500000000035513166552354023357 0ustar andyandy00000000000000package flash.ui; @:final extern class ContextMenuClipboardItems { var clear : Bool; var copy : Bool; var cut : Bool; var paste : Bool; var selectAll : Bool; function new() : Void; function clone() : ContextMenuClipboardItems; } haxe_3.4.4.orig/std/flash/ui/ContextMenuItem.hx0000664000175000017500000000050513166552354021351 0ustar andyandy00000000000000package flash.ui; @:final extern class ContextMenuItem extends flash.display.NativeMenuItem { var caption : String; var separatorBefore : Bool; var visible : Bool; function new(caption : String, separatorBefore : Bool = false, enabled : Bool = true, visible : Bool = true) : Void; function clone() : ContextMenuItem; } haxe_3.4.4.orig/std/flash/ui/GameInput.hx0000664000175000017500000000040113166552354020145 0ustar andyandy00000000000000package flash.ui; @:require(flash11_8) extern class GameInput extends flash.events.EventDispatcher { static var isSupported(default,never) : Bool; static var numDevices(default,never) : Int; static function getDeviceAt(index : Int) : GameInputDevice; } haxe_3.4.4.orig/std/flash/ui/GameInputControl.hx0000664000175000017500000000050313166552354021511 0ustar andyandy00000000000000package flash.ui; extern class GameInputControl extends flash.events.EventDispatcher implements Dynamic { var device(default,never) : GameInputDevice; var id(default,never) : String; var maxValue(default,never) : Float; var minValue(default,never) : Float; var value(default,never) : Float; function new() : Void; } haxe_3.4.4.orig/std/flash/ui/GameInputControlType.hx0000664000175000017500000000021713166552354022355 0ustar andyandy00000000000000package flash.ui; @:fakeEnum(String) extern enum GameInputControlType { ACCELERATION; BUTTON; DIRECTION; MOVEMENT; ROTATION; TRIGGER; } haxe_3.4.4.orig/std/flash/ui/GameInputDevice.hx0000664000175000017500000000110113166552354021263 0ustar andyandy00000000000000package flash.ui; @:final @:require(flash11_8) extern class GameInputDevice { var enabled : Bool; var id(default,never) : String; var name(default,never) : String; var numControls(default,never) : Int; var sampleInterval : Int; function new() : Void; function getCachedSamples(data : flash.utils.ByteArray, append : Bool = false) : Int; function getControlAt(i : Int) : GameInputControl; function startCachingSamples(numSamples : Int, controls : flash.Vector) : Void; function stopCachingSamples() : Void; static var MAX_BUFFER_SIZE(default,never) : Int; } haxe_3.4.4.orig/std/flash/ui/GameInputFinger.hx0000664000175000017500000000015113166552354021302 0ustar andyandy00000000000000package flash.ui; @:fakeEnum(String) extern enum GameInputFinger { INDEX; MIDDLE; THUMB; UNKNOWN; } haxe_3.4.4.orig/std/flash/ui/GameInputHand.hx0000664000175000017500000000013513166552354020744 0ustar andyandy00000000000000package flash.ui; @:fakeEnum(String) extern enum GameInputHand { LEFT; RIGHT; UNKNOWN; } haxe_3.4.4.orig/std/flash/ui/KeyLocation.hx0000664000175000017500000000015413166552354020502 0ustar andyandy00000000000000package flash.ui; @:fakeEnum(UInt) extern enum KeyLocation { D_PAD; LEFT; NUM_PAD; RIGHT; STANDARD; } haxe_3.4.4.orig/std/flash/ui/Keyboard.hx0000664000175000017500000004262113166552354020026 0ustar andyandy00000000000000package flash.ui; extern class Keyboard { @:require(flash10_1) static var A(default,never) : UInt; @:require(flash10_1) static var ALTERNATE(default,never) : UInt; @:require(flash10_2) static var AUDIO(default,never) : UInt; @:require(flash10_1) static var B(default,never) : UInt; @:require(flash10_2) static var BACK(default,never) : UInt; @:require(flash10_1) static var BACKQUOTE(default,never) : UInt; @:require(flash10_1) static var BACKSLASH(default,never) : UInt; static var BACKSPACE(default,never) : UInt; @:require(flash10_2) static var BLUE(default,never) : UInt; @:require(flash10_1) static var C(default,never) : UInt; static var CAPS_LOCK(default,never) : UInt; @:require(flash10_2) static var CHANNEL_DOWN(default,never) : UInt; @:require(flash10_2) static var CHANNEL_UP(default,never) : UInt; @:require(flash10_1) static var COMMA(default,never) : UInt; @:require(flash10_1) static var COMMAND(default,never) : UInt; static var CONTROL(default,never) : UInt; @:require(flash10_1) static var CharCodeStrings(default,never) : Array; @:require(flash10_1) static var D(default,never) : UInt; static var DELETE(default,never) : UInt; static var DOWN(default,never) : UInt; @:require(flash10_2) static var DVR(default,never) : UInt; @:require(flash10_1) static var E(default,never) : UInt; static var END(default,never) : UInt; static var ENTER(default,never) : UInt; @:require(flash10_1) static var EQUAL(default,never) : UInt; static var ESCAPE(default,never) : UInt; @:require(flash10_2) static var EXIT(default,never) : UInt; @:require(flash10_1) static var F(default,never) : UInt; static var F1(default,never) : UInt; static var F10(default,never) : UInt; static var F11(default,never) : UInt; static var F12(default,never) : UInt; static var F13(default,never) : UInt; static var F14(default,never) : UInt; static var F15(default,never) : UInt; static var F2(default,never) : UInt; static var F3(default,never) : UInt; static var F4(default,never) : UInt; static var F5(default,never) : UInt; static var F6(default,never) : UInt; static var F7(default,never) : UInt; static var F8(default,never) : UInt; static var F9(default,never) : UInt; @:require(flash10_2) static var FAST_FORWARD(default,never) : UInt; @:require(flash10_1) static var G(default,never) : UInt; @:require(flash10_2) static var GREEN(default,never) : UInt; @:require(flash10_2) static var GUIDE(default,never) : UInt; @:require(flash10_1) static var H(default,never) : UInt; @:require(flash10_2) static var HELP(default,never) : UInt; static var HOME(default,never) : UInt; @:require(flash10_1) static var I(default,never) : UInt; @:require(flash10_2) static var INFO(default,never) : UInt; @:require(flash10_2) static var INPUT(default,never) : UInt; static var INSERT(default,never) : UInt; @:require(flash10_1) static var J(default,never) : UInt; @:require(flash10_1) static var K(default,never) : UInt; @:require(flash10_1) static var KEYNAME_BEGIN(default,never) : String; @:require(flash10_1) static var KEYNAME_BREAK(default,never) : String; @:require(flash10_1) static var KEYNAME_CLEARDISPLAY(default,never) : String; @:require(flash10_1) static var KEYNAME_CLEARLINE(default,never) : String; @:require(flash10_1) static var KEYNAME_DELETE(default,never) : String; @:require(flash10_1) static var KEYNAME_DELETECHAR(default,never) : String; @:require(flash10_1) static var KEYNAME_DELETELINE(default,never) : String; @:require(flash10_1) static var KEYNAME_DOWNARROW(default,never) : String; @:require(flash10_1) static var KEYNAME_END(default,never) : String; @:require(flash10_1) static var KEYNAME_EXECUTE(default,never) : String; @:require(flash10_1) static var KEYNAME_F1(default,never) : String; @:require(flash10_1) static var KEYNAME_F10(default,never) : String; @:require(flash10_1) static var KEYNAME_F11(default,never) : String; @:require(flash10_1) static var KEYNAME_F12(default,never) : String; @:require(flash10_1) static var KEYNAME_F13(default,never) : String; @:require(flash10_1) static var KEYNAME_F14(default,never) : String; @:require(flash10_1) static var KEYNAME_F15(default,never) : String; @:require(flash10_1) static var KEYNAME_F16(default,never) : String; @:require(flash10_1) static var KEYNAME_F17(default,never) : String; @:require(flash10_1) static var KEYNAME_F18(default,never) : String; @:require(flash10_1) static var KEYNAME_F19(default,never) : String; @:require(flash10_1) static var KEYNAME_F2(default,never) : String; @:require(flash10_1) static var KEYNAME_F20(default,never) : String; @:require(flash10_1) static var KEYNAME_F21(default,never) : String; @:require(flash10_1) static var KEYNAME_F22(default,never) : String; @:require(flash10_1) static var KEYNAME_F23(default,never) : String; @:require(flash10_1) static var KEYNAME_F24(default,never) : String; @:require(flash10_1) static var KEYNAME_F25(default,never) : String; @:require(flash10_1) static var KEYNAME_F26(default,never) : String; @:require(flash10_1) static var KEYNAME_F27(default,never) : String; @:require(flash10_1) static var KEYNAME_F28(default,never) : String; @:require(flash10_1) static var KEYNAME_F29(default,never) : String; @:require(flash10_1) static var KEYNAME_F3(default,never) : String; @:require(flash10_1) static var KEYNAME_F30(default,never) : String; @:require(flash10_1) static var KEYNAME_F31(default,never) : String; @:require(flash10_1) static var KEYNAME_F32(default,never) : String; @:require(flash10_1) static var KEYNAME_F33(default,never) : String; @:require(flash10_1) static var KEYNAME_F34(default,never) : String; @:require(flash10_1) static var KEYNAME_F35(default,never) : String; @:require(flash10_1) static var KEYNAME_F4(default,never) : String; @:require(flash10_1) static var KEYNAME_F5(default,never) : String; @:require(flash10_1) static var KEYNAME_F6(default,never) : String; @:require(flash10_1) static var KEYNAME_F7(default,never) : String; @:require(flash10_1) static var KEYNAME_F8(default,never) : String; @:require(flash10_1) static var KEYNAME_F9(default,never) : String; @:require(flash10_1) static var KEYNAME_FIND(default,never) : String; @:require(flash10_1) static var KEYNAME_HELP(default,never) : String; @:require(flash10_1) static var KEYNAME_HOME(default,never) : String; @:require(flash10_1) static var KEYNAME_INSERT(default,never) : String; @:require(flash10_1) static var KEYNAME_INSERTCHAR(default,never) : String; @:require(flash10_1) static var KEYNAME_INSERTLINE(default,never) : String; @:require(flash10_1) static var KEYNAME_LEFTARROW(default,never) : String; @:require(flash10_1) static var KEYNAME_MENU(default,never) : String; @:require(flash10_1) static var KEYNAME_MODESWITCH(default,never) : String; @:require(flash10_1) static var KEYNAME_NEXT(default,never) : String; @:require(flash10_1) static var KEYNAME_PAGEDOWN(default,never) : String; @:require(flash10_1) static var KEYNAME_PAGEUP(default,never) : String; @:require(flash10_1) static var KEYNAME_PAUSE(default,never) : String; @:require(flash10_1) static var KEYNAME_PREV(default,never) : String; @:require(flash10_1) static var KEYNAME_PRINT(default,never) : String; @:require(flash10_1) static var KEYNAME_PRINTSCREEN(default,never) : String; @:require(flash10_1) static var KEYNAME_REDO(default,never) : String; @:require(flash10_1) static var KEYNAME_RESET(default,never) : String; @:require(flash10_1) static var KEYNAME_RIGHTARROW(default,never) : String; @:require(flash10_1) static var KEYNAME_SCROLLLOCK(default,never) : String; @:require(flash10_1) static var KEYNAME_SELECT(default,never) : String; @:require(flash10_1) static var KEYNAME_STOP(default,never) : String; @:require(flash10_1) static var KEYNAME_SYSREQ(default,never) : String; @:require(flash10_1) static var KEYNAME_SYSTEM(default,never) : String; @:require(flash10_1) static var KEYNAME_UNDO(default,never) : String; @:require(flash10_1) static var KEYNAME_UPARROW(default,never) : String; @:require(flash10_1) static var KEYNAME_USER(default,never) : String; @:require(flash10_1) static var L(default,never) : UInt; @:require(flash10_2) static var LAST(default,never) : UInt; static var LEFT(default,never) : UInt; @:require(flash10_1) static var LEFTBRACKET(default,never) : UInt; @:require(flash10_2) static var LIVE(default,never) : UInt; @:require(flash10_1) static var M(default,never) : UInt; @:require(flash10_2) static var MASTER_SHELL(default,never) : UInt; @:require(flash10_2) static var MENU(default,never) : UInt; @:require(flash10_1) static var MINUS(default,never) : UInt; @:require(flash10_1) static var N(default,never) : UInt; @:require(flash10_2) static var NEXT(default,never) : UInt; @:require(flash10_1) static var NUMBER_0(default,never) : UInt; @:require(flash10_1) static var NUMBER_1(default,never) : UInt; @:require(flash10_1) static var NUMBER_2(default,never) : UInt; @:require(flash10_1) static var NUMBER_3(default,never) : UInt; @:require(flash10_1) static var NUMBER_4(default,never) : UInt; @:require(flash10_1) static var NUMBER_5(default,never) : UInt; @:require(flash10_1) static var NUMBER_6(default,never) : UInt; @:require(flash10_1) static var NUMBER_7(default,never) : UInt; @:require(flash10_1) static var NUMBER_8(default,never) : UInt; @:require(flash10_1) static var NUMBER_9(default,never) : UInt; @:require(flash10_1) static var NUMPAD(default,never) : UInt; static var NUMPAD_0(default,never) : UInt; static var NUMPAD_1(default,never) : UInt; static var NUMPAD_2(default,never) : UInt; static var NUMPAD_3(default,never) : UInt; static var NUMPAD_4(default,never) : UInt; static var NUMPAD_5(default,never) : UInt; static var NUMPAD_6(default,never) : UInt; static var NUMPAD_7(default,never) : UInt; static var NUMPAD_8(default,never) : UInt; static var NUMPAD_9(default,never) : UInt; static var NUMPAD_ADD(default,never) : UInt; static var NUMPAD_DECIMAL(default,never) : UInt; static var NUMPAD_DIVIDE(default,never) : UInt; static var NUMPAD_ENTER(default,never) : UInt; static var NUMPAD_MULTIPLY(default,never) : UInt; static var NUMPAD_SUBTRACT(default,never) : UInt; @:require(flash10_1) static var O(default,never) : UInt; @:require(flash10_1) static var P(default,never) : UInt; static var PAGE_DOWN(default,never) : UInt; static var PAGE_UP(default,never) : UInt; @:require(flash10_2) static var PAUSE(default,never) : UInt; @:require(flash10_1) static var PERIOD(default,never) : UInt; @:require(flash10_2) static var PLAY(default,never) : UInt; @:require(flash10_2) static var PREVIOUS(default,never) : UInt; @:require(flash10_1) static var Q(default,never) : UInt; @:require(flash10_1) static var QUOTE(default,never) : UInt; @:require(flash10_1) static var R(default,never) : UInt; @:require(flash10_2) static var RECORD(default,never) : UInt; @:require(flash10_2) static var RED(default,never) : UInt; @:require(flash10_2) static var REWIND(default,never) : UInt; static var RIGHT(default,never) : UInt; @:require(flash10_1) static var RIGHTBRACKET(default,never) : UInt; @:require(flash10_1) static var S(default,never) : UInt; @:require(flash10_2) static var SEARCH(default,never) : UInt; @:require(flash10_1) static var SEMICOLON(default,never) : UInt; @:require(flash10_2) static var SETUP(default,never) : UInt; static var SHIFT(default,never) : UInt; @:require(flash10_2) static var SKIP_BACKWARD(default,never) : UInt; @:require(flash10_2) static var SKIP_FORWARD(default,never) : UInt; @:require(flash10_1) static var SLASH(default,never) : UInt; static var SPACE(default,never) : UInt; @:require(flash10_2) static var STOP(default,never) : UInt; @:require(flash10_1) static var STRING_BEGIN(default,never) : String; @:require(flash10_1) static var STRING_BREAK(default,never) : String; @:require(flash10_1) static var STRING_CLEARDISPLAY(default,never) : String; @:require(flash10_1) static var STRING_CLEARLINE(default,never) : String; @:require(flash10_1) static var STRING_DELETE(default,never) : String; @:require(flash10_1) static var STRING_DELETECHAR(default,never) : String; @:require(flash10_1) static var STRING_DELETELINE(default,never) : String; @:require(flash10_1) static var STRING_DOWNARROW(default,never) : String; @:require(flash10_1) static var STRING_END(default,never) : String; @:require(flash10_1) static var STRING_EXECUTE(default,never) : String; @:require(flash10_1) static var STRING_F1(default,never) : String; @:require(flash10_1) static var STRING_F10(default,never) : String; @:require(flash10_1) static var STRING_F11(default,never) : String; @:require(flash10_1) static var STRING_F12(default,never) : String; @:require(flash10_1) static var STRING_F13(default,never) : String; @:require(flash10_1) static var STRING_F14(default,never) : String; @:require(flash10_1) static var STRING_F15(default,never) : String; @:require(flash10_1) static var STRING_F16(default,never) : String; @:require(flash10_1) static var STRING_F17(default,never) : String; @:require(flash10_1) static var STRING_F18(default,never) : String; @:require(flash10_1) static var STRING_F19(default,never) : String; @:require(flash10_1) static var STRING_F2(default,never) : String; @:require(flash10_1) static var STRING_F20(default,never) : String; @:require(flash10_1) static var STRING_F21(default,never) : String; @:require(flash10_1) static var STRING_F22(default,never) : String; @:require(flash10_1) static var STRING_F23(default,never) : String; @:require(flash10_1) static var STRING_F24(default,never) : String; @:require(flash10_1) static var STRING_F25(default,never) : String; @:require(flash10_1) static var STRING_F26(default,never) : String; @:require(flash10_1) static var STRING_F27(default,never) : String; @:require(flash10_1) static var STRING_F28(default,never) : String; @:require(flash10_1) static var STRING_F29(default,never) : String; @:require(flash10_1) static var STRING_F3(default,never) : String; @:require(flash10_1) static var STRING_F30(default,never) : String; @:require(flash10_1) static var STRING_F31(default,never) : String; @:require(flash10_1) static var STRING_F32(default,never) : String; @:require(flash10_1) static var STRING_F33(default,never) : String; @:require(flash10_1) static var STRING_F34(default,never) : String; @:require(flash10_1) static var STRING_F35(default,never) : String; @:require(flash10_1) static var STRING_F4(default,never) : String; @:require(flash10_1) static var STRING_F5(default,never) : String; @:require(flash10_1) static var STRING_F6(default,never) : String; @:require(flash10_1) static var STRING_F7(default,never) : String; @:require(flash10_1) static var STRING_F8(default,never) : String; @:require(flash10_1) static var STRING_F9(default,never) : String; @:require(flash10_1) static var STRING_FIND(default,never) : String; @:require(flash10_1) static var STRING_HELP(default,never) : String; @:require(flash10_1) static var STRING_HOME(default,never) : String; @:require(flash10_1) static var STRING_INSERT(default,never) : String; @:require(flash10_1) static var STRING_INSERTCHAR(default,never) : String; @:require(flash10_1) static var STRING_INSERTLINE(default,never) : String; @:require(flash10_1) static var STRING_LEFTARROW(default,never) : String; @:require(flash10_1) static var STRING_MENU(default,never) : String; @:require(flash10_1) static var STRING_MODESWITCH(default,never) : String; @:require(flash10_1) static var STRING_NEXT(default,never) : String; @:require(flash10_1) static var STRING_PAGEDOWN(default,never) : String; @:require(flash10_1) static var STRING_PAGEUP(default,never) : String; @:require(flash10_1) static var STRING_PAUSE(default,never) : String; @:require(flash10_1) static var STRING_PREV(default,never) : String; @:require(flash10_1) static var STRING_PRINT(default,never) : String; @:require(flash10_1) static var STRING_PRINTSCREEN(default,never) : String; @:require(flash10_1) static var STRING_REDO(default,never) : String; @:require(flash10_1) static var STRING_RESET(default,never) : String; @:require(flash10_1) static var STRING_RIGHTARROW(default,never) : String; @:require(flash10_1) static var STRING_SCROLLLOCK(default,never) : String; @:require(flash10_1) static var STRING_SELECT(default,never) : String; @:require(flash10_1) static var STRING_STOP(default,never) : String; @:require(flash10_1) static var STRING_SYSREQ(default,never) : String; @:require(flash10_1) static var STRING_SYSTEM(default,never) : String; @:require(flash10_1) static var STRING_UNDO(default,never) : String; @:require(flash10_1) static var STRING_UPARROW(default,never) : String; @:require(flash10_1) static var STRING_USER(default,never) : String; @:require(flash10_2) static var SUBTITLE(default,never) : UInt; @:require(flash10_1) static var T(default,never) : UInt; static var TAB(default,never) : UInt; @:require(flash10_1) static var U(default,never) : UInt; static var UP(default,never) : UInt; @:require(flash10_1) static var V(default,never) : UInt; @:require(flash10_2) static var VOD(default,never) : UInt; @:require(flash10_1) static var W(default,never) : UInt; @:require(flash10_1) static var X(default,never) : UInt; @:require(flash10_1) static var Y(default,never) : UInt; @:require(flash10_2) static var YELLOW(default,never) : UInt; @:require(flash10_1) static var Z(default,never) : UInt; static var capsLock(default,never) : Bool; @:require(flash10_1) static var hasVirtualKeyboard(default,never) : Bool; static var numLock(default,never) : Bool; @:require(flash10_1) static var physicalKeyboardType(default,never) : KeyboardType; static function isAccessible() : Bool; } haxe_3.4.4.orig/std/flash/ui/KeyboardType.hx0000664000175000017500000000014213166552354020660 0ustar andyandy00000000000000package flash.ui; @:fakeEnum(String) extern enum KeyboardType { ALPHANUMERIC; KEYPAD; NONE; } haxe_3.4.4.orig/std/flash/ui/Mouse.hx0000664000175000017500000000073713166552354017360 0ustar andyandy00000000000000package flash.ui; extern class Mouse { @:require(flash10) static var cursor : Dynamic; @:require(flash10_1) static var supportsCursor(default,never) : Bool; @:require(flash11) static var supportsNativeCursor(default,never) : Bool; static function hide() : Void; @:require(flash10_2) static function registerCursor(name : String, cursor : MouseCursorData) : Void; static function show() : Void; @:require(flash11) static function unregisterCursor(name : String) : Void; } haxe_3.4.4.orig/std/flash/ui/MouseCursor.hx0000664000175000017500000000040613166552354020547 0ustar andyandy00000000000000package flash.ui; extern class MouseCursor { static var ARROW(default,never) : String; static var AUTO(default,never) : String; static var BUTTON(default,never) : String; static var HAND(default,never) : String; static var IBEAM(default,never) : String; } haxe_3.4.4.orig/std/flash/ui/MouseCursorData.hx0000664000175000017500000000032613166552354021342 0ustar andyandy00000000000000package flash.ui; @:final @:require(flash10_2) extern class MouseCursorData { var data : flash.Vector; var frameRate : Float; var hotSpot : flash.geom.Point; function new() : Void; } haxe_3.4.4.orig/std/flash/ui/Multitouch.hx0000664000175000017500000000057313166552354020423 0ustar andyandy00000000000000package flash.ui; @:require(flash10_1) extern class Multitouch { static var inputMode : MultitouchInputMode; static var mapTouchToMouse : Bool; static var maxTouchPoints(default,never) : Int; static var supportedGestures(default,never) : flash.Vector; static var supportsGestureEvents(default,never) : Bool; static var supportsTouchEvents(default,never) : Bool; } haxe_3.4.4.orig/std/flash/ui/MultitouchInputMode.hx0000664000175000017500000000017613166552354022247 0ustar andyandy00000000000000package flash.ui; @:fakeEnum(String) @:require(flash10_1) extern enum MultitouchInputMode { GESTURE; NONE; TOUCH_POINT; } haxe_3.4.4.orig/std/flash/utils/ByteArray.hx0000664000175000017500000000376713166552354020723 0ustar andyandy00000000000000package flash.utils; extern class ByteArray implements IDataOutput2 implements IDataInput2 implements ArrayAccess { var bytesAvailable(default,never) : UInt; var endian : Endian; var length : UInt; var objectEncoding : UInt; var position : UInt; @:require(flash11_4) var shareable : Bool; function new() : Void; @:require(flash11_4) function atomicCompareAndSwapIntAt(byteIndex : Int, expectedValue : Int, newValue : Int) : Int; @:require(flash11_4) function atomicCompareAndSwapLength(expectedLength : Int, newLength : Int) : Int; @:require(flash10) function clear() : Void; function compress(?algorithm : CompressionAlgorithm) : Void; @:require(flash10) function deflate() : Void; @:require(flash10) function inflate() : Void; function readBoolean() : Bool; function readByte() : Int; function readBytes(bytes : ByteArray, offset : UInt = 0, length : UInt = 0) : Void; function readDouble() : Float; function readFloat() : Float; function readInt() : Int; function readMultiByte(length : UInt, charSet : String) : String; function readObject() : Dynamic; function readShort() : Int; function readUTF() : String; function readUTFBytes(length : UInt) : String; function readUnsignedByte() : UInt; function readUnsignedInt() : UInt; function readUnsignedShort() : UInt; function toString() : String; function uncompress(?algorithm : CompressionAlgorithm) : Void; function writeBoolean(value : Bool) : Void; function writeByte(value : Int) : Void; function writeBytes(bytes : ByteArray, offset : UInt = 0, length : UInt = 0) : Void; function writeDouble(value : Float) : Void; function writeFloat(value : Float) : Void; function writeInt(value : Int) : Void; function writeMultiByte(value : String, charSet : String) : Void; function writeObject(object : Dynamic) : Void; function writeShort(value : Int) : Void; function writeUTF(value : String) : Void; function writeUTFBytes(value : String) : Void; function writeUnsignedInt(value : UInt) : Void; static var defaultObjectEncoding : UInt; } haxe_3.4.4.orig/std/flash/utils/CompressionAlgorithm.hx0000664000175000017500000000017113166552354023153 0ustar andyandy00000000000000package flash.utils; @:fakeEnum(String) @:require(flash11) extern enum CompressionAlgorithm { DEFLATE; LZMA; ZLIB; } haxe_3.4.4.orig/std/flash/utils/Dictionary.hx0000664000175000017500000000020113166552354021102 0ustar andyandy00000000000000package flash.utils; extern class Dictionary implements ArrayAccess { function new(weakKeys : Bool = false) : Void; } haxe_3.4.4.orig/std/flash/utils/Endian.hx0000664000175000017500000000013513166552354020201 0ustar andyandy00000000000000package flash.utils; @:fakeEnum(String) extern enum Endian { BIG_ENDIAN; LITTLE_ENDIAN; } haxe_3.4.4.orig/std/flash/utils/Function.hx0000664000175000017500000000006113166552354020566 0ustar andyandy00000000000000package flash.utils; typedef Function = Dynamic haxe_3.4.4.orig/std/flash/utils/IDataInput.hx0000664000175000017500000000127513166552354021013 0ustar andyandy00000000000000package flash.utils; extern interface IDataInput { var bytesAvailable(default,never) : UInt; var endian : Endian; var objectEncoding : UInt; function readBoolean() : Bool; function readByte() : Int; function readBytes(bytes : ByteArray, offset : UInt = 0, length : UInt = 0) : Void; function readDouble() : Float; function readFloat() : Float; function readInt() : Int; function readMultiByte(length : UInt, charSet : String) : String; function readObject() : Dynamic; function readShort() : Int; function readUTF() : String; function readUTFBytes(length : UInt) : String; function readUnsignedByte() : UInt; function readUnsignedInt() : UInt; function readUnsignedShort() : UInt; } haxe_3.4.4.orig/std/flash/utils/IDataInput2.hx0000664000175000017500000000011213166552354021062 0ustar andyandy00000000000000package flash.utils; extern interface IDataInput2 extends IDataInput { } haxe_3.4.4.orig/std/flash/utils/IDataOutput.hx0000664000175000017500000000127713166552354021216 0ustar andyandy00000000000000package flash.utils; extern interface IDataOutput { var endian : Endian; var objectEncoding : UInt; function writeBoolean(value : Bool) : Void; function writeByte(value : Int) : Void; function writeBytes(bytes : ByteArray, offset : UInt = 0, length : UInt = 0) : Void; function writeDouble(value : Float) : Void; function writeFloat(value : Float) : Void; function writeInt(value : Int) : Void; function writeMultiByte(value : String, charSet : String) : Void; function writeObject(object : Dynamic) : Void; function writeShort(value : Int) : Void; function writeUTF(value : String) : Void; function writeUTFBytes(value : String) : Void; function writeUnsignedInt(value : UInt) : Void; } haxe_3.4.4.orig/std/flash/utils/IDataOutput2.hx0000664000175000017500000000011413166552354021265 0ustar andyandy00000000000000package flash.utils; extern interface IDataOutput2 extends IDataOutput { } haxe_3.4.4.orig/std/flash/utils/IExternalizable.hx0000664000175000017500000000024413166552354022066 0ustar andyandy00000000000000package flash.utils; extern interface IExternalizable { function readExternal(input : IDataInput) : Void; function writeExternal(output : IDataOutput) : Void; } haxe_3.4.4.orig/std/flash/utils/JSON.hx0000664000175000017500000000036213166552354017556 0ustar andyandy00000000000000package flash.utils; @:native("JSON") @:require(flash11) extern class JSON { static function parse(text : String, ?reviver : Dynamic) : Dynamic; static function stringify(value : Dynamic, ?replacer : Dynamic, ?space : Dynamic) : String; } haxe_3.4.4.orig/std/flash/utils/Namespace.hx0000664000175000017500000000027213166552354020701 0ustar andyandy00000000000000package flash.utils; @:final extern class Namespace { var prefix(default,never) : Dynamic; var uri(default,never) : String; function new(?prefix : Dynamic, ?uri : Dynamic) : Void; } haxe_3.4.4.orig/std/flash/utils/Object.hx0000664000175000017500000000005713166552354020214 0ustar andyandy00000000000000package flash.utils; typedef Object = Dynamic haxe_3.4.4.orig/std/flash/utils/ObjectInput.hx0000664000175000017500000000135013166552354021231 0ustar andyandy00000000000000package flash.utils; extern class ObjectInput implements IDataInput { var bytesAvailable(default,never) : UInt; var endian : Endian; var objectEncoding : UInt; function new() : Void; function readBoolean() : Bool; function readByte() : Int; function readBytes(bytes : ByteArray, offset : UInt = 0, length : UInt = 0) : Void; function readDouble() : Float; function readFloat() : Float; function readInt() : Int; function readMultiByte(length : UInt, charSet : String) : String; function readObject() : Dynamic; function readShort() : Int; function readUTF() : String; function readUTFBytes(length : UInt) : String; function readUnsignedByte() : UInt; function readUnsignedInt() : UInt; function readUnsignedShort() : UInt; } haxe_3.4.4.orig/std/flash/utils/ObjectOutput.hx0000664000175000017500000000135313166552354021435 0ustar andyandy00000000000000package flash.utils; extern class ObjectOutput implements IDataOutput { var endian : Endian; var objectEncoding : UInt; function new() : Void; function writeBoolean(value : Bool) : Void; function writeByte(value : Int) : Void; function writeBytes(bytes : ByteArray, offset : UInt = 0, length : UInt = 0) : Void; function writeDouble(value : Float) : Void; function writeFloat(value : Float) : Void; function writeInt(value : Int) : Void; function writeMultiByte(value : String, charSet : String) : Void; function writeObject(object : Dynamic) : Void; function writeShort(value : Int) : Void; function writeUTF(value : String) : Void; function writeUTFBytes(value : String) : Void; function writeUnsignedInt(value : UInt) : Void; } haxe_3.4.4.orig/std/flash/utils/Proxy.hx0000664000175000017500000000230313166552354020123 0ustar andyandy00000000000000package flash.utils; extern class Proxy { function new() : Void; @:ns("http://www.adobe.com/2006/actionscript/flash/proxy") function callProperty(name : Dynamic, ?p1 : Dynamic, ?p2 : Dynamic, ?p3 : Dynamic, ?p4 : Dynamic, ?p5 : Dynamic) : Dynamic; @:ns("http://www.adobe.com/2006/actionscript/flash/proxy") function deleteProperty(name : Dynamic) : Bool; @:ns("http://www.adobe.com/2006/actionscript/flash/proxy") function getDescendants(name : Dynamic) : Dynamic; @:ns("http://www.adobe.com/2006/actionscript/flash/proxy") function getProperty(name : Dynamic) : Dynamic; @:ns("http://www.adobe.com/2006/actionscript/flash/proxy") function hasProperty(name : Dynamic) : Bool; @:ns("http://www.adobe.com/2006/actionscript/flash/proxy") function isAttribute(name : Dynamic) : Bool; @:ns("http://www.adobe.com/2006/actionscript/flash/proxy") function nextName(index : Int) : String; @:ns("http://www.adobe.com/2006/actionscript/flash/proxy") function nextNameIndex(index : Int) : Int; @:ns("http://www.adobe.com/2006/actionscript/flash/proxy") function nextValue(index : Int) : Dynamic; @:ns("http://www.adobe.com/2006/actionscript/flash/proxy") function setProperty(name : Dynamic, value : Dynamic) : Void; } haxe_3.4.4.orig/std/flash/utils/QName.hx0000664000175000017500000000027513166552354020011 0ustar andyandy00000000000000package flash.utils; @:final extern class QName { var localName(default,never) : String; var uri(default,never) : Dynamic; function new(?namespace : Dynamic, ?name : Dynamic) : Void; } haxe_3.4.4.orig/std/flash/utils/RegExp.hx0000664000175000017500000000110513166552354020173 0ustar andyandy00000000000000package flash.utils; @:realPath("flash.utils.RegExp") @:native("RegExp") extern class RegExp implements Dynamic { var dotall(default,never) : Bool; var extended(default,never) : Bool; var global(default,never) : Bool; var ignoreCase(default,never) : Bool; var lastIndex : Int; var multiline(default,never) : Bool; var source(default,never) : String; function new(?pattern : Dynamic, ?options : Dynamic) : Void; @:ns("http://adobe.com/AS3/2006/builtin") function exec(?s : String) : Dynamic; @:ns("http://adobe.com/AS3/2006/builtin") function test(?s : String) : Bool; } haxe_3.4.4.orig/std/flash/utils/SetIntervalTimer.hx0000664000175000017500000000037013166552354022245 0ustar andyandy00000000000000package flash.utils; @:final extern class SetIntervalTimer extends Timer { var id : UInt; function new(closure : Dynamic, delay : Float, repeats : Bool, rest : Array) : Void; static function clearInterval(id_to_clear : UInt) : Void; } haxe_3.4.4.orig/std/flash/utils/Telemetry.hx0000664000175000017500000000103613166552354020756 0ustar andyandy00000000000000package flash.utils; @:require(flash11_4) @:native("flash.profiler.Telemetry") extern class Telemetry extends flash.events.EventDispatcher { static var connected(default,null) : Bool; static var spanMarker(default,null) : Float; static function registerCommandHandler(commandName : String, handler : Dynamic) : Bool; static function unregisterCommandHandler(commandName : String) : Bool; static function sendMetric(metric : String, value : Dynamic) : Void; static function sendSpanMetric(metric : String, startMarker : Float) : Void; }haxe_3.4.4.orig/std/flash/utils/Timer.hx0000664000175000017500000000052313166552354020064 0ustar andyandy00000000000000package flash.utils; extern class Timer extends flash.events.EventDispatcher { var currentCount(default,never) : Int; var delay : Float; var repeatCount : Int; var running(default,never) : Bool; function new(delay : Float, repeatCount : Int = 0) : Void; function reset() : Void; function start() : Void; function stop() : Void; } haxe_3.4.4.orig/std/flash/xml/XML.hx0000664000175000017500000000422413166552354017106 0ustar andyandy00000000000000package flash.xml; @:final extern class XML implements Dynamic { function new(?value : Dynamic) : Void; function addNamespace(ns : Dynamic) : XML; function appendChild(child : Dynamic) : XML; function attribute(arg : Dynamic) : XMLList; function attributes() : XMLList; function child(propertyName : Dynamic) : XMLList; function childIndex() : Int; function children() : XMLList; function comments() : XMLList; function contains(value : Dynamic) : Bool; function copy() : XML; function descendants(?name : Dynamic) : XMLList; function elements(?name : Dynamic) : XMLList; function hasComplexContent() : Bool; function hasSimpleContent() : Bool; function inScopeNamespaces() : Array; function insertChildAfter(child1 : Dynamic, child2 : Dynamic) : Dynamic; function insertChildBefore(child1 : Dynamic, child2 : Dynamic) : Dynamic; function length() : Int; function localName() : flash.utils.Object; function name() : flash.utils.Object; function namespace(?prefix : Dynamic) : flash.utils.Namespace; function namespaceDeclarations() : Array; function nodeKind() : String; function normalize() : XML; function notification() : flash.utils.Function; function parent() : XML; function prependChild(value : Dynamic) : XML; function processingInstructions(?name : Dynamic) : XMLList; function removeNamespace(ns : Dynamic) : XML; function replace(propertyName : Dynamic, value : Dynamic) : XML; function setChildren(value : Dynamic) : XML; function setLocalName(name : Dynamic) : Void; function setName(name : Dynamic) : Void; function setNamespace(ns : Dynamic) : Void; function setNotification(f : flash.utils.Function) : Dynamic; function text() : XMLList; @:require(flash11) function toJSON(k : String) : Dynamic; function toString() : String; function toXMLString() : String; function valueOf() : XML; static var ignoreComments : Bool; static var ignoreProcessingInstructions : Bool; static var ignoreWhitespace : Bool; static var prettyIndent : Int; static var prettyPrinting : Bool; static function defaultSettings() : Dynamic; static function setSettings(?o : Dynamic) : Void; static function settings() : Dynamic; } haxe_3.4.4.orig/std/flash/xml/XMLDocument.hx0000664000175000017500000000053513166552354020606 0ustar andyandy00000000000000package flash.xml; extern class XMLDocument extends XMLNode { var docTypeDecl : Dynamic; var idMap : Dynamic; var ignoreWhite : Bool; var xmlDecl : Dynamic; function new(?source : String) : Void; function createElement(name : String) : XMLNode; function createTextNode(text : String) : XMLNode; function parseXML(source : String) : Void; } haxe_3.4.4.orig/std/flash/xml/XMLList.hx0000664000175000017500000000336013166552354017742 0ustar andyandy00000000000000package flash.xml; @:final extern class XMLList implements ArrayAccess { function new(?value : Dynamic) : Void; function addNamespace(ns : Dynamic) : XML; function appendChild(child : Dynamic) : XML; function attribute(arg : Dynamic) : XMLList; function attributes() : XMLList; function child(propertyName : Dynamic) : XMLList; function childIndex() : Int; function children() : XMLList; function comments() : XMLList; function contains(value : Dynamic) : Bool; function copy() : XMLList; function descendants(?name : Dynamic) : XMLList; function elements(?name : Dynamic) : XMLList; function hasComplexContent() : Bool; function hasSimpleContent() : Bool; function inScopeNamespaces() : Array; function insertChildAfter(child1 : Dynamic, child2 : Dynamic) : Dynamic; function insertChildBefore(child1 : Dynamic, child2 : Dynamic) : Dynamic; function length() : Int; function localName() : flash.utils.Object; function name() : flash.utils.Object; function namespace(?prefix : Dynamic) : flash.utils.Namespace; function namespaceDeclarations() : Array; function nodeKind() : String; function normalize() : XMLList; function parent() : XML; function prependChild(value : Dynamic) : XML; function processingInstructions(?name : Dynamic) : XMLList; function removeNamespace(ns : Dynamic) : XML; function replace(propertyName : Dynamic, value : Dynamic) : XML; function setChildren(value : Dynamic) : XML; function setLocalName(name : Dynamic) : Void; function setName(name : Dynamic) : Void; function setNamespace(ns : Dynamic) : Void; function text() : XMLList; @:require(flash11) function toJSON(k : String) : Dynamic; function toString() : String; function toXMLString() : String; function valueOf() : XMLList; } haxe_3.4.4.orig/std/flash/xml/XMLNode.hx0000664000175000017500000000156213166552354017716 0ustar andyandy00000000000000package flash.xml; extern class XMLNode { var attributes : Dynamic; var childNodes(default,never) : Array; var firstChild : XMLNode; var lastChild : XMLNode; var localName(default,never) : String; var namespaceURI(default,never) : String; var nextSibling : XMLNode; var nodeName : String; var nodeType : XMLNodeType; var nodeValue : String; var parentNode : XMLNode; var prefix(default,never) : String; var previousSibling : XMLNode; function new(type : XMLNodeType, value : String) : Void; function appendChild(node : XMLNode) : Void; function cloneNode(deep : Bool) : XMLNode; function getNamespaceForPrefix(prefix : String) : String; function getPrefixForNamespace(ns : String) : String; function hasChildNodes() : Bool; function insertBefore(node : XMLNode, before : XMLNode) : Void; function removeNode() : Void; function toString() : String; } haxe_3.4.4.orig/std/flash/xml/XMLNodeType.hx0000664000175000017500000000027513166552354020560 0ustar andyandy00000000000000package flash.xml; @:fakeEnum(UInt) extern enum XMLNodeType { CDATA_NODE; COMMENT_NODE; DOCUMENT_TYPE_NODE; ELEMENT_NODE; PROCESSING_INSTRUCTION_NODE; TEXT_NODE; XML_DECLARATION; } haxe_3.4.4.orig/std/flash/xml/XMLParser.hx0000664000175000017500000000027013166552354020260 0ustar andyandy00000000000000package flash.xml; @:final extern class XMLParser { function new() : Void; function getNext(tag : XMLTag) : Int; function startParse(source : String, ignoreWhite : Bool) : Void; } haxe_3.4.4.orig/std/flash/xml/XMLTag.hx0000664000175000017500000000024313166552354017537 0ustar andyandy00000000000000package flash.xml; @:final extern class XMLTag { var attrs : Dynamic; var empty : Bool; var type : XMLNodeType; var value : String; function new() : Void; } haxe_3.4.4.orig/std/haxe/CallStack.hx0000664000175000017500000002602413166552354017341 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** Elements return by `CallStack` methods. **/ enum StackItem { CFunction; Module( m : String ); FilePos( s : Null, file : String, line : Int ); Method( classname : String, method : String ); LocalFunction( ?v : Int ); } /** Get information about the call stack. **/ class CallStack { #if js static var lastException:js.Error; static function getStack(e:js.Error):Array { if (e == null) return []; // https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi var oldValue = (untyped Error).prepareStackTrace; (untyped Error).prepareStackTrace = function (error, callsites :Array) { var stack = []; for (site in callsites) { if (wrapCallSite != null) site = wrapCallSite(site); var method = null; var fullName :String = site.getFunctionName(); if (fullName != null) { var idx = fullName.lastIndexOf("."); if (idx >= 0) { var className = fullName.substr(0, idx); var methodName = fullName.substr(idx+1); method = Method(className, methodName); } } stack.push(FilePos(method, site.getFileName(), site.getLineNumber())); } return stack; } var a = makeStack(e.stack); (untyped Error).prepareStackTrace = oldValue; return a; } // support for source-map-support module @:noCompletion public static var wrapCallSite:Dynamic->Dynamic; #end /** Return the call stack elements, or an empty array if not available. **/ public static function callStack() : Array { #if neko var a = makeStack(untyped __dollar__callstack()); a.shift(); // remove Stack.callStack() return a; #elseif flash var a = makeStack( new flash.errors.Error().getStackTrace() ); a.shift(); // remove Stack.callStack() return a; #elseif php return makeStack("%s"); #elseif cpp var s:Array = untyped __global__.__hxcpp_get_call_stack(true); return makeStack(s); #elseif js try { throw new js.Error(); } catch( e : Dynamic ) { var a = getStack(e); a.shift(); // remove Stack.callStack() return a; } #elseif java var stack = []; for ( el in java.lang.Thread.currentThread().getStackTrace() ) { var className = el.getClassName(); var methodName = el.getMethodName(); var fileName = el.getFileName(); var lineNumber = el.getLineNumber(); var method = Method( className, methodName ); if ( fileName != null || lineNumber >= 0 ) { stack.push( FilePos( method, fileName, lineNumber ) ); } else { stack.push( method ); } } stack.shift(); stack.shift(); stack.pop(); return stack; #elseif cs return makeStack(new cs.system.diagnostics.StackTrace(1, true)); #elseif python var stack = []; var infos = python.lib.Traceback.extract_stack(); infos.pop(); infos.reverse(); for (elem in infos) stack.push(FilePos(null, elem._1, elem._2)); return stack; #elseif lua var stack = []; var infos = lua.Debug.traceback(); var luastack = infos.split("\n").slice(2,-1); for (s in luastack){ var parts = s.split(":"); var file = parts[0]; var line = parts[1]; // TODO: Give more information for FilePos stack.push(FilePos(null, file, Std.parseInt(line))); } return stack; #elseif hl try { throw null; } catch( e : Dynamic ) { var st = _getExceptionStack(); return makeStack(st.length > 2 ? st.sub(2,st.length - 2) : st); } #else return []; // Unsupported #end } #if hl @:hlNative("std", "exception_stack") static function _getExceptionStack() : hl.NativeArray { return null; } #end /** Return the exception stack : this is the stack elements between the place the last exception was thrown and the place it was caught, or an empty array if not available. **/ #if cpp @:noDebug #end /* Do not mess up the exception stack */ public static function exceptionStack() : Array { #if neko return makeStack(untyped __dollar__excstack()); #elseif as3 return new Array(); #elseif hl return makeStack(_getExceptionStack()); #elseif flash var err : flash.errors.Error = untyped flash.Boot.lastError; if( err == null ) return new Array(); var a = makeStack( err.getStackTrace() ); var c = callStack(); var i = c.length - 1; while( i > 0 ) { if( Std.string(a[a.length-1]) == Std.string(c[i]) ) a.pop(); else break; i--; } return a; #elseif php return makeStack("%e"); #elseif cpp var s:Array = untyped __global__.__hxcpp_get_exception_stack(); return makeStack(s); #elseif java var stack = []; for ( el in java.internal.Exceptions.currentException().getStackTrace() ) { var className = el.getClassName(); var methodName = el.getMethodName(); var fileName = el.getFileName(); var lineNumber = el.getLineNumber(); var method = Method( className, methodName ); if ( fileName != null || lineNumber >= 0 ) { stack.push( FilePos( method, fileName, lineNumber ) ); } else { stack.push( method ); } } // stack.shift(); stack.shift(); stack.pop(); return stack; #elseif cs return makeStack(new cs.system.diagnostics.StackTrace(cs.internal.Exceptions.exception, true)); #elseif python var stack = []; var exc = python.lib.Sys.exc_info(); if (exc._3 != null) { var infos = python.lib.Traceback.extract_tb(exc._3); infos.reverse(); for (elem in infos) stack.push(FilePos(null, elem._1, elem._2)); } return stack; #elseif js return untyped __define_feature__("haxe.CallStack.exceptionStack", getStack(lastException)); #else return []; // Unsupported #end } /** Returns a representation of the stack as a printable string. **/ public static function toString( stack : Array ) { var b = new StringBuf(); for( s in stack ) { b.add("\nCalled from "); itemToString(b,s); } return b.toString(); } private static function itemToString( b : StringBuf, s ) { switch( s ) { case CFunction: b.add("a C function"); case Module(m): b.add("module "); b.add(m); case FilePos(s,file,line): if( s != null ) { itemToString(b,s); b.add(" ("); } b.add(file); b.add(" line "); b.add(line); if( s != null ) b.add(")"); case Method(cname,meth): b.add(cname); b.add("."); b.add(meth); case LocalFunction(n): b.add("local function #"); b.add(n); } } #if cpp @:noDebug #end /* Do not mess up the exception stack */ private static function makeStack(s #if cs : cs.system.diagnostics.StackTrace #elseif hl : hl.NativeArray #end) { #if neko var a = new Array(); var l = untyped __dollar__asize(s); var i = 0; while( i < l ) { var x = s[i++]; if( x == null ) a.unshift(CFunction); else if( untyped __dollar__typeof(x) == __dollar__tstring ) a.unshift(Module(new String(x))); else a.unshift(FilePos(null,new String(untyped x[0]),untyped x[1])); } return a; #elseif flash var a = new Array(); var r = ~/at ([^\/]+?)\$?(\/[^\(]+)?\(\)(\[(.*?):([0-9]+)\])?/; var rlambda = ~/^MethodInfo-([0-9]+)$/g; while( r.match(s) ) { var cl = r.matched(1).split("::").join("."); var meth = r.matched(2); var item; if( meth == null ) { if( rlambda.match(cl) ) item = LocalFunction(Std.parseInt(rlambda.matched(1))); else item = Method(cl,"new"); } else item = Method(cl,meth.substr(1)); if( r.matched(3) != null ) item = FilePos( item, r.matched(4), Std.parseInt(r.matched(5)) ); a.push(item); s = r.matchedRight(); } return a; #elseif php if (!untyped __call__("isset", __var__("GLOBALS", s))) return []; var a : Array = untyped __var__("GLOBALS", s); var m = []; for( i in 0...a.length - ((s == "%s") ? 2 : 0)) { var d = a[i].split("::"); m.unshift(Method(d[0],d[1])); } return m; #elseif cpp var stack : Array = s; var m = new Array(); for(func in stack) { var words = func.split("::"); if (words.length==0) m.push(CFunction) else if (words.length==2) m.push(Method(words[0],words[1])); else if (words.length==4) m.push(FilePos( Method(words[0],words[1]),words[2],Std.parseInt(words[3]))); } return m; #elseif js if (s == null) { return []; } else if ((untyped __js__("typeof"))(s) == "string") { // Return the raw lines in browsers that don't support prepareStackTrace var stack : Array = s.split("\n"); if( stack[0] == "Error" ) stack.shift(); var m = []; var rie10 = ~/^ at ([A-Za-z0-9_. ]+) \(([^)]+):([0-9]+):([0-9]+)\)$/; for( line in stack ) { if( rie10.match(line) ) { var path = rie10.matched(1).split("."); var meth = path.pop(); var file = rie10.matched(2); var line = Std.parseInt(rie10.matched(3)); m.push(FilePos( meth == "Anonymous function" ? LocalFunction() : meth == "Global code" ? null : Method(path.join("."),meth), file, line )); } else m.push(Module(StringTools.trim(line))); // A little weird, but better than nothing } return m; } else { return cast s; } #elseif cs var stack = []; for (i in 0...s.FrameCount) { var frame = s.GetFrame(i); var m = frame.GetMethod(); if (m == null) { continue; } var method = StackItem.Method(m.ReflectedType.ToString(), m.Name); var fileName = frame.GetFileName(); var lineNumber = frame.GetFileLineNumber(); if (fileName != null || lineNumber >= 0) stack.push(FilePos(method, fileName, lineNumber)); else stack.push(method); } return stack; #elseif hl var stack = []; var r = ~/^([A-Za-z0-9.$_]+)\.([A-Za-z0-9_]+)\((.+):([0-9]+)\)$/; for( i in 0...s.length-1 ) { var str = @:privateAccess String.fromUCS2(s[i]); if( r.match(str) ) stack.push(FilePos(Method(r.matched(1), r.matched(2)), r.matched(3), Std.parseInt(r.matched(4)))); else stack.push(Module(str)); } return stack; #else return null; #end } } haxe_3.4.4.orig/std/haxe/Constraints.hx0000664000175000017500000000452513166552354020011 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** This type unifies with any function type. It is intended to be used as a type parameter constraint. If used as a real type, the underlying type will be `Dynamic`. **/ @:callable abstract Function(Dynamic) { } /** This type unifies with an enum instance if all constructors of the enum require no arguments. It is intended to be used as a type parameter constraint. If used as a real type, the underlying type will be `Dynamic`. **/ abstract FlatEnum(Dynamic) { } /** This type unifies with any instance of classes that have a constructor which * is public and * unifies with the type used for type parameter `T`. If a type parameter A is assigned to a type parameter B which is constrained to `Constructible`, A must be explicitly constrained to `Constructible` as well. It is intended to be used as a type parameter constraint. If used as a real type, the underlying type will be `Dynamic`. **/ abstract Constructible(Dynamic) { } interface IMap { public function get(k:K):Null; public function set(k:K, v:V):Void; public function exists(k:K):Bool; public function remove(k:K):Bool; public function keys():Iterator; public function iterator():Iterator; public function toString():String; }haxe_3.4.4.orig/std/haxe/DynamicAccess.hx0000664000175000017500000000556013166552354020210 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** DynamicAccess is an abstract type for working with anonymous structures that are intended to hold collections of objects by the string key. For example, these types of structures are often created from JSON. Basically, it wraps `Reflect` calls in a `Map`-like interface. **/ abstract DynamicAccess(Dynamic) from Dynamic to Dynamic { /** Creates a new structure. **/ public inline function new() this = {}; /** Returns a value by specified `key`. If the structure does not contain the given key, null is returned. If `key` is null, the result is unspecified. **/ @:arrayAccess public inline function get(key:String):Null { #if js return untyped this[key]; // we know it's an object, so we don't need a check #else return Reflect.field(this, key); #end } /** Sets a `value` for a specified `key`. If the structure contains the given key, its value will be overwritten. Returns the given value. If `key` is null, the result is unspecified. **/ @:arrayAccess public inline function set(key:String, value:T):T { #if js return untyped this[key] = value; #else Reflect.setField(this, key, value); return value; #end } /** Tells if the structure contains a specified `key`. If `key` is null, the result is unspecified. **/ public inline function exists(key:String):Bool return Reflect.hasField(this, key); /** Removes a specified `key` from the structure. Returns true, if `key` was present in structure, or false otherwise. If `key` is null, the result is unspecified. **/ public inline function remove(key:String):Bool return Reflect.deleteField(this, key); /** Returns an array of `keys` in a structure. **/ public inline function keys():Array return Reflect.fields(this); } haxe_3.4.4.orig/std/haxe/EntryPoint.hx0000664000175000017500000000565713166552354017624 0ustar andyandy00000000000000package haxe; #if (neko && !macro && !interp) import neko.vm.Lock; import neko.vm.Mutex; import neko.vm.Thread; #elseif cpp import cpp.vm.Lock; import cpp.vm.Mutex; import cpp.vm.Thread; #elseif java import java.vm.Lock; import java.vm.Mutex; import java.vm.Thread; #elseif sys private class Lock { public function new() { } public inline function release() { } public inline function wait( ?t : Float ) { } } private class Mutex { public function new() { } public inline function acquire() { } public inline function release() { } } private class Thread { public static function create( f : Void -> Void ) { f(); } } #end /** If haxe.MainLoop is kept from DCE, then we will insert an haxe.EntryPoint.run() call just at then end of main(). This class can be redefined by custom frameworks so they can handle their own main loop logic. **/ class EntryPoint { #if sys static var sleepLock = new Lock(); static var mutex = new Mutex(); #end static var pending = new ArrayVoid>(); public static var threadCount(default,null) : Int = 0; /** Wakeup a sleeping run() **/ public static function wakeup() { #if sys sleepLock.release(); #end } public static function runInMainThread( f : Void -> Void ) { #if sys mutex.acquire(); pending.push(f); mutex.release(); wakeup(); #else pending.push(f); #end } public static function addThread( f : Void -> Void ) { #if sys mutex.acquire(); threadCount++; mutex.release(); Thread.create(function() { f(); mutex.acquire(); threadCount--; if( threadCount == 0 ) wakeup(); mutex.release(); }); #else threadCount++; pending.push(function() { f(); threadCount--; } ); #end } static function processEvents() : Float { // flush all pending calls while( true ) { #if sys mutex.acquire(); var f = pending.shift(); mutex.release(); #else var f = pending.shift(); #end if( f == null ) break; f(); } if( !MainLoop.hasEvents() && threadCount == 0 ) return -1; return @:privateAccess MainLoop.tick(); } /** Start the main loop. Depending on the platform, this can return immediately or will only return when the application exits. **/ @:keep public static function run() @:privateAccess { #if js var nextTick = processEvents(); #if nodejs if( nextTick < 0 ) return; (untyped setTimeout)(run,nextTick); #else var window : Dynamic = js.Browser.window; var rqf : Dynamic = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame; rqf(run); #end #elseif flash flash.Lib.current.stage.addEventListener(flash.events.Event.ENTER_FRAME, function(_) processEvents()); #elseif sys while( true ) { var nextTick = processEvents(); if( nextTick < 0 ) break; if( nextTick > 0 ) sleepLock.wait(nextTick); // wait until nextTick or wakeup() call } #else // no implementation available, let's exit immediately #end } } haxe_3.4.4.orig/std/haxe/EnumFlags.hx0000664000175000017500000000572713166552354017370 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** A typed interface for bit flags. This is not a real object, only a typed interface for an actual Int. Each flag can be tested/set with the corresponding enum instance. Up to 32 flags can be stored that way. Enum constructor indices are preserved from Haxe syntax, so the first declared is index 0, the next index 1 etc. The methods are optimized if the enum instance is passed directly, e.g. as has(EnumCtor). Otherwise Type.enumIndex() reflection is used. **/ abstract EnumFlags(Int) { /** Initializes the bitflags to `i`. **/ public inline function new(i = 0) { this = i; } /** Checks if the index of enum instance `v` is set. This method is optimized if `v` is an enum instance expression such as SomeEnum.SomeCtor. If `v` is null, the result is unspecified. **/ public inline function has( v : T ) : Bool { return this & (1 << Type.enumIndex(v)) != 0; } /** Sets the index of enum instance `v`. This method is optimized if `v` is an enum instance expression such as SomeEnum.SomeCtor. If `v` is null, the result is unspecified. **/ public inline function set( v : T ) : Void { this |= 1 << Type.enumIndex(v); } /** Unsets the index of enum instance `v`. This method is optimized if `v` is an enum instance expression such as SomeEnum.SomeCtor. If `v` is null, the result is unspecified. **/ public inline function unset( v : T ) : Void { this &= 0xFFFFFFFF - (1 << Type.enumIndex(v)); } /** Convert a integer bitflag into a typed one (this is a no-op, it does not have any impact on speed). **/ public inline static function ofInt( i : Int ) : EnumFlags { return new EnumFlags(i); } /** Convert the typed bitflag into the corresponding int value (this is a no-op, it doesn't have any impact on speed). **/ public inline function toInt() : Int { return this; } } haxe_3.4.4.orig/std/haxe/EnumTools.hx0000664000175000017500000001420113166552354017417 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** This class provides advanced methods on enums. It is ideally used with `using EnumTools` and then acts as an [extension](https://haxe.org/manual/lf-static-extension.html) to the `enum` types. If the first argument to any of the methods is null, the result is unspecified. **/ extern class EnumTools { /** Returns the name of enum `e`, including its path. If `e` is inside a package, the package structure is returned dot- separated, with another dot separating the enum name: pack1.pack2.(...).packN.EnumName If `e` is a sub-type of a Haxe module, that module is not part of the package structure. If `e` has no package, the enum name is returned. If `e` is `null`, the result is unspecified. The enum name does not include any type parameters. **/ static public inline function getName(e:Enum):String { return Type.getEnumName(e); } /** Creates an instance of enum `e` by calling its constructor `constr` with arguments `params`. If `e` or `constr` is `null`, or if enum `e` has no constructor named `constr`, or if the number of elements in `params` does not match the expected number of constructor arguments, or if any argument has an invalid type, the result is unspecified. **/ static public inline function createByName(e:Enum, constr:String, ?params:Array):T { return Type.createEnum(e, constr, params); } /** Creates an instance of enum `e` by calling its constructor number `index` with arguments `params`. The constructor indices are preserved from Haxe syntax, so the first declared is index 0, the next index 1 etc. If `e` or `index` is `null`, or if enum `e` has no constructor corresponding to index `index`, or if the number of elements in `params` does not match the expected number of constructor arguments, or if any argument has an invalid type, the result is unspecified. **/ static public inline function createByIndex(e:Enum, index:Int, ?params:Array):T { return Type.createEnumIndex(e, index, params); } /** Returns a list of all constructors of enum `e` that require no arguments. This may return the empty Array `[]` if all constructors of `e` require arguments. Otherwise an instance of `e` constructed through each of its non- argument constructors is returned, in the order of the constructor declaration. If `e` is `null`, the result is unspecified. **/ static public inline function createAll(e:Enum):Array { return Type.allEnums(e); } /** Returns a list of the names of all constructors of enum `e`. The order of the constructor names in the returned Array is preserved from the original syntax. If `c` is `null`, the result is unspecified. **/ static public inline function getConstructors(e:Enum):Array { return Type.getEnumConstructs(e); } } /** This class provides advanced methods on enum values. It is ideally used with `using EnumValueTools` and then acts as an [extension](https://haxe.org/manual/lf-static-extension.html) to the `EnumValue` types. If the first argument to any of the methods is null, the result is unspecified. **/ extern class EnumValueTools { /** Recursively compares two enum instances `a` and `b` by value. Unlike `a == b`, this function performs a deep equality check on the arguments of the constructors (if there are any). If `a` or `b` are `null`, the result is unspecified. **/ static public inline function equals(a:T, b:T):Bool { return Type.enumEq(a, b); } /** Returns the constructor name of enum instance `e`. The result String does not contain any constructor arguments. If `e` is `null`, the result is unspecified. **/ static public inline function getName(e:EnumValue):String { return Type.enumConstructor(e); } /** Returns a list of the constructor arguments of enum instance `e`. If `e` has no arguments, the result is `[]`. Otherwise the result are the values that were used as arguments to `e`, in the order of their declaration. If `e` is `null`, the result is unspecified. **/ static public inline function getParameters(e:EnumValue):Array { return Type.enumParameters(e); } /** Returns the index of enum instance `e`. This corresponds to the original syntactic position of `e`. The index of the first declared constructor is 0, the next one is 1 etc. If `e` is `null`, the result is unspecified. **/ static public inline function getIndex(e:EnumValue):Int { return Type.enumIndex(e); } /** Matches enum instance `e` against pattern `pattern`, returning `true` if matching succeeded and `false` otherwise. Example usage: ```haxe if (e.match(pattern)) { // codeIfTrue } else { // codeIfFalse } ``` This is equivalent to the following code: ```haxe switch (e) { case pattern: // codeIfTrue case _: // codeIfFalse } ``` This method is implemented in the compiler. This definition exists only for documentation. **/ static public function match(e:EnumValue, pattern:Dynamic):Bool { return false; } } haxe_3.4.4.orig/std/haxe/Http.hx0000664000175000017500000005342313166552354016422 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; #if sys import sys.net.Host; import sys.net.Socket; #end /** This class can be used to handle Http requests consistently across platforms. There are two intended usages: - call `haxe.Http.requestUrl(url)` and receive the result as a `String` (not available on flash) - create a `new haxe.Http(url)`, register your callbacks for `onData`, `onError` and `onStatus`, then call `request()`. **/ class Http { /** The url of `this` request. It is used only by the `request()` method and can be changed in order to send the same request to different target Urls. **/ public var url : String; public var responseData(default, null) : Null; #if sys public var noShutdown : Bool; public var cnxTimeout : Float; public var responseHeaders : Map; var chunk_size : Null; var chunk_buf : haxe.io.Bytes; var file : { param : String, filename : String, io : haxe.io.Input, size : Int, mimeType : String }; #elseif (js && !nodejs) public var async : Bool; public var withCredentials : Bool; #end var postData : String; var headers : List<{ header:String, value:String }>; var params : List<{ param:String, value:String }>; #if sys public static var PROXY : { host : String, port : Int, auth : { user : String, pass : String } } = null; #end /** Creates a new Http instance with `url` as parameter. This does not do a request until `request()` is called. If `url` is null, the field url must be set to a value before making the call to `request()`, or the result is unspecified. (Php) Https (SSL) connections are allowed only if the OpenSSL extension is enabled. **/ public function new( url : String ) { this.url = url; headers = new List<{ header:String, value:String }>(); params = new List<{ param:String, value:String }>(); #if (js && !nodejs) async = true; withCredentials = false; #elseif sys cnxTimeout = 10; #end #if php noShutdown = ! untyped __call__('function_exists', 'stream_socket_shutdown'); #end } /** Sets the header identified as `header` to value `value`. If `header` or `value` are null, the result is unspecified. This method provides a fluent interface. **/ public function setHeader( header : String, value : String ):Http { headers = Lambda.filter(headers, function(h) return h.header != header); headers.push({ header:header, value:value }); return this; } public function addHeader( header : String, value : String ):Http { headers.push({ header:header, value:value }); return this; } /** Sets the parameter identified as `param` to value `value`. If `header` or `value` are null, the result is unspecified. This method provides a fluent interface. **/ public function setParameter( param : String, value : String ):Http { params = Lambda.filter(params, function(p) return p.param != param); params.push({ param:param, value:value }); return this; } public function addParameter( param : String, value : String ):Http { params.push({ param:param, value:value }); return this; } /** Sets the post data of `this` Http request to `data`. There can only be one post data per request. Subsequent calls overwrite the previously set value. If `data` is null, the post data is considered to be absent. This method provides a fluent interface. **/ public function setPostData( data : String ):Http { postData = data; return this; } #if (js || flash) #if nodejs var req:js.node.http.ClientRequest; #elseif js var req:js.html.XMLHttpRequest; #elseif flash var req:flash.net.URLLoader; #end /** Cancels `this` Http request if `request` has been called and a response has not yet been received. **/ public function cancel() { if (req == null) return; #if js req.abort(); #elseif flash req.close(); #end req = null; } #end /** Sends `this` Http request to the Url specified by `this.url`. If `post` is true, the request is sent as POST request, otherwise it is sent as GET request. Depending on the outcome of the request, this method calls the `onStatus()`, `onError()` or `onData()` callback functions. If `this.url` is null, the result is unspecified. If `this.url` is an invalid or inaccessible Url, the `onError()` callback function is called. [js] If `this.async` is false, the callback functions are called before this method returns. **/ public function request( ?post : Bool ) : Void { var me = this; #if nodejs me.responseData = null; var parsedUrl = js.node.Url.parse(url); var secure = (parsedUrl.protocol == "https:"); var host = parsedUrl.hostname; var path = parsedUrl.path; var port = if (parsedUrl.port != null) Std.parseInt(parsedUrl.port) else (secure ? 443 : 80); var h:Dynamic = {}; for (i in headers) { var arr = Reflect.field(h, i.header); if (arr == null) { arr = new Array(); Reflect.setField(h, i.header, arr); } arr.push(i.value); } var uri = postData; if( uri != null ) post = true; else for( p in params ) { if( uri == null ) uri = ""; else uri += "&"; uri += StringTools.urlEncode(p.param)+"="+StringTools.urlEncode(p.value); } var question = path.split("?").length <= 1; if (!post && uri != null) path += (if( question ) "?" else "&") + uri; var opts = { protocol: parsedUrl.protocol, hostname: host, port: port, method: post ? 'POST' : 'GET', path: path, headers: h }; function httpResponse (res) { var s = res.statusCode; if (s != null) me.onStatus(s); var body = ''; res.on('data', function (d) { body += d; }); res.on('end', function (_) { me.responseData = body; me.req = null; if (s != null && s >= 200 && s < 400) { me.onData(body); } else { me.onError("Http Error #"+s); } }); } req = secure ? js.node.Https.request(untyped opts, httpResponse) : js.node.Http.request(untyped opts, httpResponse); if (post) req.write(uri); req.end(); #elseif js me.responseData = null; var r = req = js.Browser.createXMLHttpRequest(); var onreadystatechange = function(_) { if( r.readyState != 4 ) return; var s = try r.status catch( e : Dynamic ) null; if ( s != null && untyped __js__('"undefined" !== typeof window') ) { // If the request is local and we have data: assume a success (jQuery approach): var protocol = js.Browser.location.protocol.toLowerCase(); var rlocalProtocol = ~/^(?:about|app|app-storage|.+-extension|file|res|widget):$/; var isLocal = rlocalProtocol.match( protocol ); if ( isLocal ) { s = r.responseText != null ? 200 : 404; } } if( s == untyped __js__("undefined") ) s = null; if( s != null ) me.onStatus(s); if( s != null && s >= 200 && s < 400 ) { me.req = null; me.onData(me.responseData = r.responseText); } else if ( s == null ) { me.req = null; me.onError("Failed to connect or resolve host"); } else switch( s ) { case 12029: me.req = null; me.onError("Failed to connect to host"); case 12007: me.req = null; me.onError("Unknown host"); default: me.req = null; me.responseData = r.responseText; me.onError("Http Error #"+r.status); } }; if( async ) r.onreadystatechange = onreadystatechange; var uri = postData; if( uri != null ) post = true; else for( p in params ) { if( uri == null ) uri = ""; else uri += "&"; uri += StringTools.urlEncode(p.param)+"="+StringTools.urlEncode(p.value); } try { if( post ) r.open("POST",url,async); else if( uri != null ) { var question = url.split("?").length <= 1; r.open("GET",url+(if( question ) "?" else "&")+uri,async); uri = null; } else r.open("GET",url,async); } catch( e : Dynamic ) { me.req = null; onError(e.toString()); return; } r.withCredentials = withCredentials; if( !Lambda.exists(headers, function(h) return h.header == "Content-Type") && post && postData == null ) r.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); for( h in headers ) r.setRequestHeader(h.header,h.value); r.send(uri); if( !async ) onreadystatechange(null); #elseif flash me.responseData = null; var loader = req = new flash.net.URLLoader(); loader.addEventListener( "complete", function(e) { me.req = null; me.responseData = loader.data; me.onData( loader.data ); }); loader.addEventListener( "httpStatus", function(e:flash.events.HTTPStatusEvent){ // on Firefox 1.5, Flash calls onHTTPStatus with 0 (!??) if( e.status != 0 ) me.onStatus( e.status ); }); loader.addEventListener( "ioError", function(e:flash.events.IOErrorEvent){ me.req = null; me.responseData = loader.data; me.onError(e.text); }); loader.addEventListener( "securityError", function(e:flash.events.SecurityErrorEvent){ me.req = null; me.onError(e.text); }); // headers var param = false; var vars = new flash.net.URLVariables(); for( p in params ){ param = true; Reflect.setField(vars,p.param,p.value); } var small_url = url; if( param && !post ){ var k = url.split("?"); if( k.length > 1 ) { small_url = k.shift(); vars.decode(k.join("?")); } } // Bug in flash player 9 ??? var bug = small_url.split("xxx"); var request = new flash.net.URLRequest( small_url ); for( h in headers ) request.requestHeaders.push( new flash.net.URLRequestHeader(h.header,h.value) ); if( postData != null ) { request.data = postData; request.method = "POST"; } else { request.data = vars; request.method = if( post ) "POST" else "GET"; } try { loader.load( request ); }catch( e : Dynamic ){ me.req = null; onError("Exception: "+Std.string(e)); } #elseif sys var me = this; var output = new haxe.io.BytesOutput(); var old = onError; var err = false; onError = function(e) { #if neko me.responseData = neko.Lib.stringReference(output.getBytes()); #else me.responseData = output.getBytes().toString(); #end err = true; // Resetting back onError before calling it allows for a second "retry" request to be sent without onError being wrapped twice onError = old; onError(e); } customRequest(post,output); if( !err ) #if neko me.onData(me.responseData = neko.Lib.stringReference(output.getBytes())); #else me.onData(me.responseData = output.getBytes().toString()); #end #end } #if sys /** Note: Deprecated in 4.0 **/ @:noCompletion inline public function fileTransfert( argname : String, filename : String, file : haxe.io.Input, size : Int, mimeType = "application/octet-stream" ) { fileTransfer(argname, filename, file, size, mimeType); } public function fileTransfer( argname : String, filename : String, file : haxe.io.Input, size : Int, mimeType = "application/octet-stream" ) { this.file = { param : argname, filename : filename, io : file, size : size, mimeType : mimeType }; } public function customRequest( post : Bool, api : haxe.io.Output, ?sock : sys.net.Socket, ?method : String ) { this.responseData = null; var url_regexp = ~/^(https?:\/\/)?([a-zA-Z\.0-9_-]+)(:[0-9]+)?(.*)$/; if( !url_regexp.match(url) ) { onError("Invalid URL"); return; } var secure = (url_regexp.matched(1) == "https://"); if( sock == null ) { if( secure ) { #if php sock = new php.net.SslSocket(); #elseif java sock = new java.net.SslSocket(); #elseif (!no_ssl && (hxssl || hl || cpp || (neko && !(macro || interp)))) sock = new sys.ssl.Socket(); #else throw "Https is only supported with -lib hxssl"; #end } else sock = new Socket(); } var host = url_regexp.matched(2); var portString = url_regexp.matched(3); var request = url_regexp.matched(4); if( request == "" ) request = "/"; var port = if ( portString == null || portString == "" ) secure ? 443 : 80 else Std.parseInt(portString.substr(1, portString.length - 1)); var data; var multipart = (file != null); var boundary = null; var uri = null; if( multipart ) { post = true; boundary = Std.string(Std.random(1000))+Std.string(Std.random(1000))+Std.string(Std.random(1000))+Std.string(Std.random(1000)); while( boundary.length < 38 ) boundary = "-" + boundary; var b = new StringBuf(); for( p in params ) { b.add("--"); b.add(boundary); b.add("\r\n"); b.add('Content-Disposition: form-data; name="'); b.add(p.param); b.add('"'); b.add("\r\n"); b.add("\r\n"); b.add(p.value); b.add("\r\n"); } b.add("--"); b.add(boundary); b.add("\r\n"); b.add('Content-Disposition: form-data; name="'); b.add(file.param); b.add('"; filename="'); b.add(file.filename); b.add('"'); b.add("\r\n"); b.add("Content-Type: "+file.mimeType+"\r\n"+"\r\n"); uri = b.toString(); } else { for( p in params ) { if( uri == null ) uri = ""; else uri += "&"; uri += StringTools.urlEncode(p.param)+"="+StringTools.urlEncode(p.value); } } var b = new StringBuf(); if( method != null ) { b.add(method); b.add(" "); } else if( post ) b.add("POST "); else b.add("GET "); if( Http.PROXY != null ) { b.add("http://"); b.add(host); if( port != 80 ) { b.add(":"); b.add(port); } } b.add(request); if( !post && uri != null ) { if( request.indexOf("?",0) >= 0 ) b.add("&"); else b.add("?"); b.add(uri); } b.add(" HTTP/1.1\r\nHost: "+host+"\r\n"); if( postData != null ) b.add("Content-Length: "+postData.length+"\r\n"); else if( post && uri != null ) { if( multipart || !Lambda.exists(headers, function(h) return h.header == "Content-Type") ) { b.add("Content-Type: "); if( multipart ) { b.add("multipart/form-data"); b.add("; boundary="); b.add(boundary); } else b.add("application/x-www-form-urlencoded"); b.add("\r\n"); } if( multipart ) b.add("Content-Length: "+(uri.length+file.size+boundary.length+6)+"\r\n"); else b.add("Content-Length: "+uri.length+"\r\n"); } b.add("Connection: close\r\n"); for( h in headers ) { b.add(h.header); b.add(": "); b.add(h.value); b.add("\r\n"); } b.add("\r\n"); if( postData != null) b.add(postData); else if( post && uri != null ) b.add(uri); try { if( Http.PROXY != null ) sock.connect(new Host(Http.PROXY.host),Http.PROXY.port); else sock.connect(new Host(host),port); sock.write(b.toString()); if( multipart ) { var bufsize = 4096; var buf = haxe.io.Bytes.alloc(bufsize); while( file.size > 0 ) { var size = if( file.size > bufsize ) bufsize else file.size; var len = 0; try { len = file.io.readBytes(buf,0,size); } catch( e : haxe.io.Eof ) break; sock.output.writeFullBytes(buf,0,len); file.size -= len; } sock.write("\r\n"); sock.write("--"); sock.write(boundary); sock.write("--"); } readHttpResponse(api,sock); sock.close(); } catch( e : Dynamic ) { try sock.close() catch( e : Dynamic ) { }; onError(Std.string(e)); } } function readHttpResponse( api : haxe.io.Output, sock : sys.net.Socket ) { // READ the HTTP header (until \r\n\r\n) var b = new haxe.io.BytesBuffer(); var k = 4; var s = haxe.io.Bytes.alloc(4); sock.setTimeout(cnxTimeout); while( true ) { var p = sock.input.readBytes(s,0,k); while( p != k ) p += sock.input.readBytes(s,p,k - p); b.addBytes(s,0,k); switch( k ) { case 1: var c = s.get(0); if( c == 10 ) break; if( c == 13 ) k = 3; else k = 4; case 2: var c = s.get(1); if( c == 10 ) { if( s.get(0) == 13 ) break; k = 4; } else if( c == 13 ) k = 3; else k = 4; case 3: var c = s.get(2); if( c == 10 ) { if( s.get(1) != 13 ) k = 4; else if( s.get(0) != 10 ) k = 2; else break; } else if( c == 13 ) { if( s.get(1) != 10 || s.get(0) != 13 ) k = 1; else k = 3; } else k = 4; case 4: var c = s.get(3); if( c == 10 ) { if( s.get(2) != 13 ) continue; else if( s.get(1) != 10 || s.get(0) != 13 ) k = 2; else break; } else if( c == 13 ) { if( s.get(2) != 10 || s.get(1) != 13 ) k = 3; else k = 1; } } } #if neko var headers = neko.Lib.stringReference(b.getBytes()).split("\r\n"); #else var headers = b.getBytes().toString().split("\r\n"); #end var response = headers.shift(); var rp = response.split(" "); var status = Std.parseInt(rp[1]); if( status == 0 || status == null ) throw "Response status error"; // remove the two lasts \r\n\r\n headers.pop(); headers.pop(); responseHeaders = new haxe.ds.StringMap(); var size = null; var chunked = false; for( hline in headers ) { var a = hline.split(": "); var hname = a.shift(); var hval = if( a.length == 1 ) a[0] else a.join(": "); hval = StringTools.ltrim( StringTools.rtrim( hval ) ); responseHeaders.set(hname, hval); switch(hname.toLowerCase()) { case "content-length": size = Std.parseInt(hval); case "transfer-encoding": chunked = (hval.toLowerCase() == "chunked"); } } onStatus(status); var chunk_re = ~/^([0-9A-Fa-f]+)[ ]*\r\n/m; chunk_size = null; chunk_buf = null; var bufsize = 1024; var buf = haxe.io.Bytes.alloc(bufsize); if( chunked ) { try { while( true ) { var len = sock.input.readBytes(buf,0,bufsize); if( !readChunk(chunk_re,api,buf,len) ) break; } } catch ( e : haxe.io.Eof ) { throw "Transfer aborted"; } } else if( size == null ) { if( !noShutdown ) sock.shutdown(false,true); try { while( true ) { var len = sock.input.readBytes(buf,0,bufsize); api.writeBytes(buf,0,len); } } catch( e : haxe.io.Eof ) { } } else { api.prepare(size); try { while( size > 0 ) { var len = sock.input.readBytes(buf,0,if( size > bufsize ) bufsize else size); api.writeBytes(buf,0,len); size -= len; } } catch( e : haxe.io.Eof ) { throw "Transfer aborted"; } } if( chunked && (chunk_size != null || chunk_buf != null) ) throw "Invalid chunk"; if( status < 200 || status >= 400 ) throw "Http Error #"+status; api.close(); } function readChunk(chunk_re : EReg, api : haxe.io.Output, buf : haxe.io.Bytes, len ) { if( chunk_size == null ) { if( chunk_buf != null ) { var b = new haxe.io.BytesBuffer(); b.add(chunk_buf); b.addBytes(buf,0,len); buf = b.getBytes(); len += chunk_buf.length; chunk_buf = null; } #if neko if( chunk_re.match(neko.Lib.stringReference(buf)) ) { #else if( chunk_re.match(buf.toString()) ) { #end var p = chunk_re.matchedPos(); if( p.len <= len ) { var cstr = chunk_re.matched(1); chunk_size = Std.parseInt("0x"+cstr); if( cstr == "0" ) { chunk_size = null; chunk_buf = null; return false; } len -= p.len; return readChunk(chunk_re,api,buf.sub(p.len,len),len); } } // prevent buffer accumulation if( len > 10 ) { onError("Invalid chunk"); return false; } chunk_buf = buf.sub(0,len); return true; } if( chunk_size > len ) { chunk_size -= len; api.writeBytes(buf,0,len); return true; } var end = chunk_size + 2; if( len >= end ) { if( chunk_size > 0 ) api.writeBytes(buf,0,chunk_size); len -= end; chunk_size = null; if( len == 0 ) return true; return readChunk(chunk_re,api,buf.sub(end,len),len); } if( chunk_size > 0 ) api.writeBytes(buf,0,chunk_size); chunk_size -= len; return true; } #end /** This method is called upon a successful request, with `data` containing the result String. The intended usage is to bind it to a custom function: `httpInstance.onData = function(data) { // handle result }` **/ public dynamic function onData( data : String ) { } /** This method is called upon a request error, with `msg` containing the error description. The intended usage is to bind it to a custom function: `httpInstance.onError = function(msg) { // handle error }` **/ public dynamic function onError( msg : String ) { } /** This method is called upon a Http status change, with `status` being the new status. The intended usage is to bind it to a custom function: `httpInstance.onStatus = function(status) { // handle status }` **/ public dynamic function onStatus( status : Int ) { } #if (!flash && !nodejs) /** Makes a synchronous request to `url`. This creates a new Http instance and makes a GET request by calling its `request(false)` method. If `url` is null, the result is unspecified. **/ public static function requestUrl( url : String ) : String { var h = new Http(url); #if js h.async = false; #end var r = null; h.onData = function(d){ r = d; } h.onError = function(e){ throw e; } h.request(false); return r; } #end } haxe_3.4.4.orig/std/haxe/Int32.hx0000664000175000017500000002242413166552354016377 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** Int32 provides a 32-bit integer with consistent overflow behavior across all platforms. **/ abstract Int32(Int) from Int to Int { @:op(-A) private function negate():Int32; @:op(++A) private inline function preIncrement():Int32 return this = clamp(++this); @:op(A++) private inline function postIncrement():Int32 { var ret = this++; this = clamp(this); return ret; } @:op(--A) private inline function preDecrement():Int32 return this = clamp(--this); @:op(A--) private inline function postDecrement():Int32 { var ret = this--; this = clamp(this); return ret; } @:op(A + B) private static inline function add(a:Int32, b:Int32):Int32 return clamp( (a : Int) + (b : Int) ); @:op(A + B) @:commutative private static inline function addInt(a:Int32, b:Int):Int32 return clamp( (a : Int) + (b : Int) ); @:op(A + B) @:commutative private static function addFloat(a:Int32, b:Float):Float; @:op(A - B) private static inline function sub(a:Int32, b:Int32):Int32 return clamp( (a : Int) - (b : Int) ); @:op(A - B) private static inline function subInt(a:Int32, b:Int):Int32 return clamp( (a : Int) - (b : Int) ); @:op(A - B) private static inline function intSub(a:Int, b:Int32):Int32 return clamp( (a : Int) - (b : Int) ); @:op(A - B) private static function subFloat(a:Int32, b:Float):Float; @:op(A - B) public static function floatSub(a:Float, b:Int32):Float; #if (as3 || js || php || python || lua) #if js // on JS we want to try using Math.imul, but we have to assign that function to Int32.mul only once, // or else V8 will deoptimize it, so we need to be a bit funky with this. // See https://github.com/HaxeFoundation/haxe/issues/5367 for benchmarks. @:op(A * B) inline static function mul(a:Int32, b:Int32):Int32 return _mul(a, b); static var _mul:Int32->Int32->Int32 = untyped if (Math.imul != null) Math.imul else function(a:Int32, b:Int32):Int32 return clamp( (a : Int) * ((b : Int) & 0xFFFF) + clamp( (a : Int) * ((b : Int) >>> 16) << 16 ) ); #else @:op(A * B) private static function mul(a:Int32, b:Int32):Int32 return clamp( (a : Int) * ((b : Int) & 0xFFFF) + clamp( (a : Int) * ((b : Int) >>> 16) << 16 ) ); #end @:op(A * B) @:commutative private static inline function mulInt(a:Int32, b:Int):Int32 return mul(a, b); #else @:op(A * B) private static function mul(a:Int32, b:Int32):Int32; @:op(A * B) @:commutative private static function mulInt(a:Int32, b:Int):Int32; #end @:op(A * B) @:commutative private static function mulFloat(a:Int32, b:Float):Float; @:op(A / B) private static function div(a:Int32, b:Int32):Float; @:op(A / B) private static function divInt(a:Int32, b:Int):Float; @:op(A / B) private static function intDiv(a:Int, b:Int32):Float; @:op(A / B) private static function divFloat(a:Int32, b:Float):Float; @:op(A / B) private static function floatDiv(a:Float, b:Int32):Float; @:op(A % B) private static function mod(a:Int32, b:Int32):Int32; @:op(A % B) private static function modInt(a:Int32, b:Int):Int; @:op(A % B) private static function intMod(a:Int, b:Int32):Int; @:op(A % B) private static function modFloat(a:Int32, b:Float):Float; @:op(A % B) private static function floatMod(a:Float, b:Int32):Float; @:op(A == B) private static function eq(a:Int32, b:Int32):Bool; @:op(A == B) @:commutative private static function eqInt(a:Int32, b:Int):Bool; @:op(A == B) @:commutative private static function eqFloat(a:Int32, b:Float):Bool; @:op(A != B) private static function neq(a:Int32, b:Int32):Bool; @:op(A != B) @:commutative private static function neqInt(a:Int32, b:Int):Bool; @:op(A != B) @:commutative private static function neqFloat(a:Int32, b:Float):Bool; @:op(A < B) private static function lt(a:Int32, b:Int32):Bool; @:op(A < B) private static function ltInt(a:Int32, b:Int):Bool; @:op(A < B) private static function intLt(a:Int, b:Int32):Bool; @:op(A < B) private static function ltFloat(a:Int32, b:Float):Bool; @:op(A < B) private static function floatLt(a:Float, b:Int32):Bool; @:op(A <= B) private static function lte(a:Int32, b:Int32):Bool; @:op(A <= B) private static function lteInt(a:Int32, b:Int):Bool; @:op(A <= B) private static function intLte(a:Int, b:Int32):Bool; @:op(A <= B) private static function lteFloat(a:Int32, b:Float):Bool; @:op(A <= B) private static function floatLte(a:Float, b:Int32):Bool; @:op(A > B) private static function gt(a:Int32, b:Int32):Bool; @:op(A > B) private static function gtInt(a:Int32, b:Int):Bool; @:op(A > B) private static function intGt(a:Int, b:Int32):Bool; @:op(A > B) private static function gtFloat(a:Int32, b:Float):Bool; @:op(A > B) private static function floatGt(a:Float, b:Int32):Bool; @:op(A >= B) private static function gte(a:Int32, b:Int32):Bool; @:op(A >= B) private static function gteInt(a:Int32, b:Int):Bool; @:op(A >= B) private static function intGte(a:Int, b:Int32):Bool; @:op(A >= B) private static function gteFloat(a:Int32, b:Float):Bool; @:op(A >= B) private static function floatGte(a:Float, b:Int32):Bool; #if lua @:op(~A) private static inline function complement( a : Int32 ) : Int32 return lua.Boot.clamp(~a); #else @:op(~A) private function complement():Int32; #end @:op(A & B) private static function and(a:Int32, b:Int32):Int32; @:op(A & B) @:commutative private static function andInt(a:Int32, b:Int):Int32; #if lua @:op(A | B) private static function or(a:Int32, b:Int32):Int32 return clamp((a:Int) | (b:Int)); @:op(A | B) @:commutative private static function orInt(a:Int32, b:Int):Int32 return clamp((a:Int) | b); #else @:op(A | B) private static function or(a:Int32, b:Int32):Int32; @:op(A | B) @:commutative private static function orInt(a:Int32, b:Int):Int32; #end #if lua @:op(A ^ B) private static function xor(a:Int32, b:Int32):Int32 return clamp((a:Int) ^ (b:Int)); @:op(A ^ B) @:commutative private static function xorInt(a:Int32, b:Int):Int32 return clamp((a:Int) ^ b); #else @:op(A ^ B) private static function xor(a:Int32, b:Int32):Int32; @:op(A ^ B) @:commutative private static function xorInt(a:Int32, b:Int):Int32; #end #if lua @:op(A >> B) private static function shr(a:Int32, b:Int32):Int32 return clamp((a:Int) >> (b:Int)); @:op(A >> B) private static function shrInt(a:Int32, b:Int):Int32 return clamp((a:Int) >> b); @:op(A >> B) private static function intShr(a:Int, b:Int32):Int32 return clamp(a >> (b:Int)); #else @:op(A >> B) private static function shr(a:Int32, b:Int32):Int32; @:op(A >> B) private static function shrInt(a:Int32, b:Int):Int32; @:op(A >> B) private static function intShr(a:Int, b:Int32):Int32; #end @:op(A >>> B) private static function ushr(a:Int32, b:Int32):Int32; @:op(A >>> B) private static function ushrInt(a:Int32, b:Int):Int32; @:op(A >>> B) private static function intUshr(a:Int, b:Int32):Int32; #if (php || python || lua) // PHP may be 64-bit, so shifts must be clamped @:op(A << B) private static inline function shl(a:Int32, b:Int32):Int32 return clamp( (a : Int) << (b : Int) ); @:op(A << B) private static inline function shlInt(a:Int32, b:Int):Int32 return clamp( (a : Int) << b ); @:op(A << B) private static inline function intShl(a:Int, b:Int32):Int32 return clamp( a << (b : Int) ); #else @:op(A << B) private static function shl(a:Int32, b:Int32):Int32; @:op(A << B) private static function shlInt(a:Int32, b:Int):Int32; @:op(A << B) private static function intShl(a:Int, b:Int32):Int32; #end @:to private inline function toFloat():Float return this; /** Compare `a` and `b` in unsigned mode. **/ public static function ucompare( a : Int32, b : Int32 ) : Int { if( a < 0 ) return b < 0 ? ( ~b - ~a ) : 1; return b < 0 ? -1 : (a - b); } #if php static var extraBits : Int = untyped __php__("PHP_INT_SIZE") * 8 - 32; #end #if !lua inline #end static function clamp( x : Int ) : Int { // force to-int conversion on platforms that require it #if (as3 || js) return x | 0; #elseif php // we might be on 64-bit php, so sign extend from 32-bit return (x << extraBits) >> extraBits; #elseif python return python.Syntax.pythonCode("{0} % {1}", (x + python.Syntax.opPow(2, 31)), python.Syntax.opPow(2, 32)) - python.Syntax.opPow(2, 31); #elseif lua return lua.Boot.clamp(x); #else return (x); #end } } haxe_3.4.4.orig/std/haxe/Int64.hx0000664000175000017500000003161413166552354016405 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; using haxe.Int64; /** A cross-platform signed 64-bit integer. Int64 instances can be created from two 32-bit words using `Int64.make()`. **/ #if flash @:notNull #end abstract Int64(__Int64) from __Int64 to __Int64 { private inline function new( x : __Int64 ) this = x; /** Makes a copy of `this` Int64. **/ public inline function copy():Int64 return make( high, low ); /** Construct an Int64 from two 32-bit words `high` and `low`. **/ public static inline function make( high:Int32, low:Int32 ) : Int64 return new Int64( new __Int64(high, low) ); /** Returns an Int64 with the value of the Int `x`. `x` is sign-extended to fill 64 bits. **/ @:from public static inline function ofInt( x : Int ) : Int64 #if lua return make( (x:Int32) >> 31, (x:Int32)); #else return make( x >> 31, x ); #end /** Returns an Int with the value of the Int64 `x`. Throws an exception if `x` cannot be represented in 32 bits. **/ public static inline function toInt( x : Int64 ) : Int { if( x.high != x.low >> 31 ) throw "Overflow"; return x.low; } /** Returns whether the value `val` is of type `haxe.Int64` **/ inline public static function is( val : Dynamic ) : Bool return Std.is(val,__Int64); /** Returns the high 32-bit word of `x`. **/ @:deprecated("Use high instead") public static inline function getHigh( x : Int64 ) : Int32 return x.high; /** Returns the low 32-bit word of `x`. **/ @:deprecated("Use low instead") public static inline function getLow( x : Int64 ) : Int32 return x.low; /** Returns `true` if `x` is less than zero. **/ public static inline function isNeg( x : Int64) : Bool return x.high < 0; /** Returns `true` if `x` is exactly zero. **/ public static inline function isZero( x : Int64 ) : Bool return x == 0; /** Compares `a` and `b` in signed mode. Returns a negative value if `a < b`, positive if `a > b`, or 0 if `a == b`. **/ public static inline function compare( a : Int64, b : Int64 ) : Int { var v = a.high - b.high; v = if( v != 0 ) v else Int32.ucompare(a.low, b.low); return a.high < 0 ? (b.high < 0 ? v : -1) : (b.high >= 0 ? v : 1); } /** Compares `a` and `b` in unsigned mode. Returns a negative value if `a < b`, positive if `a > b`, or 0 if `a == b`. **/ public static inline function ucompare( a : Int64, b : Int64 ) : Int { var v = Int32.ucompare(a.high, b.high); return if( v != 0 ) v else Int32.ucompare(a.low, b.low); } /** Returns a signed decimal `String` representation of `x`. **/ public static inline function toStr(x:Int64) : String return x.toString(); #if as3 public #else private #end function toString() : String { var i : Int64 = cast this; if ( i == 0 ) return "0"; var str = ""; var neg = false; if( i.isNeg() ) { neg = true; // i = -i; cannot negate here as --9223372036854775808 = -9223372036854775808 } var ten : Int64 = 10; while( i != 0 ) { var r = i.divMod( ten ); if (r.modulus.isNeg()) { str = Int64.neg(r.modulus).low + str; i = Int64.neg(r.quotient); } else { str = r.modulus.low + str; i = r.quotient; } } if( neg ) str = "-" + str; return str; } public static inline function parseString( sParam : String ) : Int64 { return Int64Helper.parseString( sParam ); } public static inline function fromFloat( f : Float ) : Int64 { return Int64Helper.fromFloat( f ); } /** Performs signed integer divison of `dividend` by `divisor`. Returns `{ quotient : Int64, modulus : Int64 }`. **/ public static function divMod( dividend : Int64, divisor : Int64 ) : { quotient : Int64, modulus : Int64 } { // Handle special cases of 0 and 1 if( divisor.high == 0 ) { switch( divisor.low ) { case 0: throw "divide by zero"; case 1: return { quotient : dividend.copy(), modulus : 0 }; } } var divSign = dividend.isNeg() != divisor.isNeg(); var modulus = dividend.isNeg() ? -dividend : dividend.copy(); divisor = divisor.isNeg() ? -divisor : divisor; var quotient : Int64 = 0; var mask : Int64 = 1; while( !divisor.isNeg() ) { var cmp = ucompare( divisor, modulus ); divisor <<= 1; mask <<= 1; if( cmp >= 0 ) break; } while( mask != 0 ) { if( ucompare(modulus, divisor) >= 0 ) { quotient |= mask; modulus -= divisor; } mask >>>= 1; divisor >>>= 1; } if( divSign ) quotient = -quotient; if( dividend.isNeg() ) modulus = -modulus; return { quotient : quotient, modulus : modulus }; } /** Returns the negative of `x`. **/ @:op(-A) public static inline function neg( x : Int64 ) : Int64 { var high = ~x.high; var low = -x.low; if( low == 0 ) high++; return make( high, low ); } @:op(++A) private inline function preIncrement() : Int64 { this = copy(); this.low++; if( this.low == 0 ) this.high++; return cast this; } @:op(A++) private inline function postIncrement() : Int64 { var ret = this; preIncrement(); return ret; } @:op(--A) private inline function preDecrement() : Int64 { this = copy(); if( this.low == 0 ) this.high--; this.low--; return cast this; } @:op(A--) private inline function postDecrement() : Int64 { var ret = this; preDecrement(); return ret; } /** Returns the sum of `a` and `b`. **/ @:op(A + B) public static inline function add( a : Int64, b : Int64 ) : Int64 { var high = a.high + b.high; var low = a.low + b.low; if( Int32.ucompare( low, a.low ) < 0 ) high++; return make( high, low ); } @:op(A + B) @:commutative private static inline function addInt( a : Int64, b : Int ) : Int64 return add( a, b ); /** Returns `a` minus `b`. **/ @:op(A - B) public static inline function sub( a : Int64, b : Int64 ) : Int64 { var high = a.high - b.high; var low = a.low - b.low; if( Int32.ucompare( a.low, b.low ) < 0 ) high--; return make( high, low ); } @:op(A - B) private static inline function subInt( a : Int64, b : Int ) : Int64 return sub( a, b ); @:op(A - B) private static inline function intSub( a : Int, b : Int64 ) : Int64 return sub( a, b ); /** Returns the product of `a` and `b`. **/ @:op(A * B) public static #if !lua inline #end function mul( a : Int64, b : Int64 ) : Int64 { var mask = 0xFFFF; var al = a.low & mask, ah = a.low >>> 16; var bl = b.low & mask, bh = b.low >>> 16; var p00 = al * bl; var p10 = ah * bl; var p01 = al * bh; var p11 = ah * bh; var low = p00; var high = p11 + (p01 >>> 16) + (p10 >>> 16); p01 <<= 16; low += p01; if( Int32.ucompare(low, p01) < 0 ) high++; p10 <<= 16; low += p10; if( Int32.ucompare(low, p10) < 0 ) high++; high += a.low * b.high + a.high * b.low; return make( high, low ); } @:op(A * B) @:commutative private static inline function mulInt( a : Int64, b : Int ) : Int64 return mul( a, b ); /** Returns the quotient of `a` divided by `b`. **/ @:op(A / B) public static inline function div( a : Int64, b : Int64 ) : Int64 return divMod(a, b).quotient; @:op(A / B) private static inline function divInt( a : Int64, b : Int ) : Int64 return div( a, b ); @:op(A / B) private static inline function intDiv( a : Int, b : Int64 ) : Int64 return div( a, b ).toInt(); /** Returns the modulus of `a` divided by `b`. **/ @:op(A % B) public static inline function mod( a : Int64, b : Int64 ) : Int64 return divMod(a, b).modulus; @:op(A % B) private static inline function modInt( a : Int64, b : Int ) : Int64 return mod( a, b ).toInt(); @:op(A % B) private static inline function intMod( a : Int, b : Int64 ) : Int64 return mod( a, b ).toInt(); /** Returns `true` if `a` is equal to `b`. **/ @:op(A == B) public static inline function eq( a : Int64, b : Int64 ) : Bool return a.high == b.high && a.low == b.low; @:op(A == B) @:commutative private static inline function eqInt( a : Int64, b : Int ) : Bool return eq( a, b ); /** Returns `true` if `a` is not equal to `b`. **/ @:op(A != B) public static inline function neq( a : Int64, b : Int64 ) : Bool return a.high != b.high || a.low != b.low; @:op(A != B) @:commutative private static inline function neqInt( a : Int64, b : Int ) : Bool return neq(a, b); @:op(A < B) private static inline function lt( a : Int64, b : Int64 ) : Bool return compare(a, b) < 0; @:op(A < B) private static inline function ltInt( a : Int64, b : Int ) : Bool return lt(a, b); @:op(A < B) private static inline function intLt( a : Int, b : Int64 ) : Bool return lt(a, b); @:op(A <= B) private static inline function lte( a : Int64, b : Int64 ) : Bool return compare(a, b) <= 0; @:op(A <= B) private static inline function lteInt( a : Int64, b : Int ) : Bool return lte(a, b); @:op(A <= B) private static inline function intLte( a : Int, b : Int64 ) : Bool return lte(a, b); @:op(A > B) private static inline function gt( a : Int64, b : Int64 ) : Bool return compare(a, b) > 0; @:op(A > B) private static inline function gtInt( a : Int64, b : Int ) : Bool return gt(a, b); @:op(A > B) private static inline function intGt( a : Int, b : Int64 ) : Bool return gt( a, b ); @:op(A >= B) private static inline function gte( a : Int64, b : Int64 ) : Bool return compare(a, b) >= 0; @:op(A >= B) private static inline function gteInt( a : Int64, b : Int ) : Bool return gte(a, b); @:op(A >= B) private static inline function intGte( a : Int, b : Int64 ) : Bool return gte(a, b); /** Returns the bitwise NOT of `a`. **/ @:op(~A) private static inline function complement( a : Int64 ) : Int64 return make( ~a.high, ~a.low ); /** Returns the bitwise AND of `a` and `b`. **/ @:op(A & B) public static inline function and( a : Int64, b : Int64 ) : Int64 return make( a.high & b.high, a.low & b.low ); /** Returns the bitwise OR of `a` and `b`. **/ @:op(A | B) public static inline function or( a : Int64, b : Int64 ) : Int64 return make( a.high | b.high, a.low | b.low ); /** Returns the bitwise XOR of `a` and `b`. **/ @:op(A ^ B) public static inline function xor( a : Int64, b : Int64 ) : Int64 return make( a.high ^ b.high, a.low ^ b.low ); /** Returns `a` left-shifted by `b` bits. **/ @:op(A << B) public static inline function shl( a : Int64, b : Int ) : Int64 { b &= 63; return if( b == 0 ) a.copy() else if( b < 32 ) make( (a.high << b) | (a.low >>> (32-b)), a.low << b) else make( a.low << (b-32), 0 ); } /** Returns `a` right-shifted by `b` bits in signed mode. `a` is sign-extended. **/ @:op(A >> B) public static inline function shr( a : Int64, b : Int) : Int64 { b &= 63; return if( b == 0 ) a.copy() else if( b < 32 ) make( a.high >> b, (a.high << (32-b)) | (a.low >>> b) ); else make( a.high >> 31, a.high >> (b - 32) ); } /** Returns `a` right-shifted by `b` bits in unsigned mode. `a` is padded with zeroes. **/ @:op(A >>> B) public static inline function ushr( a : Int64, b : Int ) : Int64 { b &= 63; return if( b == 0 ) a.copy() else if( b < 32 ) make( a.high >>> b, (a.high << (32-b)) | (a.low >>> b) ); else make( 0, a.high >>> (b - 32) ); } public var high(get, never) : Int32; private inline function get_high() return this.high; private inline function set_high(x) return this.high = x; public var low(get, never) : Int32; private inline function get_low() return this.low; private inline function set_low(x) return this.low = x; } /** * This typedef will fool @:coreApi into thinking that we are using * the same underlying type, even though it might be different on * specific platforms. */ private typedef __Int64 = ___Int64; private class ___Int64 { public var high : Int32; public var low : Int32; public inline function new( high, low ) { this.high = high; this.low = low; } /** We also define toString here to ensure we always get a pretty string when tracing or calling Std.string. This tends not to happen when toString is only in the abstract. **/ public function toString() : String return Int64.toStr( cast this ); } haxe_3.4.4.orig/std/haxe/Int64Helper.hx0000664000175000017500000000573413166552354017551 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; using haxe.Int64; import StringTools; /** Helper for parsing to `Int64` instances. **/ class Int64Helper { /** Create `Int64` from given string. **/ public static function parseString( sParam : String ) : Int64 { var base = Int64.ofInt(10); var current = Int64.ofInt(0); var multiplier = Int64.ofInt(1); var sIsNegative = false; var s = StringTools.trim(sParam); if (s.charAt(0) == "-") { sIsNegative = true; s = s.substring(1, s.length); } var len = s.length; for (i in 0...len) { var digitInt = s.charCodeAt(len - 1 - i) - '0'.code; if (digitInt < 0 || digitInt > 9) { throw "NumberFormatError"; } var digit:Int64 = Int64.ofInt(digitInt); if (sIsNegative) { current = Int64.sub(current, Int64.mul(multiplier, digit)); if (!Int64.isNeg(current)) { throw "NumberFormatError: Underflow"; } } else { current = Int64.add(current, Int64.mul(multiplier, digit)); if (Int64.isNeg(current)) { throw "NumberFormatError: Overflow"; } } multiplier = Int64.mul(multiplier, base); } return current; } /** Create `Int64` from given float. **/ public static function fromFloat( f : Float ) : Int64 { if (Math.isNaN(f) || !Math.isFinite(f)) { throw "Number is NaN or Infinite"; } var noFractions = f - (f % 1); // 2^53-1 and -2^53: these are parseable without loss of precision if (noFractions > 9007199254740991) { throw "Conversion overflow"; } if (noFractions < -9007199254740991) { throw "Conversion underflow"; } var result = Int64.ofInt(0); var neg = noFractions < 0; var rest = neg ? -noFractions : noFractions; var i = 0; while (rest >= 1) { var curr = rest % 2; rest = rest / 2; if (curr >= 1) { result = Int64.add(result, Int64.shl(Int64.ofInt(1), i)); } i++; } if (neg) { result = Int64.neg(result); } return result; } } haxe_3.4.4.orig/std/haxe/Json.hx0000664000175000017500000000504113166552354016405 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** Cross-platform JSON API: it will automatically use the optimized native API if available. Use `-D haxeJSON` to force usage of the Haxe implementation even if a native API is found: This will provide extra encoding features such as enums (replaced by their index) and StringMaps. @see https://haxe.org/manual/std-Json.html **/ class Json { /** Parses given JSON-encoded `text` and returns the resulting object. JSON objects are parsed into anonymous structures and JSON arrays are parsed into `Array`. If given `text` is not valid JSON, an exception will be thrown. @see https://haxe.org/manual/std-Json-parsing.html **/ public static inline function parse( text : String ) : Dynamic { return haxe.format.JsonParser.parse(text); } /** Encodes the given `value` and returns the resulting JSON string. If `replacer` is given and is not null, it is used to retrieve the actual object to be encoded. The `replacer` function takes two parameters, the key and the value being encoded. Initial key value is an empty string. If `space` is given and is not null, the result will be pretty-printed. Successive levels will be indented by this string. @see https://haxe.org/manual/std-Json-encoding.html **/ public static inline function stringify( value : Dynamic, ?replacer:Dynamic -> Dynamic -> Dynamic, ?space : String ) : String { return haxe.format.JsonPrinter.print(value, replacer, space); } } haxe_3.4.4.orig/std/haxe/Log.hx0000664000175000017500000001064013166552354016216 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** Log primarily provides the `trace()` method, which is invoked upon a call to `trace()` in Haxe code. **/ class Log { /** Outputs `v` in a platform-dependent way. The second parameter `infos` is injected by the compiler and contains information about the position where the `trace()` call was made. This method can be rebound to a custom function: var oldTrace = haxe.Log.trace; // store old function haxe.Log.trace = function(v, ?infos) { // handle trace } ... haxe.Log.trace = oldTrace; If it is bound to null, subsequent calls to `trace()` will cause an exception. **/ public static dynamic function trace( v : Dynamic, ?infos : PosInfos ) : Void { #if flash #if (fdb || native_trace) var pstr = infos == null ? "(null)" : infos.fileName + ":" + infos.lineNumber; var str = flash.Boot.__string_rec(v, ""); if( infos != null && infos.customParams != null ) for( v in infos.customParams ) str += "," + flash.Boot.__string_rec(v, ""); untyped __global__["trace"](pstr+": "+str); #else untyped flash.Boot.__trace(v,infos); #end #elseif neko untyped { $print(infos.fileName + ":" + infos.lineNumber + ": ", v); if( infos.customParams != null ) for( v in infos.customParams ) $print(",", v); $print("\n"); } #elseif js untyped js.Boot.__trace(v,infos); #elseif (php && php7) php.Boot.trace(v, infos); #elseif php if (infos!=null && infos.customParams!=null) { var extra:String = ""; for( v in infos.customParams ) extra += "," + v; untyped __call__('_hx_trace', v + extra, infos); } else untyped __call__('_hx_trace', v, infos); #elseif cpp if (infos!=null && infos.customParams!=null) { var extra:String = ""; for( v in infos.customParams ) extra += "," + v; untyped __trace(v + extra,infos); } else untyped __trace(v,infos); #elseif (cs || java || lua) var str:String = null; if (infos != null) { str = infos.fileName + ":" + infos.lineNumber + ": " + v; if (infos.customParams != null) { str += "," + infos.customParams.join(","); } } else { str = v; } #if cs cs.system.Console.WriteLine(str); #elseif java untyped __java__("java.lang.System.out.println(str)"); #elseif lua if (str == null) str = "null"; untyped __define_feature__("use._hx_print",_hx_print(str)); #end #elseif (python) var str:String = null; if (infos != null) { str = infos.fileName + ":" + Std.string(infos.lineNumber) + ": " + v; if (infos.customParams != null) { str += "," + infos.customParams.join(","); } } else { str = v; } python.Lib.println(str); #elseif hl var pstr = infos == null ? "(null)" : infos.fileName + ":" + infos.lineNumber; var str = Std.string(v); if( infos != null && infos.customParams != null ) for( v in infos.customParams ) str += "," + Std.string(v); Sys.println(pstr+": "+str); #end } #if (flash || js) /** Clears the trace output. **/ public static dynamic function clear() : Void { #if flash untyped flash.Boot.__clear_trace(); #elseif js untyped js.Boot.__clear_trace(); #end } #end #if flash /** Sets the color of the trace output to `rgb`. **/ public static dynamic function setColor( rgb : Int ) { untyped flash.Boot.__set_trace_color(rgb); } #end } haxe_3.4.4.orig/std/haxe/MainLoop.hx0000664000175000017500000000664413166552354017224 0ustar andyandy00000000000000package haxe; import haxe.EntryPoint; class MainEvent { var f : Void -> Void; var prev : MainEvent; var next : MainEvent; public var nextRun(default,null) : Float; public var priority(default,null) : Int; function new(f, p) { this.f = f; this.priority = p; nextRun = -1; } /** Delay the execution of the event for the given time, in seconds. If t is null, the event will be run at tick() time. **/ public function delay( t : Null ) { nextRun = t == null ? -1 : haxe.Timer.stamp() + t; } /** Call the event. Will do nothing is the event has been stopped. **/ public inline function call() { if( f != null ) f(); } /** Stop the event from firing anymore. **/ public function stop() { if( f == null ) return; f = null; nextRun = -1; if( prev == null ) @:privateAccess MainLoop.pending = next; else prev.next = next; if( next != null ) next.prev = prev; } } @:access(haxe.MainEvent) class MainLoop { static var pending : MainEvent = null; public static var threadCount(get, never) : Int; inline static function get_threadCount() return EntryPoint.threadCount; public inline static function hasEvents() { return pending != null; } public static function addThread( f : Void -> Void ) { EntryPoint.addThread(f); } public static function runInMainThread( f : Void -> Void ) { EntryPoint.runInMainThread(f); } /** Add a pending event to be run into the main loop. **/ public static function add( f : Void -> Void, priority = 0 ) : MainEvent @:privateAccess { if( f == null ) throw "Event function is null"; var e = new MainEvent(f, priority); var head = pending; if( head != null ) head.prev = e; e.next = head; pending = e; return e; } static function sortEvents() { // pending = haxe.ds.ListSort.sort(pending, function(e1, e2) return e1.nextRun > e2.nextRun ? -1 : 1); // we can't use directly ListSort because it requires prev/next to be public, which we don't want here // we do then a manual inline, this also allow use to do a Float comparison of nextRun var list = pending; if( list == null ) return; var insize = 1, nmerges, psize = 0, qsize = 0; var p, q, e, tail : MainEvent; while( true ) { p = list; list = null; tail = null; nmerges = 0; while( p != null ) { nmerges++; q = p; psize = 0; for( i in 0...insize ) { psize++; q = q.next; if( q == null ) break; } qsize = insize; while( psize > 0 || (qsize > 0 && q != null) ) { if( psize == 0 ) { e = q; q = q.next; qsize--; } else if( qsize == 0 || q == null || (p.priority > q.priority || (p.priority == q.priority && p.nextRun <= q.nextRun)) ) { e = p; p = p.next; psize--; } else { e = q; q = q.next; qsize--; } if( tail != null ) tail.next = e; else list = e; e.prev = tail; tail = e; } p = q; } tail.next = null; if( nmerges <= 1 ) break; insize *= 2; } list.prev = null; // not cycling pending = list; } /** Run the pending events. Return the time for next event. **/ static function tick() { sortEvents(); var e = pending; var now = haxe.Timer.stamp(); var wait = 1e9; while( e != null ) { var next = e.next; var wt = e.nextRun - now; if( e.nextRun < 0 || wt <= 0 ) { wait = 0; e.call(); } else if( wait > wt ) wait = wt; e = next; } return wait; } }haxe_3.4.4.orig/std/haxe/PosInfos.hx0000664000175000017500000000326613166552354017243 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** PosInfos is a magic type which can be used to generate position information into the output for debugging use. If a function has a final optional argument of this type, i.e. (..., ?pos:haxe.PosInfos), each call to that function which does not assign a value to that argument has its position added as call argument. This can be used to track positions of calls in e.g. a unit testing framework. **/ typedef PosInfos = { var fileName : String; var lineNumber : Int; var className : String; var methodName : String; @:optional var customParams : Array; }haxe_3.4.4.orig/std/haxe/Resource.hx0000664000175000017500000000564113166552354017271 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** Resource can be used to access resources that were added through the -resource file@name command line parameter. Depending on their type they can be obtained as String through getString(name), or as binary data through getBytes(name). A list of all available resource names can be obtained from listNames(). **/ class Resource { static var content : Array<{ name : String, data : String, str : String }>; /** Lists all available resource names. The resource name is the name part of the -resource file@name command line parameter. **/ public static function listNames() : Array { return [for (x in content) x.name]; } /** Retrieves the resource identified by `name` as a String. If `name` does not match any resource name, null is returned. **/ public static function getString( name : String ) : String { for( x in content ) if( x.name == name ) { #if neko return new String(x.data); #else if( x.str != null ) return x.str; var b : haxe.io.Bytes = haxe.crypto.Base64.decode(x.data); return b.toString(); #end } return null; } /** Retrieves the resource identified by `name` as an instance of haxe.io.Bytes. If `name` does not match any resource name, null is returned. **/ public static function getBytes( name : String ) : haxe.io.Bytes { for( x in content ) if( x.name == name ) { #if neko return haxe.io.Bytes.ofData(cast x.data); #else if( x.str != null ) return haxe.io.Bytes.ofString(x.str); return haxe.crypto.Base64.decode(x.data); #end } return null; } static function __init__() { #if neko var tmp = untyped __resources__(); content = untyped Array.new1(tmp,__dollar__asize(tmp)); #elseif php content = null; #elseif as3 null; #else content = untyped __resources__(); #end } } haxe_3.4.4.orig/std/haxe/Serializer.hx0000664000175000017500000003406113166552354017611 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** The Serializer class can be used to encode values and objects into a `String`, from which the `Unserializer` class can recreate the original representation. This class can be used in two ways: - create a `new Serializer()` instance, call its `serialize()` method with any argument and finally retrieve the String representation from `toString()` - call `Serializer.run()` to obtain the serialized representation of a single argument Serialization is guaranteed to work for all haxe-defined classes, but may or may not work for instances of external/native classes. The specification of the serialization format can be found here: **/ class Serializer { /** If the values you are serializing can contain circular references or objects repetitions, you should set `USE_CACHE` to true to prevent infinite loops. This may also reduce the size of serialization Strings at the expense of performance. This value can be changed for individual instances of Serializer by setting their useCache field. **/ public static var USE_CACHE = false; /** Use constructor indexes for enums instead of names. This may reduce the size of serialization Strings, but makes them less suited for long-term storage: If constructors are removed or added from the enum, the indices may no longer match. This value can be changed for individual instances of Serializer by setting their useEnumIndex field. **/ public static var USE_ENUM_INDEX = false; static var BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789%:"; static var BASE64_CODES = null; var buf : StringBuf; var cache : Array; var shash : haxe.ds.StringMap; var scount : Int; /** The individual cache setting for `this` Serializer instance. See USE_CACHE for a complete description. **/ public var useCache : Bool; /** The individual enum index setting for `this` Serializer instance. See USE_ENUM_INDEX for a complete description. **/ public var useEnumIndex : Bool; /** Creates a new Serializer instance. Subsequent calls to `this.serialize` will append values to the internal buffer of this String. Once complete, the contents can be retrieved through a call to `this.toString`. Each Serializer instance maintains its own cache if this.useCache` is true. **/ public function new() { buf = new StringBuf(); cache = new Array(); useCache = USE_CACHE; useEnumIndex = USE_ENUM_INDEX; shash = new haxe.ds.StringMap(); scount = 0; } /** Return the String representation of `this` Serializer. The exact format specification can be found here: https://haxe.org/manual/serialization/format **/ public function toString() { return buf.toString(); } /* prefixes : a : array b : hash c : class d : Float e : reserved (float exp) f : false g : object end h : array/list/hash end i : Int j : enum (by index) k : NaN l : list m : -Inf n : null o : object p : +Inf q : haxe.ds.IntMap r : reference s : bytes (base64) t : true u : array nulls v : date w : enum x : exception y : urlencoded string z : zero A : Class B : Enum M : haxe.ds.ObjectMap C : custom */ function serializeString( s : String ) { var x = shash.get(s); if( x != null ) { buf.add("R"); buf.add(x); return; } shash.set(s,scount++); #if old_serialize // no more support for -D old_serialize due to 'j' reuse #if error #end #end buf.add("y"); s = StringTools.urlEncode(s); buf.add(s.length); buf.add(":"); buf.add(s); } function serializeRef(v) { #if js var vt = untyped __js__("typeof")(v); #end for( i in 0...cache.length ) { #if js var ci = cache[i]; if( untyped __js__("typeof")(ci) == vt && ci == v ) { #else if( cache[i] == v ) { #end buf.add("r"); buf.add(i); return true; } } cache.push(v); return false; } #if flash // only the instance variables function serializeClassFields(v,c) { var xml : flash.xml.XML = untyped __global__["flash.utils.describeType"](c); var vars = xml.factory[0].child("variable"); for( i in 0...vars.length() ) { var f = vars[i].attribute("name").toString(); if( !v.hasOwnProperty(f) ) continue; serializeString(f); serialize(Reflect.field(v,f)); } buf.add("g"); } #end function serializeFields(v) { for( f in Reflect.fields(v) ) { serializeString(f); serialize(Reflect.field(v,f)); } buf.add("g"); } /** Serializes `v`. All haxe-defined values and objects with the exception of functions can be serialized. Serialization of external/native objects is not guaranteed to work. The values of `this.useCache` and `this.useEnumIndex` may affect serialization output. **/ public function serialize( v : Dynamic ) { switch( Type.typeof(v) ) { case TNull: buf.add("n"); case TInt: var v : Int = v; if( v == 0 ) { buf.add("z"); return; } buf.add("i"); buf.add(v); case TFloat: var v : Float = v; if( Math.isNaN(v) ) buf.add("k"); else if( !Math.isFinite(v) ) buf.add(if( v < 0 ) "m" else "p"); else { buf.add("d"); buf.add(v); } case TBool: buf.add(if( v ) "t" else "f"); case TClass(c): if( #if neko untyped c.__is_String #else c == String #end ) { serializeString(v); return; } if( useCache && serializeRef(v) ) return; switch( #if (neko || cs || python) Type.getClassName(c) #else c #end ) { case #if (neko || cs || python) "Array" #else cast Array #end: var ucount = 0; buf.add("a"); #if (flash || python || hl) var v : Array = v; #end var l = #if (neko || flash || php || cs || java || python || hl || lua) v.length #elseif cpp v.__length() #else __getField(v, "length") #end; for( i in 0...l ) { if( v[i] == null ) ucount++; else { if( ucount > 0 ) { if( ucount == 1 ) buf.add("n"); else { buf.add("u"); buf.add(ucount); } ucount = 0; } serialize(v[i]); } } if( ucount > 0 ) { if( ucount == 1 ) buf.add("n"); else { buf.add("u"); buf.add(ucount); } } buf.add("h"); case #if (neko || cs || python) "List" #else cast List #end: buf.add("l"); var v : List = v; for( i in v ) serialize(i); buf.add("h"); case #if (neko || cs || python) "Date" #else cast Date #end: var d : Date = v; buf.add("v"); buf.add(d.getTime()); case #if (neko || cs || python) "haxe.ds.StringMap" #else cast haxe.ds.StringMap #end: buf.add("b"); var v : haxe.ds.StringMap = v; for( k in v.keys() ) { serializeString(k); serialize(v.get(k)); } buf.add("h"); case #if (neko || cs || python) "haxe.ds.IntMap" #else cast haxe.ds.IntMap #end: buf.add("q"); var v : haxe.ds.IntMap = v; for( k in v.keys() ) { buf.add(":"); buf.add(k); serialize(v.get(k)); } buf.add("h"); case #if (neko || cs || python) "haxe.ds.ObjectMap" #else cast haxe.ds.ObjectMap #end: buf.add("M"); var v : haxe.ds.ObjectMap = v; for ( k in v.keys() ) { #if (js || neko) var id = Reflect.field(k, "__id__"); Reflect.deleteField(k, "__id__"); serialize(k); Reflect.setField(k, "__id__", id); #else serialize(k); #end serialize(v.get(k)); } buf.add("h"); case #if (neko || cs || python) "haxe.io.Bytes" #else cast haxe.io.Bytes #end: var v : haxe.io.Bytes = v; #if neko var chars = new String(base_encode(v.getData(),untyped BASE64.__s)); buf.add("s"); buf.add(chars.length); buf.add(":"); buf.add(chars); #else buf.add("s"); buf.add(Math.ceil((v.length * 8) / 6)); buf.add(":"); var i = 0; var max = v.length - 2; var b64 = BASE64_CODES; if( b64 == null ) { b64 = new haxe.ds.Vector(BASE64.length); for( i in 0...BASE64.length ) b64[i] = BASE64.charCodeAt(i); BASE64_CODES = b64; } while( i < max ) { var b1 = v.get(i++); var b2 = v.get(i++); var b3 = v.get(i++); buf.addChar(b64[b1 >> 2]); buf.addChar(b64[((b1 << 4) | (b2 >> 4)) & 63]); buf.addChar(b64[((b2 << 2) | (b3 >> 6)) & 63]); buf.addChar(b64[b3 & 63]); } if( i == max ) { var b1 = v.get(i++); var b2 = v.get(i++); buf.addChar(b64[b1 >> 2]); buf.addChar(b64[((b1 << 4) | (b2 >> 4)) & 63]); buf.addChar(b64[(b2 << 2) & 63]); } else if( i == max + 1 ) { var b1 = v.get(i++); buf.addChar(b64[b1 >> 2]); buf.addChar(b64[(b1 << 4) & 63]); } #end default: if( useCache ) cache.pop(); if( #if flash try v.hxSerialize != null catch( e : Dynamic ) false #elseif (cs || java || python) Reflect.hasField(v, "hxSerialize") #elseif (php && php7) php.Global.method_exists(v, 'hxSerialize') #else v.hxSerialize != null #end ) { buf.add("C"); serializeString(Type.getClassName(c)); if( useCache ) cache.push(v); v.hxSerialize(this); buf.add("g"); } else { buf.add("c"); serializeString(Type.getClassName(c)); if( useCache ) cache.push(v); #if flash serializeClassFields(v,c); #else serializeFields(v); #end } } case TObject: if (Std.is(v,Class)) { var className = Type.getClassName(v); #if (flash || cpp) // Currently, Enum and Class are the same for flash and cpp. // use resolveEnum to test if it is actually an enum if (Type.resolveEnum(className)!=null) buf.add("B") else #end buf.add("A"); serializeString(className); } else if (Std.is(v,Enum)) { buf.add("B"); serializeString(Type.getEnumName(v)); } else { if( useCache && serializeRef(v) ) return; buf.add("o"); serializeFields(v); } case TEnum(e): if( useCache ) { if( serializeRef(v) ) return; cache.pop(); } buf.add(useEnumIndex?"j":"w"); serializeString(Type.getEnumName(e)); #if neko if( useEnumIndex ) { buf.add(":"); buf.add(v.index); } else serializeString(new String(v.tag)); buf.add(":"); if( v.args == null ) buf.add(0); else { var l : Int = untyped __dollar__asize(v.args); buf.add(l); for( i in 0...l ) serialize(v.args[i]); } #elseif flash if( useEnumIndex ) { buf.add(":"); var i : Int = v.index; buf.add(i); } else serializeString(v.tag); buf.add(":"); var pl : Array = v.params; if( pl == null ) buf.add(0); else { buf.add(pl.length); for( p in pl ) serialize(p); } #elseif cpp var enumBase:cpp.EnumBase = v; if( useEnumIndex ) { buf.add(":"); buf.add(enumBase.getIndex()); } else serializeString(enumBase.getTag()); buf.add(":"); var len = enumBase.getParamCount(); buf.add(len); for( p in 0...len ) serialize( enumBase.getParamI(p)); #elseif php if( useEnumIndex ) { buf.add(":"); buf.add(v.index); } else serializeString(v.tag); buf.add(":"); var l : Int = untyped __call__("count", v.params); if( l == 0 || v.params == null) buf.add(0); else { buf.add(l); for( i in 0...l ) { #if (php && php7) serialize(v.params[i]); #elseif php serialize(untyped __field__(v, __php__("params"), i)); #end } } #elseif (java || cs || python || hl) if( useEnumIndex ) { buf.add(":"); buf.add(Type.enumIndex(v)); } else serializeString(Type.enumConstructor(v)); buf.add(":"); var arr:Array = Type.enumParameters(v); if (arr != null) { buf.add(arr.length); for (v in arr) serialize(v); } else { buf.add("0"); } #else if( useEnumIndex ) { buf.add(":"); buf.add(v[1]); } else serializeString(v[0]); buf.add(":"); var l = __getField(v, "length"); buf.add(l - 2); for( i in 2...l ) serialize(v[i]); #end if( useCache ) cache.push(v); case TFunction: throw "Cannot serialize function"; default: #if neko if( untyped (__i32__kind != null && __dollar__iskind(v,__i32__kind)) ) { buf.add("i"); buf.add(v); return; } #end throw "Cannot serialize "+Std.string(v); } } @:extern inline function __getField(o:Dynamic, f:String):Dynamic return untyped o[f]; public function serializeException( e : Dynamic ) { buf.add("x"); #if flash if( untyped __is__(e,__global__["Error"]) ) { var e : flash.errors.Error = e; var s = e.getStackTrace(); if( s == null ) serialize(e.message); else serialize(s); return; } #end serialize(e); } /** Serializes `v` and returns the String representation. This is a convenience function for creating a new instance of Serializer, serialize `v` into it and obtain the result through a call to toString(). **/ public static function run( v : Dynamic ) { var s = new Serializer(); s.serialize(v); return s.toString(); } #if neko static var base_encode = neko.Lib.load("std","base_encode",2); #end } haxe_3.4.4.orig/std/haxe/Template.hx0000664000175000017500000002644613166552354017263 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; private enum TemplateExpr { OpVar( v : String ); OpExpr( expr : Void -> Dynamic ); OpIf( expr : Void -> Dynamic, eif : TemplateExpr, eelse : TemplateExpr ); OpStr( str : String ); OpBlock( l : List ); OpForeach( expr : Void -> Dynamic, loop : TemplateExpr ); OpMacro( name : String, params : List ); } private typedef Token = { var s : Bool; var p : String; var l : Array; } private typedef ExprToken = { var s : Bool; var p : String; } /** Template provides a basic templating mechanism to replace values in a source String, and to have some basic logic. A complete documentation of the supported syntax is available at: **/ class Template { static var splitter = ~/(::[A-Za-z0-9_ ()&|!+=\/><*."-]+::|\$\$([A-Za-z0-9_-]+)\()/; static var expr_splitter = ~/(\(|\)|[ \r\n\t]*"[^"]*"[ \r\n\t]*|[!+=\/><*.&|-]+)/; static var expr_trim = ~/^[ ]*([^ ]+)[ ]*$/; static var expr_int = ~/^[0-9]+$/; static var expr_float = ~/^([+-]?)(?=\d|,\d)\d*(,\d*)?([Ee]([+-]?\d+))?$/; /** Global replacements which are used across all Template instances. This has lower priority than the context argument of execute(). **/ public static var globals : Dynamic = {}; var expr : TemplateExpr; var context : Dynamic; var macros : Dynamic; var stack : List; var buf : StringBuf; /** Creates a new Template instance from `str`. `str` is parsed into tokens, which are stored for internal use. This means that multiple execute() operations on a single Template instance are more efficient than one execute() operations on multiple Template instances. If `str` is null, the result is unspecified. **/ public function new( str : String ) { var tokens = parseTokens(str); expr = parseBlock(tokens); if( !tokens.isEmpty() ) throw "Unexpected '"+tokens.first().s+"'"; } /** Executes `this` Template, taking into account `context` for replacements and `macros` for callback functions. If `context` has a field 'name', its value replaces all occurrences of ::name:: in the Template. Otherwise Template.globals is checked instead, If 'name' is not a field of that either, ::name:: is replaced with null. If `macros` has a field 'name', all occurrences of $$name(args) are replaced with the result of calling that field. The first argument is always the resolve() method, followed by the given arguments. If `macros` has no such field, the result is unspecified. If `context` is null, the result is unspecified. If `macros` is null, no macros are used. **/ public function execute( context : Dynamic, ?macros : Dynamic ):String { this.macros = if( macros == null ) {} else macros; this.context = context; stack = new List(); buf = new StringBuf(); run(expr); return buf.toString(); } function resolve( v : String ) : Dynamic { if( v == "__current__" ) return context; var value = Reflect.getProperty(context, v); if( value != null || Reflect.hasField(context,v) ) return value; for( ctx in stack ) { value = Reflect.getProperty(ctx,v); if( value != null || Reflect.hasField(ctx,v) ) return value; } return Reflect.field(globals,v); } function parseTokens( data : String ) { var tokens = new List(); while( splitter.match(data) ) { var p = splitter.matchedPos(); if( p.pos > 0 ) tokens.add({ p : data.substr(0,p.pos), s : true, l : null }); // : ? if( data.charCodeAt(p.pos) == 58 ) { tokens.add({ p : data.substr(p.pos + 2,p.len - 4), s : false, l : null }); data = splitter.matchedRight(); continue; } // macro parse var parp = p.pos + p.len; var npar = 1; var params = []; var part = ""; while( true ) { var c = data.charCodeAt(parp); parp++; if( c == 40 ) { npar++; } else if( c == 41 ) { npar--; if (npar <= 0) break; } else if( c == null ){ throw "Unclosed macro parenthesis"; } if ( c == 44 && npar == 1) { params.push(part); part = ""; } else { part += String.fromCharCode(c); } } params.push(part); tokens.add({ p : splitter.matched(2), s : false, l : params }); data = data.substr(parp,data.length - parp); } if( data.length > 0 ) tokens.add({ p : data, s : true, l : null }); return tokens; } function parseBlock( tokens : List ) { var l = new List(); while( true ) { var t = tokens.first(); if( t == null ) break; if( !t.s && (t.p == "end" || t.p == "else" || t.p.substr(0,7) == "elseif ") ) break; l.add(parse(tokens)); } if( l.length == 1 ) return l.first(); return OpBlock(l); } function parse( tokens : List ) { var t = tokens.pop(); var p = t.p; if( t.s ) return OpStr(p); // macro if( t.l != null ) { var pe = new List(); for( p in t.l ) pe.add(parseBlock(parseTokens(p))); return OpMacro(p,pe); } // 'end' , 'else', 'elseif' can't be found here if( p.substr(0,3) == "if " ) { p = p.substr(3,p.length - 3); var e = parseExpr(p); var eif = parseBlock(tokens); var t = tokens.first(); var eelse; if( t == null ) throw "Unclosed 'if'"; if( t.p == "end" ) { tokens.pop(); eelse = null; } else if( t.p == "else" ) { tokens.pop(); eelse = parseBlock(tokens); t = tokens.pop(); if( t == null || t.p != "end" ) throw "Unclosed 'else'"; } else { // elseif t.p = t.p.substr(4,t.p.length - 4); eelse = parse(tokens); } return OpIf(e,eif,eelse); } if( p.substr(0,8) == "foreach " ) { p = p.substr(8,p.length - 8); var e = parseExpr(p); var efor = parseBlock(tokens); var t = tokens.pop(); if( t == null || t.p != "end" ) throw "Unclosed 'foreach'"; return OpForeach(e,efor); } if( expr_splitter.match(p) ) return OpExpr(parseExpr(p)); return OpVar(p); } function parseExpr( data : String ) { var l = new List(); var expr = data; while( expr_splitter.match(data) ) { var p = expr_splitter.matchedPos(); var k = p.pos + p.len; if( p.pos != 0 ) l.add({ p : data.substr(0,p.pos), s : true }); var p = expr_splitter.matched(0); l.add({ p : p, s : p.indexOf('"') >= 0 }); data = expr_splitter.matchedRight(); } if( data.length != 0 ) l.add({ p : data, s : true }); var e:Void->Dynamic; try { e = makeExpr(l); if( !l.isEmpty() ) throw l.first().p; } catch( s : String ) { throw "Unexpected '"+s+"' in "+expr; } return function() { try { return e(); } catch( exc : Dynamic ) { throw "Error : "+Std.string(exc)+" in "+expr; } } } function makeConst( v : String ) : Void -> Dynamic { expr_trim.match(v); v = expr_trim.matched(1); if( v.charCodeAt(0) == 34 ) { var str = v.substr(1,v.length-2); return function() return str; } if( expr_int.match(v) ) { var i = Std.parseInt(v); return function() { return i; }; } if( expr_float.match(v) ) { var f = Std.parseFloat(v); return function() { return f; }; } var me = this; return function() { return me.resolve(v); }; } function makePath( e : Void -> Dynamic, l : List ) { var p = l.first(); if( p == null || p.p != "." ) return e; l.pop(); var field = l.pop(); if( field == null || !field.s ) throw field.p; var f = field.p; expr_trim.match(f); f = expr_trim.matched(1); return makePath(function() { return Reflect.field(e(),f); },l); } function makeExpr( l ) { return makePath(makeExpr2(l),l); } function makeExpr2( l : List ) : Void -> Dynamic { var p = l.pop(); if( p == null ) throw ""; if( p.s ) return makeConst(p.p); switch( p.p ) { case "(": var e1:Dynamic = makeExpr(l); var p = l.pop(); if( p == null || p.s ) throw p; if( p.p == ")" ) return e1; var e2:Dynamic = makeExpr(l); var p2 = l.pop(); if( p2 == null || p2.p != ")" ) throw p2; return switch( p.p ) { case "+": function() { return cast e1() + e2(); }; case "-": function() { return cast e1() - e2(); }; case "*": function() { return cast e1() * e2(); }; case "/": function() { return cast e1() / e2(); }; case ">": function() { return cast e1() > e2(); }; case "<": function() { return cast e1() < e2(); }; case ">=": function() { return cast e1() >= e2(); }; case "<=": function() { return cast e1() <= e2(); }; case "==": function() { return cast e1() == e2(); }; case "!=": function() { return cast e1() != e2(); }; case "&&": function() { return cast e1() && e2(); }; case "||": function() { return cast e1() || e2(); }; default: throw "Unknown operation "+p.p; } case "!": var e : Void->Dynamic = makeExpr(l); return function() { var v : Dynamic = e(); return (v == null || v == false); }; case "-": var e = makeExpr(l); return function() { return -e(); }; } throw p.p; } function run( e : TemplateExpr ) { switch( e ) { case OpVar(v): buf.add(Std.string(resolve(v))); case OpExpr(e): buf.add(Std.string(e())); case OpIf(e,eif,eelse): var v : Dynamic = e(); if( v == null || v == false ) { if( eelse != null ) run(eelse); } else run(eif); case OpStr(str): buf.add(str); case OpBlock(l): for( e in l ) run(e); case OpForeach(e,loop): var v : Dynamic = e(); try { var x : Dynamic = v.iterator(); if( x.hasNext == null ) throw null; v = x; } catch( e : Dynamic ) try { if( v.hasNext == null ) throw null; } catch( e : Dynamic ) { throw "Cannot iter on " + v; } stack.push(context); var v : Iterator = v; for( ctx in v ) { context = ctx; run(loop); } context = stack.pop(); case OpMacro(m,params): var v : Dynamic = Reflect.field(macros,m); var pl = new Array(); var old = buf; pl.push(resolve); for( p in params ) { switch( p ) { case OpVar(v): pl.push(resolve(v)); default: buf = new StringBuf(); run(p); pl.push(buf.toString()); } } buf = old; try { buf.add(Std.string(Reflect.callMethod(macros,v,pl))); } catch( e : Dynamic ) { var plstr = try pl.join(",") catch( e : Dynamic ) "???"; var msg = "Macro call "+m+"("+plstr+") failed ("+Std.string(e)+")"; #if neko neko.Lib.rethrow(msg); #else throw msg; #end } } } } haxe_3.4.4.orig/std/haxe/Timer.hx0000664000175000017500000001264613166552354016565 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** The Timer class allows you to create asynchronous timers on platforms that support events. The intended usage is to create an instance of the Timer class with a given interval, set its run() method to a custom function to be invoked and eventually call stop() to stop the Timer. Note that a running Timer may or may not prevent the program to exit automatically when main() returns. It is also possible to extend this class and override its run() method in the child class. **/ class Timer { #if (flash || js) private var id : Null; #elseif java private var timer : java.util.Timer; private var task : java.util.TimerTask; #else private var event : MainLoop.MainEvent; #end /** Creates a new timer that will run every `time_ms` milliseconds. After creating the Timer instance, it calls `this.run` repeatedly, with delays of `time_ms` milliseconds, until `this.stop` is called. The first invocation occurs after `time_ms` milliseconds, not immediately. The accuracy of this may be platform-dependent. **/ public function new( time_ms : Int ){ #if flash var me = this; id = untyped __global__["flash.utils.setInterval"](function() { me.run(); },time_ms); #elseif js var me = this; id = untyped setInterval(function() me.run(),time_ms); #elseif java timer = new java.util.Timer(); timer.scheduleAtFixedRate(task = new TimerTask(this), haxe.Int64.ofInt(time_ms), haxe.Int64.ofInt(time_ms)); #else var dt = time_ms / 1000; event = MainLoop.add(function() { @:privateAccess event.nextRun += dt; run(); }); event.delay(dt); #end } /** Stops `this` Timer. After calling this method, no additional invocations of `this.run` will occur. It is not possible to restart `this` Timer once stopped. **/ public function stop() { #if (flash || js) if( id == null ) return; #if flash untyped __global__["flash.utils.clearInterval"](id); #elseif js untyped clearInterval(id); #end id = null; #elseif java if(timer != null) { timer.cancel(); timer = null; } task = null; #else if( event != null ) { event.stop(); event = null; } #end } /** This method is invoked repeatedly on `this` Timer. It can be overridden in a subclass, or rebound directly to a custom function: var timer = new haxe.Timer(1000); // 1000ms delay timer.run = function() { ... } Once bound, it can still be rebound to different functions until `this` Timer is stopped through a call to `this.stop`. **/ public dynamic function run() { } /** Invokes `f` after `time_ms` milliseconds. This is a convenience function for creating a new Timer instance with `time_ms` as argument, binding its run() method to `f` and then stopping `this` Timer upon the first invocation. If `f` is null, the result is unspecified. **/ public static function delay( f : Void -> Void, time_ms : Int ) { var t = new haxe.Timer(time_ms); t.run = function() { t.stop(); f(); }; return t; } /** Measures the time it takes to execute `f`, in seconds with fractions. This is a convenience function for calculating the difference between Timer.stamp() before and after the invocation of `f`. The difference is passed as argument to Log.trace(), with "s" appended to denote the unit. The optional `pos` argument is passed through. If `f` is null, the result is unspecified. **/ public static function measure( f : Void -> T, ?pos : PosInfos ) : T { var t0 = stamp(); var r = f(); Log.trace((stamp() - t0) + "s", pos); return r; } /** Returns a timestamp, in seconds with fractions. The value itself might differ depending on platforms, only differences between two values make sense. **/ public static inline function stamp() : Float { #if flash return flash.Lib.getTimer() / 1000; #elseif (neko || php) return Sys.time(); #elseif js return Date.now().getTime() / 1000; #elseif cpp return untyped __global__.__time_stamp(); #elseif python return Sys.cpuTime(); #elseif sys return Sys.time(); #else return 0; #end } } #if java @:nativeGen private class TimerTask extends java.util.TimerTask { var timer:Timer; public function new(timer:Timer):Void { super(); this.timer = timer; } @:overload override public function run():Void { timer.run(); } } #end haxe_3.4.4.orig/std/haxe/Ucs2.hx0000664000175000017500000001452613166552354016320 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** Cross platform UCS2 string API. **/ abstract Ucs2(String) { @:extern public var length(get,never) : Int; @:extern inline function new(str:String) : Void { // this implementation only allows platforms which have native UCS2 String. // other platforms should create a shadow class in their _std directory #if !(flash || js) throw "Ucs2 String not supported on this platform"; #end this = str; } @:extern inline function get_length() { return this.length; } /** Returns a Ucs2 where all characters of `this` Ucs2 are upper case. Affects the characters `a-z`. Other characters remain unchanged. **/ @:extern public inline function toUpperCase() : Ucs2 { return new Ucs2(this.toUpperCase()); } /** Returns a Ucs2 where all characters of `this` Ucs2 are lower case. Affects the characters `A-Z`. Other characters remain unchanged. **/ @:extern public inline function toLowerCase() : Ucs2 { return new Ucs2(this.toLowerCase()); } /** Returns the character at position `index` of `this` Ucs2. If `index` is negative or exceeds `this.length`, the empty Ucs2 "" is returned. **/ @:extern public inline function charAt(index : Int) : Ucs2 { return new Ucs2(this.charAt(index)); } /** Returns the character code at position `index` of `this` Ucs2. If `index` is negative or exceeds `this.length`, null is returned. To obtain the character code of a single character, "x".code can be used instead to @:extern public inline the character code at compile time. Note that this only works on Ucs2 literals of length 1. **/ @:extern public inline function charCodeAt( index : Int) : Null { return this.charCodeAt(index); } /** Returns the position of the leftmost occurrence of `str` within `this` Ucs2. If `startIndex` is given, the search is performed within the substring of `this` Ucs2 starting from `startIndex`. Otherwise the search is performed within `this` Ucs2. In either case, the returned position is relative to the beginning of `this` Ucs2. If `str` cannot be found, -1 is returned. **/ @:extern public inline function indexOf( str : Ucs2, ?startIndex : Int ) : Int { return this.indexOf(str.toNativeString(),startIndex); } /** Returns the position of the rightmost occurrence of `str` within `this` Ucs2. If `startIndex` is given, the search is performed within the substring of `this` Ucs2 from 0 to `startIndex`. Otherwise the search is performed within `this` Ucs2. In either case, the returned position is relative to the beginning of `this` Ucs2. If `str` cannot be found, -1 is returned. **/ @:extern public inline function lastIndexOf( str : Ucs2, ?startIndex : Int ) : Int { return this.lastIndexOf(str.toNativeString(),startIndex); } /** Splits `this` Ucs2 at each occurrence of `delimiter`. If `this` Ucs2 is the empty Ucs2 "", the result is not consistent across targets and may either be `[]` (on Js, Cpp) or `[""]`. If `delimiter` is the empty Ucs2 "", `this` Ucs2 is split into an Array of `this.length` elements, where the elements correspond to the characters of `this` Ucs2. If `delimiter` is not found within `this` Ucs2, the result is an Array with one element, which equals `this` Ucs2. If `delimiter` is null, the result is unspecified. Otherwise, `this` Ucs2 is split into parts at each occurrence of `delimiter`. If `this` Ucs2 starts (or ends) with `delimiter`, the result Array contains a leading (or trailing) empty Ucs2 "" element. Two subsequent delimiters also result in an empty Ucs2 "" element. **/ @:extern public inline function split( delimiter : Ucs2 ) : Array { return cast this.split(delimiter.toNativeString()); } /** Returns `len` characters of `this` Ucs2, starting at position `pos`. If `len` is omitted, all characters from position `pos` to the end of `this` Ucs2 are included. If `pos` is negative, its value is calculated from the end of `this` Ucs2 by `this.length + pos`. If this yields a negative value, 0 is used instead. If the calculated position + `len` exceeds `this.length`, the characters from that position to the end of `this` Ucs2 are returned. If `len` is negative, the result is unspecified. **/ @:extern public inline function substr( pos : Int, ?len : Int ) : Ucs2 { return new Ucs2(this.substr(pos,len)); } /** Returns the part of `this` Ucs2 from `startIndex` to `endIndex`. If `startIndex` or `endIndex` are negative, 0 is used instead. If `startIndex` exceeds `endIndex`, they are swapped. If the (possibly swapped) `endIndex` is omitted or exceeds `this.length`, `this.length` is used instead. If the (possibly swapped) `startIndex` exceeds `this.length`, the empty Ucs2 "" is returned. **/ @:extern public inline function substring( startIndex : Int, ?endIndex : Int ) : Ucs2 { return new Ucs2(this.substring(startIndex,endIndex)); } /** Returns the native underlying String. **/ @:extern public inline function toNativeString() : String { return this; } /** Returns the Ucs2 corresponding to the character code `code`. If `code` is negative or has another invalid value, the result is unspecified. **/ @:extern public static inline function fromCharCode( code : Int ) : Ucs2 { return new Ucs2(String.fromCharCode(code)); } }haxe_3.4.4.orig/std/haxe/Unserializer.hx0000664000175000017500000003163213166552354020155 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; @:noDoc typedef TypeResolver = { function resolveClass( name : String ) : Class; function resolveEnum( name : String ) : Enum; } /** The `Unserializer` class is the complement to the `Serializer` class. It parses a serialization `String` and creates objects from the contained data. This class can be used in two ways: - create a `new Unserializer()` instance with a given serialization String, then call its `unserialize()` method until all values are extracted - call `Unserializer.run()` to unserialize a single value from a given String The specification of the serialization format can be found here: **/ class Unserializer { /** This value can be set to use custom type resolvers. A type resolver finds a `Class` or `Enum` instance from a given `String`. By default, the Haxe `Type` Api is used. A type resolver must provide two methods: 1. `resolveClass(name:String):Class` is called to determine a `Class` from a class name 2. `resolveEnum(name:String):Enum` is called to determine an `Enum` from an enum name This value is applied when a new `Unserializer` instance is created. Changing it afterwards has no effect on previously created instances. **/ public static var DEFAULT_RESOLVER : TypeResolver = new DefaultResolver(); static var BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789%:"; #if !neko static var CODES = null; static function initCodes() { var codes = #if flash new flash.utils.ByteArray(); #else new Array(); #end for( i in 0...BASE64.length ) codes[StringTools.fastCodeAt(BASE64,i)] = i; return codes; } #end var buf : String; var pos : Int; var length : Int; var cache : Array; var scache : Array; var resolver : TypeResolver; #if neko var upos : Int; #end /** Creates a new Unserializer instance, with its internal buffer initialized to `buf`. This does not parse `buf` immediately. It is parsed only when calls to `this.unserialize` are made. Each Unserializer instance maintains its own cache. **/ public function new( buf : String ) { this.buf = buf; length = buf.length; pos = 0; #if neko upos = 0; #end scache = new Array(); cache = new Array(); var r = DEFAULT_RESOLVER; if( r == null ) { r = new DefaultResolver(); DEFAULT_RESOLVER = r; } resolver = r; } /** Sets the type resolver of `this` Unserializer instance to `r`. If `r` is null, a special resolver is used which returns null for all input values. See `DEFAULT_RESOLVER` for more information on type resolvers. **/ public function setResolver( r ) { if( r == null ) resolver = NullResolver.instance; else resolver = r; } /** Gets the type resolver of `this` Unserializer instance. See `DEFAULT_RESOLVER` for more information on type resolvers. **/ public function getResolver() { return resolver; } inline function get(p) : Int { return StringTools.fastCodeAt(buf, p); } function readDigits() { var k = 0; var s = false; var fpos = pos; while( true ) { var c = get(pos); if( StringTools.isEof(c) ) break; if( c == "-".code ) { if( pos != fpos ) break; s = true; pos++; continue; } if( c < "0".code || c > "9".code ) break; k = k * 10 + (c - "0".code); pos++; } if( s ) k *= -1; return k; } function readFloat() { var p1 = pos; while( true ) { var c = get(pos); if( StringTools.isEof(c)) break; // + - . , 0-9 if( (c >= 43 && c < 58) || c == "e".code || c == "E".code ) pos++; else break; } return Std.parseFloat(buf.substr(p1,pos-p1)); } function unserializeObject(o) { while( true ) { if( pos >= length ) throw "Invalid object"; if( get(pos) == "g".code ) break; var k = unserialize(); if( !Std.is(k,String) ) throw "Invalid object key"; var v = unserialize(); Reflect.setField(o,k,v); } pos++; } function unserializeEnum( edecl, tag ) { if( get(pos++) != ":".code ) throw "Invalid enum format"; var nargs = readDigits(); if( nargs == 0 ) return Type.createEnum(edecl,tag); var args = new Array(); while( nargs-- > 0 ) args.push(unserialize()); return Type.createEnum(edecl,tag,args); } /** Unserializes the next part of `this` Unserializer instance and returns the according value. This function may call `this.resolver.resolveClass` to determine a Class from a String, and `this.resolver.resolveEnum` to determine an Enum from a String. If `this` Unserializer instance contains no more or invalid data, an exception is thrown. This operation may fail on structurally valid data if a type cannot be resolved or if a field cannot be set. This can happen when unserializing Strings that were serialized on a different Haxe target, in which the serialization side has to make sure not to include platform-specific data. Classes are created from `Type.createEmptyInstance`, which means their constructors are not called. **/ public function unserialize() : Dynamic { switch( get(pos++) ) { case "n".code: return null; case "t".code: return true; case "f".code: return false; case "z".code: return 0; case "i".code: return readDigits(); case "d".code: return readFloat(); case "y".code: var len = readDigits(); if( get(pos++) != ":".code || length - pos < len ) throw "Invalid string length"; var s = buf.substr(pos,len); pos += len; s = StringTools.urlDecode(s); scache.push(s); return s; case "k".code: return Math.NaN; case "m".code: return Math.NEGATIVE_INFINITY; case "p".code: return Math.POSITIVE_INFINITY; case "a".code: var buf = buf; var a = new Array(); #if cpp var cachePos = cache.length; #end cache.push(a); while( true ) { var c = get(pos); if( c == "h".code ) { pos++; break; } if( c == "u".code ) { pos++; var n = readDigits(); a[a.length+n-1] = null; } else a.push(unserialize()); } #if cpp return cache[cachePos] = cpp.NativeArray.resolveVirtualArray(a); #else return a; #end case "o".code: var o = {}; cache.push(o); unserializeObject(o); return o; case "r".code: var n = readDigits(); if( n < 0 || n >= cache.length ) throw "Invalid reference"; return cache[n]; case "R".code: var n = readDigits(); if( n < 0 || n >= scache.length ) throw "Invalid string reference"; return scache[n]; case "x".code: throw unserialize(); case "c".code: var name = unserialize(); var cl = resolver.resolveClass(name); if( cl == null ) throw "Class not found " + name; var o = Type.createEmptyInstance(cl); cache.push(o); unserializeObject(o); return o; case "w".code: var name = unserialize(); var edecl = resolver.resolveEnum(name); if( edecl == null ) throw "Enum not found " + name; var e = unserializeEnum(edecl, unserialize()); cache.push(e); return e; case "j".code: var name = unserialize(); var edecl = resolver.resolveEnum(name); if( edecl == null ) throw "Enum not found " + name; pos++; /* skip ':' */ var index = readDigits(); var tag = Type.getEnumConstructs(edecl)[index]; if( tag == null ) throw "Unknown enum index "+name+"@"+index; var e = unserializeEnum(edecl, tag); cache.push(e); return e; case "l".code: var l = new List(); cache.push(l); var buf = buf; while( get(pos) != "h".code ) l.add(unserialize()); pos++; return l; case "b".code: var h = new haxe.ds.StringMap(); cache.push(h); var buf = buf; while( get(pos) != "h".code ) { var s = unserialize(); h.set(s,unserialize()); } pos++; return h; case "q".code: var h = new haxe.ds.IntMap(); cache.push(h); var buf = buf; var c = get(pos++); while( c == ":".code ) { var i = readDigits(); h.set(i,unserialize()); c = get(pos++); } if( c != "h".code ) throw "Invalid IntMap format"; return h; case "M".code: var h = new haxe.ds.ObjectMap(); cache.push(h); var buf = buf; while( get(pos) != "h".code ) { var s = unserialize(); h.set(s,unserialize()); } pos++; return h; case "v".code: var d; if( get(pos) >= '0'.code && get(pos) <= '9'.code && get(pos + 1) >= '0'.code && get(pos + 1) <= '9'.code && get(pos + 2) >= '0'.code && get(pos + 2) <= '9'.code && get(pos + 3) >= '0'.code && get(pos + 3) <= '9'.code && get(pos + 4) == '-'.code ) { // Included for backwards compatibility d = Date.fromString(buf.substr(pos,19)); pos += 19; } else d = Date.fromTime(readFloat()); cache.push(d); return d; case "s".code: var len = readDigits(); var buf = buf; if( get(pos++) != ":".code || length - pos < len ) throw "Invalid bytes length"; #if neko var bytes = haxe.io.Bytes.ofData( base_decode(untyped buf.substr(pos,len).__s,untyped BASE64.__s) ); #else var codes = CODES; if( codes == null ) { codes = initCodes(); CODES = codes; } var i = pos; var rest = len & 3; var size = (len >> 2) * 3 + ((rest >= 2) ? rest - 1 : 0); var max = i + (len - rest); var bytes = haxe.io.Bytes.alloc(size); var bpos = 0; while( i < max ) { var c1 = codes[StringTools.fastCodeAt(buf,i++)]; var c2 = codes[StringTools.fastCodeAt(buf,i++)]; bytes.set(bpos++,(c1 << 2) | (c2 >> 4)); var c3 = codes[StringTools.fastCodeAt(buf,i++)]; bytes.set(bpos++,(c2 << 4) | (c3 >> 2)); var c4 = codes[StringTools.fastCodeAt(buf,i++)]; bytes.set(bpos++,(c3 << 6) | c4); } if( rest >= 2 ) { var c1 = codes[StringTools.fastCodeAt(buf,i++)]; var c2 = codes[StringTools.fastCodeAt(buf,i++)]; bytes.set(bpos++,(c1 << 2) | (c2 >> 4)); if( rest == 3 ) { var c3 = codes[StringTools.fastCodeAt(buf,i++)]; bytes.set(bpos++,(c2 << 4) | (c3 >> 2)); } } #end pos += len; cache.push(bytes); return bytes; case "C".code: var name = unserialize(); var cl = resolver.resolveClass(name); if( cl == null ) throw "Class not found " + name; var o : Dynamic = Type.createEmptyInstance(cl); cache.push(o); o.hxUnserialize(this); if( get(pos++) != "g".code ) throw "Invalid custom data"; return o; case "A".code: var name = unserialize(); var cl = resolver.resolveClass(name); if( cl == null ) throw "Class not found " + name; return cl; case "B".code: var name = unserialize(); var e = resolver.resolveEnum(name); if( e == null ) throw "Enum not found " + name; return e; default: } pos--; throw ("Invalid char "+buf.charAt(pos)+" at position "+pos); } /** Unserializes `v` and returns the according value. This is a convenience function for creating a new instance of Unserializer with `v` as buffer and calling its unserialize() method once. **/ public static function run( v : String ) : Dynamic { return new Unserializer(v).unserialize(); } #if neko static var base_decode = neko.Lib.load("std","base_decode",2); #end } private class DefaultResolver { public function new() {} @:final public inline function resolveClass(name:String):Class return Type.resolveClass(name); @:final public inline function resolveEnum(name:String):Enum return Type.resolveEnum(name); } private class NullResolver { function new() {} @:final public inline function resolveClass(name:String):Class return null; @:final public inline function resolveEnum(name:String):Enum return null; public static var instance(get,null):NullResolver; inline static function get_instance():NullResolver { if (instance == null) instance = new NullResolver(); return instance; } } haxe_3.4.4.orig/std/haxe/Utf8.hx0000664000175000017500000000620413166552354016324 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; /** Since not all platforms guarantee that `String` always uses UTF-8 encoding, you can use this cross-platform API to perform operations on such strings. **/ class Utf8 { var __b : String; /** Allocate a new Utf8 buffer using an optional bytes size. **/ public function new( ?size : Int ) { __b = ""; } /** Add the given UTF8 character code to the buffer. **/ public inline function addChar( c : Int ) : Void { __b += String.fromCharCode(c); } /** Returns the buffer converted to a String. **/ public inline function toString() : String { return __b; } /** Call the `chars` function for each UTF8 char of the string. **/ public static function iter( s : String, chars : Int -> Void ) { for( i in 0...s.length ) chars(s.charCodeAt(i)); } /** Encode the input ISO string into the corresponding UTF8 one. **/ public static function encode( s : String ) : String { throw "Not implemented"; } /** Decode an UTF8 string back to an ISO string. Throw an exception if a given UTF8 character is not supported by the decoder. **/ public static function decode( s : String ) : String { throw "Not implemented"; } /** Similar to `String.charCodeAt` but uses the UTF8 character position. **/ public static inline function charCodeAt( s : String, index : Int ) : Int { return s.charCodeAt(index); } /** Tells if the String is correctly encoded as UTF8. **/ public static inline function validate( s : String ) : Bool { return true; } /** Returns the number of UTF8 chars of the String. **/ #if js @:extern #end public static inline function length( s : String ) : Int { return s.length; } /** Compare two UTF8 strings, character by character. **/ public static function compare( a : String, b : String ) : Int { return a > b ? 1 : (a == b ? 0 : -1); } /** This is similar to `String.substr` but the `pos` and `len` parts are considering UTF8 characters. **/ public static inline function sub( s : String, pos : Int, len : Int ) : String { return s.substr(pos,len); } } haxe_3.4.4.orig/std/haxe/crypto/Adler32.hx0000664000175000017500000000412013166552354020205 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.crypto; /** Calculates the Adler32 of the given Bytes. */ class Adler32 { var a1 : Int; var a2 : Int; public function new() { a1 = 1; a2 = 0; } public function get() { return (a2 << 16) | a1; } public function update( b : haxe.io.Bytes, pos, len ) { var a1 = a1, a2 = a2; for( p in pos...pos + len ) { var c = b.get(p); a1 = (a1 + c) % 65521; a2 = (a2 + a1) % 65521; } this.a1 = a1; this.a2 = a2; } public function equals( a : Adler32 ) { return a.a1 == a1 && a.a2 == a2; } public function toString() { return StringTools.hex(a2,8) + StringTools.hex(a1,8); } public static function read( i : haxe.io.Input ) { var a = new Adler32(); var a2a = i.readByte(); var a2b = i.readByte(); var a1a = i.readByte(); var a1b = i.readByte(); a.a1 = (a1a << 8) | a1b; a.a2 = (a2a << 8) | a2b; return a; } public static function make( b : haxe.io.Bytes ) { var a = new Adler32(); a.update(b,0,b.length); return a.get(); } } haxe_3.4.4.orig/std/haxe/crypto/Base64.hx0000664000175000017500000000365713166552354020053 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.crypto; /** Allows to encode/decode String and bytes using Base64 encoding. **/ class Base64 { public static var CHARS(default,null) = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; public static var BYTES(default,null) = haxe.io.Bytes.ofString(CHARS); public static function encode( bytes : haxe.io.Bytes, complement = true ) : String { var str = new BaseCode(BYTES).encodeBytes(bytes).toString(); if( complement ) switch (bytes.length % 3) { case 1: str += "=="; case 2: str += "="; default: } return str; } public static function decode( str : String, complement = true ) : haxe.io.Bytes { if( complement ) while( str.charCodeAt(str.length-1) == "=".code ) str = str.substr(0,-1); return new BaseCode(BYTES).decodeBytes(haxe.io.Bytes.ofString(str)); } } haxe_3.4.4.orig/std/haxe/crypto/BaseCode.hx0000664000175000017500000001013013166552354020454 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.crypto; /** Allows to encode/decode String and bytes using a power of two base dictionary. **/ class BaseCode { var base : haxe.io.Bytes; var nbits : Int; var tbl : Array; public function new( base : haxe.io.Bytes ) { var len = base.length; var nbits = 1; while( len > 1 << nbits ) nbits++; if( nbits > 8 || len != 1 << nbits ) throw "BaseCode : base length must be a power of two."; this.base = base; this.nbits = nbits; } public function encodeBytes( b : haxe.io.Bytes ) : haxe.io.Bytes { #if (neko && !interp) return haxe.io.Bytes.ofData( base_encode(b.getData(),base.getData()) ); #else var nbits = this.nbits; var base = this.base; var size = Std.int(b.length * 8 / nbits); var out = haxe.io.Bytes.alloc(size + (((b.length * 8) % nbits == 0) ? 0 : 1) ); var buf = 0; var curbits = 0; var mask = (1 << nbits) - 1; var pin = 0; var pout = 0; while( pout < size ) { while( curbits < nbits ) { curbits += 8; buf <<= 8; buf |= b.get(pin++); } curbits -= nbits; out.set(pout++,base.get((buf >> curbits) & mask)); } if( curbits > 0 ) out.set(pout++,base.get((buf << (nbits - curbits)) & mask)); return out; #end } function initTable() { var tbl = new Array(); for( i in 0...256 ) tbl[i] = -1; for( i in 0...base.length ) tbl[base.get(i)] = i; this.tbl = tbl; } public function decodeBytes( b : haxe.io.Bytes ) : haxe.io.Bytes { #if (neko && !interp) return haxe.io.Bytes.ofData( base_decode(b.getData(),base.getData()) ); #else var nbits = this.nbits; var base = this.base; if( this.tbl == null ) initTable(); var tbl = this.tbl; var size = (b.length * nbits) >> 3; var out = haxe.io.Bytes.alloc(size); var buf = 0; var curbits = 0; var pin = 0; var pout = 0; while( pout < size ) { while( curbits < 8 ) { curbits += nbits; buf <<= nbits; var i = tbl[b.get(pin++)]; if( i == -1 ) throw "BaseCode : invalid encoded char"; buf |= i; } curbits -= 8; out.set(pout++,(buf >> curbits) & 0xFF); } return out; #end } public function encodeString( s : String ) { #if (neko && !interp) return neko.NativeString.toString( base_encode(neko.NativeString.ofString(s),base.getData()) ); #else return encodeBytes(haxe.io.Bytes.ofString(s)).toString(); #end } public function decodeString( s : String ) { #if (neko && !interp) return neko.NativeString.toString( base_decode(neko.NativeString.ofString(s),base.getData()) ); #else return decodeBytes(haxe.io.Bytes.ofString(s)).toString(); #end } public static function encode( s : String, base : String ) { var b = new BaseCode(haxe.io.Bytes.ofString(base)); return b.encodeString(s); } public static function decode( s : String, base : String ) { var b = new BaseCode(haxe.io.Bytes.ofString(base)); return b.decodeString(s); } #if neko private static var base_encode = neko.Lib.load("std","base_encode",2); private static var base_decode = neko.Lib.load("std","base_decode",2); #end } haxe_3.4.4.orig/std/haxe/crypto/Crc32.hx0000664000175000017500000000437713166552354017703 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.crypto; /** Calculates the Crc32 of the given Bytes. */ class Crc32 { var crc : Int; public function new() { crc = 0xFFFFFFFF; } public function byte( b : Int ) { var tmp = (crc ^ b) & 0xFF; for( j in 0...8 ) { if( tmp & 1 == 1 ) tmp = (tmp >>> 1) ^ 0xEDB88320; else tmp >>>= 1; } crc = (crc >>> 8) ^ tmp; } public function update( b : haxe.io.Bytes, pos, len ) { var b = b.getData(); for( i in pos...pos+len ) { var tmp = (crc ^ haxe.io.Bytes.fastGet(b,i)) & 0xFF; for( j in 0...8 ) { if( tmp & 1 == 1 ) tmp = (tmp >>> 1) ^ 0xEDB88320; else tmp >>>= 1; } crc = (crc >>> 8) ^ tmp; } } public function get() { return crc ^ 0xFFFFFFFF; } /** Calculates the CRC32 of the given data bytes **/ public static function make( data : haxe.io.Bytes ) : Int { var init = 0xFFFFFFFF; var crc = init; var b = data.getData(); for( i in 0...data.length ) { var tmp = (crc ^ haxe.io.Bytes.fastGet(b,i)) & 0xFF; for( j in 0...8 ) { if( tmp & 1 == 1 ) tmp = (tmp >>> 1) ^ 0xEDB88320; else tmp >>>= 1; } crc = (crc >>> 8) ^ tmp; } return crc ^ init; } } haxe_3.4.4.orig/std/haxe/crypto/Hmac.hx0000664000175000017500000000502113166552354017662 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.crypto; /** Hash methods for Hmac calculation. */ enum HashMethod { MD5; SHA1; SHA256; } /** Calculates a Hmac of the given Bytes using a HashMethod. */ class Hmac { var method : HashMethod; var blockSize : Int; var length : Int; public function new( hashMethod : HashMethod ) { method = hashMethod; blockSize = switch ( hashMethod ) { case MD5, SHA1, SHA256: 64; } length = switch ( hashMethod ) { case MD5: 16; case SHA1: 20; case SHA256: 32; } } inline function doHash( b : haxe.io.Bytes ) : haxe.io.Bytes { return switch ( method ) { case MD5: Md5.make(b); case SHA1: Sha1.make(b); case SHA256: Sha256.make(b); } } function nullPad( s : haxe.io.Bytes, chunkLen : Int ) : haxe.io.Bytes { var r = chunkLen - (s.length % chunkLen); if(r == chunkLen && s.length != 0) return s; var sb = new haxe.io.BytesBuffer(); sb.add(s); for(x in 0...r) sb.addByte(0); return sb.getBytes(); } public function make( key : haxe.io.Bytes, msg : haxe.io.Bytes ) : haxe.io.Bytes { if(key.length > blockSize) { key = doHash(key); } key = nullPad(key, blockSize); var Ki = new haxe.io.BytesBuffer(); var Ko = new haxe.io.BytesBuffer(); for (i in 0...key.length) { Ko.addByte(key.get(i) ^ 0x5c); Ki.addByte(key.get(i) ^ 0x36); } // hash(Ko + hash(Ki + message)) Ki.add(msg); Ko.add(doHash(Ki.getBytes())); return doHash(Ko.getBytes()); } } haxe_3.4.4.orig/std/haxe/crypto/Md5.hx0000664000175000017500000002141713166552354017446 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.crypto; /** Creates a MD5 of a String. **/ class Md5 { public static function encode( s : String ) : String { #if neko return untyped new String(base_encode(make_md5(s.__s),"0123456789abcdef".__s)); #elseif php return untyped __call__("md5", s); #else var m = new Md5(); var h = m.doEncode(str2blks(s)); return m.hex(h); #end } public static function make( b : haxe.io.Bytes ) : haxe.io.Bytes { #if neko return haxe.io.Bytes.ofData(make_md5(b.getData())); #elseif php return haxe.io.Bytes.ofData( haxe.io.BytesData.ofString(untyped __call__("md5", b.getData().toString(), true))); #else var h = new Md5().doEncode(bytes2blks(b)); var out = haxe.io.Bytes.alloc(16); var p = 0; for( i in 0...4 ) { out.set(p++,h[i]&0xFF); out.set(p++,(h[i]>>8)&0xFF); out.set(p++,(h[i]>>16)&0xFF); out.set(p++,h[i]>>>24); } return out; #end } #if neko static var base_encode = neko.Lib.load("std","base_encode",2); static var make_md5 = neko.Lib.load("std","make_md5",1); #elseif !php /* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorithm, as defined in RFC 1321. * Copyright (C) Paul Johnston 1999 - 2000. * Updated by Greg Holt 2000 - 2001. * See http://pajhome.org.uk/site/legal.html for details. */ function new() { } function bitOR(a, b){ var lsb = (a & 0x1) | (b & 0x1); var msb31 = (a >>> 1) | (b >>> 1); return (msb31 << 1) | lsb; } function bitXOR(a, b){ var lsb = (a & 0x1) ^ (b & 0x1); var msb31 = (a >>> 1) ^ (b >>> 1); return (msb31 << 1) | lsb; } function bitAND(a, b){ var lsb = (a & 0x1) & (b & 0x1); var msb31 = (a >>> 1) & (b >>> 1); return (msb31 << 1) | lsb; } function addme(x, y) { var lsw = (x & 0xFFFF)+(y & 0xFFFF); var msw = (x >> 16)+(y >> 16)+(lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } function hex( a : Array ){ var str = ""; var hex_chr = "0123456789abcdef"; for( num in a ) for( j in 0...4 ) str += hex_chr.charAt((num >> (j * 8 + 4)) & 0x0F) + hex_chr.charAt((num >> (j * 8)) & 0x0F); return str; } static function bytes2blks( b : haxe.io.Bytes ){ var nblk = ((b.length + 8) >> 6) + 1; var blks = new Array(); //preallocate size var blksSize = nblk * 16; #if (neko || cs || cpp || java || hl) blks[blksSize - 1] = 0; #end #if !(cpp || cs || hl) //C++ and C# will already initialize them with zeroes. for( i in 0...blksSize ) blks[i] = 0; #end var i = 0; while( i < b.length ) { blks[i >> 2] |= b.get(i) << ((((b.length << 3) + i) & 3) << 3); i++; } blks[i >> 2] |= 0x80 << (((b.length * 8 + i) % 4) * 8); var l = b.length * 8; var k = nblk * 16 - 2; blks[k] = (l & 0xFF); blks[k] |= ((l >>> 8) & 0xFF) << 8; blks[k] |= ((l >>> 16) & 0xFF) << 16; blks[k] |= ((l >>> 24) & 0xFF) << 24; return blks; } static function str2blks( str : String ){ #if !(neko || cpp || php) var str = haxe.io.Bytes.ofString(str); #end var nblk = ((str.length + 8) >> 6) + 1; var blks = new Array(); //preallocate size var blksSize = nblk * 16; #if (neko || cs || cpp || java || hl) blks[blksSize - 1] = 0; #end #if !(cpp || cs || hl) //C++ and C# will already initialize them with zeroes. for( i in 0...blksSize ) blks[i] = 0; #end var i = 0; var max = str.length; var l = max * 8; while( i < max ) { blks[i >> 2] |= #if !(neko || cpp || php) str.get(i) #else StringTools.fastCodeAt(str, i) #end << (((l + i) % 4) * 8); i++; } blks[i >> 2] |= 0x80 << (((l + i) % 4) * 8); var k = nblk * 16 - 2; blks[k] = (l & 0xFF); blks[k] |= ((l >>> 8) & 0xFF) << 8; blks[k] |= ((l >>> 16) & 0xFF) << 16; blks[k] |= ((l >>> 24) & 0xFF) << 24; return blks; } function rol(num, cnt){ return (num << cnt) | (num >>> (32 - cnt)); } function cmn(q, a, b, x, s, t){ return addme(rol((addme(addme(a, q), addme(x, t))), s), b); } function ff(a, b, c, d, x, s, t){ return cmn(bitOR(bitAND(b, c), bitAND((~b), d)), a, b, x, s, t); } function gg(a, b, c, d, x, s, t){ return cmn(bitOR(bitAND(b, d), bitAND(c, (~d))), a, b, x, s, t); } function hh(a, b, c, d, x, s, t){ return cmn(bitXOR(bitXOR(b, c), d), a, b, x, s, t); } function ii(a, b, c, d, x, s, t){ return cmn(bitXOR(c, bitOR(b, (~d))), a, b, x, s, t); } function doEncode( x : Array ) : Array { var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; var step; var i = 0; while( i < x.length ) { var olda = a; var oldb = b; var oldc = c; var oldd = d; step = 0; a = ff(a, b, c, d, x[i+ 0], 7 , -680876936); d = ff(d, a, b, c, x[i+ 1], 12, -389564586); c = ff(c, d, a, b, x[i+ 2], 17, 606105819); b = ff(b, c, d, a, x[i+ 3], 22, -1044525330); a = ff(a, b, c, d, x[i+ 4], 7 , -176418897); d = ff(d, a, b, c, x[i+ 5], 12, 1200080426); c = ff(c, d, a, b, x[i+ 6], 17, -1473231341); b = ff(b, c, d, a, x[i+ 7], 22, -45705983); a = ff(a, b, c, d, x[i+ 8], 7 , 1770035416); d = ff(d, a, b, c, x[i+ 9], 12, -1958414417); c = ff(c, d, a, b, x[i+10], 17, -42063); b = ff(b, c, d, a, x[i+11], 22, -1990404162); a = ff(a, b, c, d, x[i+12], 7 , 1804603682); d = ff(d, a, b, c, x[i+13], 12, -40341101); c = ff(c, d, a, b, x[i+14], 17, -1502002290); b = ff(b, c, d, a, x[i+15], 22, 1236535329); a = gg(a, b, c, d, x[i+ 1], 5 , -165796510); d = gg(d, a, b, c, x[i+ 6], 9 , -1069501632); c = gg(c, d, a, b, x[i+11], 14, 643717713); b = gg(b, c, d, a, x[i+ 0], 20, -373897302); a = gg(a, b, c, d, x[i+ 5], 5 , -701558691); d = gg(d, a, b, c, x[i+10], 9 , 38016083); c = gg(c, d, a, b, x[i+15], 14, -660478335); b = gg(b, c, d, a, x[i+ 4], 20, -405537848); a = gg(a, b, c, d, x[i+ 9], 5 , 568446438); d = gg(d, a, b, c, x[i+14], 9 , -1019803690); c = gg(c, d, a, b, x[i+ 3], 14, -187363961); b = gg(b, c, d, a, x[i+ 8], 20, 1163531501); a = gg(a, b, c, d, x[i+13], 5 , -1444681467); d = gg(d, a, b, c, x[i+ 2], 9 , -51403784); c = gg(c, d, a, b, x[i+ 7], 14, 1735328473); b = gg(b, c, d, a, x[i+12], 20, -1926607734); a = hh(a, b, c, d, x[i+ 5], 4 , -378558); d = hh(d, a, b, c, x[i+ 8], 11, -2022574463); c = hh(c, d, a, b, x[i+11], 16, 1839030562); b = hh(b, c, d, a, x[i+14], 23, -35309556); a = hh(a, b, c, d, x[i+ 1], 4 , -1530992060); d = hh(d, a, b, c, x[i+ 4], 11, 1272893353); c = hh(c, d, a, b, x[i+ 7], 16, -155497632); b = hh(b, c, d, a, x[i+10], 23, -1094730640); a = hh(a, b, c, d, x[i+13], 4 , 681279174); d = hh(d, a, b, c, x[i+ 0], 11, -358537222); c = hh(c, d, a, b, x[i+ 3], 16, -722521979); b = hh(b, c, d, a, x[i+ 6], 23, 76029189); a = hh(a, b, c, d, x[i+ 9], 4 , -640364487); d = hh(d, a, b, c, x[i+12], 11, -421815835); c = hh(c, d, a, b, x[i+15], 16, 530742520); b = hh(b, c, d, a, x[i+ 2], 23, -995338651); a = ii(a, b, c, d, x[i+ 0], 6 , -198630844); d = ii(d, a, b, c, x[i+ 7], 10, 1126891415); c = ii(c, d, a, b, x[i+14], 15, -1416354905); b = ii(b, c, d, a, x[i+ 5], 21, -57434055); a = ii(a, b, c, d, x[i+12], 6 , 1700485571); d = ii(d, a, b, c, x[i+ 3], 10, -1894986606); c = ii(c, d, a, b, x[i+10], 15, -1051523); b = ii(b, c, d, a, x[i+ 1], 21, -2054922799); a = ii(a, b, c, d, x[i+ 8], 6 , 1873313359); d = ii(d, a, b, c, x[i+15], 10, -30611744); c = ii(c, d, a, b, x[i+ 6], 15, -1560198380); b = ii(b, c, d, a, x[i+13], 21, 1309151649); a = ii(a, b, c, d, x[i+ 4], 6 , -145523070); d = ii(d, a, b, c, x[i+11], 10, -1120210379); c = ii(c, d, a, b, x[i+ 2], 15, 718787259); b = ii(b, c, d, a, x[i+ 9], 21, -343485551); a = addme(a, olda); b = addme(b, oldb); c = addme(c, oldc); d = addme(d, oldd); i += 16; } return [a,b,c,d]; } #end } haxe_3.4.4.orig/std/haxe/crypto/Sha1.hx0000664000175000017500000001073113166552354017612 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.crypto; /** Creates a Sha1 of a String. */ class Sha1 { public static function encode( s:String ) : String { #if php return untyped __call__("sha1", s); #else var sh = new Sha1(); var h = sh.doEncode(str2blks(s)); return sh.hex(h); #end } public static function make( b : haxe.io.Bytes ) : haxe.io.Bytes { #if php return haxe.io.Bytes.ofData(haxe.io.BytesData.ofString(untyped __call__("sha1", b.getData().toString(), true))); #else var h = new Sha1().doEncode(bytes2blks(b)); var out = haxe.io.Bytes.alloc(20); var p = 0; for( i in 0...5 ) { out.set(p++,h[i]>>>24); out.set(p++,(h[i]>>16)&0xFF); out.set(p++,(h[i]>>8)&0xFF); out.set(p++,h[i]&0xFF); } return out; #end } #if !php function new() { } function doEncode( x : Array ) : Array { var w = new Array(); var a = 0x67452301; var b = 0xEFCDAB89; var c = 0x98BADCFE; var d = 0x10325476; var e = 0xC3D2E1F0; var i = 0; while( i < x.length ) { var olda = a; var oldb = b; var oldc = c; var oldd = d; var olde = e; var j = 0; while( j < 80 ) { if(j < 16) w[j] = x[i + j]; else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); var t = rol(a, 5) + ft(j, b, c, d) + e + w[j] + kt(j); e = d; d = c; c = rol(b, 30); b = a; a = t; j++; } a += olda; b += oldb; c += oldc; d += oldd; e += olde; i += 16; } return [a,b,c,d,e]; } /* Convert a string to a sequence of 16-word blocks, stored as an array. Append padding bits and the length, as described in the SHA1 standard. */ static function str2blks( s :String ) : Array { #if !(neko || cpp || php) var s = haxe.io.Bytes.ofString(s); #end var nblk = ((s.length + 8) >> 6) + 1; var blks = new Array(); for (i in 0...nblk*16) blks[i] = 0; for (i in 0...s.length){ var p = i >> 2; blks[p] |= #if !(neko || cpp || php) s.get(i) #else StringTools.fastCodeAt(s,i) #end << (24 - ((i & 3) << 3)); } var i = s.length; var p = i >> 2; blks[p] |= 0x80 << (24 - ((i & 3) << 3)); blks[nblk * 16 - 1] = s.length * 8; return blks; } static function bytes2blks( b : haxe.io.Bytes ) : Array { var nblk = ((b.length + 8) >> 6) + 1; var blks = new Array(); for (i in 0...nblk*16) blks[i] = 0; for (i in 0...b.length){ var p = i >> 2; blks[p] |= b.get(i) << (24 - ((i & 3) << 3)); } var i = b.length; var p = i >> 2; blks[p] |= 0x80 << (24 - ((i & 3) << 3)); blks[nblk * 16 - 1] = b.length * 8; return blks; } /** Bitwise rotate a 32-bit number to the left */ inline function rol( num : Int, cnt : Int ) : Int { return (num << cnt) | (num >>> (32 - cnt)); } /** Perform the appropriate triplet combination function for the current iteration */ function ft( t : Int, b : Int, c : Int, d : Int ) : Int { if ( t < 20 ) return (b & c) | ((~b) & d); if ( t < 40 ) return b ^ c ^ d; if ( t < 60 ) return (b & c) | (b & d) | (c & d); return b ^ c ^ d; } /** Determine the appropriate additive constant for the current iteration */ function kt( t : Int ) : Int { if( t < 20) return 0x5A827999; if ( t < 40) return 0x6ED9EBA1; if (t < 60) return 0x8F1BBCDC; return 0xCA62C1D6; } function hex( a : Array ){ var str = ""; for( num in a ) { str += StringTools.hex(num, 8); } return str.toLowerCase(); } #end } haxe_3.4.4.orig/std/haxe/crypto/Sha224.hx0000664000175000017500000001460113166552354017761 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of Charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERChANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.crypto; /** Creates a Sha224 of a String. */ class Sha224 { public static function encode( s:String ) : String { #if php return untyped __call__("hash", "sha224", s); #else var sh = new Sha224(); var h = sh.doEncode(s, s.length*8); return sh.hex(h); #end } public static function make( b : haxe.io.Bytes ) : haxe.io.Bytes { #if php return haxe.io.Bytes.ofData(haxe.io.BytesData.ofString(untyped __call__("hash", "sha224", b.getData().toString(), true))); #else var h = new Sha224().doEncode(b.toString(), b.length*8); var out = haxe.io.Bytes.alloc(28); var p = 0; for( i in 0...8 ) { out.set(p++,h[i]>>>24); out.set(p++,(h[i]>>16)&0xFF); out.set(p++,(h[i]>>8)&0xFF); out.set(p++,h[i]&0xFF); } return out; #end } public function new() { } function doEncode( str : String, strlen : Int ) : Array { var K : Array = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6 , 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351 , 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 ]; var HASH : Array = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ]; var W = new Array(); W[64] = 0; var a:Int,b:Int,c:Int,d:Int,e:Int,f:Int,g:Int,h:Int,i:Int,j:Int; var T1, T2; var i : Int = 0; var blocks : Array = str2blks(str); blocks[strlen >> 5] |= 0x80 << (24 - strlen % 32); blocks[((strlen + 64 >> 9) << 4) + 15] = strlen; while ( i < blocks.length ) { a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7]; for ( j in 0...64 ) { if (j < 16) { W[j] = blocks[j + i]; } else { W[j] = safeAdd(safeAdd(safeAdd(Gamma1(W[j - 2]), W[j - 7]), Gamma0(W[j - 15])), W[j - 16]); } T1 = safeAdd(safeAdd(safeAdd(safeAdd(h, Sigma1(e)), Ch(e, f, g)), K[j]), W[j]); T2 = safeAdd(Sigma0(a), Maj(a, b, c)); h = g; g = f; f = e; e = safeAdd(d, T1); d = c; c = b; b = a; a = safeAdd(T1, T2); } HASH[0] = safeAdd(a, HASH[0]); HASH[1] = safeAdd(b, HASH[1]); HASH[2] = safeAdd(c, HASH[2]); HASH[3] = safeAdd(d, HASH[3]); HASH[4] = safeAdd(e, HASH[4]); HASH[5] = safeAdd(f, HASH[5]); HASH[6] = safeAdd(g, HASH[6]); HASH[7] = safeAdd(h, HASH[7]); i += 16; } return HASH; } static function str2blks( s :String ) : Array { var nblk = ((s.length + 8) >> 6) + 1; var blks = new Array(); for (i in 0...nblk*16) blks[i] = 0; for (i in 0...s.length){ var p = i >> 2; blks[p] |= s.charCodeAt(i) << (24 - ((i & 3) << 3)); } var i = s.length; var p = i >> 2; blks[p] |= 0x80 << (24 - ((i & 3) << 3)); blks[nblk * 16 - 1] = s.length * 8; return blks; } static function safeAdd(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16); return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); } // ++ function ROTR(X, n) { return ( X >>> n ) | (X << (32 - n)); } // ++ function SHR(X, n) { return ( X >>> n ); } // ++ function Ch(x, y, z) { return ((x & y) ^ ((~x) & z)); } // ++ function Maj(x, y, z) { return ((x & y) ^ (x & z) ^ (y & z)); } function Sigma0(x) { return ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22); } function Sigma1(x) { return ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25); } function Gamma0(x) { return ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3); } function Gamma1(x) { return ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10); } function hex( a : Array ){ var str = ""; for( num in a ) { str += StringTools.hex(num, 8); } return str.substring(0, 56).toLowerCase(); } } haxe_3.4.4.orig/std/haxe/crypto/Sha256.hx0000664000175000017500000001337413166552354017774 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.crypto; /** Creates a Sha256 of a String. */ class Sha256 { public static function encode( s:String ) : String { #if php return untyped __call__("hash", "sha256", s); #else var sh = new Sha256(); var h = sh.doEncode(str2blks(s), s.length*8); return sh.hex(h); #end } public static function make( b : haxe.io.Bytes ) : haxe.io.Bytes { #if php return haxe.io.Bytes.ofData(haxe.io.BytesData.ofString(untyped __call__("hash", "sha256", b.getData().toString(), true))); #else var h = new Sha256().doEncode(bytes2blks(b), b.length*8); var out = haxe.io.Bytes.alloc(32); var p = 0; for( i in 0...8 ) { out.set(p++,h[i]>>>24); out.set(p++,(h[i]>>16)&0xFF); out.set(p++,(h[i]>>8)&0xFF); out.set(p++,h[i]&0xFF); } return out; #end } public function new() { } function doEncode( m : Array, l : Int ) : Array { var K : Array = [ 0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B, 0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01, 0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7, 0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC, 0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152, 0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147, 0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC, 0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85, 0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819, 0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08, 0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F, 0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208, 0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2 ]; var HASH : Array = [ 0x6A09E667,0xBB67AE85,0x3C6EF372,0xA54FF53A, 0x510E527F,0x9B05688C,0x1F83D9AB,0x5BE0CD19 ]; var W = new Array(); W[64] = 0; var a:Int,b:Int,c:Int,d:Int,e:Int,f:Int,g:Int,h:Int; var T1, T2; m[l >> 5] |= 0x80 << (24 - l % 32); m[((l + 64 >> 9) << 4) + 15] = l; var i : Int = 0; while ( i < m.length ) { a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7]; for ( j in 0...64 ) { if (j < 16) W[j] = m[j + i]; else W[j] = safeAdd(safeAdd(safeAdd(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]); T1 = safeAdd(safeAdd(safeAdd(safeAdd(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]); T2 = safeAdd(Sigma0256(a), Maj(a, b, c)); h = g; g = f; f = e; e = safeAdd(d, T1); d = c; c = b; b = a; a = safeAdd(T1, T2); } HASH[0] = safeAdd(a, HASH[0]); HASH[1] = safeAdd(b, HASH[1]); HASH[2] = safeAdd(c, HASH[2]); HASH[3] = safeAdd(d, HASH[3]); HASH[4] = safeAdd(e, HASH[4]); HASH[5] = safeAdd(f, HASH[5]); HASH[6] = safeAdd(g, HASH[6]); HASH[7] = safeAdd(h, HASH[7]); i += 16; } return HASH; } /* Convert a string to a sequence of 16-word blocks, stored as an array. Append padding bits and the length, as described in the SHA1 standard. */ static function str2blks( s :String ) : Array { #if !(neko || cpp || php) var s = haxe.io.Bytes.ofString(s); #end var nblk = ((s.length + 8) >> 6) + 1; var blks = new Array(); for (i in 0...nblk*16) blks[i] = 0; for (i in 0...s.length){ var p = i >> 2; blks[p] |= #if !(neko || cpp || php) s.get(i) #else s.charCodeAt(i) #end << (24 - ((i & 3) << 3)); } var i = s.length; var p = i >> 2; blks[p] |= 0x80 << (24 - ((i & 3) << 3)); blks[nblk * 16 - 1] = s.length * 8; return blks; } static function bytes2blks( b : haxe.io.Bytes ) : Array { var nblk = ((b.length + 8) >> 6) + 1; var blks = new Array(); for (i in 0...nblk*16) blks[i] = 0; for (i in 0...b.length){ var p = i >> 2; blks[p] |= b.get(i) << (24 - ((i & 3) << 3)); } var i = b.length; var p = i >> 2; blks[p] |= 0x80 << (24 - ((i & 3) << 3)); blks[nblk * 16 - 1] = b.length * 8; return blks; } function S(X, n) { return ( X >>> n ) | (X << (32 - n)); } function R(X, n) { return ( X >>> n ); } function Ch(x, y, z) { return ((x & y) ^ ((~x) & z)); } function Maj(x, y, z) { return ((x & y) ^ (x & z) ^ (y & z)); } function Sigma0256(x) { return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); } function Sigma1256(x) { return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); } function Gamma0256(x) { return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); } function Gamma1256(x) { return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); } function safeAdd(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } function hex( a : Array ){ var str = ""; for( num in a ) { str += StringTools.hex(num, 8); } return str.toLowerCase(); } } haxe_3.4.4.orig/std/haxe/ds/ArraySort.hx0000664000175000017500000001044113166552354020030 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** ArraySort provides a stable implementation of merge sort through its `sort` method. It should be used instead of `Array.sort` in cases where the order of equal elements has to be retained on all targets. **/ class ArraySort { /** Sorts Array `a` according to the comparison function `cmp`, where `cmp(x,y)` returns 0 if `x == y`, a positive Int if `x > y` and a negative Int if `x < y`. This operation modifies Array `a` in place. This operation is stable: The order of equal elements is preserved. If `a` or `cmp` are null, the result is unspecified. **/ static public function sort(a:Array, cmp:T -> T -> Int) { rec(a, cmp, 0, a.length); } static function rec(a:Array, cmp, from, to) { var middle = (from + to) >> 1; if (to - from < 12) { if (to <= from) return; for (i in (from + 1)...to) { var j = i; while (j > from) { if (compare(a, cmp, j, j - 1) < 0) swap(a, j - 1, j); else break; j--; } } return; } rec(a, cmp, from, middle); rec(a, cmp, middle, to); doMerge(a, cmp, from, middle, to, middle - from, to - middle); } static function doMerge(a:Array, cmp, from, pivot, to, len1, len2) { var first_cut, second_cut, len11, len22, new_mid; if (len1 == 0 || len2 == 0) return; if (len1 + len2 == 2) { if (compare(a, cmp, pivot, from) < 0) swap(a, pivot, from); return; } if (len1 > len2) { len11 = len1 >> 1; first_cut = from + len11; second_cut = lower(a, cmp, pivot, to, first_cut); len22 = second_cut - pivot; } else { len22 = len2 >> 1; second_cut = pivot + len22; first_cut = upper(a, cmp, from, pivot, second_cut); len11 = first_cut - from; } rotate(a, cmp, first_cut, pivot, second_cut); new_mid = first_cut + len22; doMerge(a, cmp, from, first_cut, new_mid, len11, len22); doMerge(a, cmp, new_mid, second_cut, to, len1 - len11, len2 - len22); } static function rotate(a:Array, cmp, from, mid, to) { var n; if (from == mid || mid == to) return; n = gcd(to - from, mid - from); while (n-- != 0) { var val = a[from + n]; var shift = mid - from; var p1 = from + n, p2 = from + n + shift; while (p2 != from + n) { a[p1] = a[p2]; p1 = p2; if (to - p2 > shift) p2 += shift; else p2 = from + (shift - (to - p2)); } a[p1] = val; } } static function gcd(m, n) { while (n != 0) { var t = m % n; m = n; n = t; } return m; } static function upper(a:Array, cmp, from, to, val) { var len = to - from, half, mid; while (len > 0) { half = len >> 1; mid = from + half; if (compare(a, cmp, val, mid) < 0) len = half; else { from = mid + 1; len = len - half - 1; } } return from; } static function lower(a:Array, cmp, from, to, val) { var len = to - from, half, mid; while (len > 0) { half = len >> 1; mid = from + half; if (compare(a, cmp, mid, val) < 0) { from = mid + 1; len = len - half - 1; } else len = half; } return from; } static function swap(a:Array, i, j) { var tmp = a[i]; a[i] = a[j]; a[j] = tmp; } static inline function compare(a:Array, cmp, i, j) { return cmp(a[i], a[j]); } }haxe_3.4.4.orig/std/haxe/ds/BalancedTree.hx0000664000175000017500000001515513166552354020422 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** BalancedTree allows key-value mapping with arbitrary keys, as long as they can be ordered. By default, `Reflect.compare` is used in the `compare` method, which can be overridden in subclasses. Operations have a logarithmic average and worst-case cost. Iteration over keys and values, using `keys` and `iterator` respectively, are in-order. **/ class BalancedTree { var root:TreeNode; /** Creates a new BalancedTree, which is initially empty. **/ public function new() { } /** Binds `key` to `value`. If `key` is already bound to a value, that binding disappears. If `key` is null, the result is unspecified. **/ public function set(key:K, value:V) { root = setLoop(key, value, root); } /** Returns the value `key` is bound to. If `key` is not bound to any value, `null` is returned. If `key` is null, the result is unspecified. **/ public function get(key:K):Null { var node = root; while (node != null) { var c = compare(key, node.key); if (c == 0) return node.value; if (c < 0) node = node.left; else node = node.right; } return null; } /** Removes the current binding of `key`. If `key` has no binding, `this` BalancedTree is unchanged and false is returned. Otherwise the binding of `key` is removed and true is returned. If `key` is null, the result is unspecified. **/ public function remove(key:K) { try { root = removeLoop(key, root); return true; } catch (e:String) { return false; } } /** Tells if `key` is bound to a value. This method returns true even if `key` is bound to null. If `key` is null, the result is unspecified. **/ public function exists(key:K) { var node = root; while (node != null) { var c = compare(key, node.key); if (c == 0) return true; else if (c < 0) node = node.left; else node = node.right; } return false; } /** Iterates over the bound values of `this` BalancedTree. This operation is performed in-order. **/ public function iterator():Iterator { var ret = []; iteratorLoop(root, ret); return ret.iterator(); } /** Iterates over the keys of `this` BalancedTree. This operation is performed in-order. **/ public function keys():Iterator { var ret = []; keysLoop(root, ret); return ret.iterator(); } function setLoop(k:K, v:V, node:TreeNode) { if (node == null) return new TreeNode(null, k, v, null); var c = compare(k, node.key); return if (c == 0) new TreeNode(node.left, k, v, node.right, node.get_height()); else if (c < 0) { var nl = setLoop(k, v, node.left); balance(nl, node.key, node.value, node.right); } else { var nr = setLoop(k, v, node.right); balance(node.left, node.key, node.value, nr); } } function removeLoop(k:K, node:TreeNode) { if (node == null) throw "Not_found"; var c = compare(k, node.key); return if (c == 0) merge(node.left, node.right); else if (c < 0) balance(removeLoop(k, node.left), node.key, node.value, node.right); else balance(node.left, node.key, node.value, removeLoop(k, node.right)); } function iteratorLoop(node:TreeNode, acc:Array) { if (node != null) { iteratorLoop(node.left, acc); acc.push(node.value); iteratorLoop(node.right, acc); } } function keysLoop(node:TreeNode, acc:Array) { if (node != null) { keysLoop(node.left, acc); acc.push(node.key); keysLoop(node.right, acc); } } function merge(t1, t2) { if (t1 == null) return t2; if (t2 == null) return t1; var t = minBinding(t2); return balance(t1, t.key, t.value, removeMinBinding(t2)); } function minBinding(t:TreeNode) { return if (t == null) throw "Not_found"; else if (t.left == null) t; else minBinding(t.left); } function removeMinBinding(t:TreeNode) { return if (t.left == null) t.right; else balance(removeMinBinding(t.left), t.key, t.value, t.right); } function balance(l:TreeNode, k:K, v:V, r:TreeNode):TreeNode { var hl = l.get_height(); var hr = r.get_height(); return if (hl > hr + 2) { if (l.left.get_height() >= l.right.get_height()) new TreeNode(l.left, l.key, l.value, new TreeNode(l.right, k, v, r)); else new TreeNode(new TreeNode(l.left,l.key, l.value, l.right.left), l.right.key, l.right.value, new TreeNode(l.right.right, k, v, r)); } else if (hr > hl + 2) { if (r.right.get_height() > r.left.get_height()) new TreeNode(new TreeNode(l, k, v, r.left), r.key, r.value, r.right); else new TreeNode(new TreeNode(l, k, v, r.left.left), r.left.key, r.left.value, new TreeNode(r.left.right, r.key, r.value, r.right)); } else { new TreeNode(l, k, v, r, (hl > hr ? hl : hr) + 1); } } function compare(k1:K, k2:K) { return Reflect.compare(k1, k2); } public function toString() { return root == null ? '{}' : '{${root.toString()}}'; } } /** A tree node of `haxe.ds.BalancedTree`. **/ class TreeNode { public var left : TreeNode; public var right : TreeNode; public var key : K; public var value : V; #if as3 public #end var _height : Int; public function new(l, k, v, r, h = -1) { left = l; key = k; value = v; right = r; if (h == -1) _height = (left.get_height() > right.get_height() ? left.get_height() : right.get_height()) + 1; else _height = h; } @:extern public inline function get_height() return this == null ? 0 : _height; public function toString() { return (left == null ? "" : left.toString() + ", ") + '$key=$value' + (right == null ? "" : ", " +right.toString()); } }haxe_3.4.4.orig/std/haxe/ds/Either.hx0000664000175000017500000000240113166552354017317 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** Either represents values which are either of type `L` (Left) or type `R` (Right). **/ enum Either { Left(v:L); Right(v:R); }haxe_3.4.4.orig/std/haxe/ds/EnumValueMap.hx0000664000175000017500000000431713166552354020446 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** EnumValueMap allows mapping of enum value keys to arbitrary values. Keys are compared by value and recursively over their parameters. If any parameter is not an enum value, `Reflect.compare` is used to compare them. **/ class EnumValueMap extends haxe.ds.BalancedTree implements haxe.Constraints.IMap { override function compare(k1:EnumValue, k2:EnumValue):Int { var d = k1.getIndex() - k2.getIndex(); if (d != 0) return d; var p1 = k1.getParameters(); var p2 = k2.getParameters(); if (p1.length == 0 && p2.length == 0) return 0; return compareArgs(p1, p2); } function compareArgs(a1:Array, a2:Array):Int { var ld = a1.length - a2.length; if (ld != 0) return ld; for (i in 0...a1.length) { var d = compareArg(a1[i], a2[i]); if (d != 0) return d; } return 0; } function compareArg(v1:Dynamic, v2:Dynamic):Int { return if (Reflect.isEnumValue(v1) && Reflect.isEnumValue(v2)) { compare(v1, v2); } else if (Std.is(v1, Array) && Std.is(v2, Array)) { compareArgs(v1, v2); } else { Reflect.compare(v1, v2); } } }haxe_3.4.4.orig/std/haxe/ds/GenericStack.hx0000664000175000017500000001032313166552354020443 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** A cell of `haxe.ds.GenericStack`. @see https://haxe.org/manual/std-GenericStack.html **/ #if (flash || cpp) @:generic #end class GenericCell { public var elt : T; public var next : GenericCell; public function new(elt,next) { this.elt = elt; this.next = next; } } #if cpp @:generic private class GenericStackIterator extends cpp.FastIterator { public var current : GenericCell; override public function hasNext():Bool { return current!=null; } override public function next():T { var result = current.elt; current = current.next; return result; } public function new(head) { current = head; } } #end /** A stack of elements. This class is generic, which means one type is generated for each type parameter T on static targets. For example: - `new GenericStack()` generates `GenericStack_Int` - `new GenericStack()` generates `GenericStack_String` The generated name is an implementation detail and should not be relied upon. @see https://haxe.org/manual/std-GenericStack.html **/ #if (flash || cpp) @:generic #end class GenericStack { public var head : GenericCell; /** Creates a new empty GenericStack. **/ public function new() { } /** Pushes element `item` onto the stack. **/ public inline function add( item : T ) { head = new GenericCell(item,head); } /** Returns the topmost stack element without removing it. If the stack is empty, null is returned. **/ public inline function first() : Null { return if( head == null ) null else head.elt; } /** Returns the topmost stack element and removes it. If the stack is empty, null is returned. **/ public inline function pop() : Null { var k = head; if( k== null ) return null; else { head = k.next; return k.elt; } } /** Tells if the stack is empty. **/ public inline function isEmpty() : Bool { return (head == null); } /** Removes the first element which is equal to `v` according to the `==` operator. This method traverses the stack until it finds a matching element and unlinks it, returning true. If no matching element is found, false is returned. **/ public function remove( v : T ) : Bool { var prev:GenericCell = null; var l = head; while( l != null ) { if( l.elt == v ) { if( prev == null ) head = l.next; else prev.next = l.next; break; } prev = l; l = l.next; } return (l != null); } #if cpp /** Returns an iterator over the elements of `this` GenericStack. **/ public function iterator() : Iterator { return new GenericStackIterator(head); } #else /** Returns an iterator over the elements of `this` GenericStack. **/ public function iterator() : Iterator { var l = head; return { hasNext : function() { return l != null; }, next : function() { var k = l; l = k.next; return k.elt; } }; } #end /** Returns a String representation of `this` GenericStack. **/ public function toString() { var a = new Array(); var l = head; while( l != null ) { a.push(l.elt); l = l.next; } return "{"+a.join(",")+"}"; } } haxe_3.4.4.orig/std/haxe/ds/HashMap.hx0000664000175000017500000000451713166552354017432 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** HashMap allows mapping of hashable objects to arbitrary values. See `Map` for documentation details. @see https://haxe.org/manual/std-Map.html **/ abstract HashMap(HashMapData) { /** Creates a new HashMap. **/ public inline function new() { this = new HashMapData(); } /** See `Map.set` **/ public inline function set(k:K, v:V) { this.keys.set(k.hashCode(), k); this.values.set(k.hashCode(), v); } /** See `Map.get` **/ public inline function get(k:K) { return this.values.get(k.hashCode()); } /** See `Map.exists` **/ public inline function exists(k:K) { return this.values.exists(k.hashCode()); } /** See `Map.remove` **/ public inline function remove(k:K) { this.values.remove(k.hashCode()); return this.keys.remove(k.hashCode()); } /** See `Map.keys` **/ public inline function keys() { return this.keys.iterator(); } /** See `Map.iterator` **/ public inline function iterator() { return this.values.iterator(); } } private class HashMapData { public var keys:IntMap; public var values:IntMap; public inline function new() { keys = new IntMap(); values = new IntMap(); } }haxe_3.4.4.orig/std/haxe/ds/IntMap.hx0000664000175000017500000000362313166552354017276 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** IntMap allows mapping of Int keys to arbitrary values. See `Map` for documentation details. @see https://haxe.org/manual/std-Map.html **/ extern class IntMap implements haxe.Constraints.IMap { /** Creates a new IntMap. **/ public function new() : Void; /** See `Map.set` **/ public function set( key : Int, value : T ) : Void; /** See `Map.get` **/ public function get( key : Int ) : Null; /** See `Map.exists` **/ public function exists( key : Int ) : Bool; /** See `Map.remove` **/ public function remove( key : Int ) : Bool; /** See `Map.keys` **/ public function keys() : Iterator; /** See `Map.iterator` **/ public function iterator() : Iterator; /** See `Map.toString` **/ public function toString() : String; } haxe_3.4.4.orig/std/haxe/ds/ListSort.hx0000664000175000017500000000753413166552354017676 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** ListSort provides a stable implementation of merge sort through its `sort` method. It has a O(N.log(N)) complexity and does not require additional memory allocation. **/ class ListSort { // Note : we prefer [inline] over [@:generic] here since we want to inline the comparison function as well /** Sorts List `lst` according to the comparison function `cmp`, where `cmp(x,y)` returns 0 if `x == y`, a positive Int if `x > y` and a negative Int if `x < y`. This operation modifies List `a` in place and returns its head once modified. The `prev` of the head is set to the tail of the sorted list. If `list` or `cmp` are null, the result is unspecified. **/ public static inline function sort(list:T, cmp : T -> T -> Int) : T { // ported from http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html if( list == null ) return null; var insize = 1, nmerges, psize = 0, qsize = 0; var p, q, e, tail : T = null; while( true ) { p = list; list = null; tail = null; nmerges = 0; while( p != null ) { nmerges++; q = p; psize = 0; for( i in 0...insize ) { psize++; q = q.next; if( q == null ) break; } qsize = insize; while( psize > 0 || (qsize > 0 && q != null) ) { if( psize == 0 ) { e = q; q = q.next; qsize--; } else if( qsize == 0 || q == null || cmp(p,q) <= 0 ) { e = p; p = p.next; psize--; } else { e = q; q = q.next; qsize--; } if( tail != null ) tail.next = e; else list = e; e.prev = tail; tail = e; } p = q; } tail.next = null; if( nmerges <= 1 ) break; insize *= 2; } list.prev = tail; return list; } /** Same as `sort` but on single linked list. **/ public static inline function sortSingleLinked(list:T, cmp : T -> T -> Int) : T { if( list == null ) return null; var insize = 1, nmerges, psize = 0, qsize = 0; var p, q, e, tail : T; while( true ) { p = list; list = null; tail = null; nmerges = 0; while( p != null ) { nmerges++; q = p; psize = 0; for( i in 0...insize ) { psize++; q = q.next; if( q == null ) break; } qsize = insize; while( psize > 0 || (qsize > 0 && q != null) ) { if( psize == 0 ) { e = q; q = q.next; qsize--; } else if( qsize == 0 || q == null || cmp(p,q) <= 0 ) { e = p; p = p.next; psize--; } else { e = q; q = q.next; qsize--; } if( tail != null ) tail.next = e; else list = e; tail = e; } p = q; } tail.next = null; if( nmerges <= 1 ) break; insize *= 2; } return list; } }haxe_3.4.4.orig/std/haxe/ds/ObjectMap.hx0000664000175000017500000000377313166552354017760 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** ObjectMap allows mapping of object keys to arbitrary values. On static targets, the keys are considered to be strong references. Refer to `haxe.ds.WeakMap` for a weak reference version. See `Map` for documentation details. @see https://haxe.org/manual/std-Map.html **/ extern class ObjectMap < K: { }, V > implements haxe.Constraints.IMap { /** Creates a new ObjectMap. **/ public function new():Void; /** See `Map.set` **/ public function set(key:K, value:V):Void; /** See `Map.get` **/ public function get(key:K):Null; /** See `Map.exists` **/ public function exists(key:K):Bool; /** See `Map.remove` **/ public function remove(key:K):Bool; /** See `Map.keys` **/ public function keys():Iterator; /** See `Map.iterator` **/ public function iterator():Iterator; /** See `Map.toString` **/ public function toString():String; }haxe_3.4.4.orig/std/haxe/ds/Option.hx0000664000175000017500000000245513166552354017360 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** An Option is a wrapper type which can either have a value (Some) or not a value (None). @see https://haxe.org/manual/std-Option.html **/ enum Option { Some(v:T); None; }haxe_3.4.4.orig/std/haxe/ds/StringMap.hx0000664000175000017500000000366213166552354020015 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** StringMap allows mapping of String keys to arbitrary values. See `Map` for documentation details. @see https://haxe.org/manual/std-Map.html **/ extern class StringMap implements haxe.Constraints.IMap { /** Creates a new StringMap. **/ public function new() : Void; /** See `Map.set` **/ public function set( key : String, value : T ) : Void; /** See `Map.get` **/ public function get( key : String ) : Null; /** See `Map.exists` **/ public function exists( key : String ) : Bool; /** See `Map.remove` **/ public function remove( key : String ) : Bool; /** See `Map.keys` **/ public function keys() : Iterator; /** See `Map.iterator` **/ public function iterator() : Iterator; /** See `Map.toString` **/ public function toString() : String; } haxe_3.4.4.orig/std/haxe/ds/Vector.hx0000664000175000017500000002100613166552354017343 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; #if cpp using cpp.NativeArray; #end private typedef VectorData = #if flash10 flash.Vector #elseif neko neko.NativeArray #elseif cs cs.NativeArray #elseif java java.NativeArray #elseif lua lua.Table #else Array #end /** A Vector is a storage of fixed size. It can be faster than Array on some targets, and is never slower. @see https://haxe.org/manual/std-vector.html **/ abstract Vector(VectorData) { /** Creates a new Vector of length `length`. Initially `this` Vector contains `length` neutral elements: - always null on dynamic targets - 0, 0.0 or false for Int, Float and Bool respectively on static targets - null for other types on static targets If `length` is less than or equal to 0, the result is unspecified. **/ public inline function new(length:Int) { #if flash10 this = new flash.Vector(length, true); #elseif neko this = untyped __dollar__amake(length); #elseif js this = untyped __new__(Array, length); #elseif cs this = new cs.NativeArray(length); #elseif java this = new java.NativeArray(length); #elseif cpp this = NativeArray.create(length); #elseif python this = python.Syntax.pythonCode("[{0}]*{1}", null, length); #elseif lua this = untyped __lua_table__({length:length}); #else this = []; untyped this.length = length; #end } /** Returns the value at index `index`. If `index` is negative or exceeds `this.length`, the result is unspecified. **/ @:op([]) public inline function get(index:Int):T { #if cpp return this.unsafeGet(index); #elseif python return python.internal.ArrayImpl.unsafeGet(this, index); #else return this[index]; #end } /** Sets the value at index `index` to `val`. If `index` is negative or exceeds `this.length`, the result is unspecified. **/ @:op([]) public inline function set(index:Int, val:T):T { #if cpp return this.unsafeSet(index,val); #elseif python return python.internal.ArrayImpl.unsafeSet(this, index, val); #else return this[index] = val; #end } /** Returns the length of `this` Vector. **/ public var length(get, never):Int; inline function get_length():Int { #if neko return untyped __dollar__asize(this); #elseif cs return this.Length; #elseif java return this.length; #elseif python return this.length; #else return untyped this.length; #end } /** Copies `length` of elements from `src` Vector, beginning at `srcPos` to `dest` Vector, beginning at `destPos` The results are unspecified if `length` results in out-of-bounds access, or if `src` or `dest` are null **/ public static #if (cs || java || neko || cpp) inline #end function blit(src:Vector, srcPos:Int, dest:Vector, destPos:Int, len:Int):Void { #if neko untyped __dollar__ablit(dest,destPos,src,srcPos,len); #elseif java java.lang.System.arraycopy(src, srcPos, dest, destPos, len); #elseif cs cs.system.Array.Copy(cast src, srcPos,cast dest, destPos, len); #elseif cpp dest.toData().blit(destPos,src.toData(), srcPos,len); #else if (src == dest) { if (srcPos < destPos) { var i = srcPos + len; var j = destPos + len; for (k in 0...len) { i--; j--; src[j] = src[i]; } } else if (srcPos > destPos) { var i = srcPos; var j = destPos; for (k in 0...len) { src[j] = src[i]; i++; j++; } } } else { for (i in 0...len) { dest[destPos + i] = src[srcPos + i]; } } #end } /** Creates a new Array, copy the content from the Vector to it, and returns it. **/ public #if (flash || cpp || js || java) inline #end function toArray():Array { #if cpp return this.copy(); #elseif python return this.copy(); #elseif js return this.slice(0); #else var a = new Array(); var len = length; #if (neko) // prealloc good size if( len > 0 ) a[len - 1] = get(0); #end for( i in 0...len ) a[i] = get(i); return a; #end } /** Extracts the data of `this` Vector. This returns the internal representation type. **/ public inline function toData():VectorData return cast this; /** Initializes a new Vector from `data`. Since `data` is the internal representation of Vector, this is a no-op. If `data` is null, the corresponding Vector is also `null`. **/ static public inline function fromData(data:VectorData):Vector return cast data; /** Creates a new Vector by copying the elements of `array`. This always creates a copy, even on platforms where the internal representation is Array. The elements are not copied and retain their identity, so `a[i] == Vector.fromArrayCopy(a).get(i)` is true for any valid i. If `array` is null, the result is unspecified. **/ #if as3 @:extern #end static public inline function fromArrayCopy(array:Array):Vector { #if python return cast array.copy(); #elseif flash10 return fromData(flash.Vector.ofArray(array)); #elseif java return fromData(java.Lib.nativeArray(array,false)); #elseif cs return fromData(cs.Lib.nativeArray(array,false)); #elseif cpp return cast array.copy(); #elseif js return fromData(array.slice(0)); #else // TODO: Optimize this for others? var vec = new Vector(array.length); for (i in 0...array.length) vec.set(i, array[i]); return vec; #end } /** Returns a shallow copy of `this` Vector. The elements are not copied and retain their identity, so `a[i] == a.copy()[i]` is true for any valid `i`. However, `a == a.copy()` is always false. **/ #if cs @:extern #end public inline function copy():Vector { var r = new Vector(length); Vector.blit(cast this, 0, r, 0, length); return r; } /** Returns a string representation of `this` Vector, with `sep` separating each element. The result of this operation is equal to `Std.string(this[0]) + sep + Std.string(this[1]) + sep + ... + sep + Std.string(this[this.length-1])` If `this` Vector has length 0, the result is the empty String `""`. If `this` has exactly one element, the result is equal to a call to `Std.string(this[0])`. If `sep` is null, the result is unspecified. **/ #if cs @:extern #end public inline function join(sep:String):String { #if (flash10||cpp) return this.join(sep); #else var b = new StringBuf(); var i = 0; var len = length; for(i in 0...len) { b.add( Std.string(get(i)) ); if(i < len-1) { b.add(sep); } } return b.toString(); #end } /** Creates a new Vector by applying function `f` to all elements of `this`. The order of elements is preserved. If `f` is null, the result is unspecified. **/ #if cs @:extern #end public inline function map(f:T->S):Vector { var length = length; var r = new Vector(length); var i = 0; var len = length; for(i in 0...len) { var v = f(get(i)); r.set(i, v); } return r; } /** Sorts `this` Vector according to the comparison function `f`, where `f(x,y)` returns 0 if x == y, a positive Int if x > y and a negative Int if x < y. This operation modifies `this` Vector in place. The sort operation is not guaranteed to be stable, which means that the order of equal elements may not be retained. If `f` is null, the result is unspecified. **/ public inline function sort(f:T->T->Int):Void { #if (neko || cs || java) throw "not yet supported"; #elseif lua haxe.ds.ArraySort.sort(cast this, f); #else this.sort(f); #end } } haxe_3.4.4.orig/std/haxe/ds/WeakMap.hx0000664000175000017500000000412613166552354017432 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; /** WeakMap allows mapping of object keys to arbitrary values. The keys are considered to be weak references on static targets. See `Map` for documentation details. @see https://haxe.org/manual/std-Map.html **/ class WeakMap implements haxe.Constraints.IMap { /** Creates a new WeakMap. **/ public function new():Void { throw "Not implemented for this platform"; } /** See `Map.set` **/ public function set(key:K, value:V):Void { } /** See `Map.get` **/ public function get(key:K):Null { return null; } /** See `Map.exists` **/ public function exists(key:K):Bool { return false; } /** See `Map.remove` **/ public function remove(key:K):Bool { return false; } /** See `Map.keys` **/ public function keys():Iterator { return null; } /** See `Map.iterator` **/ public function iterator():Iterator { return null; } /** See `Map.toString` **/ public function toString():String { return null; } }haxe_3.4.4.orig/std/haxe/extern/AsVar.hx0000664000175000017500000000247513166552354020025 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.extern; /** If this type is used as an argument type, the compiler ensures that argument expressions are bound to a local variable. **/ @:forward @:analyzer(as_var) abstract AsVar(T) from T to T {}haxe_3.4.4.orig/std/haxe/extern/EitherType.hx0000664000175000017500000000277713166552354021100 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.extern; /** An abstract type allowing values to be either of `T1` or `T2` type. Supports implicit casts from/to either types. It is useful for interfacing with external code on dynamic platforms such as JavaScript or Python. Otherwise, use of this type is discouraged. @see **/ abstract EitherType(Dynamic) from T1 to T1 from T2 to T2 {} haxe_3.4.4.orig/std/haxe/extern/Rest.hx0000664000175000017500000000267213166552354017725 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.extern; /** A special abstract type that represents "rest" function argument. Should be used as a type for the last argument of an extern method, representing that arbitrary number of arguments of given type can be passed to that method. @see **/ abstract Rest(Array) {} haxe_3.4.4.orig/std/haxe/format/JsonParser.hx0000664000175000017500000001613313166552354021056 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.format; /** An implementation of JSON parser in Haxe. This class is used by `haxe.Json` when native JSON implementation is not available. @see https://haxe.org/manual/std-Json-parsing.html **/ class JsonParser { /** Parses given JSON-encoded `str` and returns the resulting object. JSON objects are parsed into anonymous structures and JSON arrays are parsed into `Array`. If given `str` is not valid JSON, an exception will be thrown. If `str` is null, the result is unspecified. **/ static public inline function parse(str : String) : Dynamic { return new JsonParser(str).parseRec(); } var str : String; var pos : Int; function new( str : String ) { this.str = str; this.pos = 0; } function parseRec() : Dynamic { while( true ) { var c = nextChar(); switch( c ) { case ' '.code, '\r'.code, '\n'.code, '\t'.code: // loop case '{'.code: var obj = {}, field = null, comma : Null = null; while( true ) { var c = nextChar(); switch( c ) { case ' '.code, '\r'.code, '\n'.code, '\t'.code: // loop case '}'.code: if( field != null || comma == false ) invalidChar(); return obj; case ':'.code: if( field == null ) invalidChar(); Reflect.setField(obj,field,parseRec()); field = null; comma = true; case ','.code: if( comma ) comma = false else invalidChar(); case '"'.code: if( comma ) invalidChar(); field = parseString(); default: invalidChar(); } } case '['.code: var arr = [], comma : Null = null; while( true ) { var c = nextChar(); switch( c ) { case ' '.code, '\r'.code, '\n'.code, '\t'.code: // loop case ']'.code: if( comma == false ) invalidChar(); return arr; case ','.code: if( comma ) comma = false else invalidChar(); default: if( comma ) invalidChar(); pos--; arr.push(parseRec()); comma = true; } } case 't'.code: var save = pos; if( nextChar() != 'r'.code || nextChar() != 'u'.code || nextChar() != 'e'.code ) { pos = save; invalidChar(); } return true; case 'f'.code: var save = pos; if( nextChar() != 'a'.code || nextChar() != 'l'.code || nextChar() != 's'.code || nextChar() != 'e'.code ) { pos = save; invalidChar(); } return false; case 'n'.code: var save = pos; if( nextChar() != 'u'.code || nextChar() != 'l'.code || nextChar() != 'l'.code ) { pos = save; invalidChar(); } return null; case '"'.code: return parseString(); case '0'.code, '1'.code,'2'.code,'3'.code,'4'.code,'5'.code,'6'.code,'7'.code,'8'.code,'9'.code,'-'.code: return parseNumber(c); default: invalidChar(); } } } function parseString() { var start = pos; var buf = null; while( true ) { var c = nextChar(); if( c == '"'.code ) break; if( c == '\\'.code ) { if (buf == null) { buf = new StringBuf(); } buf.addSub(str,start, pos - start - 1); c = nextChar(); switch( c ) { case "r".code: buf.addChar("\r".code); case "n".code: buf.addChar("\n".code); case "t".code: buf.addChar("\t".code); case "b".code: buf.addChar(8); case "f".code: buf.addChar(12); case "/".code, '\\'.code, '"'.code: buf.addChar(c); case 'u'.code: var uc = Std.parseInt("0x" + str.substr(pos, 4)); pos += 4; #if (neko || php || cpp || lua) if( uc <= 0x7F ) buf.addChar(uc); else if( uc <= 0x7FF ) { buf.addChar(0xC0 | (uc >> 6)); buf.addChar(0x80 | (uc & 63)); } else if( uc <= 0xFFFF ) { buf.addChar(0xE0 | (uc >> 12)); buf.addChar(0x80 | ((uc >> 6) & 63)); buf.addChar(0x80 | (uc & 63)); } else { buf.addChar(0xF0 | (uc >> 18)); buf.addChar(0x80 | ((uc >> 12) & 63)); buf.addChar(0x80 | ((uc >> 6) & 63)); buf.addChar(0x80 | (uc & 63)); } #else buf.addChar(uc); #end default: throw "Invalid escape sequence \\" + String.fromCharCode(c) + " at position " + (pos - 1); } start = pos; } #if (neko || php || cpp) // ensure utf8 chars are not cut else if( c >= 0x80 ) { pos++; if( c >= 0xFC ) pos += 4; else if( c >= 0xF8 ) pos += 3; else if( c >= 0xF0 ) pos += 2; else if( c >= 0xE0 ) pos++; } #end else if( StringTools.isEof(c) ) throw "Unclosed string"; } if (buf == null) { return str.substr(start, pos - start - 1); } else { buf.addSub(str,start, pos - start - 1); return buf.toString(); } } inline function parseNumber( c : Int ) : Dynamic { var start = pos - 1; var minus = c == '-'.code, digit = !minus, zero = c == '0'.code; var point = false, e = false, pm = false, end = false; while( true ) { c = nextChar(); switch( c ) { case '0'.code : if (zero && !point) invalidNumber(start); if (minus) { minus = false; zero = true; } digit = true; case '1'.code,'2'.code,'3'.code,'4'.code,'5'.code,'6'.code,'7'.code,'8'.code,'9'.code : if (zero && !point) invalidNumber(start); if (minus) minus = false; digit = true; zero = false; case '.'.code : if (minus || point) invalidNumber(start); digit = false; point = true; case 'e'.code, 'E'.code : if (minus || zero || e) invalidNumber(start); digit = false; e = true; case '+'.code, '-'.code : if (!e || pm) invalidNumber(start); digit = false; pm = true; default : if (!digit) invalidNumber(start); pos--; end = true; } if (end) break; } var f = Std.parseFloat(str.substr(start, pos - start)); var i = Std.int(f); return if( i == f ) i else f; } inline function nextChar() { return StringTools.fastCodeAt(str,pos++); } function invalidChar() { pos--; // rewind throw "Invalid char "+StringTools.fastCodeAt(str,pos)+" at position "+pos; } function invalidNumber( start : Int ) { throw "Invalid number at position "+start+": " + str.substr(start, pos - start); } } haxe_3.4.4.orig/std/haxe/format/JsonPrinter.hx0000664000175000017500000001413013166552354021240 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.format; /** An implementation of JSON printer in Haxe. This class is used by `haxe.Json` when native JSON implementation is not available. @see https://haxe.org/manual/std-Json-encoding.html **/ class JsonPrinter { /** Encodes `o`'s value and returns the resulting JSON string. If `replacer` is given and is not null, it is used to retrieve actual object to be encoded. The `replacer` function takes two parameters, the key and the value being encoded. Initial key value is an empty string. If `space` is given and is not null, the result will be pretty-printed. Successive levels will be indented by this string. **/ static public function print(o:Dynamic, ?replacer:Dynamic -> Dynamic -> Dynamic, ?space:String) : String { var printer = new JsonPrinter(replacer, space); printer.write("", o); return printer.buf.toString(); } var buf : #if flash flash.utils.ByteArray #else StringBuf #end; var replacer : Dynamic -> Dynamic -> Dynamic; var indent:String; var pretty:Bool; var nind:Int; function new(replacer:Dynamic -> Dynamic -> Dynamic, space:String) { this.replacer = replacer; this.indent = space; this.pretty = space != null; this.nind = 0; #if flash buf = new flash.utils.ByteArray(); buf.endian = flash.utils.Endian.BIG_ENDIAN; buf.position = 0; #else buf = new StringBuf(); #end } inline function ipad ():Void { if (pretty) add(StringTools.lpad('', indent, nind * indent.length)); } inline function newl ():Void { if (pretty) addChar('\n'.code); } function write(k:Dynamic, v:Dynamic) { if (replacer != null) v = replacer(k, v); switch( Type.typeof(v) ) { case TUnknown: add('"???"'); case TObject: objString(v); case TInt: add(#if as3 Std.string(v) #else v #end); case TFloat: add(Math.isFinite(v) ? v : 'null'); case TFunction: add('""'); case TClass(c): if( c == String ) quote(v); else if( c == Array ) { var v : Array = v; addChar('['.code); var len = v.length; var last = len - 1; for (i in 0...len) { if (i > 0) addChar(','.code) else nind++; newl(); ipad(); write(i, v[i]); if (i == last) { nind--; newl(); ipad(); } } addChar(']'.code); } else if( c == haxe.ds.StringMap ) { var v : haxe.ds.StringMap = v; var o = {}; for( k in v.keys() ) Reflect.setField(o,k,v.get(k)); objString(o); } else if( c == Date ) { var v : Date = v; quote(v.toString()); } else #if flash classString(v); #else objString(v); #end case TEnum(_): var i : Dynamic = Type.enumIndex(v); add(i); case TBool: add(#if (php || as3) (v ? 'true' : 'false') #else v #end); case TNull: add('null'); } } @:extern inline function addChar(c:Int) { #if flash buf.writeByte(c); #else buf.addChar(c); #end } @:extern inline function add(v:String) { #if flash // argument is not always a string but will be automatically casted buf.writeUTFBytes(v); #else buf.add(v); #end } #if flash function classString ( v : Dynamic ) { fieldsString(v,Type.getInstanceFields(Type.getClass(v))); } #end inline function objString( v : Dynamic ) { fieldsString(v,Reflect.fields(v)); } function fieldsString( v : Dynamic, fields : Array ) { addChar('{'.code); var len = fields.length; var last = len - 1; var first = true; for( i in 0...len ) { var f = fields[i]; var value = Reflect.field(v,f); if( Reflect.isFunction(value) ) continue; if( first ) { nind++; first = false; } else addChar(','.code); newl(); ipad(); quote(f); addChar(':'.code); if (pretty) addChar(' '.code); write(f, value); if (i == last) { nind--; newl(); ipad(); } } addChar('}'.code); } function quote( s : String ) { #if (neko || php || cpp) if( s.length != haxe.Utf8.length(s) ) { quoteUtf8(s); return; } #end addChar('"'.code); var i = 0; while( true ) { var c = StringTools.fastCodeAt(s, i++); if( StringTools.isEof(c) ) break; switch( c ) { case '"'.code: add('\\"'); case '\\'.code: add('\\\\'); case '\n'.code: add('\\n'); case '\r'.code: add('\\r'); case '\t'.code: add('\\t'); case 8: add('\\b'); case 12: add('\\f'); default: #if flash if( c >= 128 ) add(String.fromCharCode(c)) else addChar(c); #else addChar(c); #end } } addChar('"'.code); } #if (neko || php || cpp) function quoteUtf8( s : String ) { var u = new haxe.Utf8(); haxe.Utf8.iter(s,function(c) { switch( c ) { case '\\'.code, '"'.code: u.addChar('\\'.code); u.addChar(c); case '\n'.code: u.addChar('\\'.code); u.addChar('n'.code); case '\r'.code: u.addChar('\\'.code); u.addChar('r'.code); case '\t'.code: u.addChar('\\'.code); u.addChar('t'.code); case 8: u.addChar('\\'.code); u.addChar('b'.code); case 12: u.addChar('\\'.code); u.addChar('f'.code); default: u.addChar(c); } }); buf.add('"'); buf.add(u.toString()); buf.add('"'); } #end } haxe_3.4.4.orig/std/haxe/io/ArrayBufferView.hx0000664000175000017500000000703613166552354021154 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef ArrayBufferViewData = ArrayBufferViewImpl; class ArrayBufferViewImpl { public var bytes : haxe.io.Bytes; public var byteOffset : Int; public var byteLength : Int; public function new(bytes, pos, length) { this.bytes = bytes; this.byteOffset = pos; this.byteLength = length; } public function sub( begin : Int, ?length : Int ) { if( length == null ) length = byteLength - begin; if( begin < 0 || length < 0 || begin + length > byteLength ) throw Error.OutsideBounds; return new ArrayBufferViewImpl(bytes, byteOffset + begin, length); } public function subarray( ?begin : Int, ?end : Int ) { if( begin == null ) begin = 0; if( end == null ) end = byteLength - begin; return sub(begin, end - begin); } } abstract ArrayBufferView(ArrayBufferViewData) { /** On some platforms configurations (for instance JS with no TypedArray support as in IE8-), Haxe will try to emulate the array buffers API. However in that case memory sharing will not be supported : each typed array or will copy its own data set. This flag allows users to detect if we are doing such emulation. At the moment only JavaScript is concerned. **/ public static var EMULATED(get,never) : Bool; static inline function get_EMULATED() : Bool { return false; } public var buffer(get,never) : haxe.io.Bytes; public var byteOffset(get, never) : Int; public var byteLength(get, never) : Int; public inline function new( size : Int ) { this = new ArrayBufferViewData(haxe.io.Bytes.alloc(size), 0, size); } inline function get_byteOffset() : Int return this.byteOffset; inline function get_byteLength() : Int return this.byteLength; inline function get_buffer() : haxe.io.Bytes return this.bytes; public inline function sub( begin : Int, ?length : Int ) : ArrayBufferView { return fromData(this.sub(begin,length)); } public inline function subarray( ?begin : Int, ?end : Int ) : ArrayBufferView { return fromData(this.subarray(begin,end)); } public inline function getData() : ArrayBufferViewData { return this; } public static inline function fromData( a : ArrayBufferViewData ) : ArrayBufferView { return cast a; } public static function fromBytes( bytes : haxe.io.Bytes, pos = 0, ?length : Int ) : ArrayBufferView { if( length == null ) length = bytes.length - pos; if( pos < 0 || length < 0 || pos + length > bytes.length ) throw Error.OutsideBounds; return fromData(new ArrayBufferViewData(bytes, pos, length)); } }haxe_3.4.4.orig/std/haxe/io/BufferInput.hx0000664000175000017500000000374013166552354020340 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; class BufferInput extends haxe.io.Input { public var i : haxe.io.Input; public var buf : haxe.io.Bytes; public var available : Int; public var pos : Int; public function new(i, buf, ?pos = 0, ?available = 0) { this.i = i; this.buf = buf; this.pos = pos; this.available = available; } public function refill() { if( pos > 0 ) { buf.blit(0, buf, pos, available); pos = 0; } available += i.readBytes(buf, available, buf.length - available); } override function readByte() { if( available == 0 ) refill(); var c = buf.get(pos); pos++; available--; return c; } override function readBytes( buf : haxe.io.Bytes, pos : Int, len : Int ) { if( available == 0 ) refill(); var size = if( len > available ) available else len; buf.blit(pos, this.buf, this.pos, size); this.pos += size; this.available -= size; return size; } }haxe_3.4.4.orig/std/haxe/io/Bytes.hx0000664000175000017500000003720713166552354017202 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; #if cpp using cpp.NativeArray; #end class Bytes { public var length(default,null) : Int; var b : BytesData; function new(length,b) { this.length = length; this.b = b; #if flash b.endian = flash.utils.Endian.LITTLE_ENDIAN; #end } public inline function get( pos : Int ) : Int { #if neko return untyped $sget(b,pos); #elseif flash return b[pos]; #elseif php return b.get(pos); #elseif cpp return untyped b[pos]; #elseif java return untyped b[pos] & 0xFF; #elseif python return python.Syntax.arrayAccess(b, pos); #else return b[pos]; #end } public inline function set( pos : Int, v : Int ) : Void { #if neko untyped $sset(b,pos,v); #elseif flash b[pos] = v; #elseif php b.set(pos, v); #elseif cpp untyped b[pos] = v; #elseif java b[pos] = cast v; #elseif cs b[pos] = cast v; #elseif python python.Syntax.arraySet(b, pos, v & 0xFF); #else b[pos] = v & 0xFF; #end } public function blit( pos : Int, src : Bytes, srcpos : Int, len : Int ) : Void { #if !neko if( pos < 0 || srcpos < 0 || len < 0 || pos + len > length || srcpos + len > src.length ) throw Error.OutsideBounds; #end #if neko try untyped $sblit(b,pos,src.b,srcpos,len) catch( e : Dynamic ) throw Error.OutsideBounds; #elseif php b.blit(pos, src.b, srcpos, len); #elseif flash b.position = pos; if( len > 0 ) b.writeBytes(src.b,srcpos,len); #elseif java java.lang.System.arraycopy(src.b, srcpos, b, pos, len); #elseif cs cs.system.Array.Copy(src.b, srcpos, b, pos, len); #elseif python python.Syntax.pythonCode("self.b[{0}:{0}+{1}] = src.b[srcpos:srcpos+{1}]", pos, len); #elseif cpp b.blit(pos, src.b, srcpos, len); #else var b1 = b; var b2 = src.b; if( b1 == b2 && pos > srcpos ) { var i = len; while( i > 0 ) { i--; b1[i + pos] = b2[i + srcpos]; } return; } for( i in 0...len ) b1[i+pos] = b2[i+srcpos]; #end } public function fill( pos : Int, len : Int, value : Int ) { #if flash var v4 = value&0xFF; v4 |= v4<<8; v4 |= v4<<16; b.position = pos; for( i in 0...len>>2 ) b.writeUnsignedInt(v4); pos += len&~3; for( i in 0...len&3 ) set(pos++,value); #elseif cpp untyped __global__.__hxcpp_memory_memset(b,pos,len,value); #else for( i in 0...len ) set(pos++, value); #end } public function sub( pos : Int, len : Int ) : Bytes { #if !neko if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds; #end #if neko return try new Bytes(len,untyped __dollar__ssub(b,pos,len)) catch( e : Dynamic ) throw Error.OutsideBounds; #elseif flash b.position = pos; var b2 = new flash.utils.ByteArray(); b.readBytes(b2,0,len); return new Bytes(len,b2); #elseif php return new Bytes(len, b.sub(pos, len)); #elseif java var newarr = new java.NativeArray(len); java.lang.System.arraycopy(b, pos, newarr, 0, len); return new Bytes(len, newarr); #elseif cs var newarr = new cs.NativeArray(len); cs.system.Array.Copy(b, pos, newarr, 0, len); return new Bytes(len, newarr); #elseif python return new Bytes(len, python.Syntax.arrayAccess(b, pos, pos+len) ); #else return new Bytes(len,b.slice(pos,pos+len)); #end } public function compare( other : Bytes ) : Int { #if neko return untyped __dollar__compare(b,other.b); #elseif flash var len = (length < other.length) ? length : other.length; var b1 = b; var b2 = other.b; b1.position = 0; b2.position = 0; b1.endian = flash.utils.Endian.BIG_ENDIAN; b2.endian = flash.utils.Endian.BIG_ENDIAN; for( i in 0...len>>2 ) if( b1.readUnsignedInt() != b2.readUnsignedInt() ) { b1.position -= 4; b2.position -= 4; var d = b1.readUnsignedInt() - b2.readUnsignedInt(); b1.endian = flash.utils.Endian.LITTLE_ENDIAN; b2.endian = flash.utils.Endian.LITTLE_ENDIAN; return d; } for( i in 0...len & 3 ) if( b1.readUnsignedByte() != b2.readUnsignedByte() ) { b1.endian = flash.utils.Endian.LITTLE_ENDIAN; b2.endian = flash.utils.Endian.LITTLE_ENDIAN; return b1[b1.position-1] - b2[b2.position-1]; } b1.endian = flash.utils.Endian.LITTLE_ENDIAN; b2.endian = flash.utils.Endian.LITTLE_ENDIAN; return length - other.length; #elseif php return b.compare(other.b); //#elseif cs //TODO: memcmp if unsafe flag is on #elseif cpp return b.memcmp(other.b); #else var b1 = b; var b2 = other.b; var len = (length < other.length) ? length : other.length; for( i in 0...len ) if( b1[i] != b2[i] ) return untyped b1[i] - untyped b2[i]; return length - other.length; #end } /** Returns the IEEE double precision value at given position (in low endian encoding). Result is unspecified if reading outside of the bounds **/ #if (neko_v21 || (cpp && !cppia) || flash) inline #end public function getDouble( pos : Int ) : Float { #if neko_v21 return untyped $sgetd(b, pos, false); #elseif flash b.position = pos; return b.readDouble(); #elseif cpp if( pos < 0 || pos + 8 > length ) throw Error.OutsideBounds; return untyped __global__.__hxcpp_memory_get_double(b,pos); #else return FPHelper.i64ToDouble(getInt32(pos),getInt32(pos+4)); #end } /** Returns the IEEE single precision value at given position (in low endian encoding). Result is unspecified if reading outside of the bounds **/ #if (neko_v21 || (cpp && !cppia) || flash) inline #end public function getFloat( pos : Int ) : Float { #if neko_v21 return untyped $sgetf(b, pos, false); #elseif flash b.position = pos; return b.readFloat(); #elseif cpp if( pos < 0 || pos + 4 > length ) throw Error.OutsideBounds; return untyped __global__.__hxcpp_memory_get_float(b,pos); #else var b = new haxe.io.BytesInput(this,pos,4); return b.readFloat(); #end } /** Store the IEEE double precision value at given position in low endian encoding. Result is unspecified if writing outside of the bounds. **/ #if (neko_v21 || flash) inline #end public function setDouble( pos : Int, v : Float ) : Void { #if neko_v21 untyped $ssetd(b, pos, v, false); #elseif neko untyped $sblit(b, pos, FPHelper._double_bytes(v,false), 0, 8); #elseif flash b.position = pos; b.writeDouble(v); #elseif cpp if( pos < 0 || pos + 8 > length ) throw Error.OutsideBounds; untyped __global__.__hxcpp_memory_set_double(b,pos,v); #else var i = FPHelper.doubleToI64(v); setInt32(pos, i.low); setInt32(pos + 4, i.high); #end } /** Store the IEEE single precision value at given position in low endian encoding. Result is unspecified if writing outside of the bounds. **/ #if (neko_v21 || flash) inline #end public function setFloat( pos : Int, v : Float ) : Void { #if neko_v21 untyped $ssetf(b, pos, v, false); #elseif neko untyped $sblit(b, pos, FPHelper._float_bytes(v,false), 0, 4); #elseif flash b.position = pos; b.writeFloat(v); #elseif cpp if( pos < 0 || pos + 4 > length ) throw Error.OutsideBounds; untyped __global__.__hxcpp_memory_set_float(b,pos,v); #else setInt32(pos, FPHelper.floatToI32(v)); #end } /** Returns the 16 bit unsigned integer at given position (in low endian encoding). **/ public inline function getUInt16( pos : Int ) : Int { #if neko_v21 return untyped $sget16(b, pos, false); #else return get(pos) | (get(pos + 1) << 8); #end } /** Store the 16 bit unsigned integer at given position (in low endian encoding). **/ public inline function setUInt16( pos : Int, v : Int ) : Void { #if neko_v21 untyped $sset16(b, pos, v, false); #else set(pos, v); set(pos + 1, v >> 8); #end } /** Returns the 32 bit integer at given position (in low endian encoding). **/ public inline function getInt32( pos : Int ) : Int { #if neko_v21 return untyped $sget32(b, pos, false); #elseif (php || python) var v = get(pos) | (get(pos + 1) << 8) | (get(pos + 2) << 16) | (get(pos+3) << 24); return if( v & 0x80000000 != 0 ) v | 0x80000000 else v; #elseif lua var v = get(pos) | (get(pos + 1) << 8) | (get(pos + 2) << 16) | (get(pos+3) << 24); return lua.Boot.clamp(if( v & 0x80000000 != 0 ) v | 0x80000000 else v); #else return get(pos) | (get(pos + 1) << 8) | (get(pos + 2) << 16) | (get(pos+3) << 24); #end } /** Returns the 64 bit integer at given position (in low endian encoding). **/ public inline function getInt64( pos : Int ) : haxe.Int64 { return haxe.Int64.make(getInt32(pos+4),getInt32(pos)); } /** Store the 32 bit integer at given position (in low endian encoding). **/ public inline function setInt32( pos : Int, v : Int ) : Void { #if neko_v21 untyped $sset32(b, pos, v, false); #else set(pos, v); set(pos + 1, v >> 8); set(pos + 2, v >> 16); set(pos + 3, v >>> 24); #end } /** Store the 64 bit integer at given position (in low endian encoding). **/ public inline function setInt64( pos : Int, v : haxe.Int64 ) : Void { setInt32(pos, v.low); setInt32(pos + 4, v.high); } public function getString( pos : Int, len : Int ) : String { #if !neko if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds; #end #if neko return try new String(untyped __dollar__ssub(b,pos,len)) catch( e : Dynamic ) throw Error.OutsideBounds; #elseif flash b.position = pos; return b.readUTFBytes(len); #elseif php return b.getString(pos, len); #elseif cpp var result:String=""; untyped __global__.__hxcpp_string_of_bytes(b,result,pos,len); return result; #elseif cs return cs.system.text.Encoding.UTF8.GetString(b, pos, len); #elseif java try return new String(b, pos, len, "UTF-8") catch (e:Dynamic) throw e; #elseif python return python.Syntax.pythonCode("self.b[{0}:{0}+{1}].decode('UTF-8','replace')", pos, len); #elseif lua var begin = cast(Math.min(pos,b.length),Int); var end = cast(Math.min(pos+len,b.length),Int); return [for (i in begin...end) String.fromCharCode(b[i])].join(""); #else var s = ""; var b = b; var fcc = String.fromCharCode; var i = pos; var max = pos+len; // utf8-decode and utf16-encode while( i < max ) { var c = b[i++]; if( c < 0x80 ) { if( c == 0 ) break; s += fcc(c); } else if( c < 0xE0 ) s += fcc( ((c & 0x3F) << 6) | (b[i++] & 0x7F) ); else if( c < 0xF0 ) { var c2 = b[i++]; s += fcc( ((c & 0x1F) << 12) | ((c2 & 0x7F) << 6) | (b[i++] & 0x7F) ); } else { var c2 = b[i++]; var c3 = b[i++]; var u = ((c & 0x0F) << 18) | ((c2 & 0x7F) << 12) | ((c3 & 0x7F) << 6) | (b[i++] & 0x7F); // surrogate pair s += fcc( (u >> 10) + 0xD7C0 ); s += fcc( (u & 0x3FF) | 0xDC00 ); } } return s; #end } @:deprecated("readString is deprecated, use getString instead") @:noCompletion public inline function readString(pos:Int, len:Int):String { return getString(pos, len); } public function toString() : String { #if neko return new String(untyped __dollar__ssub(b,0,length)); #elseif flash b.position = 0; return b.readUTFBytes(length); #elseif php return b.toString(); #elseif cs return cs.system.text.Encoding.UTF8.GetString(b, 0, length); #elseif java try { return new String(b, 0, length, "UTF-8"); } catch (e:Dynamic) throw e; #else return getString(0,length); #end } public function toHex() : String { var s = new StringBuf(); var chars = []; var str = "0123456789abcdef"; for( i in 0...str.length ) chars.push(str.charCodeAt(i)); for( i in 0...length ) { var c = get(i); s.addChar(chars[c >> 4]); s.addChar(chars[c & 15]); } return s.toString(); } public inline function getData() : BytesData { return b; } public static function alloc( length : Int ) : Bytes { #if neko return new Bytes(length,untyped __dollar__smake(length)); #elseif flash var b = new flash.utils.ByteArray(); b.length = length; return new Bytes(length,b); #elseif php return new Bytes(length, BytesData.alloc(length)); #elseif cpp var a = new BytesData(); if (length>0) cpp.NativeArray.setSize(a, length); return new Bytes(length, a); #elseif cs return new Bytes(length, new cs.NativeArray(length)); #elseif java return new Bytes(length, new java.NativeArray(length)); #elseif python return new Bytes(length, new python.Bytearray(length)); #else var a = new Array(); for( i in 0...length ) a.push(0); return new Bytes(length,a); #end } @:pure public static function ofString( s : String ) : Bytes { #if neko return new Bytes(s.length,untyped __dollar__ssub(s.__s,0,s.length)); #elseif flash var b = new flash.utils.ByteArray(); b.writeUTFBytes(s); return new Bytes(b.length,b); #elseif php var x = BytesData.ofString(s); return new Bytes(x.length, x); #elseif cpp var a = new BytesData(); untyped __global__.__hxcpp_bytes_of_string(a,s); return new Bytes(a.length, a); #elseif cs var b = cs.system.text.Encoding.UTF8.GetBytes(s); return new Bytes(b.Length, b); #elseif java try { var b:BytesData = untyped s.getBytes("UTF-8"); return new Bytes(b.length, b); } catch (e:Dynamic) throw e; #elseif python var b:BytesData = new python.Bytearray(s, "UTF-8"); return new Bytes(b.length, b); #elseif lua var bytes = [for (c in 0...s.length) StringTools.fastCodeAt(s,c)]; return new Bytes(bytes.length, bytes); #else var a = new Array(); // utf16-decode and utf8-encode var i = 0; while( i < s.length ) { var c : Int = StringTools.fastCodeAt(s,i++); // surrogate pair if( 0xD800 <= c && c <= 0xDBFF ) c = (c - 0xD7C0 << 10) | (StringTools.fastCodeAt(s,i++) & 0x3FF); if( c <= 0x7F ) a.push(c); else if( c <= 0x7FF ) { a.push( 0xC0 | (c >> 6) ); a.push( 0x80 | (c & 63) ); } else if( c <= 0xFFFF ) { a.push( 0xE0 | (c >> 12) ); a.push( 0x80 | ((c >> 6) & 63) ); a.push( 0x80 | (c & 63) ); } else { a.push( 0xF0 | (c >> 18) ); a.push( 0x80 | ((c >> 12) & 63) ); a.push( 0x80 | ((c >> 6) & 63) ); a.push( 0x80 | (c & 63) ); } } return new Bytes(a.length,a); #end } public static function ofData( b : BytesData ) { #if flash return new Bytes(b.length,b); #elseif neko return new Bytes(untyped __dollar__ssize(b),b); #elseif php return new Bytes(b.length, b); #elseif cs return new Bytes(b.Length,b); #else return new Bytes(b.length,b); #end } /** Read the most efficiently possible the n-th byte of the data. Behavior when reading outside of the available data is unspecified. **/ public inline static function fastGet( b : BytesData, pos : Int ) : Int { #if neko return untyped __dollar__sget(b,pos); #elseif flash return b[pos]; #elseif php return b.get(pos); #elseif cpp return untyped b.unsafeGet(pos); #elseif java return untyped b[pos] & 0xFF; #else return b[pos]; #end } } haxe_3.4.4.orig/std/haxe/io/BytesBuffer.hx0000664000175000017500000001233113166552354020323 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; class BytesBuffer { #if neko var b : Dynamic; // neko string buffer #elseif flash var b : flash.utils.ByteArray; #elseif php var b : String; #elseif cpp var b : BytesData; #elseif cs var b : cs.system.io.MemoryStream; #elseif java var b : java.io.ByteArrayOutputStream; #else var b : Array; #end /** The length of the buffer in bytes. **/ public var length(get,never) : Int; public function new() { #if neko b = untyped StringBuf.__make(); #elseif flash b = new flash.utils.ByteArray(); b.endian = flash.utils.Endian.LITTLE_ENDIAN; #elseif php b = ""; #elseif cpp b = new BytesData(); #elseif cs b = new cs.system.io.MemoryStream(); #elseif java b = new java.io.ByteArrayOutputStream(); #else b = new Array(); #end } inline function get_length() : Int { #if neko return untyped __dollar__ssize( StringBuf.__to_string(b) ); #elseif cs return haxe.Int64.toInt( b.Length ); #elseif java return b.size(); #else return b.length; #end } public inline function addByte( byte : Int ) { #if neko untyped StringBuf.__add_char(b,byte); #elseif flash b.writeByte(byte); #elseif php b += untyped __call__("chr", byte); #elseif cpp b.push(untyped byte); #elseif cs b.WriteByte(cast byte); #elseif java b.write(byte); #else b.push(byte); #end } public inline function add( src : Bytes ) { #if neko untyped StringBuf.__add(b,src.getData()); #elseif flash b.writeBytes(src.getData()); #elseif php b += src.getData().toString(); #elseif cs b.Write(src.getData(), 0, src.length); #elseif java b.write(src.getData(), 0, src.length); #elseif js var b1 = b; var b2 = @:privateAccess src.b; for( i in 0...src.length ) b.push(b2[i]); #else var b1 = b; var b2 = src.getData(); for( i in 0...src.length ) b.push(b2[i]); #end } public inline function addString( v : String ) { #if neko untyped StringBuf.__add(b, v.__s); #elseif flash b.writeUTFBytes(v); #else add(Bytes.ofString(v)); #end } public #if flash inline #end function addInt32( v : Int ) { #if flash b.writeUnsignedInt(v); #else addByte(v&0xFF); addByte((v>>8)&0xFF); addByte((v>>16)&0xFF); addByte(v>>>24); #end } public #if flash inline #end function addInt64( v : haxe.Int64 ) { addInt32(v.low); addInt32(v.high); } public inline function addFloat( v : Float ) { #if flash b.writeFloat(v); #else addInt32(FPHelper.floatToI32(v)); #end } public inline function addDouble( v : Float ) { #if flash b.writeDouble(v); #else addInt64(FPHelper.doubleToI64(v)); #end } public inline function addBytes( src : Bytes, pos : Int, len : Int ) { #if !neko if( pos < 0 || len < 0 || pos + len > src.length ) throw Error.OutsideBounds; #end #if neko try untyped StringBuf.__add_sub(b,src.getData(),pos,len) catch( e : Dynamic ) throw Error.OutsideBounds; #elseif flash if( len > 0 ) b.writeBytes(src.getData(),pos,len); #elseif php b += src.getData().sub(pos, len).toString() ; #elseif cs b.Write(src.getData(), pos, len); #elseif java b.write(src.getData(), pos, len); #elseif js var b1 = b; var b2 = @:privateAccess src.b; for( i in pos...pos+len ) b.push(b2[i]); #else var b1 = b; var b2 = src.getData(); for( i in pos...pos+len ) b.push(b2[i]); #end } /** Returns either a copy or a reference of the current bytes. Once called, the buffer can no longer be used. **/ public function getBytes() : Bytes untyped { #if neko var str = StringBuf.__to_string(b); var bytes = new Bytes(__dollar__ssize(str),str); #elseif flash var bytes = new Bytes(b.length,b); b.position = 0; #elseif php var bytes = new Bytes(b.length, BytesData.ofString(b)); #elseif cs var buf = b.GetBuffer(); var bytes = new Bytes(cast b.Length, buf); #elseif java var buf = b.toByteArray(); var bytes = new Bytes(buf.length, buf); #elseif python var buf = new python.Bytearray(b); var bytes = new Bytes(buf.length, buf); #elseif js var bytes = new Bytes(new js.html.Uint8Array(b).buffer); #else var bytes = new Bytes(b.length,b); #end b = null; return bytes; } } haxe_3.4.4.orig/std/haxe/io/BytesData.hx0000664000175000017500000000431213166552354017763 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; #if neko typedef BytesData = neko.NativeString; #elseif flash typedef BytesData = flash.utils.ByteArray; #elseif php typedef BytesData = php.BytesData; #elseif cpp typedef BytesData = Array< cpp.UInt8 >; #elseif java typedef BytesData = java.NativeArray; #elseif cs typedef BytesData = cs.NativeArray; #elseif python typedef BytesData = python.Bytearray; #elseif js typedef BytesData = js.html.ArrayBuffer; #elseif hl class BytesDataImpl { public var bytes : hl.Bytes; public var length : Int; public function new(b,length) { this.bytes = b; this.length = length; } } @:forward(bytes,length) abstract BytesDataAbstract(BytesDataImpl) { public inline function new(b, length) { this = new BytesDataImpl(b, length); } @:arrayAccess inline function get(i:Int) return this.bytes[i]; @:arrayAccess inline function set(i:Int,v:Int) return this.bytes[i] = v; @:to inline function toBytes() : hl.Bytes { return this == null ? null : this.bytes; } } typedef BytesData = BytesDataAbstract; #else typedef BytesData = Array; #end haxe_3.4.4.orig/std/haxe/io/BytesInput.hx0000664000175000017500000001242313166552354020213 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; class BytesInput extends Input { var b : #if js js.html.Uint8Array #elseif hl hl.Bytes #else BytesData #end; #if !flash var pos : Int; var len : Int; var totlen : Int; #end /** The current position in the stream in bytes. */ public var position(get,set) : Int; /** The length of the stream in bytes. */ public var length(get,never) : Int; public function new( b : Bytes, ?pos : Int, ?len : Int ) { if( pos == null ) pos = 0; if( len == null ) len = b.length - pos; if( pos < 0 || len < 0 || pos + len > b.length ) throw Error.OutsideBounds; #if flash var ba = b.getData(); ba.position = pos; if( len != ba.bytesAvailable ) { // truncate this.b = new flash.utils.ByteArray(); ba.readBytes(this.b,0,len); } else this.b = ba; this.b.endian = flash.utils.Endian.LITTLE_ENDIAN; #else this.b = #if (js || hl) @:privateAccess b.b #else b.getData() #end; this.pos = pos; this.len = len; this.totlen = len; #end #if python bigEndian = false; #end } inline function get_position() : Int { #if flash return b.position; #else return pos; #end } inline function get_length() : Int { #if flash return b.length; #else return totlen; #end } function set_position( p : Int ) : Int { if( p < 0 ) p = 0; else if( p > length ) p = length; #if flash return b.position = p; #else len = totlen - p; return pos = p; #end } public override function readByte() : Int { #if flash return try b.readUnsignedByte() catch( e : Dynamic ) throw new Eof(); #else if( this.len == 0 ) throw new Eof(); len--; #if neko return untyped __dollar__sget(b,pos++); #elseif php return b.get(pos++); #elseif cpp return untyped b[pos++]; #elseif java return untyped b[pos++] & 0xFF; #else return b[pos++]; #end #end } public override function readBytes( buf : Bytes, pos, len ) : Int { #if !neko if( pos < 0 || len < 0 || pos + len > buf.length ) throw Error.OutsideBounds; #end #if flash var avail : Int = b.bytesAvailable; if( len > avail && avail > 0 ) len = avail; try b.readBytes(buf.getData(),pos,len) catch( e : Dynamic ) throw new Eof(); #elseif java var avail : Int = this.len; if ( len > avail ) len = avail; if (len == 0) throw new Eof(); java.lang.System.arraycopy(this.b, this.pos, buf.getData(), pos, len); this.pos += len; this.len -= len; #elseif cs var avail : Int = this.len; if ( len > avail ) len = avail; if (len == 0) throw new Eof(); cs.system.Array.Copy(this.b,this.pos, buf.getData(), pos, len); this.pos += len; this.len -= len; #else if( this.len == 0 && len > 0 ) throw new Eof(); if( this.len < len ) len = this.len; #if neko try untyped __dollar__sblit(buf.getData(),pos,b,this.pos,len) catch( e : Dynamic ) throw Error.OutsideBounds; #elseif php buf.getData().blit(pos, b, this.pos, len); #elseif hl @:privateAccess buf.b.blit(pos, b, this.pos, len); #else var b1 = b; var b2 = #if js @:privateAccess buf.b #else buf.getData() #end; for( i in 0...len ) b2[pos+i] = b1[this.pos+i]; #end this.pos += len; this.len -= len; #end return len; } #if flash @:dox(hide) override function set_bigEndian(e) { bigEndian = e; b.endian = e ? flash.utils.Endian.BIG_ENDIAN : flash.utils.Endian.LITTLE_ENDIAN; return e; } @:dox(hide) override function readFloat() { return try b.readFloat() catch( e : Dynamic ) throw new Eof(); } @:dox(hide) override function readDouble() { return try b.readDouble() catch( e : Dynamic ) throw new Eof(); } @:dox(hide) override function readInt8() { return try b.readByte() catch( e : Dynamic ) throw new Eof(); } @:dox(hide) override function readInt16() { return try b.readShort() catch( e : Dynamic ) throw new Eof(); } @:dox(hide) override function readUInt16() : Int { return try b.readUnsignedShort() catch( e : Dynamic ) throw new Eof(); } @:dox(hide) override function readInt32() : Int { return try b.readInt() catch( e : Dynamic ) throw new Eof(); } @:dox(hide) override function readString( len : Int ) { return try b.readUTFBytes(len) catch( e : Dynamic ) throw new Eof(); } #end } haxe_3.4.4.orig/std/haxe/io/BytesOutput.hx0000664000175000017500000000635113166552354020417 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; class BytesOutput extends Output { #if flash var b : flash.utils.ByteArray; #else var b : BytesBuffer; #end /** The length of the stream in bytes. **/ public var length(get,never) : Int; public function new() { #if flash b = new flash.utils.ByteArray(); b.endian = flash.utils.Endian.LITTLE_ENDIAN; #else b = new BytesBuffer(); #end #if python bigEndian = false; #end } inline function get_length() : Int { return b.length; } override function writeByte(c) { #if flash b.writeByte(c); #else b.addByte(c); #end } override function writeBytes( buf : Bytes, pos, len ) : Int { #if flash if( pos < 0 || len < 0 || pos + len > buf.length ) throw Error.OutsideBounds; b.writeBytes(buf.getData(),pos,len); #else b.addBytes(buf,pos,len); #end return len; } #if flash // optimized operations @:dox(hide) override function set_bigEndian(e) { bigEndian = e; b.endian = e ? flash.utils.Endian.BIG_ENDIAN : flash.utils.Endian.LITTLE_ENDIAN; return e; } @:dox(hide) override function writeFloat( f : Float ) { b.writeFloat(f); } @:dox(hide) override function writeDouble( f : Float ) { b.writeDouble(f); } @:dox(hide) override function writeInt8( x : Int ) { if( x < -0x80 || x >= 0x80 ) throw Error.Overflow; b.writeByte(x); } @:dox(hide) override function writeInt16( x : Int ) { if( x < -0x8000 || x >= 0x8000 ) throw Error.Overflow; b.writeShort(x); } @:dox(hide) override function writeUInt16( x : Int ) { if( x < 0 || x >= 0x10000 ) throw Error.Overflow; b.writeShort(x); } @:dox(hide) override function writeInt32( x : Int ) { b.writeInt(x); } @:dox(hide) override function prepare( size : Int ) { if( size > 0 ) b[size-1] = b[size-1]; } @:dox(hide) override function writeString( s : String ) { b.writeUTFBytes(s); } #end /** Returns the `Bytes` of this output. This function should not be called more than once on a given `BytesOutput` instance. **/ public function getBytes() : Bytes { #if flash var bytes = b; b = null; return untyped new Bytes(bytes.length,bytes); #else return b.getBytes(); #end } } haxe_3.4.4.orig/std/haxe/io/Eof.hx0000664000175000017500000000247213166552354016621 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; /** This exception is raised when reading while data is no longer available in the `haxe.io.Input`. **/ class Eof { public function new() { } @:keep function toString() { return "Eof"; } } haxe_3.4.4.orig/std/haxe/io/Error.hx0000664000175000017500000000272013166552354017175 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; /** The possible IO errors that can occur **/ enum Error { /** The IO is set into nonblocking mode and some data cannot be read or written **/ Blocked; /** An integer value is outside its allowed range **/ Overflow; /** An operation on Bytes is outside of its valid range **/ OutsideBounds; /** Other errors **/ Custom( e : Dynamic ); } haxe_3.4.4.orig/std/haxe/io/FPHelper.hx0000664000175000017500000002544213166552354017557 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; /** Helper that converts between floating point and binary representation. Always works in low-endian encoding. **/ class FPHelper { #if neko_v21 // stored in helper #elseif neko static var i64tmp = new neko.vm.Tls(); #elseif !(java || cs) static var i64tmp = Int64.ofInt(0); #end #if neko #if neko_v21 static var helpers = new neko.vm.Tls>(); #else static var helperf = new neko.vm.Tls(); static var helperd = new neko.vm.Tls(); static var _float_of_bytes = neko.Lib.load("std","float_of_bytes",2); static var _double_of_bytes = neko.Lib.load("std","double_of_bytes",2); static var _float_bytes = neko.Lib.load("std","float_bytes",2); static var _double_bytes = neko.Lib.load("std","double_bytes",2); #end #elseif flash static var helper = { var b = new flash.utils.ByteArray(); b.endian = flash.utils.Endian.LITTLE_ENDIAN; b; } #elseif php static var isLittleEndian : Bool = untyped __call__('unpack','S','\x01\x00')[1] == 1; #else static inline var LN2 = 0.6931471805599453; // Math.log(2) #end #if neko_v21 inline #end public static function i32ToFloat( i : Int ) : Float { #if neko #if neko_v21 return untyped $itof(i,false); #else var helper = helperf.value; if( helper == null ) helperf.value = helper = neko.NativeString.alloc(4); untyped $sset(helper,0,i&0xFF); untyped $sset(helper,1,(i>>8)&0xFF); untyped $sset(helper,2,(i>>16)&0xFF); untyped $sset(helper,3,i>>>24); return _float_of_bytes(helper,false); #end #elseif cpp return untyped __global__.__hxcpp_reinterpret_le_int32_as_float32(i); #elseif cs var helper = new SingleHelper(0); if( cs.system.BitConverter.IsLittleEndian ) { helper.i = i; } else { helper.i = ((i >>> 24) & 0xFF) | (((i >> 16) & 0xFF) << 8) | (((i >> 8) & 0xFF) << 16) | ((i & 0xFF) << 24); } return helper.f; #elseif java return java.lang.Float.FloatClass.intBitsToFloat(i); #elseif php return untyped __call__('unpack', 'f', __call__('pack', 'l', i))[1]; #elseif flash var helper = helper; helper.position = 0; helper.writeUnsignedInt(i); helper.position = 0; return helper.readFloat(); #else var sign = 1 - ((i >>> 31) << 1); var exp = (i >>> 23) & 0xFF; var sig = i & 0x7FFFFF; if( sig == 0 && exp == 0 ) return 0.0; return sign*(1 + Math.pow(2, -23)*sig) * Math.pow(2, exp-127); #end } #if neko_v21 inline #end public static function floatToI32( f : Float ) : Int { #if neko #if neko_v21 return untyped $ftoi(f,false); #else var r = _float_bytes(f,false); return untyped $sget(r,0) | ($sget(r,1)<<8) | ($sget(r,2)<<16) | ($sget(r,3)<<24); #end #elseif cpp return untyped __global__.__hxcpp_reinterpret_float32_as_le_int32(f); #elseif cs var helper = new SingleHelper(f); if( cs.system.BitConverter.IsLittleEndian ) { return helper.i; } else { var i = helper.i; return ((i >>> 24) & 0xFF) | (((i >> 16) & 0xFF) << 8) | (((i >> 8) & 0xFF) << 16) | ((i & 0xFF) << 24); } #elseif java return java.lang.Float.FloatClass.floatToRawIntBits(f); #elseif flash var helper = helper; helper.position = 0; helper.writeFloat(f); helper.position = 0; return helper.readUnsignedInt(); #elseif php return untyped __call__('unpack','l',__call__('pack', 'f', f))[1]; #else if( f == 0 ) return 0; var af = f < 0 ? -f : f; var exp = Math.floor(Math.log(af) / LN2); if( exp < -127 ) exp = -127 else if( exp > 128 ) exp = 128; var sig = Math.round((af / Math.pow(2, exp) - 1) * 0x800000); if( sig == 0x800000 && exp < 128 ){ sig = 0; exp++; } return (f < 0 ? 0x80000000 : 0) | ((exp + 127) << 23) | sig; #end } #if neko_v21 inline #end public static function i64ToDouble( low : Int, high : Int ) : Float { #if neko #if neko_v21 return untyped $itod(low,high,false); #else var helper = helperd.value; if( helper == null ) helperd.value = helper = neko.NativeString.alloc(8); untyped $sset(helper,0,low&0xFF); untyped $sset(helper,1,(low>>8)&0xFF); untyped $sset(helper,2,(low>>16)&0xFF); untyped $sset(helper,3,low>>>24); untyped $sset(helper,4,high&0xFF); untyped $sset(helper,5,(high>>8)&0xFF); untyped $sset(helper,6,(high>>16)&0xFF); untyped $sset(helper,7,high>>>24); return _double_of_bytes(helper,false); #end #elseif cpp return untyped __global__.__hxcpp_reinterpret_le_int32s_as_float64(low,high); #elseif cs var helper = new FloatHelper(0); if( cs.system.BitConverter.IsLittleEndian ) { helper.i = haxe.Int64.make(high,low); } else { var i1 = high, i2 = low; var j2 = ((i1 >>> 24) & 0xFF) | (((i1 >> 16) & 0xFF) << 8) | (((i1 >> 8) & 0xFF) << 16) | ((i1 & 0xFF) << 24); var j1 = ((i2 >>> 24) & 0xFF) | (((i2 >> 16) & 0xFF) << 8) | (((i2 >> 8) & 0xFF) << 16) | ((i2 & 0xFF) << 24); helper.i = haxe.Int64.make(j1,j2); } return helper.f; #elseif java return java.lang.Double.DoubleClass.longBitsToDouble( Int64.make(high,low) ); #elseif flash var helper = helper; helper.position = 0; helper.writeUnsignedInt(low); helper.writeUnsignedInt(high); helper.position = 0; return helper.readDouble(); #elseif php return untyped __call__('unpack', 'd', __call__('pack', 'ii', isLittleEndian ? low : high, isLittleEndian ? high : low))[1]; #else #if python if (low == 0 && high == 2146435072) { return Math.POSITIVE_INFINITY; } else if (low == 0 && high == -1048576 ) { return Math.NEGATIVE_INFINITY; } #end var sign = 1 - ((high >>> 31) << 1); var exp = ((high >> 20) & 0x7FF) - 1023; var sig = (high&0xFFFFF) * 4294967296. + (low>>>31) * 2147483648. + (low&0x7FFFFFFF); if( sig == 0 && exp == -1023 ) return 0.0; return sign*(1.0 + Math.pow(2, -52)*sig) * Math.pow(2, exp); #end } /** Returns an Int64 representing the bytes representation of the double precision IEEE float value. WARNING : for performance reason, the same Int64 value might be reused every time. Copy its low/high values before calling again. We still ensure that this is safe to use in a multithread environment **/ public static function doubleToI64( v : Float ) : Int64 { #if neko #if neko_v21 var helper = helpers.value; if( helper == null ) { helpers.value = helper = neko.NativeArray.alloc(2); helper[0] = neko.NativeArray.alloc(2); helper[1] = haxe.Int64.ofInt(0); } var i64 : haxe.Int64 = helper[1], int2 = helper[0]; untyped $dtoi(v,int2,false); @:privateAccess { i64.set_low(int2[0]); i64.set_high(int2[1]); } return i64; #else var r = _double_bytes(v,false), i64 = i64tmp.value; if( i64 == null ) i64 = i64tmp.value = haxe.Int64.ofInt(0); @:privateAccess { i64.set_low(untyped $sget(r,0) | ($sget(r,1)<<8) | ($sget(r,2)<<16) | ($sget(r,3)<<24)); i64.set_high(untyped $sget(r,4) | ($sget(r,5)<<8) | ($sget(r,6)<<16) | ($sget(r,7)<<24)); } return i64; #end #elseif cpp return Int64.make(untyped __global__.__hxcpp_reinterpret_float64_as_le_int32_high(v), untyped __global__.__hxcpp_reinterpret_float64_as_le_int32_low(v) ); #elseif java return java.lang.Double.DoubleClass.doubleToRawLongBits(v); #elseif cs var helper = new FloatHelper(v); if( cs.system.BitConverter.IsLittleEndian ) { return helper.i; } else { var i = helper.i; var i1 = haxe.Int64.getHigh(i), i2 = haxe.Int64.getLow(i); var j2 = ((i1 >>> 24) & 0xFF) | (((i1 >> 16) & 0xFF) << 8) | (((i1 >> 8) & 0xFF) << 16) | ((i1 & 0xFF) << 24); var j1 = ((i2 >>> 24) & 0xFF) | (((i2 >> 16) & 0xFF) << 8) | (((i2 >> 8) & 0xFF) << 16) | ((i2 & 0xFF) << 24); return haxe.Int64.make(j1,j2); } #elseif flash var helper = helper; helper.position = 0; helper.writeDouble(v); helper.position = 0; var i64 = i64tmp; @:privateAccess { i64.set_low(cast helper.readUnsignedInt()); i64.set_high(cast helper.readUnsignedInt()); } return i64; #elseif php var a = untyped __call__('unpack',isLittleEndian ? 'V2' : 'N2',__call__('pack', 'd', v)); var i64 = i64tmp; @:privateAccess { i64.set_low(a[isLittleEndian ? 1 : 2]); i64.set_high(a[isLittleEndian ? 2 : 1]); } return i64; #else var i64 = i64tmp; if( v == 0 ) { @:privateAccess { i64.set_low(0); i64.set_high(0); } } else if (!Math.isFinite(v)) @:privateAccess { if (v > 0) { i64.set_low(0); i64.set_high(2146435072); } else { i64.set_low(0); i64.set_high(-1048576); } } else { var av = v < 0 ? -v : v; var exp = Math.floor(Math.log(av) / LN2); var sig = Math.fround(((av / Math.pow(2, exp)) - 1) * 4503599627370496.); // 2^52 var sig_l = Std.int(sig); var sig_h = Std.int(sig / 4294967296.0); @:privateAccess { i64.set_low(sig_l); i64.set_high((v < 0 ? 0x80000000 : 0) | ((exp + 1023) << 20) | sig_h); } } return i64; #end } } #if cs @:meta(System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)) @:nativeGen @:struct private class SingleHelper { @:meta(System.Runtime.InteropServices.FieldOffset(0)) public var i:Int; @:meta(System.Runtime.InteropServices.FieldOffset(0)) public var f:Single; public function new(f:Single) { this.i = 0; this.f = f; } } @:meta(System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)) @:nativeGen @:struct private class FloatHelper { @:meta(System.Runtime.InteropServices.FieldOffset(0)) public var i:haxe.Int64; @:meta(System.Runtime.InteropServices.FieldOffset(0)) public var f:Float; public function new(f:Float) { this.i = haxe.Int64.ofInt(0); this.f = f; } } #end haxe_3.4.4.orig/std/haxe/io/Float32Array.hx0000664000175000017500000000601313166552354020314 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef Float32ArrayData = ArrayBufferView.ArrayBufferViewData; abstract Float32Array(Float32ArrayData) { public static inline var BYTES_PER_ELEMENT = 4; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) { this = new ArrayBufferView(elements * BYTES_PER_ELEMENT).getData(); } inline function get_length() { return this.byteLength >> 2; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) : Float { return this.bytes.getFloat((index<<2) + this.byteOffset); } @:arrayAccess public inline function set( index : Int, value : Float ) : Float { if( index >= 0 && index < length ) { this.bytes.setFloat((index<<2) + this.byteOffset, value); return value; } return 0; } public inline function sub( begin : Int, ?length : Int ) : Float32Array { return fromData(this.sub(begin<<2,length == null ? null : length<<2)); } public inline function subarray( ?begin : Int, ?end : Int ) : Float32Array { return fromData(this.subarray(begin==null?null:begin<<2,end==null?null:end<<2)); } public inline function getData() : Float32ArrayData { return this; } public static function fromData( d : Float32ArrayData ) : Float32Array { return cast d; } public static function fromArray( a : Array, pos = 0, ?length : Int ) : Float32Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; var i = new Float32Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos = 0, ?length : Int ) : Float32Array { return fromData(ArrayBufferView.fromBytes(bytes,bytePos,(length == null ? (bytes.length - bytePos)>>2 : length)<<2).getData()); } } haxe_3.4.4.orig/std/haxe/io/Float64Array.hx0000664000175000017500000000601313166552354020321 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef Float64ArrayData = ArrayBufferView.ArrayBufferViewData; abstract Float64Array(Float64ArrayData) { public static inline var BYTES_PER_ELEMENT = 8; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) { this = new ArrayBufferView(elements * BYTES_PER_ELEMENT).getData(); } inline function get_length() { return this.byteLength >> 3; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) : Float { return this.bytes.getFloat((index<<3) + this.byteOffset); } @:arrayAccess public inline function set( index : Int, value : Float ) : Float { if( index >= 0 && index < length ) { this.bytes.setFloat((index<<3) + this.byteOffset, value); return value; } return 0; } public inline function sub( begin : Int, ?length : Int ) : Float64Array { return fromData(this.sub(begin<<3,length == null ? null : length<<3)); } public inline function subarray( ?begin : Int, ?end : Int ) : Float64Array { return fromData(this.subarray(begin==null?null:begin<<3,end==null?null:end<<3)); } public inline function getData() : Float64ArrayData { return this; } public static function fromData( d : Float64ArrayData ) : Float64Array { return cast d; } public static function fromArray( a : Array, pos = 0, ?length : Int ) : Float64Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; var i = new Float64Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos = 0, ?length : Int ) : Float64Array { return fromData(ArrayBufferView.fromBytes(bytes,bytePos,(length == null ? (bytes.length - bytePos)>>3 : length)<<3).getData()); } } haxe_3.4.4.orig/std/haxe/io/Input.hx0000664000175000017500000002044113166552354017203 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; /** An Input is an abstract reader. See other classes in the `haxe.io` package for several possible implementations. All functions which read data throw `Eof` when the end of the stream is reached. **/ class Input { /** Endianness (word byte order) used when reading numbers. If `true`, big-endian is used, otherwise `little-endian` is used. **/ public var bigEndian(default,set) : Bool; #if cs private var helper:BytesData; #elseif java private var helper:java.nio.ByteBuffer; #end /** Read and return one byte. **/ public function readByte() : Int { #if cpp throw "Not implemented"; #else return throw "Not implemented"; #end } /** Read `len` bytes and write them into `s` to the position specified by `pos`. Returns the actual length of read data that can be smaller than `len`. See `readFullBytes` that tries to read the exact amount of specified bytes. **/ public function readBytes( s : Bytes, pos : Int, len : Int ) : Int { var k = len; var b = #if (js || hl) @:privateAccess s.b #else s.getData() #end; if( pos < 0 || len < 0 || pos + len > s.length ) throw Error.OutsideBounds; try { while( k > 0 ) { #if neko untyped __dollar__sset(b,pos,readByte()); #elseif php b.set(pos, readByte()); #elseif cpp b[pos] = untyped readByte(); #else b[pos] = cast readByte(); #end pos++; k--; } } catch (eof: haxe.io.Eof){} return len-k; } /** Close the input source. Behaviour while reading after calling this method is unspecified. **/ public function close() : Void { } function set_bigEndian( b : Bool ) : Bool { bigEndian = b; return b; } /* ------------------ API ------------------ */ /** Read and return all available data. The `bufsize` optional argument specifies the size of chunks by which data is read. Its default value is target-specific. **/ public function readAll( ?bufsize : Int ) : Bytes { if( bufsize == null ) #if php bufsize = 8192; // default value for PHP and max under certain circumstances #else bufsize = (1 << 14); // 16 Ko #end var buf = Bytes.alloc(bufsize); var total = new haxe.io.BytesBuffer(); try { while( true ) { var len = readBytes(buf,0,bufsize); if( len == 0 ) throw Error.Blocked; total.addBytes(buf,0,len); } } catch( e : Eof ) { } return total.getBytes(); } /** Read `len` bytes and write them into `s` to the position specified by `pos`. Unlike `readBytes`, this method tries to read the exact `len` amount of bytes. **/ public function readFullBytes( s : Bytes, pos : Int, len : Int ) : Void { while( len > 0 ) { var k = readBytes(s,pos,len); if (k == 0) throw Error.Blocked; pos += k; len -= k; } } /** Read and return `nbytes` bytes. **/ public function read( nbytes : Int ) : Bytes { var s = Bytes.alloc(nbytes); var p = 0; while( nbytes > 0 ) { var k = readBytes(s,p,nbytes); if( k == 0 ) throw Error.Blocked; p += k; nbytes -= k; } return s; } /** Read a string until a character code specified by `end` is occurred. The final character is not included in the resulting string. **/ public function readUntil( end : Int ) : String { var buf = new BytesBuffer(); var last : Int; while( (last = readByte()) != end ) buf.addByte( last ); return buf.getBytes().toString(); } /** Read a line of text separated by CR and/or LF bytes. The CR/LF characters are not included in the resulting string. **/ public function readLine() : String { var buf = new BytesBuffer(); var last : Int; var s; try { while( (last = readByte()) != 10 ) buf.addByte( last ); s = buf.getBytes().toString(); if( s.charCodeAt(s.length-1) == 13 ) s = s.substr(0,-1); } catch( e : Eof ) { s = buf.getBytes().toString(); if( s.length == 0 ) #if neko neko.Lib.rethrow #else throw #end (e); } return s; } /** Read a 32-bit floating point number. Endianness is specified by the `bigEndian` property. **/ public function readFloat() : Float { return FPHelper.i32ToFloat(readInt32()); } /** Read a 64-bit double-precision floating point number. Endianness is specified by the `bigEndian` property. **/ public function readDouble() : Float { var i1 = readInt32(); var i2 = readInt32(); return bigEndian ? FPHelper.i64ToDouble(i2,i1) : FPHelper.i64ToDouble(i1,i2); } /** Read a 8-bit signed integer. **/ public function readInt8() : Int { var n = readByte(); if( n >= 128 ) return n - 256; return n; } /** Read a 16-bit signed integer. Endianness is specified by the `bigEndian` property. **/ public function readInt16() : Int { var ch1 = readByte(); var ch2 = readByte(); var n = bigEndian ? ch2 | (ch1 << 8) : ch1 | (ch2 << 8); if( n & 0x8000 != 0 ) return n - 0x10000; return n; } /** Read a 16-bit unsigned integer. Endianness is specified by the `bigEndian` property. **/ public function readUInt16() : Int { var ch1 = readByte(); var ch2 = readByte(); return bigEndian ? ch2 | (ch1 << 8) : ch1 | (ch2 << 8); } /** Read a 24-bit signed integer. Endianness is specified by the `bigEndian` property. **/ public function readInt24() : Int { var ch1 = readByte(); var ch2 = readByte(); var ch3 = readByte(); var n = bigEndian ? ch3 | (ch2 << 8) | (ch1 << 16) : ch1 | (ch2 << 8) | (ch3 << 16); if( n & 0x800000 != 0 ) return n - 0x1000000; return n; } /** Read a 24-bit unsigned integer. Endianness is specified by the `bigEndian` property. **/ public function readUInt24() : Int { var ch1 = readByte(); var ch2 = readByte(); var ch3 = readByte(); return bigEndian ? ch3 | (ch2 << 8) | (ch1 << 16) : ch1 | (ch2 << 8) | (ch3 << 16); } /** Read a 32-bit signed integer. Endianness is specified by the `bigEndian` property. **/ public function readInt32() : Int { var ch1 = readByte(); var ch2 = readByte(); var ch3 = readByte(); var ch4 = readByte(); #if (php || python) // php will overflow integers. Convert them back to signed 32-bit ints. var n = bigEndian ? ch4 | (ch3 << 8) | (ch2 << 16) | (ch1 << 24) : ch1 | (ch2 << 8) | (ch3 << 16) | (ch4 << 24); if (n & 0x80000000 != 0) return ( n | 0x80000000); else return n; #elseif lua var n = bigEndian ? ch4 | (ch3 << 8) | (ch2 << 16) | (ch1 << 24) : ch1 | (ch2 << 8) | (ch3 << 16) | (ch4 << 24); return lua.Boot.clamp(n); #else return bigEndian ? ch4 | (ch3 << 8) | (ch2 << 16) | (ch1 << 24) : ch1 | (ch2 << 8) | (ch3 << 16) | (ch4 << 24); #end } /** Read and `len` bytes as a string. **/ public function readString( len : Int ) : String { var b = Bytes.alloc(len); readFullBytes(b,0,len); #if neko return neko.Lib.stringReference(b); #else return b.toString(); #end } #if neko static var _float_of_bytes = neko.Lib.load("std","float_of_bytes",2); static var _double_of_bytes = neko.Lib.load("std","double_of_bytes",2); static function __init__() untyped { Input.prototype.bigEndian = false; } #end #if (flash || js || python) function getDoubleSig(bytes:Array) { return (((bytes[1]&0xF) << 16) | (bytes[2] << 8) | bytes[3] ) * 4294967296. + (bytes[4] >> 7) * 2147483648 + (((bytes[4]&0x7F) << 24) | (bytes[5] << 16) | (bytes[6] << 8) | bytes[7]); } #end } haxe_3.4.4.orig/std/haxe/io/Int32Array.hx0000664000175000017500000000575513166552354020015 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef Int32ArrayData = ArrayBufferView.ArrayBufferViewData; abstract Int32Array(Int32ArrayData) { public static inline var BYTES_PER_ELEMENT = 4; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) { this = new ArrayBufferView(elements * BYTES_PER_ELEMENT).getData(); } inline function get_length() { return this.byteLength >> 2; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) : Int { return this.bytes.getInt32((index<<2) + this.byteOffset); } @:arrayAccess public inline function set( index : Int, value : Int ) : Int { if( index >= 0 && index < length ) { this.bytes.setInt32((index<<2) + this.byteOffset, value); return value; } return 0; } public inline function sub( begin : Int, ?length : Int ) : Int32Array { return fromData(this.sub(begin<<2,length == null ? null : length<<2)); } public inline function subarray( ?begin : Int, ?end : Int ) : Int32Array { return fromData(this.subarray(begin==null?null:begin<<2,end==null?null:end<<2)); } public inline function getData() : Int32ArrayData { return this; } public static function fromData( d : Int32ArrayData ) : Int32Array { return cast d; } public static function fromArray( a : Array, pos = 0, ?length : Int ) : Int32Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; var i = new Int32Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos = 0, ?length : Int ) : Int32Array { return fromData(ArrayBufferView.fromBytes(bytes,bytePos,(length == null ? (bytes.length - bytePos)>>2 : length)<<2).getData()); } } haxe_3.4.4.orig/std/haxe/io/Output.hx0000664000175000017500000001550213166552354017406 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; /** An Output is an abstract write. A specific output implementation will only have to override the `writeByte` and maybe the `write`, `flush` and `close` methods. See `File.write` and `String.write` for two ways of creating an Output. **/ class Output { /** Endianness (word byte order) used when writing numbers. If `true`, big-endian is used, otherwise `little-endian` is used. **/ public var bigEndian(default, set) : Bool; #if java private var helper:java.nio.ByteBuffer; #end /** Write one byte. **/ public function writeByte( c : Int ) : Void { throw "Not implemented"; } /** Write `len` bytes from `s` starting by position specified by `pos`. Returns the actual length of written data that can differ from `len`. See `writeFullBytes` that tries to write the exact amount of specified bytes. **/ public function writeBytes( s : Bytes, pos : Int, len : Int ) : Int { #if !neko if( pos < 0 || len < 0 || pos + len > s.length ) throw Error.OutsideBounds; #end var b = #if js @:privateAccess s.b #else s.getData() #end; var k = len; while( k > 0 ) { #if neko writeByte(untyped __dollar__sget(b,pos)); #elseif php writeByte(b.get(pos)); #elseif cpp writeByte(untyped b[pos]); #elseif hl writeByte(b[pos]); #else writeByte(untyped b[pos]); #end pos++; k--; } return len; } /** Flush any buffered data. **/ public function flush() { } /** Close the output. Behaviour while writing after calling this method is unspecified. **/ public function close() { } function set_bigEndian( b ) { bigEndian = b; return b; } /* ------------------ API ------------------ */ /** Write all bytes stored in `s`. **/ public function write( s : Bytes ) : Void { var l = s.length; var p = 0; while( l > 0 ) { var k = writeBytes(s,p,l); if( k == 0 ) throw Error.Blocked; p += k; l -= k; } } /** Write `len` bytes from `s` starting by position specified by `pos`. Unlike `writeBytes`, this method tries to write the exact `len` amount of bytes. **/ public function writeFullBytes( s : Bytes, pos : Int, len : Int ) { while( len > 0 ) { var k = writeBytes(s,pos,len); pos += k; len -= k; } } /** Write `x` as 32-bit floating point number. Endianness is specified by the `bigEndian` property. **/ public function writeFloat( x : Float ) { writeInt32(FPHelper.floatToI32(x)); } /** Write `x` as 64-bit double-precision floating point number. Endianness is specified by the `bigEndian` property. **/ public function writeDouble( x : Float ) { var i64 = FPHelper.doubleToI64(x); if( bigEndian ) { writeInt32(i64.high); writeInt32(i64.low); } else { writeInt32(i64.low); writeInt32(i64.high); } } /** Write `x` as 8-bit signed integer. **/ public function writeInt8( x : Int ) { if( x < -0x80 || x >= 0x80 ) throw Error.Overflow; writeByte(x & 0xFF); } /** Write `x` as 16-bit signed integer. Endianness is specified by the `bigEndian` property. **/ public function writeInt16( x : Int ) { if( x < -0x8000 || x >= 0x8000 ) throw Error.Overflow; writeUInt16(x & 0xFFFF); } /** Write `x` as 16-bit unsigned integer. Endianness is specified by the `bigEndian` property. **/ public function writeUInt16( x : Int ) { if( x < 0 || x >= 0x10000 ) throw Error.Overflow; if( bigEndian ) { writeByte(x >> 8); writeByte(x & 0xFF); } else { writeByte(x & 0xFF); writeByte(x >> 8); } } /** Write `x` as 24-bit signed integer. Endianness is specified by the `bigEndian` property. **/ public function writeInt24( x : Int ) { if( x < -0x800000 || x >= 0x800000 ) throw Error.Overflow; writeUInt24(x & 0xFFFFFF); } /** Write `x` as 24-bit unsigned integer. Endianness is specified by the `bigEndian` property. **/ public function writeUInt24( x : Int ) { if( x < 0 || x >= 0x1000000 ) throw Error.Overflow; if( bigEndian ) { writeByte(x >> 16); writeByte((x >> 8) & 0xFF); writeByte(x & 0xFF); } else { writeByte(x & 0xFF); writeByte((x >> 8) & 0xFF); writeByte(x >> 16); } } /** Write `x` as 32-bit signed integer. Endianness is specified by the `bigEndian` property. **/ public function writeInt32( x : Int ) { if( bigEndian ) { writeByte( x >>> 24 ); writeByte( (x >> 16) & 0xFF ); writeByte( (x >> 8) & 0xFF ); writeByte( x & 0xFF ); } else { writeByte( x & 0xFF ); writeByte( (x >> 8) & 0xFF ); writeByte( (x >> 16) & 0xFF ); writeByte( x >>> 24 ); } } /** Inform that we are about to write at least `nbytes` bytes. The underlying implementation can allocate proper working space depending on this information, or simply ignore it. This is not a mandatory call but a tip and is only used in some specific cases. **/ public function prepare( nbytes : Int ) { } /** Read all available data from `i` and write it. The `bufsize` optional argument specifies the size of chunks by which data is read and written. Its default value is 4096. **/ public function writeInput( i : Input, ?bufsize : Int ) { if( bufsize == null ) bufsize = 4096; var buf = Bytes.alloc(bufsize); try { while( true ) { var len = i.readBytes(buf,0,bufsize); if( len == 0 ) throw Error.Blocked; var p = 0; while( len > 0 ) { var k = writeBytes(buf,p,len); if( k == 0 ) throw Error.Blocked; p += k; len -= k; } } } catch( e : Eof ) { } } /** Write `s` string. **/ public function writeString( s : String ) { #if neko var b = untyped new Bytes(s.length,s.__s); #else var b = Bytes.ofString(s); #end writeFullBytes(b,0,b.length); } #if neko static function __init__() untyped { Output.prototype.bigEndian = false; } #end } haxe_3.4.4.orig/std/haxe/io/Path.hx0000664000175000017500000002045513166552354017005 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; /** This class provides a convenient way of working with paths. It supports the common path formats: - directory1/directory2/filename.extension - directory1\directory2\filename.extension **/ class Path { /** The directory. This is the leading part of the path that is not part of the file name and the extension. Does not end with a `/` or `\` separator. If the path has no directory, the value is null. **/ public var dir : String; /** The file name. This is the part of the part between the directory and the extension. If there is no file name, e.g. for ".htaccess" or "/dir/", the value is the empty String "". **/ public var file : String; /** The file extension. It is separated from the file name by a dot. This dot is not part of the extension. If the path has no extension, the value is null. **/ public var ext : String; /** True if the last directory separator is a backslash, false otherwise. **/ public var backslash : Bool; /** Creates a new Path instance by parsing `path`. Path information can be retrieved by accessing the dir, file and ext properties. **/ public function new( path : String ) { switch (path) { case "." | "..": dir = path; file = ""; return; } var c1 = path.lastIndexOf("/"); var c2 = path.lastIndexOf("\\"); if( c1 < c2 ) { dir = path.substr(0,c2); path = path.substr(c2+1); backslash = true; } else if( c2 < c1 ) { dir = path.substr(0,c1); path = path.substr(c1+1); } else dir = null; var cp = path.lastIndexOf("."); if( cp != -1 ) { ext = path.substr(cp+1); file = path.substr(0,cp); } else { ext = null; file = path; } } /** Returns a String representation of `this` path. If `this.backslash` is true, backslash is used as directory separator, otherwise slash is used. This only affects the separator between `this.dir` and `this.file`. If `this.directory` or `this.extension` is null, their representation is the empty String "". **/ public function toString() : String { return (if( dir == null ) "" else dir + if( backslash ) "\\" else "/") + file + (if( ext == null ) "" else "." + ext); } /** Returns the String representation of `path` without the file extension. If `path` is null, the result is unspecified. **/ public static function withoutExtension( path : String ) : String { var s = new Path(path); s.ext = null; return s.toString(); } /** Returns the String representation of `path` without the directory. If `path` is null, the result is unspecified. **/ public static function withoutDirectory( path ) : String { var s = new Path(path); s.dir = null; return s.toString(); } /** Returns the directory of `path`. If the directory is null, the empty String `""` is returned. If `path` is null, the result is unspecified. **/ public static function directory( path ) : String { var s = new Path(path); if( s.dir == null ) return ""; return s.dir; } /** Returns the extension of `path`. If the extension is null, the empty String `""` is returned. If `path` is null, the result is unspecified. **/ public static function extension( path ) : String { var s = new Path(path); if( s.ext == null ) return ""; return s.ext; } /** Returns a String representation of `path` where the extension is `ext`. If `path` has no extension, `ext` is added as extension. If `path` or `ext` are null, the result is unspecified. **/ public static function withExtension( path, ext ) : String { var s = new Path(path); s.ext = ext; return s.toString(); } /** Joins all paths in `paths` together. If `paths` is empty, the empty String `""` is returned. Otherwise the paths are joined with a slash between them. If `paths` is null, the result is unspecified. **/ public static function join(paths:Array) : String { var paths = paths.filter(function(s) return s != null && s != ""); if (paths.length == 0) { return ""; } var path = paths[0]; for (i in 1...paths.length) { path = addTrailingSlash(path); path += paths[i]; } return normalize(path); } /** Normalize a given `path` (e.g. make '/usr/local/../lib' to '/usr/lib'). Also replaces backslashes \ with slashes / and afterwards turns multiple slashes into a single one. If `path` is null, the result is unspecified. **/ public static function normalize(path : String) : String { var slash = "/"; path = path.split("\\").join(slash); if (path == slash) return slash; var target = []; for( token in path.split(slash) ) { if(token == '..' && target.length > 0 && target[target.length-1] != "..") { target.pop(); } else if(token != '.') { target.push(token); } } var tmp = target.join(slash); var regex = ~/([^:])\/+/g; var result = regex.replace(tmp, "$1" +slash); var acc = new StringBuf(); var colon = false; var slashes = false; for (i in 0...tmp.length) { switch (StringTools.fastCodeAt(tmp, i)) { case ":".code: acc.add(":"); colon = true; case "/".code if (!colon): slashes = true; case i: colon = false; if (slashes) { acc.add("/"); slashes = false; } acc.addChar(i); } } return acc.toString(); } /** Adds a trailing slash to `path`, if it does not have one already. If the last slash in `path` is a backslash, a backslash is appended to `path`. If the last slash in `path` is a slash, or if no slash is found, a slash is appended to `path`. In particular, this applies to the empty String `""`. If `path` is null, the result is unspecified. **/ public static function addTrailingSlash( path : String ) : String { if (path.length == 0) return "/"; var c1 = path.lastIndexOf("/"); var c2 = path.lastIndexOf("\\"); return if ( c1 < c2 ) { if (c2 != path.length - 1) path + "\\"; else path; } else { if (c1 != path.length - 1) path + "/"; else path; } } /** Removes trailing slashes from `path`. If `path` does not end with a `/` or `\`, `path` is returned unchanged. Otherwise the substring of `path` excluding the trailing slashes or backslashes is returned. If `path` is null, the result is unspecified. **/ @:require(haxe_ver >= 3.1) public static function removeTrailingSlashes ( path : String ) : String { while (true) { switch(path.charCodeAt(path.length - 1)) { case '/'.code | '\\'.code: path = path.substr(0, -1); case _: break; } } return path; } /** Returns true if the path is an absolute path, and false otherwise. **/ @:require(haxe_ver >= 3.2) public static function isAbsolute ( path : String ) : Bool { if (StringTools.startsWith(path, '/')) return true; if (path.charAt(1) == ':') return true; if (StringTools.startsWith(path, '\\\\')) return true; return false; } private static function unescape( path : String ) : String { var regex = ~/-x([0-9][0-9])/g; return regex.map(path, function(regex) return String.fromCharCode(Std.parseInt(regex.matched(1)))); } private static function escape( path : String, allowSlashes : Bool = false ) : String { var regex = allowSlashes ? ~/[^A-Za-z0-9_\/\\\.]/g : ~/[^A-Za-z0-9_\.]/g; return regex.map(path, function(v) return '-x' + v.matched(0).charCodeAt(0)); } } haxe_3.4.4.orig/std/haxe/io/StringInput.hx0000664000175000017500000000251213166552354020371 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; class StringInput extends BytesInput { public function new( s : String ) { #if neko // don't copy the string super( neko.Lib.bytesReference(s) ); #else super( haxe.io.Bytes.ofString(s) ); #end } }haxe_3.4.4.orig/std/haxe/io/UInt16Array.hx0000664000175000017500000000577213166552354020143 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef UInt16ArrayData = ArrayBufferView.ArrayBufferViewData; abstract UInt16Array(UInt16ArrayData) { public static inline var BYTES_PER_ELEMENT = 2; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) { this = new ArrayBufferView(elements * BYTES_PER_ELEMENT).getData(); } inline function get_length() { return this.byteLength >> 1; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) : Int { return this.bytes.getUInt16((index<<1) + this.byteOffset); } @:arrayAccess public inline function set( index : Int, value : Int ) : Int { if( index >= 0 && index < length ) { this.bytes.setUInt16((index<<1) + this.byteOffset, value); return value; } return 0; } public inline function sub( begin : Int, ?length : Int ) : UInt16Array { return fromData(this.sub(begin<<1,length == null ? null : length<<1)); } public inline function subarray( ?begin : Int, ?end : Int ) : UInt16Array { return fromData(this.subarray(begin==null?null:begin<<1,end==null?null:end<<1)); } public inline function getData() : UInt16ArrayData { return this; } public static function fromData( d : UInt16ArrayData ) : UInt16Array { return cast d; } public static function fromArray( a : Array, pos = 0, ?length : Int ) : UInt16Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; var i = new UInt16Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos = 0, ?length : Int ) : UInt16Array { return fromData(ArrayBufferView.fromBytes(bytes,bytePos,(length == null ? (bytes.length - bytePos)>>1 : length)<<1).getData()); } } haxe_3.4.4.orig/std/haxe/io/UInt32Array.hx0000664000175000017500000000577413166552354020143 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef UInt32ArrayData = ArrayBufferView.ArrayBufferViewData; abstract UInt32Array(UInt32ArrayData) { public static inline var BYTES_PER_ELEMENT = 4; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) { this = new ArrayBufferView(elements * BYTES_PER_ELEMENT).getData(); } inline function get_length() { return this.byteLength >> 2; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) : UInt { return this.bytes.getInt32((index<<2) + this.byteOffset); } @:arrayAccess public inline function set( index : Int, value : UInt ) : UInt { if( index >= 0 && index < length ) { this.bytes.setInt32((index<<2) + this.byteOffset, value); return value; } return 0; } public inline function sub( begin : Int, ?length : Int ) : UInt32Array { return fromData(this.sub(begin<<2,length == null ? null : length<<2)); } public inline function subarray( ?begin : Int, ?end : Int ) : UInt32Array { return fromData(this.subarray(begin==null?null:begin<<2,end==null?null:end<<2)); } public inline function getData() : UInt32ArrayData { return this; } public static function fromData( d : UInt32ArrayData ) : UInt32Array { return cast d; } public static function fromArray( a : Array, pos = 0, ?length : Int ) : UInt32Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; var i = new UInt32Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos = 0, ?length : Int ) : UInt32Array { return fromData(ArrayBufferView.fromBytes(bytes,bytePos,(length == null ? (bytes.length - bytePos)>>2 : length)<<2).getData()); } } haxe_3.4.4.orig/std/haxe/io/UInt8Array.hx0000664000175000017500000000553513166552354020061 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef UInt8ArrayData = ArrayBufferView.ArrayBufferViewData; abstract UInt8Array(UInt8ArrayData) { public static inline var BYTES_PER_ELEMENT = 1; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) { this = new ArrayBufferView(elements * BYTES_PER_ELEMENT).getData(); } inline function get_length() { return this.byteLength; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) { return this.bytes.get(index + this.byteOffset); } @:arrayAccess public inline function set( index : Int, value : Int ) : Int { if( index >= 0 && index < length ) { this.bytes.set(index + this.byteOffset, value); return value; } return 0; } public inline function sub( begin : Int, ?length : Int ) : UInt8Array { return fromData(this.sub(begin,length)); } public inline function subarray( ?begin : Int, ?end : Int ) : UInt8Array { return fromData(this.subarray(begin,end)); } public inline function getData() : UInt8ArrayData { return this; } public static function fromData( d : UInt8ArrayData ) : UInt8Array { return cast d; } public static function fromArray( a : Array, pos = 0, ?length : Int ) : UInt8Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; var i = new UInt8Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos : Int = 0, ?length : Int ) : UInt8Array { return fromData(ArrayBufferView.fromBytes(bytes,bytePos,length).getData()); } } haxe_3.4.4.orig/std/haxe/macro/CompilationServer.hx0000664000175000017500000000445113166552354022246 0ustar andyandy00000000000000package haxe.macro; import haxe.macro.Compiler; @:enum abstract ModuleCheckPolicy(Int) { /** Disables file modification checks, avoiding some filesystem operations. **/ var NoCheckFileTimeModification = 0; /** If a file is modified, also checks if its content changed. This check is not free, but useful when .hx files are auto-generated. **/ var CheckFileContentModification = 1; /** Disables dependency checks of the module. **/ var NoCheckDependencies = 2; /** Disables file shadowing checks. Shadowing can occur when a new file is added to a class-path that has higher priority than the class-path of the current module file. **/ var NoCheckShadowing = 3; } @:enum abstract ContextOptions(Int) { /** Affects only the normal context. **/ var NormalContext = 0; /** Affects only the macro context. **/ var MacroContext = 1; /** Affects the normal and macro contexts. **/ var NormalAndMacroContext = 2; } /** This class provides some methods which can be invoked from command line using `--macro server.field(args)`. **/ class CompilationServer { #if macro /** Sets the `ModuleCheckPolicy` of all files whose dot-path matches an element of `pathFilters`. If `recursive` is true, a dot-path is considered matched if it starts with the path filter. This automatically applies to path filters of packages. Otherwise an exact match is required. If an element in `pathFilters` is the empty String `""` it matches everything (if `recursive = true`) or only top-level types (if `recursive = false`). The argument `contextOptions` determines which context (normal, macro or both) this affects. If a call to this function is added to the compilation parameters, the compilation server should be restarted to ensure it takes effect. **/ static public function setModuleCheckPolicy(pathFilters:Array, policy:Array, ?recursive = true, ?contextOptions:ContextOptions = NormalContext) { @:privateAccess Compiler.load("server_add_module_check_policy", 4)(pathFilters, policy, recursive, contextOptions); } /** Invalidates all files given in `filePaths`, removing them from the cache. **/ static public function invalidateFiles(filePaths:Array) { @:privateAccess Compiler.load("server_invalidate_files", 1)(filePaths); } #end }haxe_3.4.4.orig/std/haxe/macro/Compiler.hx0000664000175000017500000003402513166552354020353 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Expr; /** All these methods can be called for compiler configuration macros. **/ #if hl @:hlNative("macro") #end class Compiler { /** A conditional compiler flag can be set command line using `-D key=value`. Returns the value of a compiler flag. If the compiler flag is defined but no value is set, `Compiler.getDefine` returns `"1"` (e.g. `-D key`). If the compiler flag is not defined, `Compiler.getDefine` returns `null`. @see https://haxe.org/manual/lf-condition-compilation.html **/ macro static public function getDefine( key : String ) { return macro $v{haxe.macro.Context.definedValue(key)}; } #if (neko || (macro && hl)) static var ident = ~/^[A-Za-z_][A-Za-z0-9_]*$/; static var path = ~/^[A-Za-z_][A-Za-z0-9_.]*$/; public static function allowPackage( v : String ) { #if neko load("allow_package", 1)(v); #end } /** Set a conditional compiler flag. **/ public static function define( flag : String, ?value : String ) { #if neko load("define", 2)(flag,value); #end } #if !neko private static function typePatch( cl : String, f : String, stat : Bool, t : String ) { } private static function metaPatch( meta : String, cl : String, f : String, stat : Bool ) { } private static function addGlobalMetadataImpl(pathFilter:String, meta:String, recursive:Bool, toTypes:Bool, toFields:Bool) { } #end /** Removes a (static) field from a given class by name. An error is thrown when `className` or `field` is invalid. **/ public static function removeField( className : String, field : String, ?isStatic : Bool ) { if( !path.match(className) ) throw "Invalid "+className; if( !ident.match(field) ) throw "Invalid " + field; #if neko load("type_patch", 4)(className, field, isStatic == true, null); #else typePatch(className, field, isStatic == true, null); #end } /** Set the type of a (static) field at a given class by name. An error is thrown when `className` or `field` is invalid. **/ public static function setFieldType( className : String, field : String, type : String, ?isStatic : Bool ) { if( !path.match(className) ) throw "Invalid "+className; if( !ident.match((field.charAt(0) == "$") ? field.substr(1) : field) ) throw "Invalid "+field; #if neko load("type_patch", 4)(className, field, isStatic == true, type); #else typePatch(className, field, isStatic == true, type); #end } /** Add metadata to a (static) field or class by name. An error is thrown when `className` or `field` is invalid. **/ public static function addMetadata( meta : String, className : String, ?field : String, ?isStatic : Bool ) { if( !path.match(className) ) throw "Invalid "+className; if( field != null && !ident.match(field) ) throw "Invalid "+field; #if neko load("meta_patch", 4)(meta, className, field, isStatic == true); #else metaPatch(meta, className, field, isStatic == true); #end } public static function addClassPath( path : String ) { #if neko load("add_class_path", 1)(path); #end } public static function getOutput() : String { #if neko return load("get_output", 0)(); #else return null; #end } public static function setOutput( fileOrDir : String ) { #if neko load("set_output", 1)(fileOrDir); #end } public static function getDisplayPos() : Null<{ file : String, pos : Int }> { #if neko return load("get_display_pos", 0)(); #else return null; #end } /** Adds a native library depending on the platform (e.g. `-swf-lib` for Flash). **/ public static function addNativeLib( name : String ) { #if neko load("add_native_lib", 1)(name); #end } /** Adds an argument to be passed to the native compiler (e.g. `-javac-arg` for Java). **/ public static function addNativeArg( argument : String ) { #if neko load("add_native_arg", 1)(argument); #end } /** Includes all modules in package `pack` in the compilation. In order to include single modules, their paths can be listed directly on command line: `haxe ... ModuleName pack.ModuleName`. By default `Compiler.include` will search for modules in the directories defined with `-cp`. If you want to specify a different set of paths to search for modules, you can use the optional argument `classPath`. @param rec If true, recursively adds all sub-packages. @param ignore Array of module names to ignore for inclusion. @param classPaths An alternative array of paths (directory names) to use to search for modules to include. Note that if you pass this argument, only the specified paths will be used for inclusion. @param strict If true and given package wasn't found in any of class paths, fail with an error. **/ public static function include( pack : String, ?rec = true, ?ignore : Array, ?classPaths : Array, strict = false ) { var skip = if( ignore == null ) { function(c) return false; } else { function(c) return Lambda.has(ignore, c); } var displayValue = Context.definedValue("display"); if( classPaths == null ) { classPaths = Context.getClassPath(); // do not force inclusion when using completion switch (displayValue) { case null: case "usage": case _: return; } // normalize class path for( i in 0...classPaths.length ) { var cp = StringTools.replace(classPaths[i], "\\", "/"); if(StringTools.endsWith(cp, "/")) cp = cp.substr(0, -1); if( cp == "" ) cp = "."; classPaths[i] = cp; } } var prefix = pack == '' ? '' : pack + '.'; var found = false; for( cp in classPaths ) { var path = pack == '' ? cp : cp + "/" + pack.split(".").join("/"); if( !sys.FileSystem.exists(path) || !sys.FileSystem.isDirectory(path) ) continue; found = true; for( file in sys.FileSystem.readDirectory(path) ) { if( StringTools.endsWith(file, ".hx") && file.substr(0, file.length - 3).indexOf(".") < 0 ) { var cl = prefix + file.substr(0, file.length - 3); if( skip(cl) ) continue; Context.getModule(cl); } else if( rec && sys.FileSystem.isDirectory(path + "/" + file) && !skip(prefix + file) ) include(prefix + file, true, ignore, classPaths); } } if (strict && !found) Context.error('Package "$pack" was not found in any of class paths', Context.currentPos()); } /** Exclude a class or an enum without changing it to `@:nativeGen`. **/ static function excludeBaseType( baseType : Type.BaseType ) : Void { if (!baseType.isExtern) { var meta = baseType.meta; if (!meta.has(":nativeGen")) { meta.add(":hxGen", [], baseType.pos); } baseType.exclude(); } } /** Exclude a specific class, enum, or all classes and enums in a package from being generated. Excluded types become `extern`. @param rec If true, recursively excludes all sub-packages. **/ public static function exclude( pack : String, ?rec = true ) { Context.onGenerate(function(types) { for( t in types ) { var b : Type.BaseType, name; switch( t ) { case TInst(c, _): name = c.toString(); b = c.get(); case TEnum(e, _): name = e.toString(); b = e.get(); default: continue; } var p = b.pack.join("."); if( (p == pack || name == pack) || (rec && StringTools.startsWith(p, pack + ".")) ) excludeBaseType(b); } }); } /** Exclude classes and enums listed in an extern file (one per line) from being generated. **/ public static function excludeFile( fileName : String ) { fileName = Context.resolvePath(fileName); var f = sys.io.File.read(fileName,true); var classes = new haxe.ds.StringMap(); try { while( true ) { var l = StringTools.trim(f.readLine()); if( l == "" || !~/[A-Za-z0-9._]/.match(l) ) continue; classes.set(l,true); } } catch( e : haxe.io.Eof ) { } Context.onGenerate(function(types) { for( t in types ) { switch( t ) { case TInst(c, _): if( classes.exists(c.toString()) ) excludeBaseType(c.get()); case TEnum(e, _): if( classes.exists(e.toString()) ) excludeBaseType(e.get()); default: } } }); } /** Load a type patch file that can modify the field types within declared classes and enums. **/ public static function patchTypes( file : String ) : Void { var file = Context.resolvePath(file); var f = sys.io.File.read(file, true); try { while( true ) { var r = StringTools.trim(f.readLine()); if( r == "" || r.substr(0,2) == "//" ) continue; if( StringTools.endsWith(r,";") ) r = r.substr(0,-1); if( r.charAt(0) == "-" ) { r = r.substr(1); var isStatic = StringTools.startsWith(r,"static "); if( isStatic ) r = r.substr(7); var p = r.split("."); var field = p.pop(); removeField(p.join("."),field,isStatic); continue; } if( r.charAt(0) == "@" ) { var rp = r.split(" "); var type = rp.pop(); var isStatic = rp[rp.length - 1] == "static"; if( isStatic ) rp.pop(); var meta = rp.join(" "); var p = type.split("."); var field = if( p.length > 1 && p[p.length-2].charAt(0) >= "a" ) null else p.pop(); addMetadata(meta,p.join("."),field,isStatic); continue; } if( StringTools.startsWith(r, "enum ") ) { define("fakeEnum:" + r.substr(5)); continue; } var rp = r.split(" : "); if( rp.length > 1 ) { r = rp.shift(); var isStatic = StringTools.startsWith(r,"static "); if( isStatic ) r = r.substr(7); var p = r.split("."); var field = p.pop(); setFieldType(p.join("."),field,rp.join(" : "),isStatic); continue; } throw "Invalid type patch "+r; } } catch( e : haxe.io.Eof ) { } } /** Marks types or packages to be kept by DCE. This also extends to the sub-types of resolved modules. In order to include module sub-types directly, their full dot path including the containing module has to be used (e.g. `msignal.Signal.Signal0`). This operation has no effect if the type has already been loaded, e.g. through `Context.getType`. @param path A package, module or sub-type dot path to keep. @param paths An Array of package, module or sub-type dot paths to keep. @param recursive If true, recurses into sub-packages for package paths. **/ public static function keep(?path : String, ?paths : Array, ?recursive:Bool = true) { if (null == paths) paths = []; if (null != path) paths.push(path); for (path in paths) { addGlobalMetadata(path, "@:keep", recursive, true, true); } } /** Adds metadata `meta` to all types (if `toTypes = true`) or fields (if `toFields = true`) whose dot-path matches `pathFilter`. If `recursive` is true a dot-path is considered matched if it starts with `pathFilter`. This automatically applies to path filters of packages. Otherwise an exact match is required. If `pathFilter` is the empty String `""` it matches everything (if `recursive = true`) or only top-level types (if `recursive = false`). This operation has no effect if the type has already been loaded, e.g. through `Context.getType`. **/ public static function addGlobalMetadata(pathFilter:String, meta:String, ?recursive:Bool = true, ?toTypes:Bool = true, ?toFields:Bool = false) { #if neko load("add_global_metadata_impl", 5)(pathFilter, meta, recursive, toTypes, toFields); #else addGlobalMetadataImpl(pathFilter, meta, recursive, toTypes, toFields); #end } /** Change the default JS output by using a custom generator callback **/ public static function setCustomJSGenerator( callb : JSGenApi -> Void ) { #if neko load("set_custom_js_generator", 1)(callb); #end } #if neko static inline function load( f, nargs ) : Dynamic { return @:privateAccess Context.load(f, nargs); } #end #end #if (js || lua || macro) /** Embed a JavaScript file at compile time (can be called by `--macro` or within an `__init__` method). **/ public static #if !macro macro #end function includeFile( file : String, position:IncludePosition = Top ) { return switch ((position:String).toLowerCase()) { case Inline: if (Context.getLocalModule() == "") Context.error("Cannot use inline mode when includeFile is called by `--macro`", Context.currentPos()); var f = try sys.io.File.getContent(Context.resolvePath(file)) catch( e : Dynamic ) Context.error(Std.string(e), Context.currentPos()); var p = Context.currentPos(); { expr : EUntyped( { expr : ECall( { expr : EConst(CIdent("__js__")), pos : p }, [ { expr : EConst(CString(f)), pos : p } ]), pos : p } ), pos : p }; case Top | Closure: @:privateAccess Context.includeFile(file, position); macro {}; case _: Context.error("unknown includeFile position: " + position, Context.currentPos()); } } #end } @:enum abstract IncludePosition(String) from String to String { /** Prepend the file content to the output file. */ var Top = "top"; /** Prepend the file content to the body of the top-level closure. Since the closure is in strict-mode, there may be run-time error if the input is not strict-mode-compatible. */ var Closure = "closure"; /** Directly inject the file content at the call site. */ var Inline = "inline"; } haxe_3.4.4.orig/std/haxe/macro/ComplexTypeTools.hx0000664000175000017500000000365413166552354022077 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Expr; /** This class provides some utility methods to work with AST-level types. It is best used through `using haxe.macro.ComplexTypeTools` syntax and then provides additional methods on `haxe.macro.ComplexType` instances. **/ class ComplexTypeTools { /** Converts type `c` to a human-readable `String` representation. The result is guaranteed to be valid Haxe code, but there may be differences from the original lexical syntax. **/ static public function toString( c : ComplexType ) : String return new Printer().printComplexType(c); #if macro /** Returns a type corresponding to `c`. If `c` is null, the result is null. **/ static public function toType( c : ComplexType ) : Null return c == null ? null : Context.resolveType(c,Context.currentPos()); #end } haxe_3.4.4.orig/std/haxe/macro/Context.hl.hx0000664000175000017500000001421513166552354020626 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Expr; import haxe.macro.Type.TypedExpr; @:noDoc @:hlNative("macro") class Context { #if macro public static function error( msg : String, pos : Position ) : Dynamic { return null; } public static function fatalError( msg : String, pos : Position ) : Dynamic { return null; } public static function warning( msg : String, pos : Position ) : Void { } public static function resolvePath( file : String ) : String { return null; } public static function getClassPath() : Array { return null; } public static function currentPos() : Position { return null; } @:require(haxe_ver >= 3.1) public static function getExpectedType():Null { return null; } @:require(haxe_ver >= 3.2) public static function getCallArguments():Null> { return null; } public static function getLocalClass() : Null> { var l = getLocalType(); if( l == null ) return null; return switch( l ) { case TInst(c,_): c; default: null; } } public static function getLocalModule() : String { return null; } public static function getLocalType() : Null { return null; } public static function getLocalMethod() : Null { return null; } public static function getLocalUsing() : Array> { return null; } public static function getLocalImports() : Array { return null; } private static function localVars(b:Bool) : Map { return null; } @:deprecated("Use Context.getLocalTVars() instead") public static function getLocalVars() : Map { return cast localVars(false); } @:require(haxe_ver >= 3.102) public static function getLocalTVars() : Map { return cast localVars(true); } public static function defined( s : String ) : Bool { return null; } public static function definedValue( key : String ) : String { return null; } public static function getDefines() : Map { return null; } public static function getType( name : String ) : Type { return null; } public static function getModule( name : String ) : Array { return null; } static function doParse( expr : String, pos : Position, isInline : Bool ) : Expr { return null; } public static function parse( expr : String, pos : Position ) : Expr { return doParse(expr,pos,false); } public static function parseInlineString( expr : String, pos : Position ) : Expr { return doParse(expr,pos,true); } public static function makeExpr( v : Dynamic, pos : Position ) : Expr { return null; } public static function signature( v : Dynamic ) : String { return null; } public static function onGenerate( callback : Array -> Void ) : Void { } @:require(haxe_ver >= 3.1) public static function onAfterGenerate( callback : Void -> Void ) : Void { } public static function onAfterTyping( callback : Array -> Void ) : Void { } public static function onTypeNotFound ( callback : String -> TypeDefinition ) : Void { } public static function typeof( e : Expr ) : Type { return null; } @:require(haxe_ver >= 3.1) public static function typeExpr( e : Expr ) : TypedExpr { return null; } @:require(haxe_ver >= 3.3) public static function resolveType( t : ComplexType, p : Position ) : Type { return null; } public static function toComplexType( t : Type ) : Null { return null; } public static function unify( t1 : Type, t2 : Type) : Bool { return false; } public static function follow( t : Type, ?once : Bool ) : Type { return null; } public static function followWithAbstracts(t : Type, once : Bool = false ) : Type { return null; } public static function getPosInfos( p : Position ) : { min : Int, max : Int, file : String } { return null; } public static function makePosition( inf : { min : Int, max : Int, file : String } ) : Position { return null; } public static function getResources():Map { return null; } public static function addResource( name : String, data : haxe.io.Bytes ) : Void { } public static function getBuildFields() : Array { return null; } public static function defineType( t : TypeDefinition ) : Void { } public static function defineModule( modulePath : String, types : Array, ?imports: Array, ?usings : Array ) : Void { } public static function getTypedExpr( t : Type.TypedExpr ) : Expr { return null; } @:require(haxe_ver >= 3.2) public static function storeTypedExpr( t : Type.TypedExpr ) : Expr { return null; } public static function registerModuleDependency( modulePath : String, externFile : String ) : Void { } public static function registerModuleReuseCall( modulePath : String, macroCall : String ) : Void { } public static function onMacroContextReused( callb : Void -> Bool ) : Void { } private static function includeFile( file : String, position : String ) { } private static function sExpr( e : TypedExpr, pretty : Bool ) : String { return null; } #end } haxe_3.4.4.orig/std/haxe/macro/Context.hx0000664000175000017500000004442613166552354020233 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Expr; import haxe.macro.Type.TypedExpr; /** Context provides an API for macro programming. It contains common functions that interact with the macro interpreter to query or set information. Other API functions are available in the tools classes: - `haxe.macro.ComplexTypeTools` - `haxe.macro.ExprTools` - `haxe.macro.TypeTools` **/ #if !neko @:noDoc #end class Context { #if neko /** Displays a compilation error `msg` at the given `Position` `pos` and aborts the current macro call. **/ public static function error( msg : String, pos : Position ) : Dynamic { return load("error",2)(msg, pos); } /** Displays a compilation error `msg` at the given `Position` `pos` and aborts the compilation. **/ public static function fatalError( msg : String, pos : Position ) : Dynamic { return load("fatal_error",2)(msg, pos); } /** Displays a compilation warning `msg` at the given `Position` `pos`. **/ public static function warning( msg : String, pos : Position ) { load("warning",2)(msg, pos); } /** Resolves a file name `file` based on the current class paths. The resolution follows the usual class path rules where the last declared class path has priority. If a class path was declared relative, this method returns the relative file path. Otherwise it returns the absolute file path. **/ public static function resolvePath( file : String ) : String { return load("resolve_path",1)(file); } /** Returns an `Array` of current class paths in the order of their declaration. Modifying the returned array has no effect on the compiler. Class paths can be added using `haxe.macro.Compiler.addClassPath`. **/ public static function getClassPath() : Array { return load("class_path",0)(); } /** Returns the position at which the macro was called. **/ public static function currentPos() : Position { return load("current_pos", 0)(); } /** Returns the type which is expected at the place the macro is called. This affects usages such as `var x:Int = macroCall()`, where the expected type will be reported as Int. Might return null if no specific type is expected or if the calling macro is not an expression-macro. **/ @:require(haxe_ver >= 3.1) public static function getExpectedType():Null { return load("get_expected_type", 0)(); } /** Returns the call arguments that lead to the invocation of the current `@:genericBuild` macro, if available. Returns `null` if the current macro is not a `@:genericBuild` macro. **/ @:require(haxe_ver >= 3.2) public static function getCallArguments():Null> { return load("get_call_arguments", 0)(); } /** Returns the current class in which the macro was called. If no such class exists, null is returned. **/ public static function getLocalClass() : Null> { var l : Type = load("get_local_type", 0)(); if( l == null ) return null; return switch( l ) { case TInst(c,_): c; default: null; } } /** Returns the current module path in/on which the macro was called. **/ public static function getLocalModule() : String { return load("get_local_module", 0)(); } /** Returns the current type in/on which the macro was called. If no such type exists, null is returned. **/ public static function getLocalType() : Null { return load("get_local_type", 0)(); } /** Returns the name of the method from which the macro was called. If no such method exists, null is returned. **/ public static function getLocalMethod() : Null { return load("get_local_method", 0)(); } /** Returns an `Array` of classes which are available for `using` usage in the context the macro was called. Modifying the returned array has no effect on the compiler. **/ public static function getLocalUsing() : Array> { return load("get_local_using", 0)(); } /** Returns an `Array` of all imports in the context the macro was called. Modifying the returned array has no effect on the compiler. **/ public static function getLocalImports() : Array { return load("get_local_imports", 0)(); } /** Returns a map of local variables accessible in the context the macro was called. The keys of the returned map are the variable names, the values are their types. Modifying the returned map has no effect on the compiler. **/ @:deprecated("Use Context.getLocalTVars() instead") public static function getLocalVars() : Map { return load("local_vars", 1)(false); } /** Similar to `getLocalVars`, but returns elements of type `TVar` instead of `Type`. **/ @:require(haxe_ver >= 3.102) public static function getLocalTVars() : Map { return load("local_vars", 1)(true); } /** Tells if compiler directive `s` has been set. Compiler directives are set using the `-D` command line parameter, or by calling `haxe.macro.Compiler.define`. **/ public static function defined( s : String ) : Bool { return load("defined", 1)(s); } /** Returns the value defined for compiler directive `key`. If no value is defined for `key`, null is returned. Compiler directive values are set using the `-D key=value` command line parameter, or by calling `haxe.macro.Compiler.define`. The default value is `"1"`. **/ public static function definedValue( key : String ) : String { return load("defined_value", 1)(key); } /** Returns a map of all compiler directives that have been set. Compiler directives are set using the `-D` command line parameter, or by calling `haxe.macro.Compiler.define`. Modifying the returned map has no effect on the compiler. */ public static function getDefines() : Map { return load("get_defines", 0)(); } /** Resolves a type identified by `name`. The resolution follows the usual class path rules where the last declared class path has priority. If no type can be found, an exception of type `String` is thrown. **/ public static function getType( name : String ) : Type { return load("get_type", 1)(name); } /** Resolves a module identified by `name` and returns an `Array` of all its contained types. The resolution follows the usual class path rules where the last declared class path has priority. If no module can be found, null is returned. **/ public static function getModule( name : String ) : Array { return load("get_module", 1)(name); } /** Parses `expr` as Haxe code, returning the corresponding AST. String interpolation of single quote strings within `expr` is not supported. The provided `Position` `pos` is used for all generated inner AST nodes. **/ public static function parse( expr : String, pos : Position ) : Expr { return load("do_parse", 3)(expr, pos, false); } /** Similar to `parse`, but error positions are reported within the provided String `expr`. **/ public static function parseInlineString( expr : String, pos : Position ) : Expr { return load("do_parse", 3)(expr, pos, true); } /** Builds an expression from `v`. This method generates AST nodes depending on the macro-runtime value of `v`. As such, only basic types and enums are supported and the behavior for other types is undefined. The provided `Position` `pos` is used for all generated inner AST nodes. **/ public static function makeExpr( v : Dynamic, pos : Position ) : Expr { return load("make_expr", 2)(v, pos); } /** Returns a hashed MD5 signature of value `v`. **/ public static function signature( v : Dynamic ) : String { return load("signature", 1)(v); } /** Adds a callback function `callback` which is invoked after the compiler's typing phase, just before its generation phase. The callback receives an `Array` containing all types which are about to be generated. Modifications are limited to metadata, it is mainly intended to obtain information. **/ public static function onGenerate( callback : Array -> Void ) { load("on_generate",1)(callback); } /** Adds a callback function `callback` which is invoked after the compiler generation phase. Compilation has completed at this point and cannot be influenced anymore. However, contextual information is still available. **/ @:require(haxe_ver >= 3.1) public static function onAfterGenerate( callback : Void -> Void ) { load("on_after_generate",1)(callback); } /** Adds a callback function `callback` which is invoked after the compiler is done typing, but before optimization. The callback receives the types which have been typed. It is possible to define new types in the callback, in which case it will be called again with the new types as argument. **/ public static function onAfterTyping( callback : Array -> Void ) { load("on_after_typing",1)(callback); } /** Adds a callback function `callback` which is invoked when a type name cannot be resolved. The callback may return a type definition, which is then used for the expected type. If it returns null, the type is considered to still not exist. **/ public static function onTypeNotFound ( callback : String -> TypeDefinition ) { load("on_type_not_found",1)(callback); } /** Types expression `e` and returns its type. Typing the expression may result in a compiler error which can be caught using `try ... catch`. **/ public static function typeof( e : Expr ) : Type { return load("typeof", 1)(e); } /** Types expression `e` and returns the corresponding `TypedExpr`. Typing the expression may result in a compiler error which can be caught using `try ... catch`. **/ @:require(haxe_ver >= 3.1) public static function typeExpr( e : Expr ) : TypedExpr { return load("type_expr", 1)(e); } /** Resolve type `t` and returns the corresponding `Type`. Resolving the type may result in a compiler error which can be caught using `try ... catch`. Resolution is performed based on the current context in which the macro is called. **/ @:require(haxe_ver >= 3.3) public static function resolveType( t : ComplexType, p : Position ) : Type { return load("resolve_type", 2)(t,p); } /** Returns the `ComplexType` corresponding to the given `Type` `t`. See `haxe.macro.TypeTools.toComplexType` for details. **/ public static function toComplexType( t : Type ) : Null { return load("to_complex_type", 1)(t); } /** Tries to unify `t1` and `t2` and returns `true` if successful. **/ public static function unify( t1 : Type, t2 : Type) : Bool { return load("unify", 2)(t1, t2); } /** Follows a type. See `haxe.macro.TypeTools.follow` for details. **/ public static function follow( t : Type, ?once : Bool ) : Type { return load("follow", 2)(t,once); } /** Follows a type, including abstracts' underlying implementation See `haxe.macro.TypeTools.followWithAbstracts` for details. **/ public static function followWithAbstracts(t : Type, once : Bool = false ) : Type { return load("follow_with_abstracts", 2)(t,once); } /** Returns the information stored in `Position` `p`. **/ public static function getPosInfos( p : Position ) : { min : Int, max : Int, file : String } { return load("get_pos_infos",1)(p); } /** Builds a `Position` from `inf`. **/ public static function makePosition( inf : { min : Int, max : Int, file : String } ) : Position { return load("make_position",3)(inf.min,inf.max,inf.file); } /** Returns a map of all registered resources for this compilation unit. Modifying the returned map has no effect on the compilation, use `haxe.macro.Context.addResource` to add new resources to the compilation unit. **/ public static function getResources():Map { return load("get_resources",0)(); } /** Makes resource `data` available as `name`. The resource is then available using the `haxe.macro.Resource` API. If a previous resource was bound to `name`, it is overwritten. Compilation server : when using the compilation server, the resource is bound to the Haxe module which calls the macro, so it will be included again if that module is reused. If this resource concerns several modules, prefix its name with a $ sign, this will bind it to the macro module instead. **/ public static function addResource( name : String, data : haxe.io.Bytes ) { load("add_resource",2)(name,data); } /** Returns an `Array` of fields of the class which is to be built. This is only defined for `@:build/@:autoBuild` macros. **/ public static function getBuildFields() : Array { return load("get_build_fields", 0)(); } /** Defines a new type from `TypeDefinition` `t`. **/ public static function defineType( t : TypeDefinition ) : Void { load("define_type", 1)(t); } /** Defines a new module as `modulePath` with several `TypeDefinition` `types`. This is analogous to defining a .hx file. The individual `types` can reference each other and any identifier respects the `imports` and `usings` as usual, expect that imports are not allowed to have `.*` wildcards or `in s` shorthands. **/ public static function defineModule( modulePath : String, types : Array, ?imports: Array, ?usings : Array ) : Void { if( imports == null ) imports = []; if( usings == null ) usings = []; load("define_module", 4)(modulePath, types, imports, usings); } /** Returns a syntax-level expression corresponding to typed expression `t`. This process may lose some information. **/ public static function getTypedExpr( t : Type.TypedExpr ) : Expr { return load("get_typed_expr",1)(t); } /** Store typed expression `t` internally and give a syntax-level expression that can be returned from a macro and will be replaced by the stored typed expression. If `t` is null or invalid, an exception is thrown. NOTE: the returned value references an internally stored typed expression that is reset between compilations, so care should be taken when storing the expression returned by this method in a static variable and using the compilation server. **/ @:require(haxe_ver >= 3.2) public static function storeTypedExpr( t : Type.TypedExpr ) : Expr { return load("store_typed_expr",1)(t); } /** Evaluates `e` as macro code. Any call to this function takes effect when the macro is executed, not during typing. As a consequence, this function can not introduce new local variables into the macro context and may have other restrictions. Usage example: ```haxe var e = macro function(i) return i * 2; var f:Int -> Int = haxe.macro.Context.eval(e); trace(f(2)); // 4 ``` Code passed in from outside the macro cannot reference anything in its context, such as local variables. However, it is possible to reference static methods. This method should be considered experimental. If `e` is null, the result is unspecified. **/ //@:require(haxe_ver >= 3.3) //public static function eval( e : Expr ) : Dynamic { //return load("eval",1)(e); //} /** Manually adds a dependency between module `modulePath` and an external file `externFile`. This affects the compilation cache, causing the module to be typed if `externFile` has changed. Has no effect if the compilation cache is not used. **/ public static function registerModuleDependency( modulePath : String, externFile : String ) { load("register_module_dependency", 2)(modulePath,externFile); } /** Register a macro call to be performed every time the module `modulePath` is reused by the compilation cache, meaning that neither the module itself nor its dependencies was changed since last compilation. The `macroCall` should be a String containing valid Haxe expression, similar to `--init` macros (see https://haxe.org/manual/macro-initialization.html). Multiple calls with the exact same `macroCall` value will only register the callback once. This also triggers loading of given module and its dependencies, if it's not yet loaded, but given macro call will not be called on the first module load. If the compilation cache is not used, `macroCall` expressions will not be called, but calling this function will still trigger loading of given `modulePath`. **/ public static function registerModuleReuseCall( modulePath : String, macroCall : String ) { load("register_module_reuse_call", 2)(modulePath,macroCall); } /** Register a callback function that will be called every time the macro context cached is reused with a new compilation. This enable to reset some static vars since the code might have been changed. If the callback returns false, the macro context is discarded and another one is created. **/ public static function onMacroContextReused( callb : Void -> Bool ) { load("on_macro_context_reused", 1)(callb); } @:allow(haxe.macro.TypeTools) @:allow(haxe.macro.MacroStringTools) @:allow(haxe.macro.TypedExprTools) static function load( f, nargs ) : Dynamic { #if macro return neko.Lib.load("macro", f, nargs); #else return Reflect.makeVarArgs(function(_) return throw "Can't be called outside of macro"); #end } private static function includeFile( file : String, position : String ) { load("include_file", 2)(file, position); } private static function sExpr( e : TypedExpr, pretty : Bool ) : String { return haxe.macro.Context.load("s_expr", 2)(e, pretty); } #end } haxe_3.4.4.orig/std/haxe/macro/ExampleJSGenerator.hx0000664000175000017500000001516013166552354022277 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Type; import haxe.macro.Expr; using Lambda; class ExampleJSGenerator { var api : JSGenApi; var buf : StringBuf; var inits : List; var statics : List<{ c : ClassType, f : ClassField }>; var packages : haxe.ds.StringMap; var forbidden : haxe.ds.StringMap; public function new(api) { this.api = api; buf = new StringBuf(); inits = new List(); statics = new List(); packages = new haxe.ds.StringMap(); forbidden = new haxe.ds.StringMap(); for( x in ["prototype", "__proto__", "constructor"] ) forbidden.set(x, true); api.setTypeAccessor(getType); } function getType( t : Type ) { return switch(t) { case TInst(c, _): getPath(c.get()); case TEnum(e, _): getPath(e.get()); case TAbstract(a, _): getPath(a.get()); default: throw "assert"; }; } inline function print(str) { buf.add(str); } inline function newline() { buf.add(";\n"); } inline function genExpr(e) { print(api.generateValue(e)); } function field(p) { return api.isKeyword(p) ? '["' + p + '"]' : "." + p; } function genPackage( p : Array ) { var full = null; for( x in p ) { var prev = full; if( full == null ) full = x else full += "." + x; if( packages.exists(full) ) continue; packages.set(full, true); if( prev == null ) print('if(typeof $x==\'undefined\') $x = {}'); else { var p = prev + field(x); print('if(!$p) $p = {}'); } newline(); } } function getPath( t : BaseType ) { return (t.pack.length == 0) ? t.name : t.pack.join(".") + "." + t.name; } function checkFieldName( c : ClassType, f : ClassField ) { if( forbidden.exists(f.name) ) Context.error("The field " + f.name + " is not allowed in JS", c.pos); } function genClassField( c : ClassType, p : String, f : ClassField ) { checkFieldName(c, f); var field = field(f.name); print('$p.prototype$field = '); var e = f.expr(); if( e == null ) print("null"); else { genExpr(e); } newline(); } function genStaticField( c : ClassType, p : String, f : ClassField ) { checkFieldName(c, f); var field = field(f.name); var e = f.expr(); if( e == null ) { print('$p$field = null'); newline(); } else switch( f.kind ) { case FMethod(_): print('$p$field = '); genExpr(e); newline(); default: statics.add( { c : c, f : f } ); } } function genClass( c : ClassType ) { genPackage(c.pack); api.setCurrentClass(c); var p = getPath(c); print('$p = $$hxClasses[\'$p\'] = '); if( c.constructor != null ) genExpr(c.constructor.get().expr()); else print("function() { }"); newline(); var name = p.split(".").map(api.quoteString).join(","); print('$p.__name__ = [$name]'); newline(); if( c.superClass != null ) { var psup = getPath(c.superClass.t.get()); print('$p.__super__ = $psup'); newline(); print('for(var k in $psup.prototype ) $p.prototype[k] = $psup.prototype[k]'); newline(); } for( f in c.statics.get() ) genStaticField(c, p, f); for( f in c.fields.get() ) { switch( f.kind ) { case FVar(r, _): if( r == AccResolve ) continue; default: } genClassField(c, p, f); } print('$p.prototype.__class__ = $p'); newline(); if( c.interfaces.length > 0 ) { var me = this; var inter = c.interfaces.map(function(i) return me.getPath(i.t.get())).join(","); print('$p.__interfaces__ = [$inter]'); newline(); } } function genEnum( e : EnumType ) { genPackage(e.pack); var p = getPath(e); var names = p.split(".").map(api.quoteString).join(","); var constructs = e.names.map(api.quoteString).join(","); print('$p = $$hxClasses[\'$p\'] = { __ename__ : [$names], __constructs__ : [$constructs] }'); newline(); for( c in e.constructs.keys() ) { var c = e.constructs.get(c); var f = field(c.name); print('$p$f = '); switch( c.type ) { case TFun(args, _): var sargs = args.map(function(a) return a.name).join(","); print('function($sargs) { var $$x = ["${c.name}",${c.index},$sargs]; $$x.__enum__ = $p; $$x.toString = $$estr; return $$x; }'); default: print("[" + api.quoteString(c.name) + "," + c.index + "]"); newline(); print('$p$f.toString = $$estr'); newline(); print('$p$f.__enum__ = $p'); } newline(); } var meta = api.buildMetaData(e); if( meta != null ) { print('$p.__meta__ = '); genExpr(meta); newline(); } } function genStaticValue( c : ClassType, cf : ClassField ) { var p = getPath(c); var f = field(cf.name); print('$p$f = '); genExpr(cf.expr()); newline(); } function genType( t : Type ) { switch( t ) { case TInst(c, _): var c = c.get(); if( c.init != null ) inits.add(c.init); if( !c.isExtern ) genClass(c); case TEnum(r, _): var e = r.get(); if( !e.isExtern ) genEnum(e); default: } } public function generate() { print("var $_, $hxClasses = $hxClasses || {}, $estr = function() { return js.Boot.__string_rec(this,''); }"); newline(); print("function $bind(o,m) { var f = function(){ return f.method.apply(f.scope, arguments); }; f.scope = o; f.method = m; return f; };"); newline(); for( t in api.types ) genType(t); for( e in inits ) { print(api.generateStatement(e)); newline(); } for( s in statics ) { genStaticValue(s.c,s.f); newline(); } if( api.main != null ) { genExpr(api.main); newline(); } sys.io.File.saveContent(api.outputFile, buf.toString()); } #if macro public static function use() { Compiler.setCustomJSGenerator(function(api) new ExampleJSGenerator(api).generate()); } #end } haxe_3.4.4.orig/std/haxe/macro/Expr.hx0000664000175000017500000003604713166552354017525 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; #if (macro && !doc_gen) @:coreType abstract Position { } #else /** Represents a position in a file. **/ typedef Position = { /** Reference to the filename. **/ var file : String; /** Position of the first character. **/ var min : Int; /** Position of the last character. **/ var max : Int; } #end /** Represents a constant. @see https://haxe.org/manual/expression-constants.html **/ enum Constant { /** Represents an integer literal. **/ CInt( v : String ); /** Represents a float literal. **/ CFloat( f : String ); /** Represents a string literal. **/ CString( s : String ); /** Represents an identifier. **/ CIdent( s : String ); /** Represents a regular expression literal. Example: `~/haxe/i` * The first argument _haxe_ is a string with regular expression pattern. * The second argument _i_ is a string with regular expression flags. @see https://haxe.org/manual/std-regex.html **/ CRegexp( r : String, opt : String ); } /** A binary operator. @see https://haxe.org/manual/types-numeric-operators.html **/ enum Binop { /** `+` **/ OpAdd; /** `*` **/ OpMult; /** `/` **/ OpDiv; /** `-` **/ OpSub; /** `=` **/ OpAssign; /** `==` **/ OpEq; /** `!=` **/ OpNotEq; /** `>` **/ OpGt; /** `>=` **/ OpGte; /** `<` **/ OpLt; /** `<=` **/ OpLte; /** `&` **/ OpAnd; /** `|` **/ OpOr; /** `^` **/ OpXor; /** `&&` **/ OpBoolAnd; /** `||` **/ OpBoolOr; /** `<<` **/ OpShl; /** `>>` **/ OpShr; /** `>>>` **/ OpUShr; /** `%` **/ OpMod; /** `+=` `-=` `/=` `*=` `<<=` `>>=` `>>>=` `|=` `&=` `^=` `%=` **/ OpAssignOp( op : Binop ); /** `...` **/ OpInterval; /** `=>` **/ OpArrow; } /** A unary operator. @see https://haxe.org/manual/types-numeric-operators.html **/ enum Unop { /** `++` **/ OpIncrement; /** `--` **/ OpDecrement; /** `!` **/ OpNot; /** `-` **/ OpNeg; /** `~` **/ OpNegBits; } /** Represents a node in the AST. @see https://haxe.org/manual/macro-reification-expression.html **/ typedef Expr = { /** The expression kind. **/ var expr : ExprDef; /** The position of the expression. **/ var pos : Position; } /** Represents a AST node identical to `Expr`, but it allows constraining the type of accepted expressions. @see https://haxe.org/manual/macro-ExprOf.html **/ typedef ExprOf = Expr; /** Represents a switch case. @see https://haxe.org/manual/expression-switch.html **/ typedef Case = { /** The value expressions of the case. **/ var values : Array; /** The optional guard expressions of the case, if available. **/ @:optional var guard : Null; /** The expression of the case, if available. **/ var expr: Null; } /** Represents a variable in the AST. @see https://haxe.org/manual/expression-var.html **/ typedef Var = { /** The name of the variable. **/ var name : String; /** The type-hint of the variable, if available. **/ var type : Null; /** The expression of the variable, if available. **/ var expr : Null; } /** Represents a catch in the AST. @https://haxe.org/manual/expression-try-catch.html **/ typedef Catch = { /** The name of the catch variable. **/ var name : String; /** The type of the catch. **/ var type : ComplexType; /** The expression of the catch. **/ var expr : Expr; } /** Represents the kind of a node in the AST. **/ enum ExprDef { /** A constant. **/ EConst( c : Constant ); /** Array access `e1[e2]`. **/ EArray( e1 : Expr, e2 : Expr ); /** Binary operator `e1 op e2`. **/ EBinop( op : Binop, e1 : Expr, e2 : Expr ); /** Field access on `e.field`. **/ EField( e : Expr, field : String ); /** Parentheses `(e)`. **/ EParenthesis( e : Expr ); /** An object declaration. **/ EObjectDecl( fields : Array<{ field : String, expr : Expr }> ); /** An array declaration `[el]`. **/ EArrayDecl( values : Array ); /** A call `e(params)`. **/ ECall( e : Expr, params : Array ); /** A constructor call `new t(params)`. **/ ENew( t : TypePath, params : Array ); /** An unary operator `op` on `e`: * e++ (op = OpIncrement, postFix = true) * e-- (op = OpDecrement, postFix = true) * ++e (op = OpIncrement, postFix = false) * --e (op = OpDecrement, postFix = false) * -e (op = OpNeg, postFix = false) * !e (op = OpNot, postFix = false) * ~e (op = OpNegBits, postFix = false) **/ EUnop( op : Unop, postFix : Bool, e : Expr ); /** Variable declarations. **/ EVars( vars : Array ); /** A function declaration. **/ EFunction( name : Null, f : Function ); /** A block of expressions `{exprs}`. **/ EBlock( exprs : Array ); /** A `for` expression. **/ EFor( it : Expr, expr : Expr ); /** A `(e1 in e2)` expression. **/ EIn( e1 : Expr, e2 : Expr ); /** An `if(econd) eif` or `if(econd) eif else eelse` expression. **/ EIf( econd : Expr, eif : Expr, eelse : Null ); /** Represents a `while` expression. When `normalWhile` is `true` it is `while (...)`. When `normalWhile` is `false` it is `do {...} while (...)`. **/ EWhile( econd : Expr, e : Expr, normalWhile : Bool ); /** Represents a `switch` expression with related cases and an optional. `default` case if edef != null. **/ ESwitch( e : Expr, cases : Array, edef : Null ); /** Represents a `try`-expression with related catches. **/ ETry( e : Expr, catches : Array ); /** A `return` or `return e` expression. **/ EReturn( ?e : Null ); /** A `break` expression. **/ EBreak; /** A `continue` expression. **/ EContinue; /** An `untyped e` source code. **/ EUntyped( e : Expr ); /** A `throw e` expression. **/ EThrow( e : Expr ); /** A `cast e` or `cast (e, m)` expression. **/ ECast( e : Expr, t : Null ); /** Internally used to provide completion. **/ EDisplay( e : Expr, isCall : Bool ); /** Internally used to provide completion. **/ EDisplayNew( t : TypePath ); /** A `(econd) ? eif : eelse` expression. **/ ETernary( econd : Expr, eif : Expr, eelse : Expr ); /** A `(e:t)` expression. **/ ECheckType( e : Expr, t : ComplexType ); /** A `@m e` expression. **/ EMeta( s : MetadataEntry, e : Expr ); } /** Represents a type syntax in the AST. **/ enum ComplexType { /** Represents the type path. **/ TPath( p : TypePath ); /** Represents a function type. @see https://haxe.org/manual/types-function.html **/ TFunction( args : Array, ret : ComplexType ); /** Represents an anonymous structure type. @see https://haxe.org/manual/types-anonymous-structure.html **/ TAnonymous( fields : Array ); /** Represents parentheses around a type, e.g. the `(Int -> Void)` part in `(Int -> Void) -> String`. **/ TParent( t : ComplexType ); /** Represents typedef extensions `> Iterable`. The array `p` holds the type paths to the given types. @see https://haxe.org/manual/type-system-extensions.html **/ TExtend( p : Array, fields : Array ); /** Represents an optional type. **/ TOptional( t : ComplexType ); } /** Represents a type path in the AST. **/ typedef TypePath = { /** Represents the package of the type path. **/ var pack : Array; /** The name of the type path. **/ var name : String; /** Optional parameters of the type path. **/ @:optional var params : Array; /** Sub is set on module sub-type access: `pack.Module.Type` has name = Module, sub = Type, if available. **/ @:optional var sub : Null; } /** Represents a concrete type parameter in the AST. Haxe allows expressions in concrete type parameters, e.g. `new YourType<["hello", "world"]>`. In that case the value is `TPExpr` while in the normal case it's `TPType`. **/ enum TypeParam { /** **/ TPType( t : ComplexType ); /** **/ TPExpr( e : Expr ); } /** Represents a type parameter declaration in the AST. **/ typedef TypeParamDecl = { /** The name of the type parameter. **/ var name : String; /** The optional constraints of the type parameter. **/ @:optional var constraints : Array; /** The optional parameters of the type parameter. **/ @:optional var params : Array; /** The metadata of the type parameter. **/ @:optional var meta : Metadata; } /** Represents a function in the AST. **/ typedef Function = { /** A list of function arguments. **/ var args : Array; /** The return type-hint of the function, if available. **/ var ret : Null; /** The expression of the function body, if available. **/ var expr : Null; /** An optional list of function parameter type declarations. **/ @:optional var params : Array; } /** Represents a function argument in the AST. **/ typedef FunctionArg = { /** The name of the function argument. **/ var name : String; /** Whether or not the function argument is optional. **/ @:optional var opt : Bool; /** The type-hint of the function argument, if available. **/ var type : Null; /** The optional value of the function argument, if available. **/ @:optional var value : Null; /** The metadata of the function argument. **/ @:optional var meta : Metadata; } /** Represents a metadata entry in the AST. **/ typedef MetadataEntry = { /** The name of the metadata entry. **/ var name : String; /** The optional parameters of the metadata entry. **/ @:optional var params : Array; /** The position of the metadata entry. **/ var pos : Position; } /** Represents metadata in the AST. **/ typedef Metadata = Array; /** Represents a field in the AST. **/ typedef Field = { /** The name of the field. **/ var name : String; /** The documentation of the field, if available. If the field has no documentation, the value is `null`. **/ @:optional var doc : Null; /** The access modifiers of the field. By default fields have private access. @see https://haxe.org/manual/class-field-access-modifier.html **/ @:optional var access : Array; /** The kind of the field. **/ var kind : FieldType; /** The position of the field. **/ var pos : Position; /** The optional metadata of the field. **/ @:optional var meta : Metadata; } /** Represents an access modifier. @see https://haxe.org/manual/class-field-access-modifier.html **/ enum Access { /** Public access modifier, grants access from anywhere. @see https://haxe.org/manual/class-field-visibility.html **/ APublic; /** Private access modifier, grants access to class and its sub-classes only. @see https://haxe.org/manual/class-field-visibility.html **/ APrivate; /** Static access modifier. **/ AStatic; /** Override access modifier. @see https://haxe.org/manual/class-field-override.html **/ AOverride; /** Dynamic (re-)bindable access modifier. @see https://haxe.org/manual/class-field-dynamic.html **/ ADynamic; /** Inline access modifier. Allows expressions to be directly inserted in place of calls to them. @see https://haxe.org/manual/class-field-inline.html **/ AInline; /** Macros access modifier. Allows expression macro functions. These are normal functions which are executed as soon as they are typed. **/ AMacro; } /** Represents the field type in the AST. **/ enum FieldType { /** Represents a variable field type. **/ FVar( t : Null, ?e : Null ); /** Represents a function field type. **/ FFun( f : Function ); /** Represents a property with getter and setter field type. **/ FProp( get : String, set : String, ?t : Null, ?e : Null ); } /** Represents a type definition. **/ typedef TypeDefinition = { /** The package of the type definition. **/ var pack : Array; /** The name of the type definition. **/ var name : String; /** The position to the type definition. **/ var pos : Position; /** The optional metadata of the type definition. **/ @:optional var meta : Metadata; /** The parameter type declarations of the type definition. **/ @:optional var params : Array; /** Whether or not the type is extern. **/ @:optional var isExtern : Bool; /** The kind of the type definition. **/ var kind : TypeDefKind; /** The fields of the type definition. **/ var fields : Array; } /** Represents a type definition kind. **/ enum TypeDefKind { /** Represents an enum kind. **/ TDEnum; /** Represents a structure kind. **/ TDStructure; /** Represents a class kind. **/ TDClass( ?superClass : TypePath, ?interfaces : Array, ?isInterface : Bool ); /** Represents an alias/typedef kind. **/ TDAlias( t : ComplexType ); // ignore TypeDefinition.fields /** Represents an abstract kind. **/ TDAbstract( tthis : Null, ?from : Array, ?to: Array ); } /** This error can be used to handle or produce compilation errors in macros. **/ class Error { /** The error message. **/ public var message : String; /** The position of the error. **/ public var pos : Expr.Position; /** Instantiates an error with given message and position. **/ public function new(m,p) { this.message = m; this.pos = p; } /** Returns the string representation of the error. **/ function toString() { return message; } } /** Represents the import mode. @see https://haxe.org/manual/type-system-import.html **/ enum ImportMode { /** Represents a default import `import c`. **/ INormal; /** Represents the alias import `import c as alias`. **/ IAsName(alias:String); /** Represents the wildcard import `import *`. **/ IAll; } /** Represents the import expression. **/ typedef ImportExpr = { /** The path to the import expression. **/ var path: Array< { pos: Position, name: String } >; /** The mode of the import expression. **/ var mode: ImportMode; } haxe_3.4.4.orig/std/haxe/macro/ExprTools.hx0000664000175000017500000002270313166552354020540 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Expr; using Lambda; /** This class provides some utility methods to work with expressions. It is best used through 'using haxe.macro.ExprTools' syntax and then provides additional methods on haxe.macro.Expr instances. While mainly intended to be used in macros, it works in non-macro code as well. **/ class ExprTools { /** Converts expression `e` to a human-readable String representation. The result is guaranteed to be valid Haxe code, but there may be differences from the original lexical syntax. **/ static public function toString( e : Expr ) : String return new Printer().printExpr(e); /** Calls function `f` on each sub-expression of `e`. If `e` has no sub-expressions, this operation has no effect. Otherwise `f` is called once per sub-expression of `e`, with the sub-expression as argument. These calls are done in order of the sub-expression declarations. This method does not call itself recursively. It should instead be used in a recursive function which handles the expression nodes of interest. Usage example: ```haxe function findStrings(e:Expr) { switch(e.expr) { case EConst(CString(s)): // handle s case _: ExprTools.iter(e, findStrings); } } ``` **/ static public function iter( e : Expr, f : Expr -> Void ) : Void { switch(e.expr) { case EConst(_), EContinue, EBreak, EDisplayNew(_): case EField(e, _), EParenthesis(e), EUntyped(e), EThrow(e), EDisplay(e, _), ECheckType(e, _), EUnop(_, _, e), ECast(e, _), EMeta(_, e): f(e); case EArray(e1, e2), EWhile(e1, e2, _), EBinop(_, e1, e2), EFor(e1, e2), EIn(e1, e2): f(e1); f(e2); case EVars(vl): for (v in vl) opt2(v.expr, f); case ETry(e, cl): f(e); for (c in cl) f(c.expr); case ETernary(e1, e2, e3) | EIf(e1, e2, e3): f(e1); f(e2); opt2(e3, f); case EArrayDecl(el), ENew(_, el), EBlock(el): ExprArrayTools.iter(el, f); case EObjectDecl(fl): for (fd in fl) f(fd.expr); case ECall(e, el): f(e); ExprArrayTools.iter(el, f); case EReturn(e): opt2(e, f); case EFunction(_, func): for (arg in func.args) opt2(arg.value, f); opt2(func.expr, f); case ESwitch(e, cl, edef): f(e); for (c in cl) { ExprArrayTools.iter(c.values, f); opt2(c.guard, f); opt2(c.expr, f); } if (edef != null && edef.expr != null) f(edef); } } /** Transforms the sub-expressions of `e` by calling `f` on each of them. If `e` has no sub-expressions, this operation returns `e` unchanged. Otherwise `f` is called once per sub-expression of `e`, with the sub-expression as argument. These calls are done in order of the sub-expression declarations. This method does not call itself recursively. It should instead be used in a recursive function which handles the expression nodes of interest. Usage example: ```haxe function capitalizeStrings(e:Expr) { return switch(e.expr) { case EConst(CString(s)): { expr: EConst(CString(s.toUpperCase())), pos: e.pos }; case _: ExprTools.map(e, capitalizeStrings); } } ```haxe **/ static public function map( e : Expr, f : Expr -> Expr ) : Expr { return {pos: e.pos, expr: switch(e.expr) { case EConst(_): e.expr; case EArray(e1, e2): EArray(f(e1), f(e2)); case EBinop(op, e1, e2): EBinop(op, f(e1), f(e2)); case EField(e, field): EField(f(e), field); case EParenthesis(e): EParenthesis(f(e)); case EObjectDecl(fields): var ret = []; for (field in fields) ret.push( { field: field.field, expr: f(field.expr) } ); EObjectDecl(ret); case EArrayDecl(el): EArrayDecl(ExprArrayTools.map(el, f)); case ECall(e, params): ECall(f(e), ExprArrayTools.map(params, f)); case ENew(tp, params): ENew(tp, ExprArrayTools.map(params, f)); case EUnop(op, postFix, e): EUnop(op, postFix, f(e)); case EVars(vars): var ret = []; for (v in vars) ret.push( { name: v.name, type:v.type, expr: opt(v.expr, f) } ); EVars(ret); case EBlock(el): EBlock(ExprArrayTools.map(el, f)); case EFor(it, expr): EFor(f(it), f(expr)); case EIn(e1, e2): EIn(f(e1), f(e2)); case EIf(econd, eif, eelse): EIf(f(econd), f(eif), opt(eelse, f)); case EWhile(econd, e, normalWhile): EWhile(f(econd), f(e), normalWhile); case EReturn(e): EReturn(opt(e,f)); case EUntyped(e): EUntyped(f(e)); case EThrow(e): EThrow(f(e)); case ECast(e, t): ECast(f(e), t); case EDisplay(e, isCall): EDisplay(f(e), isCall); case ETernary(econd, eif, eelse): ETernary(f(econd), f(eif), f(eelse)); case ECheckType(e, t): ECheckType(f(e), t); case EDisplayNew(_), EContinue, EBreak: e.expr; case ETry(e, catches): var ret = []; for (c in catches) ret.push( { name:c.name, type:c.type, expr:f(c.expr) } ); ETry(f(e), ret); case ESwitch(e, cases, edef): var ret = []; for (c in cases) ret.push( { expr: opt (c.expr, f), guard: opt(c.guard, f), values: ExprArrayTools.map(c.values, f) } ); ESwitch(f(e), ret, edef == null || edef.expr == null ? edef : f(edef)); case EFunction(name, func): var ret = []; for (arg in func.args) ret.push( { name: arg.name, opt: arg.opt, type: arg.type, value: opt(arg.value, f) } ); EFunction(name, { args: ret, ret: func.ret, params: func.params, expr: f(func.expr) } ); case EMeta(m, e): EMeta(m, f(e)); }}; } /** Returns the value `e` represents. Supported expressions are: - `Int`, `Float` and `String` literals - identifiers `true`, `false` and `null` - structure declarations if all their fields are values - array declarations if all their elements are values - unary operators `-`, `!` and `~` if the operand is a value - binary operators except `=>`, `...` and assignments Parentheses, metadata and the `untyped` keyword are ignored. If any non-value is encountered, an exception of type `String` is thrown. If `e` is null, the result is unspecified. **/ static public function getValue(e:Expr):Dynamic { return switch (e.expr) { case EConst(CInt(v)): Std.parseInt(v); case EConst(CFloat(v)): Std.parseFloat(v); case EConst(CString(s)): s; case EConst(CIdent("true")): true; case EConst(CIdent("false")): false; case EConst(CIdent("null")): null; case EParenthesis(e1) | EUntyped(e1) | EMeta(_, e1): getValue(e1); case EObjectDecl(fields): var obj = {}; for (field in fields) { Reflect.setField(obj, field.field, getValue(field.expr)); } obj; case EArrayDecl(el): el.map(getValue); case EIf(econd, eif, eelse) | ETernary(econd, eif, eelse): if (eelse == null) { throw "If statements only have a value if the else clause is defined"; } else { var econd:Dynamic = getValue(econd); econd ? getValue(eif) : getValue(eelse); } case EUnop(op, false, e1): var e1:Dynamic = getValue(e1); switch (op) { case OpNot: !e1; case OpNeg: -e1; case OpNegBits: ~e1; case _: throw 'Unsupported expression: $e'; } case EBinop(op, e1, e2): var e1:Dynamic = getValue(e1); var e2:Dynamic = getValue(e2); switch (op) { case OpAdd: e1 + e2; case OpSub: e1 - e2; case OpMult: e1 * e2; case OpDiv: e1 / e2; case OpMod: e1 % e2; case OpEq: e1 == e2; case OpNotEq: e1 != e2; case OpLt: e1 < e2; case OpLte: e1 <= e2; case OpGt: e1 > e2; case OpGte: e1 >= e2; case OpOr: e1 | e2; case OpAnd: e1 & e2; case OpXor: e1 ^ e2; case OpBoolAnd: e1 && e2; case OpBoolOr: e1 || e2; case OpShl: e1 << e2; case OpShr: e1 >> e2; case OpUShr: e1 >>> e2; case _: throw 'Unsupported expression: $e'; } case _: throw 'Unsupported expression: $e'; } } static inline function opt(e:Null, f : Expr -> Expr):Expr return e == null ? null : f(e); static inline function opt2(e:Null, f : Expr -> Void):Void if (e != null) f(e); } /** This class provides functions on expression arrays for convenience. For a detailed reference on each method, see the documentation of ExprTools. */ class ExprArrayTools { static public function map( el : Array, f : Expr -> Expr):Array { var ret = []; for (e in el) ret.push(f(e)); return ret; } static public function iter( el : Array, f : Expr -> Void):Void { for (e in el) f(e); } } haxe_3.4.4.orig/std/haxe/macro/Format.hx0000664000175000017500000000714613166552354020035 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Expr; import haxe.macro.Context; /** The actual macro implemented for Std.format **/ class Format { #if macro public static function format( estr : Expr ) { var str = switch( estr.expr ) { case EConst(c): switch(c) { case CString(s): s; default: null; } default: null; }; if( str == null ) Context.error("Constant string required", estr.pos); var pos = Context.getPosInfos(estr.pos); var min = pos.min; pos.min++; var expr = null; function make(size) { pos.max = pos.min + size; var p = Context.makePosition(pos); pos.min += size; return p; } function add(e) { if( expr == null ) expr = e; else expr = { expr : EBinop(OpAdd,expr,e), pos : Context.makePosition({ min : min, max : pos.min, file : pos.file }) }; } var i = 0, start = 0; var max = str.length; while( i < max ) { if( StringTools.fastCodeAt(str,i++) != '$'.code ) continue; var len = i - start - 1; if( len > 0 || expr == null ) add({ expr : EConst(CString(str.substr(start,len))), pos : make(len) }); pos.min++; start = i; var c = StringTools.fastCodeAt(str, i); if( c == '{'.code ) { var count = 1; i++; while( i < max ) { var c = StringTools.fastCodeAt(str,i++); if( c == "}".code ) { if( --count == 0 ) break; } else if( c == "{".code ) count++; } if( count > 0 ) Context.error("Closing brace not found",make(1)); pos.min++; start++; var len = i - start - 1; var expr = str.substr(start, len); add(Context.parseInlineString(expr, make(len))); pos.min++; start++; } else if( (c >= 'a'.code && c <= 'z'.code) || (c >= 'A'.code && c <= 'Z'.code) || c == '_'.code ) { i++; while( true ) { var c = StringTools.fastCodeAt(str, i); if( (c >= 'a'.code && c <= 'z'.code) || (c >= 'A'.code && c <= 'Z'.code) || (c >= '0'.code && c <= '9'.code) || c == '_'.code ) i++; else break; } var len = i - start; var ident = str.substr(start, len); add( { expr : EConst(CIdent(ident)), pos : make(len) } ); } else if( c == '$'.code ) { start = i++; continue; } else { start = i - 1; continue; } start = i; } var len = i - start; if( len > 0 ) add({ expr : EConst(CString(str.substr(start,len))), pos : make(len) }); if( expr == null ) expr = { expr : EConst(CString("")), pos : make(0) }; return { expr : ECheckType(expr,TPath({ pack : [], name : "String", params : [] })), pos : expr.pos }; } #end } haxe_3.4.4.orig/std/haxe/macro/JSGenApi.hx0000664000175000017500000000462513166552354020204 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Type; /** This is the api that is passed to the custom JS generator. **/ typedef JSGenApi = { /** the file in which the JS code can be generated **/ var outputFile : String; /** all the types that were compiled by Haxe **/ var types : Array; /** the main call expression, if a -main class is defined **/ var main : Null; /** generate the JS code for any given typed expression **/ function generateStatement( e : TypedExpr ) : String; /** generate the JS code for a given typed expression-value **/ function generateValue( e : TypedExpr ) : String; /** define the JS code that gets generated when a class or enum is accessed in a typed expression **/ function setTypeAccessor( callb : Type -> String ) : Void; /** tells if the given identifier is a JS keyword **/ function isKeyword( ident : String ) : Bool; /** add a feature **/ function addFeature( f : String ) : Bool; /** check if a feature is used **/ function hasFeature( f : String ) : Bool; /** quote and escape the given string constant **/ function quoteString( s : String ) : String; /** create the metadata expression for the given type **/ function buildMetaData( t : BaseType ) : Null; /** select the current classe **/ function setCurrentClass( c : ClassType ) : Void; } haxe_3.4.4.orig/std/haxe/macro/MacroStringTools.hx0000664000175000017500000000642113166552354022051 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Expr; /** This class provides some utility methods to work with strings in macro context. **/ #if hl @:hlNative("macro") #end class MacroStringTools { #if macro /** Formats `String` `s` using the usual interpolation rules. The returned expression is a concatenation of string parts and escaped elements. **/ static public function formatString(s:String, pos:Position) { #if neko return Context.load("format_string", 2)(s, pos); #end } /** Tells if `e` is a format string, i.e. uses single quotes `'` as delimiters. This only works if `e` has a position which the compiler can find. While this is true for any expressions appearing in real Haxe code (i.e. some .hx file), it might not work for expressions generated by macros. This operation depends on the position of `e`. **/ static public function isFormatExpr(e:ExprOf) : Bool { #if neko return Context.load("is_fmt_string", 1)(e.pos); #else return isFmtString(e.pos); #end } #if !neko static function isFmtString(p:Position) : Bool { return false; } #end #end /** Converts an array of Strings `sl` to a field expression. If `sl` has no elements, the result is null. If `sl` has one element, the result is `EConst(CIdent(sl[0])`. Otherwise the result is a chain of `EField` nodes. If `sl` is null, the result is unspecified. **/ static public function toFieldExpr(sl:Array):Expr { return Lambda.fold(sl, function(s, e) return e == null ? (macro $i{s}) : (macro $e.$s), null); } /** Converts a path given by package `pack` and name `name` to a `String` separated by dots. If `pack` has no elements, the result is `name`. If `pack` is null, the result is unspecified. Otherwise the elements of `pack` are joined with a separating dot, with an appended dot separating the result from `name`. **/ static public function toDotPath(pack:Array, name:String):String { return if (pack.length == 0) name else pack.join(".") + "." +name; } static public function toComplex( path : String ) : ComplexType { var pack = path.split("."); return TPath( { pack : pack, name : pack.pop(), params : [] } ); } } haxe_3.4.4.orig/std/haxe/macro/MacroType.hx0000664000175000017500000000244213166552354020502 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; /** This type is meant to be used to generate custom types using a macro. For instance by doing MacroType<[my.Class.myMacro(55)]> **/ extern class MacroType { }haxe_3.4.4.orig/std/haxe/macro/PositionTools.hx0000664000175000017500000000404513166552354021425 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Expr; class PositionTools { /** Returns the `Position` where the caller of `here` is. **/ macro public static function here():ExprOf { var positionExpr = Context.makeExpr(Context.getPosInfos(Context.currentPos()), Context.currentPos()); if (Context.defined("macro")) { return macro haxe.macro.Context.makePosition($positionExpr); } else { return positionExpr; } } /** Like `Context.getPosInfos`, except this method is available on all platforms. **/ public static function getInfos( p : Position ) : { min : Int, max : Int, file : String } { #if macro return Context.getPosInfos(p); #else return p; #end } /** Like `Context.makePosition`, except this method is available on all platforms. **/ public static function make( inf : { min : Int, max : Int, file : String } ) : Position { #if macro return Context.makePosition(inf); #else return inf; #end } } haxe_3.4.4.orig/std/haxe/macro/Printer.hx0000664000175000017500000003116313166552354020224 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Expr; using Lambda; using StringTools; /** This class provides some utility methods to convert elements from the macro context to a human-readable String representation. */ class Printer { var tabs:String; var tabString:String; public function new(?tabString = "\t") { tabs = ""; this.tabString = tabString; } public function printUnop(op:Unop) return switch(op) { case OpIncrement: "++"; case OpDecrement: "--"; case OpNot: "!"; case OpNeg: "-"; case OpNegBits: "~"; } public function printBinop(op:Binop) return switch(op) { case OpAdd: "+"; case OpMult: "*"; case OpDiv: "/"; case OpSub: "-"; case OpAssign: "="; case OpEq: "=="; case OpNotEq: "!="; case OpGt: ">"; case OpGte: ">="; case OpLt: "<"; case OpLte: "<="; case OpAnd: "&"; case OpOr: "|"; case OpXor: "^"; case OpBoolAnd: "&&"; case OpBoolOr: "||"; case OpShl: "<<"; case OpShr: ">>"; case OpUShr: ">>>"; case OpMod: "%"; case OpInterval: "..."; case OpArrow: "=>"; case OpAssignOp(op): printBinop(op) + "="; } function escapeString(s:String,delim:String) { return delim + s.replace("\n","\\n").replace("\t","\\t").replace("'","\\'").replace('"',"\\\"") #if sys .replace("\x00","\\x00") #end + delim; } public function printFormatString(s:String) { return escapeString(s,"'"); } public function printString(s:String) { return escapeString(s,'"'); } public function printConstant(c:Constant) return switch(c) { case CString(s): printString(s); case CIdent(s), CInt(s), CFloat(s): s; case CRegexp(s,opt): '~/$s/$opt'; } public function printTypeParam(param:TypeParam) return switch(param) { case TPType(ct): printComplexType(ct); case TPExpr(e): printExpr(e); } public function printTypePath(tp:TypePath) return (tp.pack.length > 0 ? tp.pack.join(".") + "." : "") + tp.name + (tp.sub != null ? '.${tp.sub}' : "") + (tp.params == null ? "" : tp.params.length > 0 ? "<" + tp.params.map(printTypeParam).join(", ") + ">" : ""); // TODO: check if this can cause loops public function printComplexType(ct:ComplexType) return switch(ct) { case TPath(tp): printTypePath(tp); case TFunction(args, ret): function printArg(ct) return switch ct { case TFunction(_): "(" + printComplexType(ct) + ")"; default: printComplexType(ct); }; (args.length>0 ? args.map(printArg).join(" -> ") :"Void") + " -> " + printComplexType(ret); case TAnonymous(fields): "{ " + [for (f in fields) printField(f) + "; "].join("") + "}"; case TParent(ct): "(" + printComplexType(ct) + ")"; case TOptional(ct): "?" + printComplexType(ct); case TExtend(tpl, fields): '{> ${tpl.map(printTypePath).join(" >, ")}, ${fields.map(printField).join(", ")} }'; } public function printMetadata(meta:MetadataEntry) return '@${meta.name}' + ((meta.params != null && meta.params.length > 0) ? '(${printExprs(meta.params,", ")})' : ""); public function printAccess(access:Access) return switch(access) { case AStatic: "static"; case APublic: "public"; case APrivate: "private"; case AOverride: "override"; case AInline: "inline"; case ADynamic: "dynamic"; case AMacro: "macro"; } public function printField(field:Field) return (field.doc != null && field.doc != "" ? "/**\n" + tabs + tabString + StringTools.replace(field.doc, "\n", "\n" + tabs + tabString) + "\n" + tabs + "**/\n" + tabs : "") + (field.meta != null && field.meta.length > 0 ? field.meta.map(printMetadata).join('\n$tabs') + '\n$tabs' : "") + (field.access != null && field.access.length > 0 ? field.access.map(printAccess).join(" ") + " " : "") + switch(field.kind) { case FVar(t, eo): 'var ${field.name}' + opt(t, printComplexType, " : ") + opt(eo, printExpr, " = "); case FProp(get, set, t, eo): 'var ${field.name}($get, $set)' + opt(t, printComplexType, " : ") + opt(eo, printExpr, " = "); case FFun(func): 'function ${field.name}' + printFunction(func); } public function printTypeParamDecl(tpd:TypeParamDecl) return tpd.name + (tpd.params != null && tpd.params.length > 0 ? "<" + tpd.params.map(printTypeParamDecl).join(", ") + ">" : "") + (tpd.constraints != null && tpd.constraints.length > 0 ? ":(" + tpd.constraints.map(printComplexType).join(", ") + ")" : ""); public function printFunctionArg(arg:FunctionArg) return (arg.opt ? "?" : "") + arg.name + opt(arg.type, printComplexType, ":") + opt(arg.value, printExpr, " = "); public function printFunction(func:Function) return (func.params == null ? "" : func.params.length > 0 ? "<" + func.params.map(printTypeParamDecl).join(", ") + ">" : "") + "(" + func.args.map(printFunctionArg).join(", ") + ")" + opt(func.ret, printComplexType, ":") + opt(func.expr, printExpr, " "); public function printVar(v:Var) return v.name + opt(v.type, printComplexType, ":") + opt(v.expr, printExpr, " = "); public function printExpr(e:Expr) return e == null ? "#NULL" : switch(e.expr) { #if macro case EConst(CString(s)): haxe.macro.MacroStringTools.isFormatExpr(e) ? printFormatString(s) : printString(s); #end case EConst(c): printConstant(c); case EArray(e1, e2): '${printExpr(e1)}[${printExpr(e2)}]'; case EBinop(op, e1, e2): '${printExpr(e1)} ${printBinop(op)} ${printExpr(e2)}'; case EField(e1, n): '${printExpr(e1)}.$n'; case EParenthesis(e1): '(${printExpr(e1)})'; case EObjectDecl(fl): "{ " + fl.map(function(fld) return '${fld.field} : ${printExpr(fld.expr)}').join(", ") + " }"; case EArrayDecl(el): '[${printExprs(el, ", ")}]'; case ECall(e1, el): '${printExpr(e1)}(${printExprs(el,", ")})'; case ENew(tp, el): 'new ${printTypePath(tp)}(${printExprs(el,", ")})'; case EUnop(op, true, e1): printExpr(e1) + printUnop(op); case EUnop(op, false, e1): printUnop(op) + printExpr(e1); case EFunction(no, func) if (no != null): 'function $no' + printFunction(func); case EFunction(_, func): "function" +printFunction(func); case EVars(vl): "var " +vl.map(printVar).join(", "); case EBlock([]): '{ }'; case EBlock(el): var old = tabs; tabs += tabString; var s = '{\n$tabs' + printExprs(el, ';\n$tabs'); tabs = old; s + ';\n$tabs}'; case EFor(e1, e2): 'for (${printExpr(e1)}) ${printExpr(e2)}'; case EIn(e1, e2): '${printExpr(e1)} in ${printExpr(e2)}'; case EIf(econd, eif, null): 'if (${printExpr(econd)}) ${printExpr(eif)}'; case EIf(econd, eif, eelse): 'if (${printExpr(econd)}) ${printExpr(eif)} else ${printExpr(eelse)}'; case EWhile(econd, e1, true): 'while (${printExpr(econd)}) ${printExpr(e1)}'; case EWhile(econd, e1, false): 'do ${printExpr(e1)} while (${printExpr(econd)})'; case ESwitch(e1, cl, edef): var old = tabs; tabs += tabString; var s = 'switch ${printExpr(e1)} {\n$tabs' + cl.map(function(c) return 'case ${printExprs(c.values, ", ")}' + (c.guard != null ? ' if (${printExpr(c.guard)}):' : ":") + (c.expr != null ? (opt(c.expr, printExpr)) + ";" : "")) .join('\n$tabs'); if (edef != null) s += '\n${tabs}default:' + (edef.expr == null ? "" : printExpr(edef) + ";"); tabs = old; s + '\n$tabs}'; case ETry(e1, cl): 'try ${printExpr(e1)}' + cl.map(function(c) return ' catch(${c.name}:${printComplexType(c.type)}) ${printExpr(c.expr)}').join(""); case EReturn(eo): "return" + opt(eo, printExpr, " "); case EBreak: "break"; case EContinue: "continue"; case EUntyped(e1): "untyped " +printExpr(e1); case EThrow(e1): "throw " +printExpr(e1); case ECast(e1, cto) if (cto != null): 'cast(${printExpr(e1)}, ${printComplexType(cto)})'; case ECast(e1, _): "cast " +printExpr(e1); case EDisplay(e1, _): '#DISPLAY(${printExpr(e1)})'; case EDisplayNew(tp): '#DISPLAY(${printTypePath(tp)})'; case ETernary(econd, eif, eelse): '${printExpr(econd)} ? ${printExpr(eif)} : ${printExpr(eelse)}'; case ECheckType(e1, ct): '(${printExpr(e1)} : ${printComplexType(ct)})'; case EMeta(meta, e1): printMetadata(meta) + " " +printExpr(e1); } public function printExprs(el:Array, sep:String) { return el.map(printExpr).join(sep); } function printExtension(tpl:Array, fields: Array) { return '{\n$tabs>' + tpl.map(printTypePath).join(',\n$tabs>') + "," + (fields.length > 0 ? ('\n$tabs' + fields.map(printField).join(';\n$tabs') + ";\n}") : ("\n}")); } function printStructure(fields:Array) { return fields.length == 0 ? "{ }" : '{\n$tabs' + fields.map(printField).join(';\n$tabs') + ";\n}"; } public function printTypeDefinition(t:TypeDefinition, printPackage = true):String { var old = tabs; tabs = tabString; var str = t == null ? "#NULL" : (printPackage && t.pack.length > 0 && t.pack[0] != "" ? "package " + t.pack.join(".") + ";\n" : "") + (t.meta != null && t.meta.length > 0 ? t.meta.map(printMetadata).join(" ") + " " : "") + (t.isExtern ? "extern " : "") + switch (t.kind) { case TDEnum: "enum " + t.name + ((t.params != null && t.params.length > 0) ? "<" + t.params.map(printTypeParamDecl).join(", ") + ">" : "") + " {\n" + [for (field in t.fields) tabs + (field.doc != null && field.doc != "" ? "/**\n" + tabs + tabString + StringTools.replace(field.doc, "\n", "\n" + tabs + tabString) + "\n" + tabs + "**/\n" + tabs : "") + (field.meta != null && field.meta.length > 0 ? field.meta.map(printMetadata).join(" ") + " " : "") + (switch(field.kind) { case FVar(t, _): field.name + opt(t, printComplexType, ":"); case FProp(_, _, _, _): throw "FProp is invalid for TDEnum."; case FFun(func): field.name + printFunction(func); }) + ";" ].join("\n") + "\n}"; case TDStructure: "typedef " + t.name + ((t.params != null && t.params.length > 0) ? "<" + t.params.map(printTypeParamDecl).join(", ") + ">" : "") + " = {\n" + [for (f in t.fields) { tabs + printField(f) + ";"; }].join("\n") + "\n}"; case TDClass(superClass, interfaces, isInterface): (isInterface ? "interface " : "class ") + t.name + (t.params != null && t.params.length > 0 ? "<" + t.params.map(printTypeParamDecl).join(", ") + ">" : "") + (superClass != null ? " extends " + printTypePath(superClass) : "") + (interfaces != null ? (isInterface ? [for (tp in interfaces) " extends " + printTypePath(tp)] : [for (tp in interfaces) " implements " + printTypePath(tp)]).join("") : "") + " {\n" + [for (f in t.fields) { tabs + printFieldWithDelimiter(f); }].join("\n") + "\n}"; case TDAlias(ct): "typedef " + t.name + ((t.params != null && t.params.length > 0) ? "<" + t.params.map(printTypeParamDecl).join(", ") + ">" : "") + " = " + (switch(ct) { case TExtend(tpl, fields): printExtension(tpl, fields); case TAnonymous(fields): printStructure(fields); case _: printComplexType(ct); }) + ";"; case TDAbstract(tthis, from, to): "abstract " + t.name + ((t.params != null && t.params.length > 0) ? "<" + t.params.map(printTypeParamDecl).join(", ") + ">" : "") + (tthis == null ? "" : "(" + printComplexType(tthis) + ")") + (from == null ? "" : [for (f in from) " from " + printComplexType(f)].join("")) + (to == null ? "" : [for (t in to) " to " + printComplexType(t)].join("")) + " {\n" + [for (f in t.fields) { tabs + printFieldWithDelimiter(f); }].join("\n") + "\n}"; } tabs = old; return str; } function printFieldWithDelimiter(f:Field):String { return printField(f) + switch(f.kind) { case FVar(_, _), FProp(_, _, _, _): ";"; case FFun({expr:null}): ";"; case FFun({expr:{expr:EBlock(_)}}): ""; case FFun(_): ";"; case _: ""; }; } function opt(v:T, f:T->String, prefix = "") return v == null ? "" : (prefix + f(v)); } haxe_3.4.4.orig/std/haxe/macro/Tools.hx0000664000175000017500000000345213166552354017701 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; /** This class can be added via `using haxe.macro.Tools` in order to enable `using` functionality on these macro tool classes: - `haxe.macro.ExprTools` - `haxe.macro.ComplexTypeTools` - `haxe.macro.TypeTools` - `haxe.macro.MacroStringTools` - `haxe.macro.TypedExprTools` - `haxe.macro.PositionTools` @see **/ @:dox(hide) typedef TExprTools = ExprTools; @:dox(hide) typedef TComplexTypeTools = ComplexTypeTools; @:dox(hide) typedef TTypeTools = TypeTools; @:dox(hide) typedef TMacroStringTools = MacroStringTools; @:dox(hide) typedef TTypedExprTools = TypedExprTools; @:dox(hide) typedef TPositionTools = PositionTools; haxe_3.4.4.orig/std/haxe/macro/Type.hx0000664000175000017500000004446413166552354017532 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; /* Warning: Some of these types correspond to compiler-internal data structures and might change in minor Haxe releases in order to adapt to internal changes. */ /** Represents a reference to internal compiler structure. It exists to avoid expensive encoding if it is not required and to ensure that physical equality remains intact. A structure is only encoded when user requests it through `ref.get()`. */ typedef Ref = { public function get() : T; public function toString() : String; } /** Represents a type. */ enum Type { /** Represents a monomorph. @see https://haxe.org/manual/types-monomorph.html **/ TMono( t : Ref> ); /** Represents an enum instance. @see https://haxe.org/manual/types-enum-instance.html **/ TEnum( t : Ref, params : Array ); /** Represents a class instance. @see https://haxe.org/manual/types-class-instance.html **/ TInst( t : Ref, params : Array ); /** Represents a typedef. @see https://haxe.org/manual/type-system-typedef.html **/ TType( t : Ref, params : Array ); /** Represents a function type. @see https://haxe.org/manual/types-function.html **/ TFun( args : Array<{ name : String, opt : Bool, t : Type }>, ret : Type ); /** Represents an anonymous structure type. @see https://haxe.org/manual/types-anonymous-structure.html **/ TAnonymous( a : Ref ); /** Represents Dynamic. @see https://haxe.org/manual/types-dynamic.html **/ TDynamic( t : Null ); /** Used internally by the compiler to delay some typing. **/ TLazy( f : Void -> Type ); /** Represents an abstract type. @see https://haxe.org/manual/types-abstract.html **/ TAbstract( t : Ref, params : Array ); } /** Represents information for anonymous structure types. */ typedef AnonType = { /** The class fields of the structure. **/ var fields : Array; /** The status/kind of the structure. **/ var status : AnonStatus; } /** Represents the kind of the anonymous structure type. **/ enum AnonStatus { /** A closed structure is considered complete. That is, no further fields can be added to it. **/ AClosed; /** An open structure allows having additional fields added to it, which is used during type inference. It is closed upon unification. **/ AOpened; /** A const structure is one that appears directly in syntax. It cannot be assigned to a smaller structure type (that is, it does not allow structural sub-typing). **/ AConst; /** Represents a structure which extends one or multiple structures defined in `tl`. @see https://haxe.org/manual/type-system-extensions.html **/ AExtend( tl:Ref> ); /** A structure that represents the static fields of a class. **/ AClassStatics( t : Ref ); /** A structure that represents the constructors of an enum. **/ AEnumStatics( t : Ref ); /** A structure that represents the static fields of an abstract. **/ AAbstractStatics( t : Ref ); } /** Represents the declaration of type parameters. */ typedef TypeParameter = { /** The name of the type parameter. **/ var name: String; /** The type of the type parameter. It is guaranteed to be a `TInst` with a `KTypeParameter` kind. **/ var t: Type; } /** Represents a class field. */ typedef ClassField = { /** The name of the class field. **/ var name : String; /** The type of the class field. **/ var type : Type; /** Whether or not the class field is public. **/ var isPublic : Bool; /** The type parameters of the class field. **/ var params : Array; /** The metadata of the class field. **/ var meta : MetaAccess; /** The class field kind. **/ var kind : FieldKind; /** Returns the typed expression of the class field. **/ function expr() : Null; /** The position of the class field. **/ var pos : Expr.Position; /** The associated documentation of the class field. **/ var doc : Null; /** The overload fields of the class field. **/ var overloads : Ref>; } /** Represents an enum constructor. */ typedef EnumField = { /** The name of the enum constructor. **/ var name : String; /** The type of the enum constructor. **/ var type : Type; /** The position of the enum constructor. **/ var pos : Expr.Position; /** The metadata of the enum constructor. **/ var meta : MetaAccess; /** The index of the enum constructor, i.e. in which position it appears in the syntax. **/ var index : Int; /** The associated documentation of the enum constructor. **/ var doc : Null; /** The type parameters of the enum constructor. **/ var params : Array; } /** Represents the kind of a class. */ enum ClassKind { /** A normal class. **/ KNormal; /** A type parameter class with a set of constraints. **/ KTypeParameter(constraints:Array); /** A structurally extended class. @deprecated **/ KExtension(cl:Ref, params:Array); /** A special kind of class to encode expressions into type parameters. **/ KExpr(expr:Expr); /** A `@:generic` base class. **/ KGeneric; /** A concrete `@:generic` instance, referencing the original class and the applied type parameters. **/ KGenericInstance(cl:Ref, params:Array); /** A special class for `haxe.macro.MacroType`. @deprecated **/ KMacroType; /** An implementation class of an abstract, i.e. where all its run-time code is. **/ KAbstractImpl(a:Ref); /** A `@:genericBuild` class **/ KGenericBuild; } /** The information that all types (`ClassType`, `EnumType`, `DefType`, `AbstractType`) have in common. **/ typedef BaseType = { /** The package of the type. **/ var pack : Array; /** The name of the type. **/ var name : String; /** The module name of the type, which might be different. **/ var module : String; /** The position of the type. **/ var pos : Expr.Position; /** Whether or not the type is private. **/ var isPrivate : Bool; /** Whether or not the type is extern. **/ var isExtern : Bool; /** The type parameters of the type. **/ var params : Array; /** The metadata of the type. **/ var meta : MetaAccess; /** The associated documentation of the class field. **/ var doc : Null; /** Allows excluding the type from compilation. **/ function exclude() : Void; } /** Represents a class type. */ typedef ClassType = {> BaseType, /** The kind of the class. **/ var kind : ClassKind; /** If true the type is an interface, otherwise it is a class. **/ var isInterface : Bool; /** The parent class and its type parameters, if available. **/ var superClass : Null<{ t : Ref, params : Array }>; /** The implemented interfaces and their type parameters. **/ var interfaces : Array<{ t : Ref, params : Array }>; /** The member fields of the class. **/ var fields : Ref>; /** The static fields of the class. **/ var statics : Ref>; //var dynamic : Null; //var arrayAccess : Null; /** The constructor of the class, if available. **/ var constructor : Null>; /** The `__init__` expression of the class, if available. **/ var init : Null; /** The list of fields that have override status. **/ var overrides : Array>; } /** Represents an enum type. */ typedef EnumType = {> BaseType, /** The available enum constructors. **/ var constructs : Map; /** An ordered list of enum constructor names. **/ var names : Array; } /** Represents a typedef. */ typedef DefType = {> BaseType, /** The target type of the typedef. **/ var type : Type; } /** Represents an abstract type. */ typedef AbstractType = {>BaseType, /** The underlying type of the abstract. **/ var type : Type; /** The implementation class of the abstract, if available. **/ var impl : Null>; /** The defined binary operators of the abstract. **/ var binops : Array<{op:Expr.Binop, field:ClassField}>; /** The defined unary operators of the abstract. **/ var unops : Array<{op:Expr.Unop, postFix:Bool, field:ClassField}>; /** The available implicit from-casts of the abstract. @see https://haxe.org/manual/types-abstract-implicit-casts.html **/ var from : Array<{t:Type, field:Null}>; /** The available implicit to-casts of the abstract. @see https://haxe.org/manual/types-abstract-implicit-casts.html **/ var to : Array<{t:Type, field:Null}>; /** The defined array-access fields of the abstract. **/ var array : Array; /** The method used for resolving unknown field access, if available. **/ @:require(haxe_ver >= 3.3) var resolve : Null; } /** MetaAccess is a wrapper for the `Metadata` array. It can be used to add metadata to and remove metadata from its origin. **/ typedef MetaAccess = { /** Return the wrapped `Metadata` array. Modifying this array has no effect on the origin of `this` MetaAccess. The `add` and `remove` methods can be used for that. **/ function get() : Expr.Metadata; /** Extract metadata entries by given `name`. If there's no metadata with such name, empty array `[]` is returned. If `name` is null, compilation fails with an error. **/ function extract( name : String ) : Array; /** Adds the metadata specified by `name`, `params` and `pos` to the origin of `this` MetaAccess. Metadata names are not unique during compilation, so this method never overwrites a previous metadata. If a `Metadata` array is obtained through a call to `get`, a subsequent call to `add` has no effect on that array. If any argument is null, compilation fails with an error. **/ function add( name : String, params : Array, pos : Expr.Position ) : Void; /** Removes all `name` metadata entries from the origin of `this` MetaAccess. This method might clear several metadata entries of the same name. If a `Metadata` array is obtained through a call to `get`, a subsequent call to `remove` has no effect on that array. If `name` is null, compilation fails with an error. **/ function remove( name : String ) : Void; /** Tells if the origin of `this` MetaAccess has a `name` metadata entry. If `name` is null, compilation fails with an error. **/ function has( name : String ) : Bool; } /** Represents a field kind. */ enum FieldKind { /** A variable of property, depending on the `read` and `write` values. **/ FVar( read : VarAccess, write : VarAccess ); /** A method **/ FMethod( k : MethodKind ); } /** Represents the variable accessor. */ enum VarAccess { /** Normal access (`default`). **/ AccNormal; /** Private access (`null`). **/ AccNo; /** No access (`never`). **/ AccNever; /** Unused. **/ AccResolve; /** Access through accessor function (`get`, `set`, `dynamic`). **/ AccCall; /** Inline access (`inline`). **/ AccInline; /** Failed access due to a `@:require` metadata. **/ AccRequire( r : String, ?msg : String ); } /** Represents the method kind. */ enum MethodKind { /** A normal method. **/ MethNormal; /** An inline method. @see https://haxe.org/manual/class-field-inline.html **/ MethInline; /** A dynamic, rebindable method. @see https://haxe.org/manual/class-field-dynamic.html **/ MethDynamic; /** A macro method. **/ MethMacro; } /** Represents typed constant. */ enum TConstant { /** An `Int` literal. **/ TInt(i:Int); /** A `Float` literal, represented as String to avoid precision loss. **/ TFloat(s:String); /** A `String` literal. **/ TString(s:String); /** A `Bool` literal. **/ TBool(b:Bool); /** The constant `null`. **/ TNull; /** The constant `this`. **/ TThis; /** The constant `super`. **/ TSuper; } /** Represents a variable in the typed AST. */ typedef TVar = { /** The unique ID of the variable. **/ public var id(default, never):Int; /** The name of the variable. **/ public var name(default, never):String; /** The type of the variable. **/ public var t(default, never):Type; /** Whether or not the variable has been captured by a closure. **/ public var capture(default, never):Bool; /** Special information which is internally used to keep track of closure. information **/ public var extra(default,never):Null<{params: Array, expr: Null}>; /** The metadata of the variable. **/ public var meta(default,never):Null; } /** Represents a module type. These are the types that can be declared in a Haxe module and which are passed to the generators (except `TTypeDecl`). */ enum ModuleType { /** A class. **/ TClassDecl(c:Ref); /** An enum. **/ TEnumDecl(e:Ref); /** A typedef. **/ TTypeDecl(t:Ref); /** An abstract. **/ TAbstract(a:Ref); } /** Represents a function in the typed AST. */ typedef TFunc = { /** A list of function arguments identified by an argument variable `v` and an optional initialization `value`. **/ var args: Array<{v:TVar, value:Null}>; /** The return type of the function. **/ var t: Type; /** The expression of the function body. **/ var expr: TypedExpr; } /** Represents the kind of field access in the typed AST. */ enum FieldAccess { /** Access of field `cf` on a class instance `c` with type parameters `params`. **/ FInstance(c:Ref, params:Array, cf:Ref); /** Static access of a field `cf` on a class `c`. **/ FStatic(c:Ref, cf:Ref); /** Access of field `cf` on an anonymous structure. **/ FAnon(cf:Ref); /** Dynamic field access of a field named `s`. **/ FDynamic(s:String); /** Closure field access of field `cf` on a class instance `c` with type parameters `params`. **/ FClosure(c:Null<{c:Ref, params:Array}>, cf:Ref); /** Field access to an enum constructor `ef` of enum `e`. **/ FEnum(e:Ref, ef:EnumField); } /** Represents kind of a node in the typed AST. */ enum TypedExprDef { /** A constant. **/ TConst(c:TConstant); /** Reference to a local variable `v`. **/ TLocal(v:TVar); /** Array access `e1[e2]`. **/ TArray(e1:TypedExpr, e2:TypedExpr); /** Binary operator `e1 op e2`. **/ TBinop(op:Expr.Binop, e1:TypedExpr, e2:TypedExpr); /** Field access on `e` according to `fa`. **/ TField(e:TypedExpr, fa:FieldAccess); /** Reference to a module type `m`. **/ TTypeExpr(m:ModuleType); /** Parentheses `(e)`. **/ TParenthesis(e:TypedExpr); /** An object declaration. **/ TObjectDecl(fields:Array<{name:String, expr:TypedExpr}>); /** An array declaration `[el]`. **/ TArrayDecl(el:Array); /** A call `e(el)`. **/ TCall(e:TypedExpr, el:Array); /** A constructor call `new c(el)`. **/ TNew(c:Ref, params: Array, el:Array); /** An unary operator `op` on `e`: * e++ (op = OpIncrement, postFix = true) * e-- (op = OpDecrement, postFix = true) * ++e (op = OpIncrement, postFix = false) * --e (op = OpDecrement, postFix = false) * -e (op = OpNeg, postFix = false) * !e (op = OpNot, postFix = false) * ~e (op = OpNegBits, postFix = false) **/ TUnop(op:Expr.Unop, postFix:Bool, e:TypedExpr); /** A function declaration. **/ TFunction(tfunc:TFunc); /** A variable declaration `var v` or `var v = expr`. **/ TVar(v:TVar, expr:Null); /** A block declaration `{el}`. **/ TBlock(el:Array); /** A `for` expression. **/ TFor(v:TVar, e1:TypedExpr, e2:TypedExpr); /** An `if(econd) eif` or `if(econd) eif else eelse` expression. **/ TIf(econd:TypedExpr, eif:TypedExpr, eelse:Null); /** Represents a `while` expression. When `normalWhile` is `true` it is `while (...)`. When `normalWhile` is `false` it is `do {...} while (...)`. **/ TWhile(econd:TypedExpr, e:TypedExpr, normalWhile:Bool); /** Represents a `switch` expression with related cases and an optional `default` case if edef != null. **/ TSwitch(e:TypedExpr, cases:Array<{values:Array, expr:TypedExpr}>, edef:Null); /** Represents a `try`-expression with related catches. **/ TTry(e:TypedExpr, catches:Array<{v:TVar, expr:TypedExpr}>); /** A `return` or `return e` expression. **/ TReturn(e:Null); /** A `break` expression. **/ TBreak; /** A `continue` expression. **/ TContinue; /** A `throw e` expression. **/ TThrow(e:TypedExpr); /** A `cast e` or `cast (e, m)` expression. **/ TCast(e:TypedExpr, m:Null); /** A `@m e1` expression. **/ TMeta(m:Expr.MetadataEntry, e1:TypedExpr); /** Access to an enum parameter (generated by the pattern matcher). **/ TEnumParameter(e1:TypedExpr, ef:EnumField, index:Int); } /** Represents a typed AST node. */ typedef TypedExpr = { /** The expression kind. **/ var expr: TypedExprDef; /** The position of the expression. **/ var pos: Expr.Position; /** The type of the expression. **/ var t: Type; } haxe_3.4.4.orig/std/haxe/macro/TypeTools.hx0000664000175000017500000002526713166552354020553 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Context; import haxe.macro.Expr; import haxe.macro.Type; using Lambda; /** This class provides some utility methods to work with types. It is best used through 'using haxe.macro.TypeTools' syntax and then provides additional methods on haxe.macro.Type instances. **/ #if hl @:hlNative("macro") #end class TypeTools { static function nullable(complexType : ComplexType) : ComplexType return macro : Null<$complexType>; static function toField(cf : ClassField) : Field return { function varAccessToString(va : VarAccess, getOrSet : String) : String return { switch (va) { case AccNormal: "default"; case AccNo: "null"; case AccNever: "never"; case AccResolve: throw "Invalid TAnonymous"; case AccCall: getOrSet; case AccInline: "default"; case AccRequire(_, _): "default"; } } if (cf.params.length == 0) { name: cf.name, doc: cf.doc, access: cf.isPublic ? [ APublic ] : [ APrivate ], kind: switch([ cf.kind, cf.type ]) { case [ FVar(read, write), ret ]: FProp( varAccessToString(read, "get"), varAccessToString(write, "set"), toComplexType(ret), null); case [ FMethod(_), TFun(args, ret) ]: FFun({ args: [ for (a in args) { name: a.name, opt: a.opt, type: toComplexType(a.t), } ], ret: toComplexType(ret), expr: null, }); default: throw "Invalid TAnonymous"; }, pos: cf.pos, meta: cf.meta.get(), } else { throw "Invalid TAnonymous"; } } /** Returns a syntax-level type corresponding to Type `t`. This function is mostly inverse to `ComplexTypeTools.toType`, but may lose some information on types that do not have a corresponding syntax version, such as monomorphs. In these cases, the result is null. If `t` is null, an internal exception is thrown. **/ public static function toComplexType(type : Null) : Null return { #if macro Context.toComplexType(type); #else switch (type) { case null: null; case TMono(_.get() => t): t == null ? null : toComplexType(t); case TEnum(_.get() => baseType, params): TPath(toTypePath(baseType, params)); case TInst(_.get() => classType, params): switch (classType.kind) { case KTypeParameter(_): TPath({ name: classType.name, pack: [], }); default: TPath(toTypePath(classType, params)); } case TType(_.get() => baseType, params): TPath(toTypePath(baseType, params)); case TFun(args, ret): TFunction( [ for (a in args) a.opt ? nullable(toComplexType(a.t)) : toComplexType(a.t) ], toComplexType(ret)); case TAnonymous(_.get() => { fields: fields }): TAnonymous([ for (cf in fields) toField(cf) ]); case TDynamic(t): if (t == null) { macro : Dynamic; } else { var ct = toComplexType(t); macro : Dynamic<$ct>; } case TLazy(f): toComplexType(f()); case TAbstract(_.get() => baseType, params): TPath(toTypePath(baseType, params)); default: throw "Invalid type"; } #end } static function toTypePath(baseType : BaseType, params : Array) : TypePath return { var module = baseType.module; { pack: baseType.pack, name: module.substring(module.lastIndexOf(".") + 1), sub: baseType.name, params: [ for (t in params) TPType(toComplexType(t)) ], } } #if macro /** Follows all typedefs of `t` to reach the actual type. If `once` is true, this function does not call itself recursively, otherwise it does. This can be useful in cases where intermediate typedefs might be of interest. Affected types are monomorphs `TMono` and typedefs `TType(t,pl)`. If `t` is null, an internal exception is thrown. Usage example: var t = Context.typeof(macro null); // TMono() var ts = Context.typeof(macro "foo"); //TInst(String,[]) Context.unify(t, ts); trace(t); // TMono() trace(t.follow()); //TInst(String,[]) **/ static public inline function follow( t : Type, ?once : Bool ) : Type return Context.follow(t, once); /** Like `follow`, follows all typedefs of `t` to reach the actual type. Will however follow also abstracts to their underlying implementation, if they are not a @:coreType abstract If `t` is null, an internal exception is thrown. Usage example: var t = Context.typeof(macro new Map()); trace(t); // TAbstract(Map,[TInst(String,[]),TInst(String,[])]) trace(t.followWithAbstracts()); // TInst(haxe.ds.StringMap, [TInst(String,[])]) **/ static public inline function followWithAbstracts( t : Type, once : Bool = false ) : Type return Context.followWithAbstracts(t, once); /** Returns true if `t1` and `t2` unify, false otherwise. **/ static public inline function unify( t1 : Type, t2:Type ) : Bool return Context.unify(t1, t2); /** Tries to extract the class instance stored inside `t`. If `t` is a class instance `TInst(c,pl)`, c is returned. If `t` is of a different type, an exception of type String is thrown. If `t` is null, the result is null. **/ static public function getClass( t : Type ) return t == null ? null : switch(follow(t)) { case TInst(c, _): c.get(); case _: throw "Class instance expected"; } /** Tries to extract the enum instance stored inside `t`. If `t` is an enum instance `TEnum(e,pl)`, e is returned. If `t` is of a different type, an exception of type String is thrown. If `t` is null, the result is null. **/ static public function getEnum( t : Type ) return t == null ? null : switch(follow(t)) { case TEnum(e, _): e.get(); case _: throw "Enum instance expected"; } /** Applies the type parameters `typeParameters` to type `t` with the given types `concreteTypes`. This function replaces occurrences of type parameters in `t` if they are part of `typeParameters`. The array index of such a type parameter is then used to lookup the concrete type in `concreteTypes`. If `typeParameters.length` is not equal to `concreteTypes.length`, an exception of type `String` is thrown. If `typeParameters.length` is 0, `t` is returned unchanged. If either argument is `null`, the result is unspecified. **/ static public function applyTypeParameters(t:Type, typeParameters:Array, concreteTypes:Array):Type { if (typeParameters.length != concreteTypes.length) throw 'Incompatible arguments: ${typeParameters.length} type parameters and ${concreteTypes.length} concrete types'; else if (typeParameters.length == 0) return t; #if neko return Context.load("apply_params", 3)(typeParameters, concreteTypes, t); #else return applyParams(typeParameters, concreteTypes, t); #end } #if !neko private static function applyParams( typeParameters:Array, concreteTypes:Array, t:Type ) : Type { return null; } #end /** Transforms `t` by calling `f` on each of its subtypes. If `t` is a compound type, `f` is called on each of its components. Otherwise `t` is returned unchanged. The following types are considered compound: - TInst, TEnum, TType and TAbstract with type parameters - TFun - TAnonymous If `t` or `f` are null, the result is unspecified. **/ static public function map(t:Type, f:Type -> Type):Type { return switch(t) { case TMono(tm): switch(tm.get()) { case null: t; case t: f(t); } case TEnum(_, []) | TInst(_, []) | TType(_, []): t; case TEnum(en, tl): TEnum(en, tl.map(f)); case TInst(cl, tl): TInst(cl, tl.map(f)); case TType(t2, tl): TType(t2, tl.map(f)); case TAbstract(a, tl): TAbstract(a, tl.map(f)); case TFun(args, ret): TFun(args.map(function(arg) return { name: arg.name, opt: arg.opt, t: f(arg.t) }), f(ret)); case TAnonymous(an): t; // TODO: Ref? case TDynamic(t2): t == t2 ? t : TDynamic(f(t2)); case TLazy(ft): var ft = ft(); var ft2 = f(ft); ft == ft2 ? t : ft2; } } /** Calls function `f` on each component of type `t`. If `t` is not a compound type, this operation has no effect. The following types are considered compound: - TInst, TEnum, TType and TAbstract with type parameters - TFun - TAnonymous If `t` or `f` are null, the result is unspecified. **/ static public function iter(t:Type, f:Type -> Void):Void { switch (t) { case TMono(tm): var t = tm.get(); if (t != null) f(t); case TEnum(_, tl) | TInst(_, tl) | TType(_, tl) | TAbstract(_, tl): for (t in tl) f(t); case TDynamic(t2): if (t != t2) f(t2); case TLazy(ft): f(ft()); case TAnonymous(an): for (field in an.get().fields) f(field.type); case TFun(args, ret): for (arg in args) f(arg.t); f(ret); } } /** Converts type `t` to a human-readable String representation. **/ static public function toString( t : Type ) : String { #if neko return Context.load("s_type", 1)(t); #else return null; #end } #end /** Resolves the field named `name` on class `c`. If `isStatic` is true, the classes' static fields are checked. Otherwise the classes' member fields are checked. If the field is found, it is returned. Otherwise if `c` has a super class, `findField` recursively checks that super class. Otherwise null is returned. If any argument is null, the result is unspecified. **/ static public function findField(c:ClassType, name:String, isStatic:Bool = false):Null { var field = (isStatic ? c.statics : c.fields).get().find(function(field) return field.name == name); return if(field != null) field; else if (c.superClass != null) findField(c.superClass.t.get(), name, isStatic); else null; } } haxe_3.4.4.orig/std/haxe/macro/TypedExprTools.hx0000664000175000017500000001622713166552354021552 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.macro; import haxe.macro.Type; /** This class provides some utility methods to work with typed expressions. It is best used through 'using haxe.macro.TypedExprTools' syntax and then provides additional methods on `haxe.macro.TypedExpr` instances. **/ class TypedExprTools { static function with(e:TypedExpr, ?edef:TypedExprDef, ?t:Type) { return { expr: edef == null ? e.expr : edef, pos: e.pos, t: t == null ? e.t : t } } /** Transforms the sub-expressions of `e` by calling `f` on each of them. See `haxe.macro.ExprTools.map` for details on expression mapping in general. This function works the same way, but with a different data structure. **/ static public function map(e:TypedExpr, f:TypedExpr -> TypedExpr):TypedExpr { return switch(e.expr) { case TConst(_) | TLocal(_) | TBreak | TContinue | TTypeExpr(_): e; case TArray(e1, e2): with(e, TArray(f(e1), f(e2))); case TBinop(op, e1, e2): with(e, TBinop(op, f(e1), f(e2))); case TFor(v, e1, e2): with(e, TFor(v, f(e1), f(e2))); case TWhile(e1, e2, flag): with(e, TWhile(f(e1), f(e2), flag)); case TThrow(e1): with(e, TThrow(f(e1))); case TEnumParameter(e1, ef, i): with(e, TEnumParameter(f(e1), ef, i)); case TField(e1, fa): with(e, TField(f(e1), fa)); case TParenthesis(e1): with(e, TParenthesis(f(e1))); case TUnop(op, pre, e1): with(e, TUnop(op, pre, f(e1))); case TArrayDecl(el): with(e, TArrayDecl(el.map(f))); case TNew(t, pl, el): with(e, TNew(t, pl, el.map(f))); case TBlock(el): with(e, TBlock(el.map(f))); case TObjectDecl(fl): with(e, TObjectDecl(fl.map(function(field) return { name: field.name, expr: f(field.expr) }))); case TCall(e1, el): with(e, TCall(f(e1), el.map(f))); case TVar(v,eo): with(e, TVar(v, eo == null ? null : f(eo))); case TFunction(fu): with(e, TFunction({ t: fu.t, args: fu.args, expr: f(fu.expr)})); case TIf(e1, e2, e3): with(e, TIf(f(e1), f(e2), e3 == null ? null : f(e3))); case TSwitch(e1, cases, e2): with(e, TSwitch(f(e1), cases.map(function(c) return { values: c.values.map(f), expr: f(c.expr) }), e2 == null ? null : f(e2))); case TTry(e1, catches): with(e, TTry(f(e1), catches.map(function(c) return { v:c.v, expr: f(c.expr) }))); case TReturn(e1): with(e, TReturn(e1 == null ? null : f(e1))); case TCast(e1, mt): with(e, TCast(f(e1), mt)); case TMeta(m, e1): with(e, TMeta(m, f(e1))); } } /** Calls function `f` on each sub-expression of `e`. See `haxe.macro.ExprTools.iter` for details on iterating expressions in general. This function works the same way, but with a different data structure. **/ static public function iter(e:TypedExpr, f:TypedExpr -> Void):Void { switch(e.expr) { case TConst(_) | TLocal(_) | TBreak | TContinue | TTypeExpr(_): case TArray(e1, e2) | TBinop(_, e1, e2) | TFor(_, e1, e2) | TWhile(e1, e2, _): f(e1); f(e2); case TThrow(e1) | TEnumParameter(e1, _, _) | TField(e1, _) | TParenthesis(e1) | TUnop(_, _, e1) | TCast(e1, _) | TMeta(_, e1): f(e1); case TArrayDecl(el) | TNew(_, _, el) | TBlock(el): for (e in el) f(e); case TObjectDecl(fl): for (field in fl) f(field.expr); case TCall(e1, el): f(e1); for (e in el) f(e); case TVar(_, e1) | TReturn(e1): if (e1 != null) f(e1); case TFunction(fu): f(fu.expr); case TIf(e1, e2, e3): f(e1); f(e2); if (e3 != null) f(e3); case TSwitch(e1, cases, e2): f(e1); for (c in cases) { for (v in c.values) f(v); f(c.expr); } if (e2 != null) f(e2); case TTry(e1, catches): f(e1); for (c in catches) f(c.expr); } } /** Transforms the sub-expressions of `e` by calling `f` on each of them. Additionally, types are mapped using `ft` and variables are mapped using `fv`. See `haxe.macro.ExprTools.map` for details on expression mapping in general. This function works the same way, but with a different data structure. **/ static public function mapWithType(e:TypedExpr, f:TypedExpr -> TypedExpr, ft:Type -> Type, fv:TVar -> TVar):TypedExpr { return switch(e.expr) { case TConst(_) | TBreak | TContinue | TTypeExpr(_): with(e, ft(e.t)); case TLocal(v): with(e, TLocal(fv(v)), ft(e.t)); case TArray(e1, e2): with(e, TArray(f(e1), f(e2)), ft(e.t)); case TBinop(op, e1, e2): with(e, TBinop(op, f(e1), f(e2)), ft(e.t)); case TFor(v, e1, e2): with(e, TFor(fv(v), f(e1), f(e2)), ft(e.t)); case TWhile(e1, e2, flag): with(e, TWhile(f(e1), f(e2), flag), ft(e.t)); case TThrow(e1): with(e, TThrow(f(e1)), ft(e.t)); case TEnumParameter(e1, ef, i): with(e, TEnumParameter(f(e1), ef, i), ft(e.t)); case TField(e1, fa): with(e, TField(f(e1), fa), ft(e.t)); case TParenthesis(e1): with(e, TParenthesis(e1), ft(e.t)); case TUnop(op, pre, e1): with(e, TUnop(op, pre, f(e1)), ft(e.t)); case TArrayDecl(el): with(e, TArrayDecl(el.map(f)), ft(e.t)); case TNew(t, pl, el): with(e, TNew(t, pl, el.map(f)), ft(e.t)); case TBlock(el): with(e, TBlock(el.map(f)), ft(e.t)); case TObjectDecl(fl): with(e, TObjectDecl(fl.map(function(field) return { name: field.name, expr: f(field.expr) })), ft(e.t)); case TCall(e1, el): with(e, TCall(f(e1), el.map(f)), ft(e.t)); case TVar(v,eo): with(e, TVar(fv(v), eo == null ? null : f(eo)), ft(e.t)); case TFunction(fu): with(e, TFunction({ t: ft(fu.t), args: fu.args.map(function(arg) return { v: fv(arg.v), value: arg.value }), expr: f(fu.expr)}), ft(e.t)); case TIf(e1, e2, e3): with(e, TIf(f(e1), f(e2), e3 == null ? null : f(e3)), ft(e.t)); case TSwitch(e1, cases, e2): with(e, TSwitch(f(e1), cases.map(function(c) return { values: c.values.map(f), expr: f(c.expr) }), e2 == null ? null : f(e2)), ft(e.t)); case TTry(e1, catches): with(e, TTry(f(e1), catches.map(function(c) return { v:fv(c.v), expr: f(c.expr) })), ft(e.t)); case TReturn(e1): with(e, TReturn(e1 == null ? null : f(e1)), ft(e.t)); case TCast(e1, mt): with(e, TCast(f(e1), mt), ft(e.t)); case TMeta(m, e1): with(e, TMeta(m, f(e1)), ft(e.t)); } } #if macro static public function toString(t:TypedExpr, ?pretty = false):String { return @:privateAccess haxe.macro.Context.sExpr(t, pretty); } #end } haxe_3.4.4.orig/std/haxe/remoting/AMFConnection.hx0000664000175000017500000000542513166552354021751 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; /** Allows a connection to an AMF Remoting server such as Flash Media Server or AMFPHP. */ class AMFConnection implements AsyncConnection implements Dynamic { var __data : { error : Dynamic -> Void, #if flash cnx : flash.net.NetConnection, #else cnx : Dynamic, #end }; var __path : Array; function new( data, path ) { __data = data; __path = path; } public function resolve( name ) : AsyncConnection { var s = new AMFConnection(__data,__path.copy()); s.__path.push(name); return s; } public function setErrorHandler(h) { __data.error = h; } public function close() { __data.cnx.close(); } public function call( params : Array, ?onResult : Dynamic -> Void ) : Void { if( onResult == null ) onResult = function(e) {}; var p = params.copy(); #if flash p.unshift(new flash.net.Responder(onResult,__data.error)); #else p.unshift({ onStatus : __data.error, onResult : onResult }); #end p.unshift(__path.join(".")); untyped __data.cnx.call.apply(__data,p); } #if flash public static function urlConnect( gatewayUrl : String ) { var c = new flash.net.NetConnection(); var cnx = new AMFConnection({ cnx : c, error : function(e) throw e },[]); c.addEventListener(flash.events.NetStatusEvent.NET_STATUS,function(e:flash.events.NetStatusEvent) { cnx.__data.error(e); }); c.connect(gatewayUrl); return cnx; } public static function connect( nc ) { return new AMFConnection({ cnx : nc, error : function(e) throw e },[]); } public static function registerClassAlias( s : String, cl : Class ) { untyped __global__[ "flash.net.registerClassAlias" ]( s, cl ); } #end } haxe_3.4.4.orig/std/haxe/remoting/AsyncAdapter.hx0000664000175000017500000000362613166552354021705 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; /** Build an AsyncConnection from a synchronized Connection. **/ class AsyncAdapter implements AsyncConnection { var __cnx : Connection; var __error : { ref : Dynamic -> Void }; function new(cnx,error) { __cnx = cnx; __error = error; } public function resolve( name ) : AsyncConnection { return new AsyncAdapter(__cnx.resolve(name),__error); } public function setErrorHandler(h) { __error.ref = h; } public function call( params : Array, ?onResult : Dynamic -> Void ) { var ret; try { ret = __cnx.call(params); } catch( e : Dynamic ) { __error.ref(e); return; } if( onResult != null ) onResult(ret); } public static function create( cnx : Connection ) : AsyncConnection { return new AsyncAdapter(cnx,{ ref : function(e) throw e }); } } haxe_3.4.4.orig/std/haxe/remoting/AsyncConnection.hx0000664000175000017500000000277113166552354022424 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; /** For asynchronous connections, where the results are events that will be resolved later in the execution process. */ interface AsyncConnection implements Dynamic { function resolve( name : String ) : AsyncConnection; function call( params : Array, ?result : Dynamic -> Void ) : Void; function setErrorHandler( error : Dynamic -> Void ) : Void; } haxe_3.4.4.orig/std/haxe/remoting/AsyncDebugConnection.hx0000664000175000017500000000547013166552354023372 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; class AsyncDebugConnection implements AsyncConnection implements Dynamic { var __path : Array; var __cnx : AsyncConnection; var __data : { error : Dynamic -> Void, oncall : Array -> Array -> Void, onerror : Array -> Array -> Dynamic -> Void, onresult : Array -> Array -> Dynamic -> Void, }; function new(path,cnx,data) { __path = path; __cnx = cnx; __data = data; } public function resolve( name ) : AsyncConnection { var cnx = new AsyncDebugConnection(__path.copy(),__cnx.resolve(name),__data); cnx.__path.push(name); return cnx; } public function setErrorHandler(h) { __data.error = h; } public function setErrorDebug(h) { __data.onerror = h; } public function setResultDebug(h) { __data.onresult = h; } public function setCallDebug(h) { __data.oncall = h; } public function call( params : Array, ?onResult : Dynamic -> Void ) { var me = this; __data.oncall(__path,params); __cnx.setErrorHandler(function(e) { me.__data.onerror(me.__path,params,e); me.__data.error(e); }); __cnx.call(params,function(r) { me.__data.onresult(me.__path,params,r); if( onResult != null ) onResult(r); }); } public static function create( cnx : AsyncConnection ) { var cnx = new AsyncDebugConnection([],cnx,{ error : function(e) throw e, oncall : function(path,params) {}, onerror : null, onresult : null, }); cnx.setErrorDebug(function(path,params,e) trace(path.join(".")+"("+params.join(",")+") = ERROR "+Std.string(e))); cnx.setResultDebug(function(path,params,e) trace(path.join(".")+"("+params.join(",")+") = "+Std.string(e))); return cnx; } } haxe_3.4.4.orig/std/haxe/remoting/AsyncProxy.hx0000664000175000017500000000261713166552354021445 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; /** This class is magic. When you extend it with a class C, it will automaticaly create a stub class with all public methods forwarding remoting messages over the connection. **/ class AsyncProxy { var __cnx : AsyncConnection; function new( c ) { __cnx = c; } }haxe_3.4.4.orig/std/haxe/remoting/Connection.hx0000664000175000017500000000243413166552354021422 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; interface Connection implements Dynamic { function resolve( name : String ) : Connection; function call( params : Array ) : Dynamic; } haxe_3.4.4.orig/std/haxe/remoting/Context.hx0000664000175000017500000000434413166552354020751 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; /** Allows communication between platforms. This is a shared API that can be called on the connection at the client code. */ class Context { var objects : haxe.ds.StringMap<{ obj : Dynamic, rec : Bool }>; public function new() { objects = new haxe.ds.StringMap(); } public function addObject( name : String, obj : {}, ?recursive ) { objects.set(name,{ obj : obj, rec : recursive }); } public function call( path : Array, params : Array ) : Dynamic { if( path.length < 2 ) throw "Invalid path '"+path.join(".")+"'"; var inf = objects.get(path[0]); if( inf == null ) throw "No such object "+path[0]; var o = inf.obj; var m = Reflect.field(o,path[1]); if( path.length > 2 ) { if( !inf.rec ) throw "Can't access "+path.join("."); for( i in 2...path.length ) { o = m; m = Reflect.field(o,path[i]); } } if( !Reflect.isFunction(m) ) throw "No such method "+path.join("."); return Reflect.callMethod(o,m,params); } public static function share( name : String, obj : {} ) : Context { var ctx = new Context(); ctx.addObject(name,obj); return ctx; } } haxe_3.4.4.orig/std/haxe/remoting/ContextAll.hx0000664000175000017500000000376213166552354021405 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; class ContextAll extends Context { public override function call( path : Array, params : Array ) : Dynamic { #if neko var o : Dynamic = null; var m : Dynamic = neko.Lib.getClasses(); for( p in path ) { o = m; m = Reflect.field(o,p); } #elseif js var path2 = path.copy(); var f = path2.pop(); var o; try { o = js.Lib.eval(path2.join(".")); } catch( e : Dynamic ) { o = null; } var m = Reflect.field(o,f); #elseif flash var path2 = path.copy(); var f = path2.pop(); var o = flash.Lib.eval(path2.join(".")); var m = Reflect.field(o,f); #elseif php var path2 = path.copy(); var f = path2.pop(); var o = Type.resolveClass(path2.join(".")); var m = Reflect.field(o,f); #else var o = null; var m = null; #end if( m == null ) return super.call(path,params); return Reflect.callMethod(o,m,params); } }haxe_3.4.4.orig/std/haxe/remoting/DelayedConnection.hx0000664000175000017500000000504413166552354022712 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; class DelayedConnection implements AsyncConnection implements Dynamic { public var connection(get,set) : AsyncConnection; var __path : Array; var __data : { cnx : AsyncConnection, error : Dynamic -> Void, cache : Array<{ path : Array, params : Array, onResult : Dynamic -> Void, onError : Dynamic -> Void }>, }; function new(data,path) { __data = data; __path = path; } public function setErrorHandler(h) { __data.error = h; } public function resolve( name ) : AsyncConnection { var d = new DelayedConnection(__data,__path.copy()); d.__path.push(name); return d; } function get_connection() { return __data.cnx; } function set_connection(cnx) { __data.cnx = cnx; process(this); return cnx; } public function call( params : Array, ?onResult ) { __data.cache.push({ path : __path, params : params, onResult : onResult, onError : __data.error }); process(this); } static function process( d : DelayedConnection ) { var cnx = d.__data.cnx; if( cnx == null ) return; while( true ) { var m = d.__data.cache.shift(); if( m == null ) break; var c = cnx; for( p in m.path ) c = c.resolve(p); c.setErrorHandler(m.onError); c.call(m.params,m.onResult); } } public static function create() { return new DelayedConnection({ cnx : null, error : function(e) throw e, cache : new Array() },[]); } } haxe_3.4.4.orig/std/haxe/remoting/ExternalConnection.hx0000664000175000017500000001116713166552354023130 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; /** Synchronous communications between Flash and Javascript. **/ @:expose class ExternalConnection implements Connection implements Dynamic { var __data : { name : String, ctx : Context, #if js flash : String #end }; var __path : Array; function new( data, path ) { __data = data; __path = path; } public function resolve(field) : Connection { var e = new ExternalConnection(__data,__path.copy()); e.__path.push(field); return e; } public function close() { connections.remove(__data.name); } #if flash static function escapeString( s : String ) { return s.split("\\").join("\\\\"); } #else static inline function escapeString(s) { return s; } #end public function call( params : Array ) : Dynamic { var s = new haxe.Serializer(); s.serialize(params); var params = escapeString(s.toString()); var data = null; #if flash #if js_unflatten data = flash.external.ExternalInterface.call("haxe.remoting.ExternalConnection.doCall",__data.name,__path.join("."),params); #else data = flash.external.ExternalInterface.call("haxe_remoting_ExternalConnection.doCall",__data.name,__path.join("."),params); #end #elseif js var fobj : Dynamic = (untyped js.Browser.document)[cast __data.flash]; // FIXME(bruno): Why is this necessary? if( fobj == null ) fobj = js.Browser.document.getElementById(__data.flash); if( fobj == null ) throw "Could not find flash object '"+__data.flash+"'"; try data = fobj.externalRemotingCall(__data.name,__path.join("."),params) catch( e : Dynamic ) {}; #end if( data == null ) { #if js var domain, pageDomain; try { // check that swf in on the same domain domain = fobj.src.split("/")[2]; pageDomain = js.Browser.location.host; } catch( e : Dynamic ) { domain = null; pageDomain = null; } if( domain != pageDomain ) throw "ExternalConnection call failure : SWF need allowDomain('"+pageDomain+"')"; #end throw "Call failure : ExternalConnection is not " + #if flash "compiled in JS" #else "initialized in Flash" #end; } return new haxe.Unserializer(data).unserialize(); } static var connections = new haxe.ds.StringMap(); @:keep static function doCall( name : String, path : String, params : String ) : String { try { var cnx = connections.get(name); if( cnx == null ) throw "Unknown connection : "+name; if( cnx.__data.ctx == null ) throw "No context shared for the connection "+name; var params = new haxe.Unserializer(params).unserialize(); var ret = cnx.__data.ctx.call(path.split("."),params); var s = new haxe.Serializer(); s.serialize(ret); #if flash return escapeString(s.toString()); #else return s.toString()+"#"; #end } catch( e : Dynamic ) { var s = new haxe.Serializer(); s.serializeException(e); return s.toString(); } #if as3 return ""; #end } #if flash public static function jsConnect( name : String, ?ctx : Context ) { if( !flash.external.ExternalInterface.available ) throw "External Interface not available"; try flash.external.ExternalInterface.addCallback("externalRemotingCall",doCall) catch( e : Dynamic ) {}; var cnx = new ExternalConnection({ name : name, ctx : ctx },[]); connections.set(name,cnx); return cnx; } #elseif js public static function flashConnect( name : String, flashObjectID : String, ?ctx : Context ) { var cnx = new ExternalConnection({ ctx : ctx, name : name, flash : flashObjectID },[]); connections.set(name,cnx); return cnx; } #end } haxe_3.4.4.orig/std/haxe/remoting/FlashJsConnection.hx0000664000175000017500000001130713166552354022674 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; class FlashJsConnection #if flash implements AsyncConnection implements Dynamic #end { #if flash var __path : Array; var __data : { id : String, name : String, ctx : Context, error : Dynamic -> Void, timer : haxe.Timer, queue : Array Void>, }; function new( data, path ) { __data = data; __path = path; } public function close() { connections.remove(__data.name); } public function resolve( name ) : AsyncConnection { var c = new FlashJsConnection(__data,__path.copy()); c.__path.push(name); return c; } public function setErrorHandler(h) { __data.error = h; } public function call( params : Array, ?onResult : Dynamic -> Void ) { var s = new haxe.Serializer(); s.serialize(params); var params = escapeString(s.toString()); var error = __data.error; __data.queue.push(function() { var data = flash.external.ExternalInterface.call("haxe.remoting.FlashJsConnection.flashCall",__data.id,__data.name,__path.join("."),params); var v : Dynamic; try { if( data == null ) throw "Call failure : FlashJsConnection is not compiled in JS"; v = new haxe.Unserializer(data).unserialize(); } catch( e : Dynamic ) { error(e); return; } if( onResult != null ) onResult(v); }); if( __data.timer == null ) { __data.timer = new haxe.Timer(1); __data.timer.run = function() { var q = __data.queue.shift(); if( q == null ) { __data.timer.stop(); __data.timer = null; return; } q(); }; } } static var connections = new haxe.ds.StringMap(); static function escapeString( s : String ) { #if flash return s.split("\\").join("\\\\"); #else return s.split("\\").join("\\\\").split("&").join("&"); #end } static function doCall( name : String, path : String, params : String ) : String { try { var cnx = connections.get(name); if( cnx == null ) throw "Unknown connection : "+name; if( cnx.__data.ctx == null ) throw "No context shared for the connection "+name; var params = new haxe.Unserializer(params).unserialize(); var ret = cnx.__data.ctx.call(path.split("."),params); var s = new haxe.Serializer(); s.serialize(ret); return escapeString(s.toString()); } catch( e : Dynamic ) { var s = new haxe.Serializer(); s.serializeException(e); return s.toString(); } #if as3 return ""; #end } public static function connect( name : String, objId : String, ?ctx : Context ) { if( !flash.external.ExternalInterface.available ) throw "External Interface not available"; try flash.external.ExternalInterface.addCallback("flashJsRemotingCall",doCall) catch( e : Dynamic ) {}; var cnx = new FlashJsConnection({ id : objId, name : name, ctx : ctx, error : function(e) throw e, queue : [], timer : null, },[]); connections.set(name,cnx); return cnx; } #elseif js static function flashCall( flashObj : String, name : String, path : String, params : String ) : String { try { var fobj : Dynamic = untyped (untyped js.Browser.document)[__data.flash]; // FIXME(bruno): Why is this necessary? if( fobj == null ) fobj = js.Browser.document.getElementById(flashObj); if( fobj == null ) throw "Could not find flash object '"+flashObj+"'"; var data = null; try data = fobj.flashJsRemotingCall(name,path,params) catch( e : Dynamic ) {}; if( data == null ) throw "Flash object "+flashObj+" does not have an active FlashJsConnection"; return data; } catch( e : Dynamic ) { var s = new haxe.Serializer(); s.serializeException(e); return s.toString(); } } #end } haxe_3.4.4.orig/std/haxe/remoting/HttpAsyncConnection.hx0000664000175000017500000000513113166552354023255 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; /** Allows an asynchronous connection to the given URL which should link to a Haxe server application. */ class HttpAsyncConnection implements AsyncConnection implements Dynamic { var __data : { url : String, error : Dynamic -> Void }; var __path : Array; function new(data,path) { __data = data; __path = path; } public function resolve( name ) : AsyncConnection { var c = new HttpAsyncConnection(__data,__path.copy()); c.__path.push(name); return c; } public function setErrorHandler(h) { __data.error = h; } public function call( params : Array, ?onResult : Dynamic -> Void ) { var h = new haxe.Http(__data.url); #if (neko && no_remoting_shutdown) h.noShutdown = true; #end var s = new haxe.Serializer(); s.serialize(__path); s.serialize(params); h.setHeader("X-Haxe-Remoting","1"); h.setParameter("__x",s.toString()); var error = __data.error; h.onData = function( response : String ) { var ok = true; var ret; try { if( response.substr(0,3) != "hxr" ) throw "Invalid response : '"+response+"'"; var s = new haxe.Unserializer(response.substr(3)); ret = s.unserialize(); } catch( err : Dynamic ) { ret = null; ok = false; error(err); } if( ok && onResult != null ) onResult(ret); }; h.onError = error; h.request(true); } public static function urlConnect( url : String ) { return new HttpAsyncConnection({ url : url, error : function(e) throw e },[]); } } haxe_3.4.4.orig/std/haxe/remoting/HttpConnection.hx0000664000175000017500000000653313166552354022266 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; /** Allows a synchronous connection to the given URL which should link to a Haxe server application. */ class HttpConnection implements Connection implements Dynamic { public static var TIMEOUT = 10.; var __url : String; var __path : Array; function new(url,path) { __url = url; __path = path; } public function resolve( name ) : Connection { var c = new HttpConnection(__url,__path.copy()); c.__path.push(name); return c; } public function call( params : Array ) : Dynamic { var data = null; var h = new haxe.Http(__url); #if (js && !nodejs) h.async = false; #end #if (neko && no_remoting_shutdown) h.noShutdown = true; #end #if (neko || php || cpp) h.cnxTimeout = TIMEOUT; #end var s = new haxe.Serializer(); s.serialize(__path); s.serialize(params); h.setHeader("X-Haxe-Remoting","1"); h.setParameter("__x",s.toString()); h.onData = function(d) { data = d; }; h.onError = function(e) { throw e; }; h.request(true); if( data.substr(0,3) != "hxr" ) throw "Invalid response : '"+data+"'"; data = data.substr(3); return new haxe.Unserializer(data).unserialize(); } #if !flash public static function urlConnect( url : String ) { return new HttpConnection(url,[]); } #end #if neko public static function handleRequest( ctx : Context ) { var v = neko.Web.getParams().get("__x"); if( neko.Web.getClientHeader("X-Haxe-Remoting") == null || v == null ) return false; neko.Lib.print(processRequest(v,ctx)); return true; } #elseif php public static function handleRequest( ctx : Context ) { var v = php.Web.getParams().get("__x"); if( php.Web.getClientHeader("X-Haxe-Remoting") == null || v == null ) return false; php.Lib.print(processRequest(v,ctx)); return true; } #end public static function processRequest( requestData : String, ctx : Context ) : String { try { var u = new haxe.Unserializer(requestData); var path = u.unserialize(); var args = u.unserialize(); var data = ctx.call(path,args); var s = new haxe.Serializer(); s.serialize(data); return "hxr" + s.toString(); } catch( e : Dynamic ) { var s = new haxe.Serializer(); s.serializeException(e); return "hxr" + s.toString(); } } } haxe_3.4.4.orig/std/haxe/remoting/LocalConnection.hx0000664000175000017500000001024313166552354022372 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; /** Allows communications to a different application that runs on the same client device */ class LocalConnection implements AsyncConnection implements Dynamic { static var ID = 0; var __path : Array; var __data : { ctx : Context, results : haxe.ds.IntMap<{ error : Dynamic -> Void, result : Dynamic -> Void }>, error : Dynamic -> Void, target : String, #if flash cnx : flash.net.LocalConnection, #else cnx : Dynamic, #end }; function new(data,path) { this.__path = path; this.__data = data; } public function resolve( name ) : AsyncConnection { var s = new LocalConnection(__data,__path.copy()); s.__path.push(name); return s; } public function setErrorHandler(h) { __data.error = h; } public function call( params : Array, ?onResult : Dynamic -> Void ) : Void { try { var id = ID++; #if flash __data.cnx.send(__data.target,"remotingCall",id,__path.join("."),haxe.Serializer.run(params)); #else if( !__data.cnx.send(__data.target,"remotingCall",id,__path.join("."),haxe.Serializer.run(params)) ) throw "Remoting call failure"; #end __data.results.set(id,{ error : __data.error, result : onResult }); } catch( e : Dynamic ) { __data.error(e); } } public function close() { __data.cnx.close(); } static function remotingCall( c : LocalConnection, id : Int, path : String, args : String ) { var r; try { if( c.__data.ctx == null ) throw "No context shared for this connection"; var ret = c.__data.ctx.call(path.split("."),haxe.Unserializer.run(args)); r = haxe.Serializer.run(ret); } catch( e : Dynamic ) { var s = new haxe.Serializer(); s.serializeException(e); r = s.toString(); } // don't forward 'send' errors on connection since it's only the receiving side c.__data.cnx.send(c.__data.target,"remotingResult",id,r); } static function remotingResult( c : LocalConnection, id : Int, result : String ) { var f = c.__data.results.get(id); if( f == null ) c.__data.error("Invalid result ID "+id); c.__data.results.remove(id); var val : Dynamic; try { val = new haxe.Unserializer(result).unserialize(); } catch( e : Dynamic ) { f.error(e); return; } if( f.result != null ) f.result(val); } #if flash public static function connect( name : String, ?ctx : Context, ?allowDomains : Array ) { var l = new flash.net.LocalConnection(); var recv = name + "_recv"; var c = new LocalConnection({ ctx : ctx, error : function(e) throw e, results : new haxe.ds.IntMap(), cnx : l, target : recv, },[]); l.client = { remotingCall : remotingCall.bind(c), remotingResult : remotingResult.bind(c), }; l.addEventListener(flash.events.StatusEvent.STATUS, function(s:flash.events.StatusEvent) { if( s.level != "status" ) c.__data.error("Failed to send data on LocalConnection"); }); try l.connect(name) catch( e : Dynamic ) { l.connect(recv); c.__data.target = name; } if( allowDomains != null ) for( d in allowDomains ) l.allowDomain(d); return c; } #end } haxe_3.4.4.orig/std/haxe/remoting/Proxy.hx0000664000175000017500000000256213166552354020446 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; /** When you extend it with a class C, it will automatically create a stub class with all public methods forwarding remoting messages over the connection. **/ class Proxy { var __cnx : Connection; function new( c ) { __cnx = c; } } haxe_3.4.4.orig/std/haxe/remoting/SocketConnection.hx0000664000175000017500000001213513166552354022572 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; import haxe.remoting.SocketProtocol.Socket; /** Allows remoting communications over a socket connection */ class SocketConnection implements AsyncConnection implements Dynamic { var __path : Array; var __data : { protocol : SocketProtocol, results : List<{ onResult : Dynamic -> Void, onError : Dynamic -> Void }>, log : Array -> Array -> Dynamic -> Void, error : Dynamic -> Void, #if js queue : Array Void>, timer : haxe.Timer, #end }; function new(data,path) { __data = data; __path = path; } public function resolve(name) : AsyncConnection { var s = new SocketConnection(__data,__path.copy()); s.__path.push(name); return s; } public function call( params : Array, ?onResult : Dynamic -> Void ) { try { __data.protocol.sendRequest(__path,params); __data.results.add({ onResult : onResult, onError : __data.error }); } catch( e : Dynamic ) { __data.error(e); } } public function setErrorHandler(h) { __data.error = h; } public function setErrorLogger(h) { __data.log = h; } public function setProtocol( p : SocketProtocol ) { __data.protocol = p; } public function getProtocol() : SocketProtocol { return __data.protocol; } public function close() { try __data.protocol.socket.close() catch( e : Dynamic ) { }; } public function processMessage( data : String ) { var request; var proto = __data.protocol; data = proto.decodeData(data); try { request = proto.isRequest(data); } catch( e : Dynamic ) { var msg = Std.string(e) + " (in "+StringTools.urlEncode(data)+")"; __data.error(msg); // protocol error return; } // request if( request ) { try proto.processRequest(data,__data.log) catch( e : Dynamic ) __data.error(e); return; } // answer var f = __data.results.pop(); if( f == null ) { __data.error("No response excepted ("+data+")"); return; } var ret; try { ret = proto.processAnswer(data); } catch( e : Dynamic ) { f.onError(e); return; } if( f.onResult != null ) f.onResult(ret); } function defaultLog(path,args,e) { // exception inside the called method var astr, estr; try astr = args.join(",") catch( e : Dynamic ) astr = "???"; try estr = Std.string(e) catch( e : Dynamic ) estr = "???"; var header = "Error in call to "+path.join(".")+"("+astr+") : "; __data.error(header + estr); } public static function create( s : Socket, ?ctx : Context ) { var data = { protocol : new SocketProtocol(s,ctx), results : new List(), error : function(e) throw e, log : null, #if js queue : [], timer : null, #end }; var sc = new SocketConnection(data,[]); data.log = sc.defaultLog; #if flash s.addEventListener(flash.events.DataEvent.DATA, function(e : flash.events.DataEvent) { var data = e.data; var msgLen = sc.__data.protocol.messageLength(data.charCodeAt(0),data.charCodeAt(1)); if( msgLen == null || data.length != msgLen - 1 ) { sc.__data.error("Invalid message header"); return; } sc.processMessage(e.data.substr(2,e.data.length-2)); }); #elseif js // we can't deliver directly the message // since it might trigger a blocking action on JS side // and in that case this will trigger a Flash bug // where a new onData is called is a parallel thread // ...with the buffer of the previous onData (!) s.onData = function( data : String ) { sc.__data.queue.push(function() { var msgLen = sc.__data.protocol.messageLength(data.charCodeAt(0),data.charCodeAt(1)); if( msgLen == null || data.length != msgLen - 1 ) { sc.__data.error("Invalid message header"); return; } sc.processMessage(data.substr(2,data.length-2)); }); if( sc.__data.timer == null ) { sc.__data.timer = new haxe.Timer(1); sc.__data.timer.run = function() { var q = sc.__data.queue.shift(); if( q == null ) { sc.__data.timer.stop(); sc.__data.timer = null; return; } q(); }; } }; #end return sc; } } haxe_3.4.4.orig/std/haxe/remoting/SocketProtocol.hx0000664000175000017500000001237713166552354022304 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; typedef Socket = #if flash flash.net.XMLSocket #elseif js js.XMLSocket #elseif sys sys.net.Socket #else Dynamic #end /** The Haxe Remoting Socket Protocol is composed of serialized string exchanges. Each string is prefixed with a 2-chars header encoding the string size (up to 4KB) and postfixed with the `\0` message delimiting char. A request string is composed of the following serialized values : - the boolean true for a request - an array of strings representing the object+method path - an array of parameters A response string is composed of the following serialized values : - the boolean false for a response - a serialized value representing the result Exceptions are serialized with `serializeException` so they will be thrown immediately when they are unserialized. **/ class SocketProtocol { public var socket : Socket; public var context : Context; public function new( sock, ctx ) { this.socket = sock; this.context = ctx; } function decodeChar(c) : Null { // A...Z if( c >= 65 && c <= 90 ) return c - 65; // a...z if( c >= 97 && c <= 122 ) return c - 97 + 26; // 0...9 if( c >= 48 && c <= 57 ) return c - 48 + 52; // + if( c == 43 ) return 62; // / if( c == 47 ) return 63; return null; } function encodeChar(c) : Null { if( c < 0 ) return null; // A...Z if( c < 26 ) return c + 65; // a...z if( c < 52 ) return (c - 26) + 97; // 0...9 if( c < 62 ) return (c - 52) + 48; // + if( c == 62 ) return 43; // / if( c == 63 ) return 47; return null; } public function messageLength( c1 : Int, c2 : Int ) : Null { var e1 = decodeChar(c1); var e2 = decodeChar(c2); if( e1 == null || e2 == null ) return null; return (e1 << 6) | e2; } public function encodeMessageLength( len : Int ) { var c1 = encodeChar(len>>6); if( c1 == null ) throw "Message is too big"; var c2 = encodeChar(len&63); return { c1 : c1, c2 : c2 }; } public function sendRequest( path : Array, params : Array ) { var s = new haxe.Serializer(); s.serialize(true); s.serialize(path); s.serialize(params); sendMessage(s.toString()); } public function sendAnswer( answer : Dynamic, ?isException : Bool ) { var s = new haxe.Serializer(); s.serialize(false); if( isException ) s.serializeException(answer); else s.serialize(answer); sendMessage(s.toString()); } public function sendMessage( msg : String ) { var e = encodeMessageLength(msg.length + 3); #if sys var o = socket.output; o.writeByte(e.c1); o.writeByte(e.c2); o.writeString(msg); o.writeByte(0); #else socket.send(String.fromCharCode(e.c1)+String.fromCharCode(e.c2)+msg); #end } public dynamic function decodeData( data : String ) { return data; } public function isRequest( data : String ) { return switch( haxe.Unserializer.run(data) ) { case true: true; case false: false; default: throw "Invalid data"; } } public function processRequest( data : String, ?onError : Array -> Array -> Dynamic -> Void ) { var s = new haxe.Unserializer(data); var result : Dynamic; var isException = false; if( s.unserialize() != true ) throw "Not a request"; var path : Array = s.unserialize(); var args : Array = s.unserialize(); try { if( context == null ) throw "No context is shared"; result = context.call(path,args); } catch( e : Dynamic ) { result = e; isException = true; } // send back result/exception over network sendAnswer(result,isException); // send the error event if( isException && onError != null ) onError(path,args,result); } public function processAnswer( data : String ) : Dynamic { var s = new haxe.Unserializer(data); if( s.unserialize() != false ) throw "Not an answer"; return s.unserialize(); } #if sys public function readMessage() { var i = socket.input; var c1 = i.readByte(); var c2 = i.readByte(); var len = messageLength(c1,c2); if( len == null ) throw "Invalid header"; var data = i.readString(len - 3); if( i.readByte() != 0 ) throw "Invalid message"; return decodeData(data); } #end } haxe_3.4.4.orig/std/haxe/remoting/SocketWrapper.hx0000664000175000017500000000466513166552354022124 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; import haxe.remoting.SocketProtocol.Socket; /** @see `js.XMLSocket` **/ class SocketWrapper { static var ID = 0; static function create( prefix : String ) : String { var id = prefix + "WrappedSocket"+(ID++); var s = new Socket(); var ctx = new Context(); var cnx = haxe.remoting.ExternalConnection.jsConnect(id,ctx); ctx.addObject("sock",s); var o = {}; Reflect.setField(o,"close",cnx.close); ctx.addObject("api",o); #if flash var connected = false; s.addEventListener(flash.events.Event.CONNECT,function(_) { connected = true; cnx.api.onConnect.call([true]); }); s.addEventListener(flash.events.SecurityErrorEvent.SECURITY_ERROR,function(_) { if( connected ) cnx.api.onClose.call([]); else cnx.api.onConnect.call([false]); }); s.addEventListener(flash.events.Event.CLOSE,function(_) { cnx.api.onClose.call([]); }); s.addEventListener(flash.events.DataEvent.DATA,function(e:flash.events.DataEvent) { cnx.api.onData.call([e.data]); }); #end return id; } static function init() { if( !flash.external.ExternalInterface.available ) return null; var ctx = new Context(); var o = {}; Reflect.setField(o,"create",create); ctx.addObject("api",o); haxe.remoting.ExternalConnection.jsConnect("SocketWrapper", ctx); return null; } static var _ = init(); } haxe_3.4.4.orig/std/haxe/remoting/SyncSocketConnection.hx0000664000175000017500000000502713166552354023431 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.remoting; import haxe.remoting.SocketProtocol.Socket; class SyncSocketConnection implements Connection implements Dynamic { var __path : Array; var __proto : SocketProtocol; function new(proto,path) { __proto = proto; __path = path; } public function resolve( name ) : Connection { var s = new SyncSocketConnection(__proto,__path.copy()); s.__path.push(name); return s; } public function call( params : Array ) : Dynamic { var proto = __proto; proto.sendRequest(__path,params); while( true ) { var data = proto.readMessage(); if( proto.isRequest(data) ) { if( proto.context == null ) throw "Request received"; proto.processRequest(data,onRequestError); continue; } return proto.processAnswer(data); } } public function processRequest() { if( __proto.context == null ) throw "Can't process request"; var data = __proto.readMessage(); __proto.processRequest(data,onRequestError); } public function onRequestError( path : Array, args : Array, exc : Dynamic ) { } public function setProtocol( p : SocketProtocol ) { __proto = p; } public function getProtocol() : SocketProtocol { return __proto; } public function close() { try __proto.socket.close() catch( e : Dynamic ) { }; } public static function create( s : Socket, ?ctx : Context ) { return new SyncSocketConnection(new SocketProtocol(s,ctx),[]); } } haxe_3.4.4.orig/std/haxe/rtti/CType.hx0000664000175000017500000003253213166552354017507 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.rtti; /** The (dot-)path of the runtime type. **/ typedef Path = String /** A list of strings representing the targets where the type is available. **/ typedef Platforms = List /** The function argument runtime type information. **/ typedef FunctionArgument = { name : String, opt : Bool, t : CType, ?value:String } /** The runtime member types. **/ enum CType { CUnknown; CEnum( name : Path, params : List ); CClass( name : Path, params : List ); CTypedef( name : Path, params : List ); CFunction( args : List, ret : CType ); CAnonymous( fields : List ); CDynamic( ?t : CType ); CAbstract( name : Path, params : List ); } /** The type parameters in the runtime type information. **/ typedef PathParams = { /** The path of the type. **/ var path : Path; /** The list of parameters types. **/ var params : List; } /** An array of strings representing the names of the type parameters the type has. As of Haxe 3.2.0, this does not include the constraints. **/ typedef TypeParams = Array // no constraints /** Represents the runtime rights of a type. **/ enum Rights { RNormal; RNo; RCall( m : String ); RMethod; RDynamic; RInline; } /** The list of runtime metadata. **/ typedef MetaData = Array<{ name : String, params : Array }>; /** The runtime class field information. @see **/ typedef ClassField = { /** The name of the field. **/ var name : String; /** The type of the field. **/ var type : CType; /** Whether or not the field is public. **/ var isPublic : Bool; /** Whether or not the field overrides another field. **/ var isOverride : Bool; /** The documentation of the field. This information is only available if the compiler flag `-D use_rtti_doc` was in place. Otherwise, or if the field has no documentation, the value is `null`. **/ var doc : Null; /** The [read access](https://haxe.org/manual/dictionary.html#define-read-access) behavior of the field. **/ var get : Rights; /** The [write access](https://haxe.org/manual/dictionary.html#define-write-access) behavior of the field. **/ var set : Rights; /** An array of strings representing the names of the type parameters the field has. **/ var params : TypeParams; /** A list of strings representing the targets where the field is available. **/ var platforms : Platforms; /** The meta data the field was annotated with. **/ var meta : MetaData; /** The line number where the field is defined. This information is only available if the field has an expression. Otherwise the value is `null`. **/ var line : Null; /** The list of available overloads for the fields or `null` if no overloads exists. **/ var overloads : Null>; /** The actual expression of the field or `null` if there is no expression. **/ var expr : Null; } /** The general runtime type information. **/ typedef TypeInfos = { /** The type path of the type. **/ var path : Path; /** The type path of the module containing the type. **/ var module : Path; /** The full slash path of the .hx file containing the type. This might be `null` in case there is no such file, e.g. if the type is defined through a macro. **/ var file : Null; /** An array of strings representing the names of the type parameters the type has. **/ var params : TypeParams; /** The documentation of the type. This information is only available if the compiler flag `-D use_rtti_doc` was in place. Otherwise, or if the constructor has no documentation, the value is `null`. **/ var doc : Null; /** Whether or not the type is [private](https://haxe.org/manual/dictionary.html#define-private-type). **/ var isPrivate : Bool; /** A list of strings representing the targets where the type is available. **/ var platforms : Platforms; /** The [metadata](https://haxe.org/manual/lf-metadata.html) the type was annotated with. **/ var meta : MetaData; } /** The runtime class definition information. **/ typedef Classdef = {> TypeInfos, /** Whether or not the class is [extern](https://haxe.org/manual/lf-externs.html). **/ var isExtern : Bool; /** Whether or not the class is actually an [interface](https://haxe.org/manual/types-interfaces.html). **/ var isInterface : Bool; /** The class' parent class defined by its type path and list of type parameters. **/ var superClass : Null; /** The list of interfaces defined by their type path and list of type parameters. **/ var interfaces : List; /** The list of member [class fields](https://haxe.org/manual/class-field.html). **/ var fields : List; /** The list of static class fields. **/ var statics : List; /** The type which is dynamically implemented by the class or `null` if no such type exists. **/ var tdynamic : Null; } /** The runtime enum constructor information. @see **/ typedef EnumField = { /** The name of the constructor. **/ var name : String; /** The list of arguments the constructor has or `null` if no arguments are available. **/ var args : Null>; /** The documentation of the constructor. This information is only available if the compiler flag `-D use_rtti_doc` was in place. Otherwise, or if the constructor has no documentation, the value is `null`. **/ var doc : String; /** A list of strings representing the targets where the constructor is available. **/ var platforms : Platforms; /** The meta data the constructor was annotated with. **/ var meta : MetaData; } /** The enum runtime type information. @see **/ typedef Enumdef = {> TypeInfos, /** Whether or not the enum is [extern](https://haxe.org/manual/lf-externs.html). **/ var isExtern : Bool; /** The list of enum constructors. **/ var constructors : List; } /** The typedef runtime information. **/ typedef Typedef = {> TypeInfos, /** The type of the typedef. **/ var type : CType; /** The types of the typedef, by platform. **/ var types : Map; // by platform } /** The abstract type runtime information. @see **/ typedef Abstractdef = {> TypeInfos, var to : Array<{t:CType, field:Null}>; var from : Array<{t:CType, field:Null}>; var impl : Classdef; var athis : CType; } /** The tree types of the runtime type. **/ enum TypeTree { TPackage( name : String, full : String, subs : Array ); TClassdecl( c : Classdef ); TEnumdecl( e : Enumdef ); TTypedecl( t : Typedef ); TAbstractdecl( a : Abstractdef ); } /** List of `TypeTree`. **/ typedef TypeRoot = Array /** Contains type and equality checks functionalities for RTTI. **/ class TypeApi { public static function typeInfos( t : TypeTree ) : TypeInfos { var inf : TypeInfos; switch( t ) { case TClassdecl(c): inf = c; case TEnumdecl(e): inf = e; case TTypedecl(t): inf = t; case TAbstractdecl(a): inf = a; case TPackage(_,_,_): throw "Unexpected Package"; } return inf; } /** Returns `true` if the given `CType` is a variable or `false` if it is a function. **/ public static function isVar( t : CType ) { return switch( t ) { case CFunction(_,_): false; default: true; } } static function leq( f : T -> T -> Bool, l1 : List, l2 : List ) { var it = l2.iterator(); for( e1 in l1 ) { if( !it.hasNext() ) return false; var e2 = it.next(); if( !f(e1,e2) ) return false; } if( it.hasNext() ) return false; return true; } /** Unlike `r1 == r2`, this function performs a deep equality check on the given `Rights` instances. If `r1` or `r2` are `null`, the result is unspecified. **/ public static function rightsEq( r1 : Rights, r2 : Rights ) { if( r1 == r2 ) return true; switch( r1 ) { case RCall(m1): switch( r2 ) { case RCall(m2): return m1 == m2; default: } default: } return false; } /** Unlike `t1 == t2`, this function performs a deep equality check on the given `CType` instances. If `t1` or `t2` are `null`, the result is unspecified. **/ public static function typeEq( t1 : CType, t2 : CType ) { switch( t1 ) { case CUnknown: return t2 == CUnknown; case CEnum(name,params): switch( t2 ) { case CEnum(name2,params2): return name == name2 && leq(typeEq,params,params2); default: } case CClass(name,params): switch( t2 ) { case CClass(name2,params2): return name == name2 && leq(typeEq,params,params2); default: } case CAbstract(name,params): switch( t2 ) { case CAbstract(name2,params2): return name == name2 && leq(typeEq,params,params2); default: } case CTypedef(name,params): switch( t2 ) { case CTypedef(name2,params2): return name == name2 && leq(typeEq,params,params2); default: } case CFunction(args,ret): switch( t2 ) { case CFunction(args2,ret2): return leq(function(a:FunctionArgument,b:FunctionArgument) { return a.name == b.name && a.opt == b.opt && typeEq(a.t,b.t); },args,args2) && typeEq(ret,ret2); default: } case CAnonymous(fields): switch( t2 ) { case CAnonymous(fields2): return leq(function(a,b) return fieldEq(a,b),fields,fields2); default: } case CDynamic(t): switch( t2 ) { case CDynamic(t2): if( (t == null) != (t2 == null) ) return false; return t == null || typeEq(t,t2); default: } } return false; } /** Unlike `f1 == f2`, this function performs a deep equality check on the given `ClassField` instances. If `f1` or `f2` are `null`, the result is unspecified. **/ public static function fieldEq( f1 : ClassField, f2 : ClassField ) { if( f1.name != f2.name ) return false; if( !typeEq(f1.type,f2.type) ) return false; if( f1.isPublic != f2.isPublic ) return false; if( f1.doc != f2.doc ) return false; if( !rightsEq(f1.get,f2.get) ) return false; if( !rightsEq(f1.set,f2.set) ) return false; if( (f1.params == null) != (f2.params == null) ) return false; if( f1.params != null && f1.params.join(":") != f2.params.join(":") ) return false; return true; } /** Unlike `c1 == c2`, this function performs a deep equality check on the arguments of the enum constructors, if exists. If `c1` or `c2` are `null`, the result is unspecified. **/ public static function constructorEq( c1 : EnumField, c2: EnumField ) { if( c1.name != c2.name ) return false; if( c1.doc != c2.doc ) return false; if( (c1.args == null) != (c2.args == null) ) return false; if( c1.args != null && !leq(function(a,b) { return a.name == b.name && a.opt == b.opt && typeEq(a.t,b.t); },c1.args,c2.args) ) return false; return true; } } /** The CTypeTools class contains some extra functionalities for handling `CType` instances. **/ class CTypeTools { /** Get the string representation of `CType`. **/ static public function toString(t:CType):String { return switch (t) { case CUnknown: "unknown"; case CClass(name, params), CEnum(name, params), CTypedef(name, params), CAbstract(name, params): nameWithParams(name, params); case CFunction(args, ret): if (args.length == 0) { "Void -> " +toString(ret); } else { args.map(functionArgumentName).join(" -> ")+" -> "+toString(ret); } case CDynamic(d): if (d == null) { "Dynamic"; } else { "Dynamic<" + toString(d) + ">"; } case CAnonymous(fields): "{ " + fields.map(classField).join(", "); } } static function nameWithParams(name:String, params:List) { if (params.length == 0) { return name; } return name + "<" + params.map(toString).join(", ") + ">"; } static function functionArgumentName(arg:FunctionArgument) { return (arg.opt ? "?" : "") + (arg.name == "" ? "" : arg.name + ":") + toString(arg.t) + (arg.value == null ? "" : " = " +arg.value); } static function classField(cf:ClassField) { return cf.name + ":" +toString(cf.type); } }haxe_3.4.4.orig/std/haxe/rtti/Meta.hx0000664000175000017500000000633313166552354017351 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.rtti; private typedef MetaObject = { ?fields:Dynamic>>>, ?statics:Dynamic>>>, ?obj:Dynamic>>, } /** An API to access classes and enums metadata at runtime. @see **/ class Meta { /** Returns the metadata that were declared for the given type (class or enum) **/ public static function getType( t : Dynamic ) : Dynamic> { var meta = getMeta(t); return (meta == null || meta.obj == null) ? {} : meta.obj; } // Could move this to Type.hx? private static function isInterface(t:Dynamic):Bool { #if java return java.Lib.toNativeType(t).isInterface(); #elseif cs return cs.Lib.toNativeType(t).IsInterface; #elseif (flash && as3) return untyped flash.Lib.describeType(t).factory.extendsClass.length() == 0; #elseif (php && !php7) return untyped __php__("{0} instanceof _hx_interface", t); #else throw "Something went wrong"; #end } private static function getMeta(t:Dynamic):MetaObject { #if (php && php7) return php.Boot.getMeta(t.phpClassName); #elseif (java || cs || php || (flash && as3)) #if php t.__ensureMeta__(); #end var ret = Reflect.field(t, "__meta__"); if (ret == null && Std.is(t,Class)) { if (isInterface(t)) { var name = Type.getClassName(t), cls = Type.resolveClass(name + '_HxMeta'); if (cls != null) return Reflect.field(cls, "__meta__"); } } return ret; #elseif hl var t : hl.BaseType = t; return t.__meta__; #else return untyped t.__meta__; #end } /** Returns the metadata that were declared for the given class static fields **/ public static function getStatics( t : Dynamic ) : Dynamic>> { var meta = getMeta(t); return (meta == null || meta.statics == null) ? {} : meta.statics; } /** Returns the metadata that were declared for the given class fields or enum constructors **/ public static function getFields( t : Dynamic ) : Dynamic>> { var meta = getMeta(t); return (meta == null || meta.fields == null) ? {} : meta.fields; } } haxe_3.4.4.orig/std/haxe/rtti/Rtti.hx0000664000175000017500000000421413166552354017401 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.rtti; import haxe.rtti.CType; /** Rtti is a helper class which supplements the `@:rtti` metadata. @see **/ class Rtti { /** Returns the `haxe.rtti.CType.Classdef` corresponding to class `c`. If `c` has no runtime type information, e.g. because no `@:rtti@` was added, `null` is returned. If `c` is null, the result is unspecified. **/ static public function getRtti(c:Class):Classdef { var rtti = Reflect.field(c, "__rtti"); if (rtti == null) { throw 'Class ${Type.getClassName(c)} has no RTTI information, consider adding @:rtti'; } var x = Xml.parse(rtti).firstElement(); var infos = new haxe.rtti.XmlParser().processElement(x); switch (infos) { case TClassdecl(c): return c; case t: throw 'Enum mismatch: expected TClassDecl but found $t'; } } /** Tells if `c` has runtime type information. If `c` is null, the result is unspecified. **/ static public function hasRtti(c:Class):Bool { return Lambda.has(Type.getClassFields(c), "__rtti"); } }haxe_3.4.4.orig/std/haxe/rtti/XmlParser.hx0000664000175000017500000003644313166552354020405 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.rtti; import haxe.rtti.CType; import haxe.xml.Fast; /** XmlParser processes the runtime type information (RTTI) which is stored as a XML string in a static field `__rtti`. @see **/ class XmlParser { public var root : TypeRoot; var curplatform : String; public function new() { root = new Array(); } public function sort( ?l ) { if( l == null ) l = root; l.sort(function(e1,e2) { var n1 = switch e1 { case TPackage(p,_,_) : " "+p; default: TypeApi.typeInfos(e1).path; }; var n2 = switch e2 { case TPackage(p,_,_) : " "+p; default: TypeApi.typeInfos(e2).path; }; if( n1 > n2 ) return 1; return -1; }); for( x in l ) switch( x ) { case TPackage(_,_,l): sort(l); case TClassdecl(c): c.fields = sortFields(c.fields); c.statics = sortFields(c.statics); case TEnumdecl(_): case TAbstractdecl(_): case TTypedecl(_): } } function sortFields(fl) { var a = Lambda.array(fl); a.sort(function(f1 : ClassField,f2 : ClassField) { var v1 = TypeApi.isVar(f1.type); var v2 = TypeApi.isVar(f2.type); if( v1 && !v2 ) return -1; if( v2 && !v1 ) return 1; if( f1.name == "new" ) return -1; if( f2.name == "new" ) return 1; if( f1.name > f2.name ) return 1; return -1; }); return Lambda.list(a); } public function process( x : Xml, platform ) { curplatform = platform; xroot(new Fast(x)); } // merge inline and not inline function mergeRights( f1 : ClassField, f2 : ClassField ) { if( f1.get == RInline && f1.set == RNo && f2.get == RNormal && f2.set == RMethod ) { f1.get = RNormal; f1.set = RMethod; return true; } return Type.enumEq(f1.get, f2.get) && Type.enumEq(f1.set, f2.set); } function mergeDoc( f1 : ClassField, f2 : ClassField ) { if( f1.doc == null ) f1.doc = f2.doc; else if( f2.doc == null ) f2.doc = f1.doc; return true; } function mergeFields( f : ClassField, f2 : ClassField ) { return TypeApi.fieldEq(f,f2) || (f.name == f2.name && (mergeRights(f,f2) || mergeRights(f2,f)) && mergeDoc(f,f2) && TypeApi.fieldEq(f,f2)); } public dynamic function newField( c : Classdef, f : ClassField ) { } function mergeClasses( c : Classdef, c2 : Classdef ) { // todo : compare supers & interfaces if( c.isInterface != c2.isInterface ) return false; if( curplatform != null ) c.platforms.add(curplatform); if( c.isExtern != c2.isExtern ) c.isExtern = false; for( f2 in c2.fields ) { var found = null; for( f in c.fields ) if( mergeFields(f,f2) ) { found = f; break; } if( found == null ) { newField(c,f2); c.fields.add(f2); } else if( curplatform != null ) found.platforms.add(curplatform); } for( f2 in c2.statics ) { var found = null; for( f in c.statics ) if( mergeFields(f,f2) ) { found = f; break; } if( found == null ) { newField(c,f2); c.statics.add(f2); } else if( curplatform != null ) found.platforms.add(curplatform); } return true; } function mergeEnums( e : Enumdef, e2 : Enumdef ) { if( e.isExtern != e2.isExtern ) return false; if( curplatform != null ) e.platforms.add(curplatform); for( c2 in e2.constructors ) { var found = null; for( c in e.constructors ) if( TypeApi.constructorEq(c,c2) ) { found = c; break; } if( found == null ) return false; // don't allow by-platform constructor ? if( curplatform != null ) found.platforms.add(curplatform); } return true; } function mergeTypedefs( t : Typedef, t2 : Typedef ) { if( curplatform == null ) return false; t.platforms.add(curplatform); t.types.set(curplatform,t2.type); return true; } function mergeAbstracts( a : Abstractdef, a2 : Abstractdef ) { if( curplatform == null ) return false; if( a.to.length != a2.to.length || a.from.length != a2.from.length ) return false; for( i in 0...a.to.length ) if( !TypeApi.typeEq(a.to[i].t,a2.to[i].t) ) return false; for( i in 0...a.from.length ) if( !TypeApi.typeEq(a.from[i].t,a2.from[i].t) ) return false; if (a2.impl != null) mergeClasses(a.impl, a2.impl); a.platforms.add(curplatform); return true; } function merge( t : TypeTree ) { var inf = TypeApi.typeInfos(t); var pack = inf.path.split("."); var cur = root; var curpack = new Array(); pack.pop(); for( p in pack ) { var found = false; for( pk in cur ) switch( pk ) { case TPackage(pname,_,subs): if( pname == p ) { found = true; cur = subs; break; } default: } curpack.push(p); if( !found ) { var pk = new Array(); cur.push(TPackage(p,curpack.join("."),pk)); cur = pk; } } var prev = null; for( ct in cur ) { var tinf; try tinf = TypeApi.typeInfos(ct) catch( e : Dynamic ) continue; // compare params ? if( tinf.path == inf.path ) { var sameType = true; if( (tinf.doc == null) != (inf.doc == null) ) { if( inf.doc == null ) inf.doc = tinf.doc; else tinf.doc = inf.doc; } if (tinf.path == "haxe._Int64.NativeInt64") continue; if( tinf.module == inf.module && tinf.doc == inf.doc && tinf.isPrivate == inf.isPrivate ) switch( ct ) { case TClassdecl(c): switch( t ) { case TClassdecl(c2): if( mergeClasses(c,c2) ) return; default: sameType = false; } case TEnumdecl(e): switch( t ) { case TEnumdecl(e2): if( mergeEnums(e,e2) ) return; default: sameType = false; } case TTypedecl(td): switch( t ) { case TTypedecl(td2): if( mergeTypedefs(td,td2) ) return; default: } case TAbstractdecl(a): switch( t ) { case TAbstractdecl(a2): if( mergeAbstracts(a,a2) ) return; default: sameType = false; } case TPackage(_,_,_): sameType = false; } // we already have a mapping, but which is incompatible var msg = if( tinf.module != inf.module ) "module "+inf.module+" should be "+tinf.module; else if( tinf.doc != inf.doc ) "documentation is different"; else if( tinf.isPrivate != inf.isPrivate ) "private flag is different"; else if( !sameType ) "type kind is different"; else "could not merge definition"; throw "Incompatibilities between "+tinf.path+" in "+tinf.platforms.join(",")+" and "+curplatform+" ("+msg+")"; } } cur.push(t); } function mkPath( p : String ) : Path { return p; } function mkTypeParams( p : String ) : TypeParams { var pl = p.split(":"); if( pl[0] == "" ) return new Array(); return pl; } function mkRights( r : String ) : Rights { return switch( r ) { case "null": RNo; case "method": RMethod; case "dynamic": RDynamic; case "inline": RInline; default: RCall(r); } } function xerror( c : Fast ) : Dynamic { return throw "Invalid "+c.name; } function xroot( x : Fast ) { for( c in x.x.elements() ) merge(processElement(c)); } public function processElement( x : Xml ) { var c = new haxe.xml.Fast(x); return switch( c.name ) { case "class": TClassdecl(xclass(c)); case "enum": TEnumdecl(xenum(c)); case "typedef": TTypedecl(xtypedef(c)); case "abstract": TAbstractdecl(xabstract(c)); default: xerror(c); } } function xmeta( x : Fast ) : MetaData { var ml = []; for( m in x.nodes.m ) { var pl = []; for( p in m.nodes.e ) pl.push(p.innerHTML); ml.push({ name : m.att.n, params : pl }); } return ml; } function xoverloads( x : Fast ) : List { var l = new List(); for ( m in x.elements ) { l.add(xclassfield(m)); } return l; } function xpath( x : Fast ) : PathParams { var path = mkPath(x.att.path); var params = new List(); for( c in x.elements ) params.add(xtype(c)); return { path : path, params : params, }; } function xclass( x : Fast ) : Classdef { var csuper = null; var doc = null; var tdynamic = null; var interfaces = new List(); var fields = new List(); var statics = new List(); var meta = []; for( c in x.elements ) switch( c.name ) { case "haxe_doc": doc = c.innerData; case "extends": csuper = xpath(c); case "implements": interfaces.add(xpath(c)); case "haxe_dynamic": tdynamic = xtype(new Fast(c.x.firstElement())); case "meta": meta = xmeta(c); default: if( c.x.exists("static") ) statics.add(xclassfield(c)); else fields.add(xclassfield(c)); } return { file : if(x.has.file) x.att.file else null, path : mkPath(x.att.path), module : if( x.has.module ) mkPath(x.att.module) else null, doc : doc, isPrivate : x.x.exists("private"), isExtern : x.x.exists("extern"), isInterface : x.x.exists("interface"), params : mkTypeParams(x.att.params), superClass : csuper, interfaces : interfaces, fields : fields, statics : statics, tdynamic : tdynamic, platforms : defplat(), meta : meta, }; } function xclassfield( x : Fast, ?defPublic = false ) : ClassField { var e = x.elements; var t = xtype(e.next()); var doc = null; var meta = []; var overloads = null; for( c in e ) switch( c.name ) { case "haxe_doc": doc = c.innerData; case "meta": meta = xmeta(c); case "overloads": overloads = xoverloads(c); default: xerror(c); } return { name : x.name, type : t, isPublic : x.x.exists("public") || defPublic, isOverride : x.x.exists("override"), line : if( x.has.line ) Std.parseInt(x.att.line) else null, doc : doc, get : if( x.has.get ) mkRights(x.att.get) else RNormal, set : if( x.has.set ) mkRights(x.att.set) else RNormal, params : if( x.has.params ) mkTypeParams(x.att.params) else [], platforms : defplat(), meta : meta, overloads: overloads, expr : if( x.has.expr ) x.att.expr else null }; } function xenum( x : Fast ) : Enumdef { var cl = new List(); var doc = null; var meta = []; for( c in x.elements ) if( c.name == "haxe_doc" ) doc = c.innerData; else if ( c.name == "meta" ) meta = xmeta(c); else cl.add(xenumfield(c)); return { file : if(x.has.file) x.att.file else null, path : mkPath(x.att.path), module : if( x.has.module ) mkPath(x.att.module) else null, doc : doc, isPrivate : x.x.exists("private"), isExtern : x.x.exists("extern"), params : mkTypeParams(x.att.params), constructors : cl, platforms : defplat(), meta : meta, }; } function xenumfield( x : Fast ) : EnumField { var args = null; var xdoc = x.x.elementsNamed("haxe_doc").next(); var meta = if( x.hasNode.meta ) xmeta(x.node.meta) else []; if( x.has.a ) { var names = x.att.a.split(":"); var elts = x.elements; args = new List(); for( c in names ) { var opt = false; if( c.charAt(0) == "?" ) { opt = true; c = c.substr(1); } args.add({ name : c, opt : opt, t : xtype(elts.next()), }); } } return { name : x.name, args : args, doc : if( xdoc == null ) null else new Fast(xdoc).innerData, meta : meta, platforms : defplat(), }; } function xabstract( x : Fast ) : Abstractdef { var doc = null, impl = null, athis = null; var meta = [], to = [], from = []; for( c in x.elements ) switch( c.name ) { case "haxe_doc": doc = c.innerData; case "meta": meta = xmeta(c); case "to": for( t in c.elements ) to.push({t: xtype(new Fast(t.x.firstElement())), field: t.has.field ? t.att.field : null}); case "from": for( t in c.elements ) from.push({t: xtype(new Fast(t.x.firstElement())), field: t.has.field ? t.att.field : null}); case "impl": impl = xclass(c.node.resolve("class")); case "this": athis = xtype(new Fast(c.x.firstElement())); default: xerror(c); } return { file : if(x.has.file) x.att.file else null, path : mkPath(x.att.path), module : if( x.has.module ) mkPath(x.att.module) else null, doc : doc, isPrivate : x.x.exists("private"), params : mkTypeParams(x.att.params), platforms : defplat(), meta : meta, athis : athis, to : to, from : from, impl: impl }; } function xtypedef( x : Fast ) : Typedef { var doc = null; var t = null; var meta = []; for( c in x.elements ) if( c.name == "haxe_doc" ) doc = c.innerData; else if ( c.name == "meta" ) meta = xmeta(c); else t = xtype(c); var types = new haxe.ds.StringMap(); if( curplatform != null ) types.set(curplatform,t); return { file : if(x.has.file) x.att.file else null, path : mkPath(x.att.path), module : if( x.has.module ) mkPath(x.att.module) else null, doc : doc, isPrivate : x.x.exists("private"), params : mkTypeParams(x.att.params), type : t, types : types, platforms : defplat(), meta : meta, }; } function xtype( x : Fast ) : CType { return switch( x.name ) { case "unknown": CUnknown; case "e": CEnum(mkPath(x.att.path),xtypeparams(x)); case "c": CClass(mkPath(x.att.path),xtypeparams(x)); case "t": CTypedef(mkPath(x.att.path),xtypeparams(x)); case "x": CAbstract(mkPath(x.att.path),xtypeparams(x)); case "f": var args = new List(); var aname = x.att.a.split(":"); var eargs = aname.iterator(); var evalues = x.has.v ? x.att.v.split(":").iterator() : null; for( e in x.elements ) { var opt = false; var a = eargs.next(); if( a == null ) a = ""; if( a.charAt(0) == "?" ) { opt = true; a = a.substr(1); } var v = evalues == null ? null : evalues.next(); args.add({ name : a, opt : opt, t : xtype(e), value : v == "" ? null : v }); } var ret = args.last(); args.remove(ret); CFunction(args,ret.t); case "a": var fields = new List(); for( f in x.elements ) { var f = xclassfield(f,true); f.platforms = new List(); // platforms selection are on the type itself, not on fields fields.add(f); } CAnonymous(fields); case "d": var t = null; var tx = x.x.firstElement(); if( tx != null ) t = xtype(new Fast(tx)); CDynamic(t); default: xerror(x); } } function xtypeparams( x : Fast ) : List { var p = new List(); for( c in x.elements ) p.add(xtype(c)); return p; } function defplat() { var l = new List(); if( curplatform != null ) l.add(curplatform); return l; } } haxe_3.4.4.orig/std/haxe/unit/TestCase.hx0000664000175000017500000000631213166552354020170 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.unit; import haxe.PosInfos; /** This unit test class should be extended to create test cases. Each test method created in this extended class should start with the name "test". These test methods should call the assertion methods: * `assertTrue(a)`: Succeeds if `a` is `true`. * `assertFalse(a)`: Succeeds if `a` is `false`. * `assertEquals(expected, actual)`: Succeeds if `expected` and `actual` are equal. ```haxe class MyTestCase extends haxe.unit.TestCase { function testBasic() { assertEquals("A", "A"); } } ``` The TestCase can be tested using `TestRunner`. To run code before or after the test, override the functions `setup` and `tearDown`. @see **/ @:keepSub @:publicFields class TestCase { /** The current test status of the TestRunner. **/ public var currentTest : TestStatus; public function new( ) { } /** Override this method to execute code before the test runs. **/ public function setup() : Void { } /** Override this method to execute code after the test ran. **/ public function tearDown() : Void { } function print( v : Dynamic ) { haxe.unit.TestRunner.print(v); } /** Succeeds if `b` is `true`. **/ function assertTrue( b:Bool, ?c : PosInfos ) : Void { currentTest.done = true; if (b != true){ currentTest.success = false; currentTest.error = "expected true but was false"; currentTest.posInfos = c; throw currentTest; } } /** Succeeds if `b` is `false`. **/ function assertFalse( b:Bool, ?c : PosInfos ) : Void { currentTest.done = true; if (b == true){ currentTest.success = false; currentTest.error = "expected false but was true"; currentTest.posInfos = c; throw currentTest; } } /** Succeeds if `expected` and `actual` are equal. **/ function assertEquals( expected: T , actual: T, ?c : PosInfos ) : Void { currentTest.done = true; if (actual != expected){ currentTest.success = false; currentTest.error = "expected '" + expected + "' but was '" + actual + "'"; currentTest.posInfos = c; throw currentTest; } } } haxe_3.4.4.orig/std/haxe/unit/TestResult.hx0000664000175000017500000000517113166552354020575 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.unit; /** TestResult contains the result of the executed unit tests. **/ class TestResult { var m_tests : List; /** `true` if the unit test succesfully executed the test cases. **/ public var success(default, null) : Bool; public function new() { m_tests = new List(); success = true; } public function add( t:TestStatus ) : Void { m_tests.add(t); if( !t.success ) success = false; } /** String representation from the result of the unit test. **/ public function toString() : String { var buf = new StringBuf(); var failures = 0; for ( test in m_tests ){ if (test.success == false){ buf.add("* "); buf.add(test.classname); buf.add("::"); buf.add(test.method); buf.add("()"); buf.add("\n"); buf.add("ERR: "); if( test.posInfos != null ){ buf.add(test.posInfos.fileName); buf.add(":"); buf.add(test.posInfos.lineNumber); buf.add("("); buf.add(test.posInfos.className); buf.add("."); buf.add(test.posInfos.methodName); buf.add(") - "); } buf.add(test.error); buf.add("\n"); if (test.backtrace != null) { buf.add(test.backtrace); buf.add("\n"); } buf.add("\n"); failures++; } } buf.add("\n"); if (failures == 0) buf.add("OK "); else buf.add("FAILED "); buf.add(m_tests.length); buf.add(" tests, "); buf.add(failures); buf.add(" failed, "); buf.add( (m_tests.length - failures) ); buf.add(" success"); buf.add("\n"); return buf.toString(); } } haxe_3.4.4.orig/std/haxe/unit/TestRunner.hx0000664000175000017500000001231313166552354020564 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.unit; import Reflect; /** This class runs unit test cases and prints the result. ```haxe var r = new haxe.unit.TestRunner(); r.add(new MyTestCase()); // add other TestCases here // finally, run the tests r.run(); ``` @see **/ class TestRunner { /** The unit test results. Available after the `run()` is called. **/ public var result(default, null) : TestResult; var cases : List; #if flash static var tf : flash.text.TextField = null; #end /** Prints the given object/value. * Flash outputs the result in a new `TextField` on stage. * JavaScript outputs the result using `console.log`. * Other targets use native `print` to output the result. This function is `dynamic` so it can be overriden in custom setups. **/ public static dynamic function print( v : Dynamic ) untyped { #if flash if( tf == null ) { tf = new flash.text.TextField(); tf.selectable = false; tf.width = flash.Lib.current.stage.stageWidth; tf.autoSize = flash.text.TextFieldAutoSize.LEFT; flash.Lib.current.addChild(tf); } tf.appendText(v); #elseif neko __dollar__print(v); #elseif php php.Lib.print(v); #elseif cpp cpp.Lib.print(v); #elseif js var msg = js.Boot.__string_rec(v,""); var d; if( __js__("typeof")(document) != "undefined" && (d = document.getElementById("haxe:trace")) != null ) { msg = StringTools.htmlEscape(msg).split("\n").join("
"); d.innerHTML += msg+"
"; } else if ( __js__("typeof process") != "undefined" && __js__("process").stdout != null && __js__("process").stdout.write != null) __js__("process").stdout.write(msg); // node else if ( __js__("typeof console") != "undefined" && __js__("console").log != null ) __js__("console").log(msg); // document-less js (which may include a line break) #elseif cs cs.system.Console.Write(v); #elseif java var str:String = v; untyped __java__("java.lang.System.out.print(str)"); #elseif python python.Lib.print(v); #elseif (hl || lua) Sys.print(Std.string(v)); #end } private static function customTrace( v, ?p : haxe.PosInfos ) { print(p.fileName+":"+p.lineNumber+": "+Std.string(v)+"\n"); } public function new() { result = new TestResult(); cases = new List(); } /** Add TestCase instances to the unit test. **/ public function add( c:TestCase ) : Void{ cases.add(c); } /** Runs the unit tests and prints the results. @return `true` if the unit test succesfully executed the test cases. **/ public function run() : Bool { result = new TestResult(); for ( c in cases ){ runCase(c); } print(result.toString()); return result.success; } function runCase( t:TestCase ) : Void { var old = haxe.Log.trace; haxe.Log.trace = customTrace; var cl = Type.getClass(t); var fields = Type.getInstanceFields(cl); print( "Class: "+Type.getClassName(cl)+" "); for ( f in fields ){ var fname = f; var field = Reflect.field(t, f); if ( StringTools.startsWith(fname,"test") && Reflect.isFunction(field) ){ t.currentTest = new TestStatus(); t.currentTest.classname = Type.getClassName(cl); t.currentTest.method = fname; t.setup(); try { Reflect.callMethod(t, field, new Array()); if( t.currentTest.done ){ t.currentTest.success = true; print("."); }else{ t.currentTest.success = false; t.currentTest.error = "(warning) no assert"; print("W"); } }catch ( e : TestStatus ){ print("F"); t.currentTest.backtrace = haxe.CallStack.toString(haxe.CallStack.exceptionStack()); }catch ( e : Dynamic ){ print("E"); #if js if( e.message != null ){ t.currentTest.error = "exception thrown : "+e+" ["+e.message+"]"; }else{ t.currentTest.error = "exception thrown : "+e; } #else t.currentTest.error = "exception thrown : "+e; #end t.currentTest.backtrace = haxe.CallStack.toString(haxe.CallStack.exceptionStack()); } result.add(t.currentTest); t.tearDown(); } } print("\n"); haxe.Log.trace = old; } } haxe_3.4.4.orig/std/haxe/unit/TestStatus.hx0000664000175000017500000000365013166552354020602 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.unit; import haxe.CallStack; import haxe.PosInfos; /** The status information of a unit test case method. @see **/ class TestStatus { /** `true` when the unit test is executed. **/ public var done : Bool; /** `true` when succesfully unit tested. **/ public var success : Bool; /** The error message of the unit test method. **/ public var error : String; /** The method name of the unit test. **/ public var method : String; /** The class name of the unit test. **/ public var classname : String; /** The position information of the unit test. **/ public var posInfos : PosInfos; /** The representation of the stack exception. **/ public var backtrace : String; public function new() { done = false; success = false; } } haxe_3.4.4.orig/std/haxe/web/Dispatch.hx0000664000175000017500000003265113166552354020017 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.web; #if macro import haxe.macro.Expr; import haxe.macro.Type.ClassField; import haxe.macro.Context; #end typedef DispatchConfig = { var obj : Dynamic; var rules : Dynamic; } typedef Lock = T; enum MatchRule { MRInt; MRBool; MRFloat; MRString; MRDate; MREnum( e : String ); MRDispatch; MRSpod( c : String, lock : Bool ); MROpt( r : MatchRule ); } enum DispatchRule { DRMatch( r : MatchRule ); DRMult( r : Array ); DRArgs( r : DispatchRule, args : Array<{ name : String, rule : MatchRule, opt : Bool }>, opt : Bool ); DRMeta( r : DispatchRule ); } enum DispatchError { DENotFound( part : String ); DEInvalidValue; DEMissing; DEMissingParam( p : String ); DETooManyValues; } class Redirect { public function new() { } } class Dispatch { public var parts : Array; public var params : Map; public var name : String; public var cfg : DispatchConfig; var subDispatch : Bool; public function new(url:String, params) { parts = url.split("/"); if( parts[0] == "" ) parts.shift(); this.params = params; } public macro function dispatch( ethis : Expr, obj : ExprOf<{}> ) : ExprOf { var p = Context.currentPos(); var cfg = makeConfig(obj); return { expr : ECall({ expr : EField(ethis, "runtimeDispatch"), pos : p }, [cfg]), pos : p }; } public macro function getParams( ethis : Expr ) : Expr { var p = Context.currentPos(); if( PARAMS == null ) { PARAMS = new Array(); Context.onGenerate(buildParams); } var index = PARAMS.length; var t = Context.typeof({ expr : EConst(CIdent("null")), pos : p }); PARAMS.push( { p : p, t : t } ); var call = { expr : ECall( { expr : EField(ethis, "runtimeGetParams"), pos : p }, [ { expr : EConst(CInt(Std.string(index))), pos : p } ]), pos : p }; var rt = TPath( { pack : ["haxe", "macro"], name : "MacroType", params : [TPExpr(Context.parse("haxe.web.Dispatch.getRunParam("+index+")",p))], sub : null } ); return { expr : EBlock([ { expr : EVars([ { name : "tmp", type : rt, expr : call } ]), pos : p }, { expr : EConst(CIdent("tmp")), pos : p } ]), pos : p }; } public dynamic function onMeta( v : String, args : Null> ) { } function resolveName( name : String ) { return name; } public function runtimeDispatch( cfg : DispatchConfig ) { name = parts.shift(); if( name == null ) name = "default"; name = resolveName(name); this.cfg = cfg; var r : DispatchRule = Reflect.field(cfg.rules, name); if( r == null ) { r = Reflect.field(cfg.rules, "default"); if( r == null ) throw DENotFound(name); parts.unshift(name); name = "default"; } name = "do" + name.charAt(0).toUpperCase() + name.substr(1); var args = []; subDispatch = false; loop(args, r); if( parts.length > 0 && !subDispatch ) { if( parts.length == 1 && parts[parts.length - 1] == "" ) parts.pop() else throw DETooManyValues; } try { Reflect.callMethod(cfg.obj, Reflect.field(cfg.obj, name), args); } catch( e : Redirect ) { runtimeDispatch(cfg); } } public function redirect( url : String, ?params : Map ) { parts = url.split("/"); if( parts[0] == "" ) parts.shift(); if( params != null ) this.params = params; throw new Redirect(); } static var GET_RULES; public function runtimeGetParams( cfgIndex : Int ) : Dynamic { if( GET_RULES == null ) GET_RULES = haxe.Unserializer.run(haxe.rtti.Meta.getType(Dispatch).getParams[0]); return checkParams(GET_RULES[cfgIndex], true); } function match( v : String, r : MatchRule, opt : Bool ) : Dynamic { switch( r ) { case MRInt: if( v == null ) throw DEMissing; if( opt && v == "" ) return null; var v = Std.parseInt(v); if( v == null ) throw DEInvalidValue; return v; case MRFloat: if( v == null ) throw DEMissing; if( opt && v == "" ) return null; var v = Std.parseFloat(v); if( Math.isNaN(v) ) throw DEInvalidValue; return v; case MRString: if( v == null ) throw DEMissing; return v; case MRBool: return v != null && v != "0" && v != "false" && v != "null"; case MRDate: if( v == null ) throw DEMissing; try{ return Date.fromString(v); } catch (e:Dynamic) { throw DEInvalidValue; } case MREnum(e): if( v == null ) throw DEMissing; if( opt && v == "" ) return null; if( v == "" ) throw DEMissing; var en : Dynamic = Type.resolveEnum(e); if( en == null ) throw "assert"; var ev:Dynamic; if (v.charCodeAt(0) >= '0'.code && v.charCodeAt(0) <= '9'.code) { ev = Type.createEnumIndex(en, Std.parseInt(v)); } else { ev = Type.createEnum(en, v); } return ev; case MRDispatch: if( v != null ) parts.unshift(v); subDispatch = true; return this; case MRSpod(c, lock): if( v == null ) throw DEMissing; var v = Std.parseInt(v); if( v == null ) throw DEInvalidValue; var cl : Dynamic = Type.resolveClass(c); if( cl == null ) throw "assert"; var o : Dynamic; #if !old_spod o = cl.manager.unsafeGet(v, lock); #else o = cl.manager.get(v, lock); #end if( o == null ) throw DEInvalidValue; return o; case MROpt(r) : if( v == null ) return null; return match(v, r, true); } } function checkParams( params : Array<{ name : String, opt : Bool, rule : MatchRule }>, opt ) { var po = { }; for( p in params ) { var v = this.params.get(p.name); if( v == null ) { if( p.opt ) continue; if( opt ) return null; throw DEMissingParam(p.name); } Reflect.setField(po, p.name, match(v, p.rule,p.opt)); } return po; } function loop( args : Array, r ) { switch( r ) { case DRArgs(r, params, opt): loop(args, r); args.push( checkParams(params, opt) ); case DRMatch(r): args.push(match(parts.shift(), r, false)); case DRMult(rl): for( r in rl ) args.push(match(parts.shift(), r, false)); case DRMeta(r): loop(args, r); var c = Type.getClass(cfg.obj); var m; do { if( c == null ) throw "assert"; m = Reflect.field(haxe.rtti.Meta.getFields(c), name); c = Type.getSuperClass(c); } while( m == null ); for( mv in Reflect.fields(m) ) onMeta(mv, Reflect.field(m, mv)); } } #if macro static inline var PREFIX = "haxe.web.Dispatch.DispatchRule."; static function getType(t,p) { switch( Context.follow(t) ) { case TInst(i,_): switch( i.toString() ) { case "Int": return MRInt; case "Float": return MRFloat; case "String": return MRString; case "Date": return MRDate; case "haxe.web.Dispatch": return MRDispatch; default: var c = i.get(); var csup = c.superClass; while( csup != null ) { var name = csup.t.toString(); if( name == "neko.db.Object" || name == "sys.db.Object" ) { var lock = switch( t ) { case TType(t, _): t.get().name == "Lock"; default: false; } return MRSpod(i.toString(), lock); } else if ( name == "haxe.web.Dispatch" ) { return MRDispatch; } csup = csup.t.get().superClass; } Context.error("Unsupported dispatch type '"+i.toString()+"'",p); } case TEnum(e, _): switch( e.toString() ) { case "Bool": return MRBool; default: return MREnum(e.toString()); } case TAbstract(a,_): switch( a.toString() ) { case "Int": return MRInt; case "Float": return MRFloat; case "Bool": return MRBool; default: Context.error("Unsupported dispatch type "+a.toString(),p); } default: Context.error("Unsupported dispatch type "+Std.string(t),p); } return null; } static function makeArgs( t : haxe.macro.Type, p ) { var args = []; switch( Context.follow(t) ) { case TAnonymous(a): for( f in a.get().fields ) { var r = getType(f.type, f.pos); var opt = f.meta.has(":optional"); switch( f.type ) { case TType(t, _): if( t.get().name == "Null" ) opt = true; default: } if( r == MRBool ) opt = true; args.push( { name : f.name, rule : r, opt : opt } ); } default: Context.error("Arguments should be an anonymous object", p); } return args; } static function makeRule( f : ClassField ) : DispatchRule { switch( Context.follow(f.type) ) { case TFun(pl, _): var params = []; var rules = []; var args = null, argsOpt = false; for( p in pl ) { if( p.name == "args" ) { if( args != null ) Context.error("Duplicate arguments", f.pos); argsOpt = p.opt; args = makeArgs(p.t,f.pos); continue; } if( args != null ) Context.error("Arguments should be last parameter", f.pos); var r = getType(p.t, f.pos); if( p.opt ) r = MROpt(r); rules.push(r); } var rule = if( rules.length == 1 ) DRMatch(rules[0]); else DRMult(rules); if( args != null ) rule = DRArgs(rule, args, argsOpt); return rule; default: Context.error("Configuration entry should be a function", f.pos); } return null; } static function makeConfig( obj : Expr ) { var p = obj.pos; if( Context.defined("display") ) return { expr : EObjectDecl([ { field : "obj", expr : obj }, { field : "rules", expr : { expr : EObjectDecl([]), pos : p } } ]), pos : p }; var t = Context.typeof(obj); switch( Context.follow(t) ) { case TAnonymous(fl): var fields = []; for( f in fl.get().fields ) { if( f.name.substr(0, 2) != "do" ) continue; if (!f.meta.has(':keep')) f.meta.add(':keep', [], f.pos); var r = makeRule(f); fields.push( { field : f.name.charAt(2).toLowerCase() + f.name.substr(3), expr : Context.makeExpr(r,p) } ); } if( fields.length == 0 ) Context.error("No dispatch method found", p); var rules = { expr : EObjectDecl(fields), pos : p }; return { expr : EObjectDecl([ { field : "obj", expr : obj }, { field : "rules", expr : rules } ]), pos : p }; case TInst(i, _): var i = i.get(); // store the config inside the class metadata (only once) if( !i.meta.has("dispatchConfig") ) { var fields = {}; var tmp = i; while( true ) { for( f in tmp.fields.get() ) { if( f.name.substr(0, 2) != "do" ) continue; if (!f.meta.has(':keep')) f.meta.add(':keep', [], f.pos); var r = makeRule(f); for( m in f.meta.get() ) if( m.name.charAt(0) != ":" ) { checkMeta(f); r = DRMeta(r); break; } Reflect.setField(fields, f.name.charAt(2).toLowerCase() + f.name.substr(3), r); } if( tmp.superClass == null ) break; tmp = tmp.superClass.t.get(); } if( Reflect.fields(fields).length == 0 ) Context.error("No dispatch method found", p); var str = serialize(fields); i.meta.add("dispatchConfig", [ { expr : EConst(CString(str)), pos : p } ], p); } return { expr : EUntyped ({ expr : ECall({ expr : EField(Context.makeExpr(Dispatch,p),"extractConfig"), pos : p },[obj]), pos : p }), pos : p }; default: Context.error("Configuration should be an anonymous object",p); } return null; } static var PARAMS:Array = null; static function buildParams(_) { var rules = []; for( p in PARAMS ) rules.push(makeArgs(p.t, p.p)); var str = serialize(rules); switch( Context.getType("haxe.web.Dispatch") ) { case TInst(c, _): var c = c.get(); c.meta.remove("getParams"); c.meta.add("getParams",[{ expr : EConst(CString(str)), pos : c.pos }],c.pos); default: } } static function serialize( v : Dynamic ) { var s = new haxe.Serializer(); s.useEnumIndex = true; s.serialize(v); return s.toString(); } public static function getRunParam(i:Int) { return PARAMS[i].t; } public dynamic static function checkMeta( f : ClassField ) { } #end public static macro function make( obj : ExprOf<{}> ) : ExprOf { return makeConfig(obj); } public static macro function run( url : ExprOf, params : ExprOf>, obj : ExprOf<{}> ) : ExprOf { var p = Context.currentPos(); var cfg = makeConfig(obj); return { expr : ECall({ expr : EField({ expr : ENew({ name : "Dispatch", pack : ["haxe","web"], params : [], sub : null },[url,params]), pos : p },"runtimeDispatch"), pos : p },[cfg]), pos : p }; } static function extractConfig( obj : Dynamic ) : DispatchConfig { // extract the config from the class metadata (cache result) var c = Type.getClass(obj); var dc = haxe.rtti.Meta.getType(c); var m : Dynamic = dc.dispatchConfig[0]; if( Std.is(m,String) ) { m = haxe.Unserializer.run(m); dc.dispatchConfig[0] = m; } return { obj : obj, rules : m }; } } haxe_3.4.4.orig/std/haxe/web/Request.hx0000664000175000017500000000446613166552354017713 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.web; #if (!neko && !php && !js) #error "Not supported on this target" #end class Request { /** Returns the current page GET and POST parameters (only GET parameters for Javascript) **/ public static function getParams() : Map { #if neko return neko.Web.getParams(); #elseif php return php.Web.getParams(); #elseif js var get : String = js.Browser.location.search.substr(1); var params = new haxe.ds.StringMap(); for( p in ~/[&;]/g.split(get) ) { var pl = p.split("="); if( pl.length < 2 ) continue; var name = pl.shift(); params.set(StringTools.urlDecode(name), StringTools.urlDecode(pl.join("="))); } return params; #end } /** Returns the local server host name **/ public static function getHostName() : String { #if neko return neko.Web.getHostName(); #elseif php return php.Web.getHostName(); #elseif js return js.Browser.location.host; // includes port #end } /** Returns the original request URL (before any server internal redirections) **/ public static function getURI() : String { #if neko return neko.Web.getURI(); #elseif php return php.Web.getURI(); #elseif js return js.Browser.location.pathname; #end } } haxe_3.4.4.orig/std/haxe/xml/Check.hx0000664000175000017500000002020013166552354017303 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.xml; enum Filter { FInt; FBool; FEnum( values : Array ); FReg( matcher : EReg ); } enum Attrib { Att( name : String, ?filter : Filter, ?defvalue : String ); } enum Rule { RNode( name : String, ?attribs : Array, ?childs : Rule ); RData( ?filter : Filter ); RMulti( rule : Rule, ?atLeastOne : Bool ); RList( rules : Array, ?ordered : Bool ); RChoice( choices : Array ); ROptional( rule : Rule ); } private enum CheckResult { CMatch; CMissing( r : Rule ); CExtra( x : Xml ); CElementExpected( name : String, x : Xml ); CDataExpected( x : Xml ); CExtraAttrib( att : String, x : Xml ); CMissingAttrib( att : String, x : Xml ); CInvalidAttrib( att : String, x : Xml, f : Filter ); CInvalidData( x : Xml, f : Filter ); CInElement( x : Xml, r : CheckResult ); } class Check { static var blanks = ~/^[ \r\n\t]*$/; static function isBlank( x : Xml ) { return( x.nodeType == Xml.PCData && blanks.match(x.nodeValue) ) || x.nodeType == Xml.Comment; } static function filterMatch( s : String, f : Filter ) { switch( f ) { case FInt: return filterMatch(s,FReg(~/[0-9]+/)); case FBool: return filterMatch(s,FEnum(["true","false","0","1"])); case FEnum(values): for( v in values ) if( s == v ) return true; return false; case FReg(r): return r.match(s); } } static function isNullable( r : Rule ) { switch( r ) { case RMulti(r,one): return( one != true || isNullable(r) ); case RList(rl,_): for( r in rl ) if( !isNullable(r) ) return false; return true; case RChoice(rl): for( r in rl ) if( isNullable(r) ) return true; return false; case RData(_): return false; case RNode(_,_,_): return false; case ROptional(_): return true; } } static function check( x : Xml, r : Rule ) { switch( r ) { // check the node validity case RNode(name,attribs,childs): if( x.nodeType != Xml.Element || x.nodeName != name ) return CElementExpected(name,x); var attribs = if( attribs == null ) new Array() else attribs.copy(); // check defined attributes for( xatt in x.attributes() ) { var found = false; for( att in attribs ) switch( att ) { case Att(name,filter,_): if( xatt != name ) continue; if( filter != null && !filterMatch(x.get(xatt),filter) ) return CInvalidAttrib(name,x,filter); attribs.remove(att); found = true; } if( !found ) return CExtraAttrib(xatt,x); } // check remaining unchecked attributes for( att in attribs ) switch( att ) { case Att(name,_,defvalue): if( defvalue == null ) return CMissingAttrib(name,x); } // check childs if( childs == null ) childs = RList([]); var m = checkList(x.iterator(),childs); if( m != CMatch ) return CInElement(x,m); // set default attribs values for( att in attribs ) switch( att ) { case Att(name,_,defvalue): x.set(name,defvalue); } return CMatch; // check the data validity case RData(filter): if( x.nodeType != Xml.PCData && x.nodeType != Xml.CData ) return CDataExpected(x); if( filter != null && !filterMatch(x.nodeValue,filter) ) return CInvalidData(x,filter); return CMatch; // several choices case RChoice(choices): if( choices.length == 0 ) throw "No choice possible"; for( c in choices ) if( check(x,c) == CMatch ) return CMatch; return check(x,choices[0]); case ROptional(r): return check(x,r); default: throw "Unexpected "+Std.string(r); } } static function checkList( it : Iterator, r : Rule ) { switch( r ) { case RList(rules,ordered): var rules = rules.copy(); for( x in it ) { if( isBlank(x) ) continue; var found = false; for( r in rules ) { var m = checkList([x].iterator(),r); if( m == CMatch ) { found = true; switch(r) { case RMulti(rsub,one): if( one ) { var i; for( i in 0...rules.length ) if( rules[i] == r ) rules[i] = RMulti(rsub); } default: rules.remove(r); } break; } else if( ordered && !isNullable(r) ) return m; } if( !found ) return CExtra(x); } for( r in rules ) if( !isNullable(r) ) return CMissing(r); return CMatch; case RMulti(r,one): var found = false; for( x in it ) { if( isBlank(x) ) continue; var m = checkList([x].iterator(),r); if( m != CMatch ) return m; found = true; } if( one && !found ) return CMissing(r); return CMatch; default: var found = false; for( x in it ) { if( isBlank(x) ) continue; var m = check(x,r); if( m != CMatch ) return m; found = true; break; } if( !found ) { switch(r) { case ROptional(_): default: return CMissing(r); } } for( x in it ) { if( isBlank(x) ) continue; return CExtra(x); } return CMatch; } } static function makeWhere( path : Array ) { if( path.length == 0 ) return ""; var s = "In "; var first = true; for( x in path ) { if( first ) first = false; else s += "."; s += x.nodeName; } return s+": "; } static function makeString( x : Xml ) { if( x.nodeType == Xml.Element ) return "element "+x.nodeName; var s = x.nodeValue.split("\r").join("\\r").split("\n").join("\\n").split("\t").join("\\t"); if( s.length > 20 ) return s.substr(0,17)+"..."; return s; } static function makeRule( r : Rule ) { switch( r ) { case RNode(name,_,_): return "element "+name; case RData(_): return "data"; case RMulti(r,_): return makeRule(r); case RList(rules,_): return makeRule(rules[0]); case RChoice(choices): return makeRule(choices[0]); case ROptional(r): return makeRule(r); } } static function makeError(m,?path) { if( path == null ) path = new Array(); switch( m ) { case CMatch: throw "assert"; case CMissing(r): return makeWhere(path)+"Missing "+makeRule(r); case CExtra(x): return makeWhere(path)+"Unexpected "+makeString(x); case CElementExpected(name,x): return makeWhere(path)+makeString(x)+" while expected element "+name; case CDataExpected(x): return makeWhere(path)+makeString(x)+" while data expected"; case CExtraAttrib(att,x): path.push(x); return makeWhere(path)+"unexpected attribute "+att; case CMissingAttrib(att,x): path.push(x); return makeWhere(path)+"missing required attribute "+att; case CInvalidAttrib(att,x,_): path.push(x); return makeWhere(path)+"invalid attribute value for "+att; case CInvalidData(x,_): return makeWhere(path)+"invalid data format for "+makeString(x); case CInElement(x,m): path.push(x); return makeError(m,path); } } public static function checkNode( x : Xml, r : Rule ) { var m = checkList([x].iterator(),r); if( m == CMatch ) return; throw makeError(m); } public static function checkDocument( x : Xml, r : Rule ) { if( x.nodeType != Xml.Document ) throw "Document expected"; var m = checkList(x.iterator(),r); if( m == CMatch ) return; throw makeError(m); } } haxe_3.4.4.orig/std/haxe/xml/Fast.hx0000664000175000017500000001466313166552354017203 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.xml; private class NodeAccess implements Dynamic { var __x : Xml; public function new( x : Xml ) { __x = x; } public function resolve( name : String ) : Fast { var x = __x.elementsNamed(name).next(); if( x == null ) { var xname = if( __x.nodeType == Xml.Document ) "Document" else __x.nodeName; throw xname+" is missing element "+name; } return new Fast(x); } } private class AttribAccess implements Dynamic { var __x : Xml; public function new( x : Xml ) { __x = x; } public function resolve( name : String ) : String { if( __x.nodeType == Xml.Document ) throw "Cannot access document attribute "+name; var v = __x.get(name); if( v == null ) throw __x.nodeName+" is missing attribute "+name; return v; } } private class HasAttribAccess implements Dynamic { var __x : Xml; public function new( x : Xml ) { __x = x; } public function resolve( name : String ) : Bool { if( __x.nodeType == Xml.Document ) throw "Cannot access document attribute "+name; return __x.exists(name); } } private class HasNodeAccess implements Dynamic { var __x : Xml; public function new( x : Xml ) { __x = x; } public function resolve( name : String ) : Bool { return __x.elementsNamed(name).hasNext(); } } private class NodeListAccess implements Dynamic> { var __x : Xml; public function new( x : Xml ) { __x = x; } public function resolve( name : String ) : List { var l = new List(); for( x in __x.elementsNamed(name) ) l.add(new Fast(x)); return l; } } /** The `haxe.xml.Fast` API helps providing a fast dot-syntax access to the most common `Xml` methods. **/ class Fast { /** The current corresponding `Xml` node. **/ public var x(default, null) : Xml; /** The name of the current element. This is the same as `Xml.nodeName`. **/ public var name(get,null) : String; /** The inner PCDATA or CDATA of the node. An exception is thrown if there is no data or if there not only data but also other nodes. **/ public var innerData(get,null) : String; /** The XML string built with all the sub nodes, excluding the current one. **/ public var innerHTML(get,null) : String; /** Access to the first sub element with the given name. An exception is thrown if the element doesn't exists. Use `hasNode` to check the existence of a node. ```haxe var fast = new haxe.xml.Fast(Xml.parse("John")); var user = fast.node.user; var name = user.node.name; trace(name.innerData); // John // Uncaught Error: Document is missing element password var password = user.node.password; ``` **/ public var node(default,null) : NodeAccess; /** Access to the List of elements with the given name. ```haxe var fast = new haxe.xml.Fast(Xml.parse(" ")); var users = fast.node.users; for(user in users.nodes.user) { trace(user.att.name); } ``` **/ public var nodes(default,null) : NodeListAccess; /** Access to a given attribute. An exception is thrown if the attribute doesn't exists. Use `has` to check the existence of an attribute. ```haxe var f = new haxe.xml.Fast(Xml.parse("")); var user = f.node.user; if (user.has.name) { trace(user.att.name); // Mark } ``` **/ public var att(default,null) : AttribAccess; /** Check the existence of an attribute with the given name. **/ public var has(default,null) : HasAttribAccess; /** Check the existence of a sub node with the given name. ```haxe var f = new haxe.xml.Fast(Xml.parse("31")); var user = f.node.user; if (user.hasNode.age) { trace(user.node.age.innerData); // 31 } ``` **/ public var hasNode(default,null) : HasNodeAccess; /** The list of all sub-elements which are the nodes with type `Xml.Element`. **/ public var elements(get,null) : Iterator; public function new( x : Xml ) { if( x.nodeType != Xml.Document && x.nodeType != Xml.Element ) throw "Invalid nodeType "+x.nodeType; this.x = x; node = new NodeAccess(x); nodes = new NodeListAccess(x); att = new AttribAccess(x); has = new HasAttribAccess(x); hasNode = new HasNodeAccess(x); } function get_name() { return if( x.nodeType == Xml.Document ) "Document" else x.nodeName; } function get_innerData() { var it = x.iterator(); if( !it.hasNext() ) throw name+" does not have data"; var v = it.next(); if( it.hasNext() ) { var n = it.next(); // handle CDATA if( v.nodeType == Xml.PCData && n.nodeType == Xml.CData && StringTools.trim(v.nodeValue) == "" ) { if( !it.hasNext() ) return n.nodeValue; var n2 = it.next(); if( n2.nodeType == Xml.PCData && StringTools.trim(n2.nodeValue) == "" && !it.hasNext() ) return n.nodeValue; } throw name+" does not only have data"; } if( v.nodeType != Xml.PCData && v.nodeType != Xml.CData ) throw name+" does not have data"; return v.nodeValue; } function get_innerHTML() { var s = new StringBuf(); for( x in x ) s.add(x.toString()); return s.toString(); } function get_elements() { var it = x.elements(); return { hasNext : it.hasNext, next : function() { var x = it.next(); if( x == null ) return null; return new Fast(x); } }; } } haxe_3.4.4.orig/std/haxe/xml/Parser.hx0000664000175000017500000003013713166552354017534 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.xml; using StringTools; /* poor'man enum : reduce code size + a bit faster since inlined */ extern private class S { public static inline var IGNORE_SPACES = 0; public static inline var BEGIN = 1; public static inline var BEGIN_NODE = 2; public static inline var TAG_NAME = 3; public static inline var BODY = 4; public static inline var ATTRIB_NAME = 5; public static inline var EQUALS = 6; public static inline var ATTVAL_BEGIN = 7; public static inline var ATTRIB_VAL = 8; public static inline var CHILDS = 9; public static inline var CLOSE = 10; public static inline var WAIT_END = 11; public static inline var WAIT_END_RET = 12; public static inline var PCDATA = 13; public static inline var HEADER = 14; public static inline var COMMENT = 15; public static inline var DOCTYPE = 16; public static inline var CDATA = 17; public static inline var ESCAPE = 18; } class XmlParserException { /** * the XML parsing error message */ public var message:String; /** * the line number at which the XML parsing error occurred */ public var lineNumber:Int; /** * the character position in the reported line at which the parsing error occurred */ public var positionAtLine:Int; /** * the character position in the XML string at which the parsing error occurred */ public var position:Int; /** * the invalid XML string */ public var xml:String; public function new(message:String, xml:String, position:Int) { this.xml = xml; this.message = message; this.position = position; lineNumber = 1; positionAtLine = 0; for( i in 0...position) { var c = xml.fastCodeAt(i); if (c == '\n'.code) { lineNumber++; positionAtLine = 0; } else { if (c != '\r'.code) positionAtLine++; } } } public function toString():String { return Type.getClassName(Type.getClass(this)) + ": " + message + " at line " + lineNumber + " char " + positionAtLine; } } class Parser { static var escapes = { var h = new haxe.ds.StringMap(); h.set("lt", "<"); h.set("gt", ">"); h.set("amp", "&"); h.set("quot", '"'); h.set("apos", "'"); h; } /** * Parses the String into an XML Document. Set strict parsing to true in order to enable a strict check of XML attributes and entities. * * @throws haxe.xml.XmlParserException */ static public function parse(str:String, strict = false) { var doc = Xml.createDocument(); doParse(str, strict, 0, doc); return doc; } static function doParse(str:String, strict:Bool, p:Int = 0, ?parent:Xml):Int { var xml:Xml = null; var state = S.BEGIN; var next = S.BEGIN; var aname = null; var start = 0; var nsubs = 0; var nbrackets = 0; var c = str.fastCodeAt(p); var buf = new StringBuf(); // need extra state because next is in use var escapeNext = S.BEGIN; var attrValQuote = -1; inline function addChild(xml:Xml) { parent.addChild(xml); nsubs++; } while (!StringTools.isEof(c)) { switch(state) { case S.IGNORE_SPACES: switch(c) { case '\n'.code, '\r'.code, '\t'.code, ' '.code: default: state = next; continue; } case S.BEGIN: switch(c) { case '<'.code: state = S.IGNORE_SPACES; next = S.BEGIN_NODE; default: start = p; state = S.PCDATA; continue; } case S.PCDATA: if (c == '<'.code) { buf.addSub(str, start, p - start); var child = Xml.createPCData(buf.toString()); buf = new StringBuf(); addChild(child); state = S.IGNORE_SPACES; next = S.BEGIN_NODE; } else if (c == '&'.code) { buf.addSub(str, start, p - start); state = S.ESCAPE; escapeNext = S.PCDATA; start = p + 1; } case S.CDATA: if (c == ']'.code && str.fastCodeAt(p + 1) == ']'.code && str.fastCodeAt(p + 2) == '>'.code) { var child = Xml.createCData(str.substr(start, p - start)); addChild(child); p += 2; state = S.BEGIN; } case S.BEGIN_NODE: switch(c) { case '!'.code: if (str.fastCodeAt(p + 1) == '['.code) { p += 2; if (str.substr(p, 6).toUpperCase() != "CDATA[") throw new XmlParserException("Expected '.code: state = S.CHILDS; default: state = S.ATTRIB_NAME; start = p; continue; } case S.ATTRIB_NAME: if (!isValidChar(c)) { var tmp; if( start == p ) throw new XmlParserException("Expected attribute name", str, p); tmp = str.substr(start,p-start); aname = tmp; if( xml.exists(aname) ) throw new XmlParserException("Duplicate attribute [" + aname + "]", str, p); state = S.IGNORE_SPACES; next = S.EQUALS; continue; } case S.EQUALS: switch(c) { case '='.code: state = S.IGNORE_SPACES; next = S.ATTVAL_BEGIN; default: throw new XmlParserException("Expected =", str, p); } case S.ATTVAL_BEGIN: switch(c) { case '"'.code | '\''.code: buf = new StringBuf(); state = S.ATTRIB_VAL; start = p + 1; attrValQuote = c; default: throw new XmlParserException("Expected \"", str, p); } case S.ATTRIB_VAL: switch (c) { case '&'.code: buf.addSub(str, start, p - start); state = S.ESCAPE; escapeNext = S.ATTRIB_VAL; start = p + 1; case '>'.code | '<'.code if( strict ): // HTML allows these in attributes values throw new XmlParserException("Invalid unescaped " + String.fromCharCode(c) + " in attribute value", str, p); case _ if (c == attrValQuote): buf.addSub(str, start, p - start); var val = buf.toString(); buf = new StringBuf(); xml.set(aname, val); state = S.IGNORE_SPACES; next = S.BODY; } case S.CHILDS: p = doParse(str, strict, p, xml); start = p; state = S.BEGIN; case S.WAIT_END: switch(c) { case '>'.code: state = S.BEGIN; default : throw new XmlParserException("Expected >", str, p); } case S.WAIT_END_RET: switch(c) { case '>'.code: if( nsubs == 0 ) parent.addChild(Xml.createPCData("")); return p; default : throw new XmlParserException("Expected >", str, p); } case S.CLOSE: if (!isValidChar(c)) { if( start == p ) throw new XmlParserException("Expected node name", str, p); var v = str.substr(start,p - start); if (v != parent.nodeName) throw new XmlParserException("Expected ", str, p); state = S.IGNORE_SPACES; next = S.WAIT_END_RET; continue; } case S.COMMENT: if (c == '-'.code && str.fastCodeAt(p +1) == '-'.code && str.fastCodeAt(p + 2) == '>'.code) { addChild(Xml.createComment(str.substr(start, p - start))); p += 2; state = S.BEGIN; } case S.DOCTYPE: if(c == '['.code) nbrackets++; else if(c == ']'.code) nbrackets--; else if (c == '>'.code && nbrackets == 0) { addChild(Xml.createDocType(str.substr(start, p - start))); state = S.BEGIN; } case S.HEADER: if (c == '?'.code && str.fastCodeAt(p + 1) == '>'.code) { p++; var str = str.substr(start + 1, p - start - 2); addChild(Xml.createProcessingInstruction(str)); state = S.BEGIN; } case S.ESCAPE: if (c == ';'.code) { var s = str.substr(start, p - start); if (s.fastCodeAt(0) == '#'.code) { var c = s.fastCodeAt(1) == 'x'.code ? Std.parseInt("0" +s.substr(1, s.length - 1)) : Std.parseInt(s.substr(1, s.length - 1)); #if (neko || cpp || php || lua) if( c >= 128 ) { // UTF8-encode it if( c <= 0x7FF ) { buf.addChar(0xC0 | (c >> 6)); buf.addChar(0x80 | (c & 63)); } else if( c <= 0xFFFF ) { buf.addChar(0xE0 | (c >> 12)); buf.addChar(0x80 | ((c >> 6) & 63)); buf.addChar(0x80 | (c & 63)); } else if( c <= 0x10FFFF ) { buf.addChar(0xF0 | (c >> 18)); buf.addChar(0x80 | ((c >> 12) & 63)); buf.addChar(0x80 | ((c >> 6) & 63)); buf.addChar(0x80 | (c & 63)); } else throw new XmlParserException("Cannot encode UTF8-char " + c, str, p); } else #end buf.addChar(c); } else if (!escapes.exists(s)) { if( strict ) throw new XmlParserException("Undefined entity: " + s, str, p); buf.add('&$s;'); } else { buf.add(escapes.get(s)); } start = p + 1; state = escapeNext; } else if (!isValidChar(c) && c != "#".code) { if( strict ) throw new XmlParserException("Invalid character in entity: " + String.fromCharCode(c), str, p); buf.addChar("&".code); buf.addSub(str, start, p - start); p--; start = p + 1; state = escapeNext; } } c = str.fastCodeAt(++p); } if (state == S.BEGIN) { start = p; state = S.PCDATA; } if (state == S.PCDATA) { if (p != start || nsubs == 0) { buf.addSub(str, start, p-start); addChild(Xml.createPCData(buf.toString())); } return p; } if( !strict && state == S.ESCAPE && escapeNext == S.PCDATA ) { buf.addChar("&".code); buf.addSub(str, start, p - start); addChild(Xml.createPCData(buf.toString())); return p; } throw new XmlParserException("Unexpected end", str, p); } static inline function isValidChar(c) { return (c >= 'a'.code && c <= 'z'.code) || (c >= 'A'.code && c <= 'Z'.code) || (c >= '0'.code && c <= '9'.code) || c == ':'.code || c == '.'.code || c == '_'.code || c == '-'.code; } } haxe_3.4.4.orig/std/haxe/xml/Printer.hx0000664000175000017500000000664113166552354017726 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.xml; /** This class provides utility methods to convert Xml instances to String representation. **/ class Printer { /** Convert `Xml` to string representation. Set `pretty` to `true` to prettify the result. **/ static public function print(xml:Xml, ?pretty = false) { var printer = new Printer(pretty); printer.writeNode(xml, ""); return printer.output.toString(); } var output:StringBuf; var pretty:Bool; function new(pretty) { output = new StringBuf(); this.pretty = pretty; } function writeNode(value:Xml, tabs:String) { switch (value.nodeType) { case CData: write(tabs + ""); newline(); case Comment: var commentContent:String = value.nodeValue; commentContent = ~/[\n\r\t]+/g.replace(commentContent, ""); commentContent = ""; write(tabs); write(StringTools.trim(commentContent)); newline(); case Document: for (child in value) { writeNode(child, tabs); } case Element: write(tabs + "<"); write(value.nodeName); for (attribute in value.attributes()) { write(" " + attribute + "=\""); write(StringTools.htmlEscape(value.get(attribute), true)); write("\""); } if (hasChildren(value)) { write(">"); newline(); for (child in value) { writeNode(child, pretty ? tabs + "\t" : tabs); } write(tabs + ""); newline(); } else { write("/>"); newline(); } case PCData: var nodeValue:String = value.nodeValue; if (nodeValue.length != 0) { write(tabs + StringTools.htmlEscape(nodeValue)); newline(); } case ProcessingInstruction: write(""); newline(); case DocType: write(""); newline(); } } inline function write(input:String) { output.add(input); } inline function newline() { if (pretty) { output.add("\n"); } } function hasChildren(value:Xml):Bool { for (child in value) { switch (child.nodeType) { case Element, PCData: return true; case CData, Comment: if (StringTools.ltrim(child.nodeValue).length != 0) { return true; } case _: } } return false; } } haxe_3.4.4.orig/std/haxe/xml/Proxy.hx0000664000175000017500000000342013166552354017414 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.xml; /** This proxy can be inherited with an XML file name parameter. It will only allow access to fields which corresponds to an "id" attribute value in the XML file : ```haxe class MyXml extends haxe.xml.Proxy<"my.xml", MyStructure> { } var h = new haxe.ds.StringMap(); // ... fill h with "my.xml" content var m = new MyXml(h.get); trace(m.myNode.structField); // Access to "myNode" is only possible if you have an id="myNode" attribute // in your XML, and completion works as well. ``` **/ class Proxy { var __f : String -> T; public function new(f) { this.__f = f; } public function resolve(k) { return __f(k); } } haxe_3.4.4.orig/std/haxe/zip/Compress.hx0000664000175000017500000000314713166552354020076 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; class Compress { public function new( level : Int ) { throw "Not implemented for this platform"; } public function execute( src : haxe.io.Bytes, srcPos : Int, dst : haxe.io.Bytes, dstPos : Int ) : { done : Bool, read : Int, write : Int } { return null; } public function setFlushMode( f : FlushMode ) { } public function close() { } public static function run( s : haxe.io.Bytes, level : Int ) : haxe.io.Bytes { throw "Not implemented for this platform"; return null; } } haxe_3.4.4.orig/std/haxe/zip/Entry.hx0000664000175000017500000000275213166552354017405 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; enum ExtraField { FUnknown( tag : Int, bytes : haxe.io.Bytes ); FInfoZipUnicodePath( name : String, crc : Int ); FUtf8; } typedef Entry = { var fileName : String; var fileSize : Int; var fileTime : Date; var compressed : Bool; var dataSize : Int; var data : Null; var crc32 : Null; @:optional var extraFields : Null>; } haxe_3.4.4.orig/std/haxe/zip/FlushMode.hx0000664000175000017500000000225613166552354020171 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; enum FlushMode { NO; SYNC; FULL; FINISH; BLOCK; } haxe_3.4.4.orig/std/haxe/zip/Huffman.hx0000664000175000017500000000622513166552354017667 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; enum Huffman { Found( i : Int ); NeedBit( left : Huffman, right : Huffman ); NeedBits( n : Int, table : Array ); } class HuffTools { public function new() { } function treeDepth(t) { return switch(t) { case Found(_): 0; case NeedBits(_,_): throw "assert"; case NeedBit(a,b): var da = treeDepth(a); var db = treeDepth(b); 1 + ((da < db) ? da : db); } } function treeCompress(t) { var d = treeDepth(t); if( d == 0 ) return t; if( d == 1 ) return switch( t ) { case NeedBit(a,b): NeedBit(treeCompress(a),treeCompress(b)); default: throw "assert"; } var size = 1 << d; var table = new Array(); for( i in 0...size ) table.push(Found(-1)); treeWalk(table,0,0,d,t); return NeedBits(d,table); } function treeWalk(table,p,cd,d,t) { switch( t ) { case NeedBit(a,b): if( d > 0 ) { treeWalk(table,p,cd+1,d-1,a); treeWalk(table,p|(1<, maxbits : Int, v : Int, len : Int ) { if( len > maxbits ) throw "Invalid huffman"; var idx = (v << 5) | len; if( bits.exists(idx) ) return Found(bits.get(idx)); v <<= 1; len += 1; return NeedBit(treeMake(bits,maxbits,v,len),treeMake(bits,maxbits,v|1,len)); } public function make(lengths,pos,nlengths,maxbits) { var counts = new Array(); var tmp = new Array(); if( maxbits > 32 ) throw "Invalid huffman"; for( i in 0...maxbits ) { counts.push(0); tmp.push(0); } for( i in 0...nlengths ) { var p = lengths[i+pos]; if( p >= maxbits ) throw "Invalid huffman"; counts[p]++; } var code = 0; for( i in 1...maxbits-1 ) { code = (code + counts[i]) << 1; tmp[i] = code; } var bits = new haxe.ds.IntMap(); for( i in 0...nlengths ) { var l = lengths[i + pos]; if( l != 0 ) { var n = tmp[l-1]; tmp[l-1] = n + 1; bits.set((n << 5) | l,i); } } return treeCompress(NeedBit(treeMake(bits,maxbits,0,1),treeMake(bits,maxbits,1,1))); } } haxe_3.4.4.orig/std/haxe/zip/InflateImpl.hx0000664000175000017500000002177413166552354020515 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; import haxe.zip.Huffman; import haxe.crypto.Adler32; private class Window { public static inline var SIZE = 1 << 15; public static inline var BUFSIZE = 1 << 16; public var buffer : haxe.io.Bytes; public var pos : Int; var crc : Adler32; public function new(hasCrc) { buffer = haxe.io.Bytes.alloc(BUFSIZE); pos = 0; if( hasCrc ) crc = new Adler32(); } public function slide() { if( crc != null ) crc.update(buffer,0,SIZE); var b = haxe.io.Bytes.alloc(BUFSIZE); pos -= SIZE; b.blit(0,buffer,SIZE,pos); buffer = b; } public function addBytes(b,p,len) { if( pos + len > BUFSIZE ) slide(); buffer.blit(pos,b,p,len); pos += len; } public function addByte(c) { if( pos == BUFSIZE ) slide(); buffer.set(pos,c); pos++; } public function getLastChar() { return buffer.get(pos - 1); } public function available() { return pos; } public function checksum() { if( crc != null ) crc.update(buffer,0,pos); return crc; } } private enum State { Head; Block; CData; Flat; Crc; Dist; DistOne; Done; } /** A pure Haxe implementation of the ZLIB Inflate algorithm which allows reading compressed data without any platform-specific support. **/ class InflateImpl { static var LEN_EXTRA_BITS_TBL = [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,-1,-1]; static var LEN_BASE_VAL_TBL = [3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258]; static var DIST_EXTRA_BITS_TBL = [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,-1,-1]; static var DIST_BASE_VAL_TBL = [1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577]; static var CODE_LENGTHS_POS = [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]; var nbits : Int; var bits : Int; var state : State; var final : Bool; var huffman : Huffman; var huffdist : Null; var htools : HuffTools; var len : Int; var dist : Int; var needed : Int; var output : haxe.io.Bytes; var outpos : Int; var input : haxe.io.Input; var lengths : Array; var window : Window; static var FIXED_HUFFMAN = null; public function new( i, ?header = true, ?crc = true ) { final = false; htools = new HuffTools(); huffman = buildFixedHuffman(); huffdist = null; len = 0; dist = 0; state = header ? Head : Block; input = i; bits = 0; nbits = 0; needed = 0; output = null; outpos = 0; lengths = new Array(); for( i in 0...19 ) lengths.push(-1); window = new Window(crc); } function buildFixedHuffman() { if( FIXED_HUFFMAN != null ) return FIXED_HUFFMAN; var a = new Array(); for( n in 0...288 ) a.push(if( n <= 143 ) 8 else if( n <= 255 ) 9 else if( n <= 279 ) 7 else 8); FIXED_HUFFMAN = htools.make(a,0,288,10); return FIXED_HUFFMAN; } public function readBytes(b,pos,len) { needed = len; outpos = pos; output = b; if( len > 0 ) while( inflateLoop() ) { } return len - needed; } function getBits(n) { while( nbits < n ) { bits |= input.readByte() << nbits; nbits += 8; } var b = bits & ((1 << n) - 1); nbits -= n; bits >>= n; return b; } function getBit() { if( nbits == 0 ) { nbits = 8; bits = input.readByte(); } var b = bits & 1 == 1; nbits--; bits >>= 1; return b; } function getRevBits(n) { return if( n == 0 ) 0 else if( getBit() ) (1 << (n - 1)) | getRevBits(n-1) else getRevBits(n-1); } function resetBits() { bits = 0; nbits = 0; } function addBytes(b,p,len) { window.addBytes(b,p,len); output.blit(outpos,b,p,len); needed -= len; outpos += len; } function addByte(b) { window.addByte(b); output.set(outpos,b); needed--; outpos++; } function addDistOne(n) { var c = window.getLastChar(); for( i in 0...n ) addByte(c); } function addDist(d,len) { addBytes(window.buffer,window.pos - d,len); } function applyHuffman(h) { return switch(h) { case Found(n): n; case NeedBit(a,b): applyHuffman(getBit()?b:a); case NeedBits(n,tbl): applyHuffman(tbl[getBits(n)]); } } function inflateLengths(a,max) { var i = 0; var prev = 0; while( i < max ) { var n = applyHuffman(huffman); switch( n ) { case 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15: prev = n; a[i] = n; i++; case 16: var end = i + 3 + getBits(2); if( end > max ) throw "Invalid data"; while( i < end ) { a[i] = prev; i++; } case 17: i += 3 + getBits(3); if( i > max ) throw "Invalid data"; case 18: i += 11 + getBits(7); if( i > max ) throw "Invalid data"; default: throw "Invalid data"; } } } function inflateLoop() { switch( state ) { case Head: var cmf = input.readByte(); var cm = cmf & 15; var cinfo = cmf >> 4; if( cm != 8 ) throw "Invalid data"; var flg = input.readByte(); //var fcheck = flg & 31; var fdict = flg & 32 != 0; //var flevel = flg >> 6; if( ((cmf << 8) + flg) % 31 != 0 ) throw "Invalid data"; if( fdict ) throw "Unsupported dictionary"; state = Block; return true; case Crc: var calc = window.checksum(); if( calc == null ) { state = Done; return true; } var crc = Adler32.read(input); if( !calc.equals(crc) ) throw "Invalid CRC"; state = Done; return true; case Done: // nothing return false; case Block: final = getBit(); switch( getBits(2) ) { case 0: // no compression len = input.readUInt16(); var nlen = input.readUInt16(); if( nlen != 0xFFFF - len ) throw "Invalid data"; state = Flat; var r = inflateLoop(); resetBits(); return r; case 1: // fixed Huffman huffman = buildFixedHuffman(); huffdist = null; state = CData; return true; case 2: // dynamic Huffman var hlit = getBits(5) + 257; var hdist = getBits(5) + 1; var hclen = getBits(4) + 4; for( i in 0...hclen ) lengths[CODE_LENGTHS_POS[i]] = getBits(3); for( i in hclen...19 ) lengths[CODE_LENGTHS_POS[i]] = 0; huffman = htools.make(lengths,0,19,8); var lengths = new Array(); for( i in 0...hlit + hdist ) lengths.push(0); inflateLengths(lengths,hlit + hdist); huffdist = htools.make(lengths,hlit,hdist,16); huffman = htools.make(lengths,0,hlit,16); state = CData; return true; default: throw "Invalid data"; } case Flat: var rlen = (len < needed) ? len : needed; var bytes = input.read(rlen); len -= rlen; addBytes(bytes,0,rlen); if( len == 0 ) state = final ? Crc : Block; return needed > 0; case DistOne: var rlen = (len < needed) ? len : needed; addDistOne(rlen); len -= rlen; if( len == 0 ) state = CData; return needed > 0; case Dist: while( len > 0 && needed > 0 ) { var rdist = (len < dist) ? len : dist; var rlen = (needed < rdist) ? needed : rdist; addDist(dist,rlen); len -= rlen; } if( len == 0 ) state = CData; return needed > 0; case CData: var n = applyHuffman(huffman); if( n < 256 ) { addByte(n); return needed > 0; } else if( n == 256 ) { state = final ? Crc : Block; return true; } else { n -= 257; var extra_bits = LEN_EXTRA_BITS_TBL[n]; if( extra_bits == -1 ) throw "Invalid data"; len = LEN_BASE_VAL_TBL[n] + getBits(extra_bits); var dist_code = if( huffdist == null ) getRevBits(5) else applyHuffman(huffdist); extra_bits = DIST_EXTRA_BITS_TBL[dist_code]; if( extra_bits == -1 ) throw "Invalid data"; dist = DIST_BASE_VAL_TBL[dist_code] + getBits(extra_bits); if( dist > window.available() ) throw "Invalid data"; state = (dist == 1) ? DistOne : Dist; return true; } } } public static function run( i : haxe.io.Input, ?bufsize = 65536 ) { var buf = haxe.io.Bytes.alloc(bufsize); var output = new haxe.io.BytesBuffer(); var inflate = new InflateImpl(i); while( true ) { var len = inflate.readBytes(buf,0,bufsize); output.addBytes(buf,0,len); if( len < bufsize ) break; } return output.getBytes(); } } haxe_3.4.4.orig/std/haxe/zip/Reader.hx0000664000175000017500000001405713166552354017507 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; import haxe.zip.Entry; // see http://www.pkware.com/documents/casestudies/APPNOTE.TXT class Reader { var i : haxe.io.Input; public function new(i) { this.i = i; } function readZipDate() { var t = i.readUInt16(); var hour = (t >> 11) & 31; var min = (t >> 5) & 63; var sec = t & 31; var d = i.readUInt16(); var year = d >> 9; var month = (d >> 5) & 15; var day = d & 31; return new Date(year + 1980, month-1, day, hour, min, sec << 1); } function readExtraFields(length) { var fields = new List(); while( length > 0 ) { if( length < 4 ) throw "Invalid extra fields data"; var tag = i.readUInt16(); var len = i.readUInt16(); if( length < len ) throw "Invalid extra fields data"; switch( tag ) { case 0x7075: var version = i.readByte(); if( version != 1 ) { var data = new haxe.io.BytesBuffer(); data.addByte(version); data.add(i.read(len-1)); fields.add(FUnknown(tag,data.getBytes())); } else { var crc = i.readInt32(); var name = i.read(len - 5).toString(); fields.add(FInfoZipUnicodePath(name,crc)); } default: fields.add(FUnknown(tag,i.read(len))); } length -= 4 + len; } return fields; } public function readEntryHeader() : Entry { var i = this.i; var h = i.readInt32(); if( h == 0x02014B50 || h == 0x06054B50 ) return null; if( h != 0x04034B50 ) throw "Invalid Zip Data"; var version = i.readUInt16(); var flags = i.readUInt16(); var utf8 = flags & 0x800 != 0; if( (flags & 0xF7F1) != 0 ) throw "Unsupported flags "+flags; var compression = i.readUInt16(); var compressed = (compression != 0); if( compressed && compression != 8 ) throw "Unsupported compression "+compression; var mtime = readZipDate(); var crc32 : Null = i.readInt32(); var csize = i.readInt32(); var usize = i.readInt32(); var fnamelen = i.readInt16(); var elen = i.readInt16(); var fname = i.readString(fnamelen); var fields = readExtraFields(elen); if( utf8 ) fields.push(FUtf8); var data = null; // we have a data descriptor that store the real crc/sizes // after the compressed data, let's wait for it if( (flags & 8) != 0 ) crc32 = null; return { fileName : fname, fileSize : usize, fileTime : mtime, compressed : compressed, dataSize : csize, data : data, crc32 : crc32, extraFields : fields, }; } public function read() : List { var l = new List(); var buf = null; var tmp = null; while( true ) { var e = readEntryHeader(); if( e == null ) break; // do we have a data descriptor? (see readEntryHeader) if( e.crc32 == null ) { if( e.compressed ) { #if neko // enter progressive mode : we use a different input which has // a temporary buffer, this is necessary since we have to uncompress // progressively, and after that we might have pending read data // that needs to be processed var bufSize = 65536; if( buf == null ) { buf = new haxe.io.BufferInput(i, haxe.io.Bytes.alloc(bufSize)); tmp = haxe.io.Bytes.alloc(bufSize); i = buf; } var out = new haxe.io.BytesBuffer(); var z = new neko.zip.Uncompress(-15); z.setFlushMode(neko.zip.Flush.SYNC); while( true ) { if( buf.available == 0 ) buf.refill(); var p = bufSize - buf.available; if( p != buf.pos ) { // because of lack of "srcLen" in zip api, we need to always be stuck to the buffer end buf.buf.blit(p, buf.buf, buf.pos, buf.available); buf.pos = p; } var r = z.execute(buf.buf, buf.pos, tmp, 0); out.addBytes(tmp, 0, r.write); buf.pos += r.read; buf.available -= r.read; if( r.done ) break; } e.data = out.getBytes(); #else var bufSize = 65536; if( tmp == null ) tmp = haxe.io.Bytes.alloc(bufSize); var out = new haxe.io.BytesBuffer(); var z = new InflateImpl(i, false, false); while( true ) { var n = z.readBytes(tmp, 0, bufSize); out.addBytes(tmp, 0, n); if( n < bufSize ) break; } e.data = out.getBytes(); #end } else e.data = i.read(e.dataSize); e.crc32 = i.readInt32(); if( e.crc32 == 0x08074b50 ) e.crc32 = i.readInt32(); e.dataSize = i.readInt32(); e.fileSize = i.readInt32(); // set data to uncompressed e.dataSize = e.fileSize; e.compressed = false; } else e.data = i.read(e.dataSize); l.add(e); } return l; } public static function readZip( i : haxe.io.Input ) { var r = new Reader(i); return r.read(); } public static function unzip( f : Entry ) { if( !f.compressed ) return f.data; var c = new haxe.zip.Uncompress(-15); var s = haxe.io.Bytes.alloc(f.fileSize); var r = c.execute(f.data,0,s,0); c.close(); if( !r.done || r.read != f.data.length || r.write != f.fileSize ) throw "Invalid compressed data for "+f.fileName; f.compressed = false; f.dataSize = f.fileSize; f.data = s; return f.data; } } haxe_3.4.4.orig/std/haxe/zip/Tools.hx0000664000175000017500000000301613166552354017376 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; class Tools { public static function compress( f : Entry, level : Int ) { if( f.compressed ) return; // this should be optimized with a temp buffer // that would discard the first two bytes // (in order to prevent 2x mem usage for large files) var data = haxe.zip.Compress.run( f.data, level ); f.compressed = true; f.data = data.sub(2,data.length-6); f.dataSize = f.data.length; } } haxe_3.4.4.orig/std/haxe/zip/Uncompress.hx0000664000175000017500000000316713166552354020443 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; class Uncompress { public function new( ?windowBits : Int ) { throw "Not implemented for this platform"; } public function execute( src : haxe.io.Bytes, srcPos : Int, dst : haxe.io.Bytes, dstPos : Int ) : { done : Bool, read : Int, write : Int } { return null; } public function setFlushMode( f : FlushMode ) { } public function close() { } public static function run( src : haxe.io.Bytes, ?bufsize : Int ) : haxe.io.Bytes { return InflateImpl.run(new haxe.io.BytesInput(src),bufsize); } } haxe_3.4.4.orig/std/haxe/zip/Writer.hx0000664000175000017500000001311713166552354017555 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; class Writer { /* * The next constant is required for computing the Central * Directory Record(CDR) size. CDR consists of some fields * of constant size and a filename. Constant represents * total length of all fields with constant size for each * file in archive */ inline static var CENTRAL_DIRECTORY_RECORD_FIELDS_SIZE = 46; /* * The following constant is the total size of all fields * of Local File Header. It's required for calculating * offset of start of central directory record */ inline static var LOCAL_FILE_HEADER_FIELDS_SIZE = 30; var o : haxe.io.Output; var files : List<{ name : String, compressed : Bool, clen : Int, size : Int, crc : Int, date : Date, fields : haxe.io.Bytes }>; public function new( o : haxe.io.Output ) { this.o = o; files = new List(); } function writeZipDate( date : Date ) { var hour = date.getHours(); var min = date.getMinutes(); var sec = date.getSeconds() >> 1; o.writeUInt16( (hour << 11) | (min << 5) | sec ); var year = date.getFullYear() - 1980; var month = date.getMonth() + 1; var day = date.getDate(); o.writeUInt16( (year << 9) | (month << 5) | day ); } public function writeEntryHeader( f : Entry ) { var o = this.o; var flags = 0; if (f.extraFields != null) { for( e in f.extraFields ) switch( e ) { case FUtf8: flags |= 0x800; default: } } o.writeInt32(0x04034B50); o.writeUInt16(0x0014); // version o.writeUInt16(flags); // flags if( f.data == null ) { f.fileSize = 0; f.dataSize = 0; f.crc32 = 0; f.compressed = false; f.data = haxe.io.Bytes.alloc(0); } else { if( f.crc32 == null ) { if( f.compressed ) throw "CRC32 must be processed before compression"; f.crc32 = haxe.crypto.Crc32.make(f.data); } if( !f.compressed ) f.fileSize = f.data.length; f.dataSize = f.data.length; } o.writeUInt16(f.compressed?8:0); writeZipDate(f.fileTime); o.writeInt32(f.crc32); o.writeInt32(f.dataSize); o.writeInt32(f.fileSize); o.writeUInt16(f.fileName.length); var e = new haxe.io.BytesOutput(); if (f.extraFields != null) { for( f in f.extraFields ) switch( f ) { case FInfoZipUnicodePath(name,crc): var namebytes = haxe.io.Bytes.ofString(name); e.writeUInt16(0x7075); e.writeUInt16(namebytes.length + 5); e.writeByte(1); // version e.writeInt32(crc); e.write(namebytes); case FUnknown(tag,bytes): e.writeUInt16(tag); e.writeUInt16(bytes.length); e.write(bytes); case FUtf8: // nothing } } var ebytes = e.getBytes(); o.writeUInt16(ebytes.length); o.writeString(f.fileName); o.write(ebytes); files.add({ name : f.fileName, compressed : f.compressed, clen : f.data.length, size : f.fileSize, crc : f.crc32, date : f.fileTime, fields : ebytes }); } public function write( files : List ) { for( f in files ) { writeEntryHeader(f); o.writeFullBytes(f.data,0,f.data.length); } writeCDR(); } public function writeCDR() { var cdr_size = 0; var cdr_offset = 0; for ( f in files ) { var namelen = f.name.length; var extraFieldsLength = f.fields.length; o.writeInt32(0x02014B50); // header o.writeUInt16(0x0014); // version made-by o.writeUInt16(0x0014); // version o.writeUInt16(0); // flags o.writeUInt16(f.compressed?8:0); writeZipDate(f.date); o.writeInt32(f.crc); o.writeInt32(f.clen); o.writeInt32(f.size); o.writeUInt16(namelen); o.writeUInt16(extraFieldsLength); o.writeUInt16(0); //comment length always 0 o.writeUInt16(0); //disk number start o.writeUInt16(0); //internal file attributes o.writeInt32(0); //external file attributes o.writeInt32(cdr_offset); //relative offset of local header o.writeString(f.name); o.write(f.fields); cdr_size += CENTRAL_DIRECTORY_RECORD_FIELDS_SIZE + namelen + extraFieldsLength; cdr_offset += LOCAL_FILE_HEADER_FIELDS_SIZE + namelen + extraFieldsLength + f.clen; } //end of central dir signature o.writeInt32(0x06054B50); //number of this disk o.writeUInt16(0); //number of the disk with the start of the central directory o.writeUInt16(0); //total number of entries in the central directory on this disk o.writeUInt16(files.length); //total number of entries in the central directory o.writeUInt16(files.length); //size of the central directory record o.writeInt32(cdr_size); //offset of start of central directory with respect to the starting disk number o.writeInt32(cdr_offset); // .ZIP file comment length o.writeUInt16(0); } } haxe_3.4.4.orig/std/hl/Abstract.hx0000664000175000017500000000222113166552354016712 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; extern class Abstract { }haxe_3.4.4.orig/std/hl/Api.hx0000664000175000017500000000502413166552354015664 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; extern class Api { static inline function rethrow( v : Dynamic ) : Void { untyped $rethrow(v); } @:hlNative("std","obj_get_field") static function getField( obj : Dynamic, hash : Int ) : Dynamic; @:hlNative("std","obj_set_field") static function setField( obj : Dynamic, hash : Int, value : Dynamic ) : Void; @:hlNative("std","obj_has_field") static function hasField( obj : Dynamic, hash : Int ) : Bool; @:hlNative("std","obj_delete_field") static function deleteField( obj : Dynamic, hash : Int ) : Bool; @:hlNative("std","call_method") static function callMethod( f : haxe.Constraints.Function, args : NativeArray ) : Dynamic; @:hlNative("std","get_closure_value") static function getClosureValue( f : haxe.Constraints.Function ) : Dynamic; @:hlNative("std","no_closure") static function noClosure( f : haxe.Constraints.Function ) : haxe.Constraints.Function; @:hlNative("std", "value_cast") static function safeCast( v : Dynamic, t : Type ) : Dynamic; @:hlNative("std", "make_var_args") static function makeVarArgs( v : NativeArray -> Dynamic ) : haxe.Constraints.Function; @:hlNative("std", "get_virtual_value") static function getVirtualValue( v : Dynamic ) : Dynamic; @:hlNative("std", "set_error_handler") static function setErrorHandler( v : Dynamic -> Void ) : Void; @:hlNative("std", "breakpoint") static function breakPoint() : Void; @:hlNative("std", "sys_is64") static function is64() : Bool; } haxe_3.4.4.orig/std/hl/BaseType.hx0000664000175000017500000000400713166552354016667 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; @:keep class BaseType { public var __type__ : Type; public var __meta__ : Dynamic; public var __implementedBy__ : NativeArray; public function check( v : Dynamic ) { var t = Type.getDynamic(v); if( t.kind == HVirtual ) { var v2 = hl.Api.getVirtualValue(v); if( v2 != null ) t = Type.getDynamic(v2); } if( __implementedBy__ == null ) { if( t.safeCast(__type__) ) return true; return false; } for( i in __implementedBy__ ) if( t.safeCast(i) ) return true; return false; } } @:keep class Class extends BaseType { public var __name__ : String; public var __constructor__ : Dynamic; } @:keep class Enum extends BaseType { public var __ename__ : String; public var __emap__ : hl.types.BytesMap; public var __constructs__ : Array; public var __evalues__ : NativeArray; } @:keep class CoreType extends Class { } @:keep class CoreEnum extends Enum { } haxe_3.4.4.orig/std/hl/Boot.hx0000664000175000017500000000230213166552354016052 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; import hl.types.ArrayDyn; import hl.BaseType; @:dox(hide) extern class Boot { } haxe_3.4.4.orig/std/hl/Bytes.hx0000664000175000017500000001360613166552354016246 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; @:coreType abstract Bytes { @:extern public inline function new( v : Int ) { this = alloc(v); } @:hlNative("std","bytes_blit") public function blit( pos : Int, src : Bytes, srcPos : Int, len : Int ) : Void { } @:extern @:arrayAccess public inline function getUI8( pos : Int ) : Int { return untyped $bgetui8(this,pos); } @:extern @:arrayAccess public inline function setUI8( pos : Int, value : Int ) : Int { untyped $bsetui8(this,pos,value); return value; } @:extern public inline function getI32( pos : Int ) : Int { return untyped $bgeti32(this,pos); } public inline function getUI16( pos : Int ) : Int { return untyped $bgetui16(this, pos); } public inline function setUI16( pos : Int, v : Int ) { untyped $bsetui16(this,pos,v); } @:extern public inline function getF32( pos : Int ) : F32 { return untyped $bgetf32(this,pos); } @:extern public inline function getF64( pos : Int ) : Float { return untyped $bgetf64(this,pos); } @:extern public inline function setI32( pos : Int, value : Int ) : Void { untyped $bseti32(this, pos, value); } @:extern public inline function setF32( pos : Int, value : F32 ) : Void { untyped $bsetf32(this, pos, value); } @:extern public inline function setF64( pos : Int, value : Float ) : Void { untyped $bsetf64(this, pos, value); } @:hlNative("std","alloc_bytes") static function alloc( size : Int ) : Bytes { return null; } @:hlNative("std","parse_int") public function parseInt( pos : Int, size : Int ) : Null { return null; } @:hlNative("std","parse_float") public function parseFloat( pos : Int, size : Int ) : Float { return 0.; } @:hlNative("std","bytes_compare") public function compare( pos : Int, bytes : Bytes, bytesPos : Int, size : Int ) : Int { return 0; } @:hlNative("std","bytes_find") public function find( pos : Int, size : Int, bytes : Bytes, bytesPos : Int, bytesSize : Int ) : Int { return 0; } @:hlNative("std","bytes_fill") public function fill( pos : Int, size : Int, v : Int ) : Void { } @:hlNative("std","bsort_i32") public function sortI32( pos : Int, length : Int, f : Int->Int->Int ) : Void { } @:hlNative("std","bsort_f64") public function sortF64( pos : Int, length : Int, f : Float->Float->Int ) : Void { } /** Please note that you need to retain the original unoffset'ed Bytes so it does not get garbage collected, unless the pointer was not GC allocated. **/ @:hlNative("std","bytes_offset") public function offset( delta : Int ) : Bytes { return null; } /** Returns an offset between the two pointers. This might overflow in 64 bits if the addresses of the two pointers differs by more than 4GB **/ @:hlNative("std","bytes_subtract") public function subtract( other : Bytes ) : Int { return 0; } @:hlNative("std", "bytes_address") static function get_address( b : Bytes, high : Ref ) : Int { return 0; } @:hlNative("std", "bytes_from_address") static function from_address( low : Int, high : Int ) : Bytes { return null; } /** Creates an pointer at a given memory address (highly unsafe) **/ public static inline function fromAddress( h : haxe.Int64 ) : Bytes { return from_address(h.low, h.high); } /** Returns the address value of the bytes. On 32 bit system the upper 32 bits will always be 0 **/ public function address() : haxe.Int64 { var high = 0; var low = get_address(this, high); return haxe.Int64.make(high,low); } public function sub( pos : Int, size : Int ) { var b = new Bytes(size); b.blit(0, this, pos, size); return b; } @:hlNative("std", "ucs2length") public function ucs2Length( bytePos : Int ) : Int { return 0; } @:hlNative("std","hash") function hash() : Int { return 0; } @:hlNative("std","utf8_to_utf16") public function utf8ToUtf16( bytePos : Int, outSize : Ref ) : Bytes { return null; } @:hlNative("std","utf16_to_utf8") public function utf16ToUtf8( bytePos : Int, outSize : Ref ) : Bytes { return null; } @:hlNative("std", "ucs2_upper") function ucs2Upper( bytePos : Int, size : Int ) : Bytes { return null; } @:hlNative("std", "ucs2_lower") function ucs2Lower( bytePos : Int, size : Int ) : Bytes { return null; } @:hlNative("std", "url_encode") function urlEncode( outSize : Ref ) : Bytes { return null; } @:hlNative("std", "url_decode") function urlDecode( outSize : Ref ) : Bytes { return null; } @:hlNative("std","value_to_string") public static function fromValue( v : Dynamic, length : Ref ) : Bytes { return null; } /** Get the bytes reference from an array of basic types (no copy occurs) **/ @:extern public static inline function getArray( a : Array ) : Bytes { return untyped $abytes(a); } @:from public static inline function fromBytes( bytes : haxe.io.Bytes ) { return @:privateAccess bytes.b; } }haxe_3.4.4.orig/std/hl/BytesAccess.hx0000664000175000017500000000353613166552354017371 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; @:coreType abstract BytesAccess from Bytes to Bytes { public var sizeBits(get, never) : Int; public var nullValue(get, never) : T; @:extern inline function get_sizeBits() { return untyped $bytes_sizebits(this); } @:extern inline function get_nullValue() { return untyped $bytes_nullvalue(this); } @:extern public inline function blit( pos : Int, src : BytesAccess, srcPos : Int, len : Int ) : Void { (this:Bytes).blit(pos << sizeBits, src, srcPos << sizeBits, len << sizeBits); } @:extern @:arrayAccess public inline function get( pos : Int ) : T { return untyped $bget(this,pos); } @:extern @:arrayAccess public inline function set( pos : Int, value : T ) : T { untyped $bset(this,pos,value); return value; } }haxe_3.4.4.orig/std/hl/F32.hx0000664000175000017500000000220613166552354015504 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; typedef F32 = Single;haxe_3.4.4.orig/std/hl/F64.hx0000664000175000017500000000220613166552354015511 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; typedef F64 = Float; haxe_3.4.4.orig/std/hl/Format.hx0000664000175000017500000000451513166552354016407 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; @:enum abstract PixelFormat(Int) { var RGB = 0; var BGR = 1; var RGBX = 2; var BGRX = 3; var XBGR = 4; var XRGB = 5; var GRAY = 6; var RGBA = 7; var BGRA = 8; var ABGR = 9; var ARGB = 10; var CMYK = 11; } /** These are the bindings for the HL `fmt.hdll` library, which contains various low level formats handling. **/ class Format { /** Decode JPG data into the target buffer. **/ @:hlNative("fmt","jpg_decode") public static function decodeJPG( src : hl.Bytes, srcLen : Int, dst : hl.Bytes, width : Int, height : Int, stride : Int, format : PixelFormat, flags : Int ) : Bool { return false; } /** Decode PNG data into the target buffer. **/ @:hlNative("fmt","png_decode") public static function decodePNG( src : hl.Bytes, srcLen : Int, dst : hl.Bytes, width : Int, height : Int, stride : Int, format : PixelFormat, flags : Int ) : Bool { return false; } /** Upscale/downscale an image. Currently supported flag bits: 1 = bilinear filtering **/ @:hlNative("fmt","img_scale") public static function scaleImage( out : hl.Bytes, outPos : Int, outStride : Int, outWidth : Int, outHeight : Int, _in : hl.Bytes, inPos : Int, inStride : Int, inWidth : Int, inHeight : Int, flags : Int ) { } }haxe_3.4.4.orig/std/hl/Gc.hx0000664000175000017500000000747713166552354015522 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; enum GcFlag { /** Activate profiling: regularly print on stdout gc allocation stats **/ Profile; /** Allows to dump a hlmemory.dump file when HL runs out of memory to be examined with hl memory inspector tool. **/ DumpMem; /** Enable block tracking (see Gc.track API) **/ Track; } class Gc { public static var flags(get,set) : haxe.EnumFlags; public static function stats() { var tot = 0., count = 0., mem = 0.; _stats(tot, count, mem); return { totalAllocated : tot, allocationCount : count, currentMemory : mem }; } /** Start tracking an object field change. The check will be performed every allocation and the callback function triggered everytime a change has been performed since last check. The callback parameter is true if the object was collected. It is necessary to enable the Track flag in Gc.flags **/ public static function track( obj : Dynamic, field : String, callb : Dynamic -> Bytes -> Void ) { var oval = if( Reflect.isFunction(obj) ) Api.getClosureValue(obj) else obj; var fid = if( ~/^[0-9]+$/.match(field) ) Std.parseInt(field) else @:privateAccess field.bytes.hash(); if( !_track(oval, fid, callb) ) throw "Could not track "+obj+"."+field; } public static function untrack( obj : Dynamic ) { var oval = if( Reflect.isFunction(obj) ) Api.getClosureValue(obj) else obj; return _untrack(oval); } @:hlNative("std", "gc_untrack_all") public static function untrackAll() : Void { } @:hlNative("std", "gc_track_count") public static function trackCount() : Int { return 0; } /** Dump whole memory into target filename for analysis. **/ public static function dumpMemory( ?fileName : String = "hlmemory.dump" ) { _dump(@:privateAccess fileName.toUtf8()); } static function get_flags() : haxe.EnumFlags { return haxe.EnumFlags.ofInt(_get_flags()); } static function set_flags(v : haxe.EnumFlags) { _set_flags(v.toInt()); return v; } @:hlNative("std", "gc_dump_memory") static function _dump( b : hl.Bytes ) : Void {} @:hlNative("std", "gc_enable") public static function enable( b : Bool ) : Void {} @:hlNative("std", "gc_major") public static function major() : Void {} @:hlNative("std", "gc_stats") static function _stats( totalAllocated : hl.Ref, allocationCount : hl.Ref, currentMemory : hl.Ref ) : Void {} @:hlNative("std", "gc_track") static function _track( obj : Dynamic, fid : Int, callb : Dynamic -> Bytes -> Void ) : Bool { return false; } @:hlNative("std", "gc_untrack") static function _untrack( obj : Dynamic ) : Bool { return false; } @:hlNative("std", "gc_get_flags") static function _get_flags() : Int { return 0; } @:hlNative("std", "gc_set_flags") static function _set_flags( v : Int ) {} } haxe_3.4.4.orig/std/hl/NativeArray.hx0000664000175000017500000000440713166552354017404 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; @:generic class NativeArrayIterator { var arr : NativeArray; var pos : Int; var length : Int; public inline function new(arr:NativeArray) { this.arr = arr; pos = 0; length = arr.length; } public inline function hasNext() { return pos < length; } public inline function next() { return arr[pos++]; } } @:coreType abstract NativeArray { public var length(get,never):Int; @:extern public inline function new( length : Int ) { this = untyped $aalloc(length); } @:extern inline function get_length() : Int { return untyped $asize(this); } @:extern @:arrayAccess inline function get( pos : Int ) : T { return untyped ($aget(this,pos):T); } @:extern @:arrayAccess inline function set( pos : Int, value : T ) : T { untyped $aset(this,pos,value); return value; } @:extern public inline function sub( pos : Int, len : Int ) { var n = new NativeArray(len); n.blit(0, this, pos, len); return n; } @:hlNative("std","array_type") public function getType() : Type { return null; } @:hlNative("std","array_blit") public function blit( pos : Int, src : NativeArray, srcPos : Int, srcLen : Int ) : Void { } }haxe_3.4.4.orig/std/hl/Ref.hx0000664000175000017500000000274613166552354015677 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; @:coreType abstract Ref { @:extern @:from public static inline function make( v : T ) { return new Ref(v); } @:extern public inline function new( v : T ) { this = untyped $ref(v); } @:extern public inline function get() : T { return untyped $unref(this); } @:extern public inline function set( v : T ) : Void { return untyped $setref(this,v); } }haxe_3.4.4.orig/std/hl/Type.hx0000664000175000017500000000630213166552354016074 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; @:enum abstract TypeKind(Int) { public var HVoid = 0; public var HUI8 = 1; public var HUI16 = 2; public var HI32 = 3; public var HF32 = 4; public var HF64 = 5; public var HBool = 6; public var HBytes = 7; public var HDyn = 8; public var HFun = 9; public var HObj = 10; public var HArray = 11; public var HType = 12; public var HRef = 13; public var HVirtual = 14; public var HDynObj = 15; public var HAbstract = 16; public var HEnum = 17; public var HNull = 18; } @:coreType abstract Type { public var kind(get,never) : TypeKind; @:extern inline function get_kind() : TypeKind { return untyped $tkind(this); } @:hlNative("std","type_name") function getNameBytes() : Bytes { return null; } @:extern public static inline function getDynamic( v : Dynamic ) : Type { return untyped $tdyntype(v); } @:extern public static inline function get( v : T ) : Type { return untyped $ttype(v); } @:extern public inline function getName() : String { var s = getNameBytes(); return @:privateAccess String.fromUCS2(s); } @:hlNative("std", "type_safe_cast") public function safeCast( t : Type ) : Bool { return false; } @:hlNative("std","type_instance_fields") public function getInstanceFields() : NativeArray { return null; } @:hlNative("std","type_get_global") public function getGlobal() : Dynamic { return null; } @:hlNative("std","type_set_global") public function setGlobal( v : Dynamic ) : Bool { return false; } @:hlNative("std","type_args_count") public function getArgsCount() : Int { return 0; } @:hlNative("std","type_super") public function getSuper() : Type { return null; } @:hlNative("std","type_enum_fields") public function getEnumFields() : NativeArray { return null; } @:hlNative("std","type_enum_values") public function getEnumValues() : NativeArray { return null; } @:hlNative("std","alloc_obj") public function allocObject() : Dynamic { return null; } @:hlNative("std", "alloc_enum") public function allocEnum( index : Int, args : NativeArray, nargs : Int ) : Dynamic { return null; } }haxe_3.4.4.orig/std/hl/UI.hx0000664000175000017500000001031213166552354015464 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; typedef SentinelHandle = hl.Abstract<"ui_sentinel">; abstract Sentinel(SentinelHandle) { public function new( timeout, callback ) { this = create_sentinel(timeout,callback); } public function setPause( p : Bool ) { _pause(this, p); } public function tick() { _tick(this); } @:hlNative("ui", "ui_start_sentinel") static function create_sentinel( timeout : Float, callb : Void -> Void ) : SentinelHandle { return null; } @:hlNative("ui","ui_sentinel_tick") static function _tick( h : SentinelHandle ) : Void {} @:hlNative("ui","ui_sentinel_pause") static function _pause( h : SentinelHandle, b : Bool ) : Void {} } typedef WinHandle = hl.Abstract<"ui_window">; class Window { var h : WinHandle; public function setText( text : String ) { win_set_text(h, @:privateAccess text.bytes); } public function setEnable( b : Bool ) { win_set_enable(h, b); } public function destroy() { win_destroy(h); } @:hlNative("ui","ui_win_destroy") static function win_destroy( win : WinHandle ) : Void { } @:hlNative("ui","ui_win_set_text") static function win_set_text( win : WinHandle, text : hl.Bytes ) : Void { } @:hlNative("ui","ui_win_set_enable") static function win_set_enable( win : WinHandle, enable : Bool ) : Void { } } class Button extends Window { public function new( parent : Window, text : String ) { h = button_new(parent.h, @:privateAccess text.bytes, function() this.onClick()); } public dynamic function onClick() { } @:hlNative("ui", "ui_button_new") static function button_new( parent : WinHandle, text : hl.Bytes, onClick : Void -> Void ) : WinHandle { return null; } } class WinLog extends Window { public function new( title : String, width, height ) { h = winlog_new(@:privateAccess title.bytes,width, height); } public function setTextContent( text : String, autoScroll = false ) { winlog_set_text(h, @:privateAccess text.bytes,autoScroll); } @:hlNative("ui","ui_winlog_new") static function winlog_new( text : hl.Bytes, width : Int, height : Int ) : WinHandle { return null; } @:hlNative("ui","ui_winlog_set_text") static function winlog_set_text( win : WinHandle, text : hl.Bytes, autoScroll : Bool ) : Void { } } enum DialogFlags { YesNo; IsError; } @:enum abstract LoopResult(Int) { var NoMessage = 0; var HandledMessage = 1; var Quit = 2; } /** These are the bindings for the HL `ui.hdll` library, which contains some low level system access. **/ class UI { @:hlNative("ui","ui_init") static function init() {} static function __init__() { init(); } @:hlNative("ui","ui_dialog") static function _dialog( title : hl.Bytes, text : hl.Bytes, flags : Int ) : Int { return 0; } public static function dialog( title : String, text : String, flags : haxe.EnumFlags ) { @:privateAccess _dialog(title.bytes,text.bytes,flags.toInt()); } @:hlNative("ui","ui_loop") public static function loop( blocking : Bool ) : LoopResult { return Quit; } @:hlNative("ui","ui_stop_loop") public static function stopLoop() : Void { } @:hlNative("ui","ui_close_console") public static function closeConsole() : Void { } }haxe_3.4.4.orig/std/hl/UI16.hx0000664000175000017500000000226613166552354015644 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; @:coreType @:notNull @:runtimeValue abstract UI16 to Int from Int {} haxe_3.4.4.orig/std/hl/UI8.hx0000664000175000017500000000226513166552354015564 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl; @:coreType @:notNull @:runtimeValue abstract UI8 to Int from Int {} haxe_3.4.4.orig/std/hl/_std/Date.hx0000664000175000017500000000724213166552354016765 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import hl.Ref; @:coreApi @:final class Date { private var t : Int; public function new(year : Int, month : Int, day : Int, hour : Int, min : Int, sec : Int ) : Void { t = date_new(year, month, day, hour, min, sec); } public function getTime() : Float { return date_get_time(t); } public function getFullYear() : Int { var v = 0; date_get_inf(t, v, null, null, null, null, null, null); return v; } public function getMonth() : Int { var v = 0; date_get_inf(t, null, v, null, null, null, null, null); return v; } public function getDate() : Int { var v = 0; date_get_inf(t, null, null, v, null, null, null, null); return v; } public function getHours() : Int { var v = 0; date_get_inf(t, null, null, null, v, null, null, null); return v; } public function getMinutes() : Int { var v = 0; date_get_inf(t, null, null, null, null, v, null, null); return v; } public function getSeconds() : Int { var v = 0; date_get_inf(t, null, null, null, null, null, v, null); return v; } public function getDay() : Int { var v = 0; date_get_inf(t, null, null, null, null, null, null, v); return v; } @:keep public function toString():String { var outLen = 0; var bytes = date_to_string(t, outLen); return @:privateAccess String.__alloc__(bytes,outLen); } public static function now() : Date { var d : Date = untyped $new(Date); d.t = date_now(); return d; } static function fromInt( t : Int ) : Date { var d : Date = untyped $new(Date); d.t = t; return d; } public static function fromTime( t : Float ) : Date { var d : Date = untyped $new(Date); d.t = date_from_time(t); return d; } public static function fromString( s : String ) : Date { var d : Date = untyped $new(Date); d.t = date_from_string(@:privateAccess s.bytes, s.length<<1); return d; } @:hlNative static function date_new( year : Int, month : Int, day : Int, hours : Int, minutes : Int, seconds : Int ) : Int { return 0; } @:hlNative static function date_now() : Int { return 0; } @:hlNative static function date_from_time( t : Float ) : Int { return 0; } @:hlNative static function date_from_string( b : hl.Bytes, len : Int ) : Int { return 0; } @:hlNative static function date_get_time( t : Int ) : Float { return 0.; } @:hlNative static function date_get_inf( t : Int, year : Ref, month : Ref, day : Ref, hours : Ref, minutes : Ref, seconds : Ref, wday : Ref ) : Void { } @:hlNative static function date_to_string( t : Int, outLen : Ref ) : hl.Bytes { return null; } } haxe_3.4.4.orig/std/hl/_std/EReg.hx0000664000175000017500000001200613166552354016724 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ private typedef ERegValue = hl.Abstract<"ereg">; @:access(String) @:coreApi @:final class EReg { var r : ERegValue; var last : String; var global : Bool; public function new( r : String, opt : String ) : Void { var a = opt.split("g"); global = a.length > 1; if( global ) opt = a.join(""); this.r = regexp_new_options(r.bytes, opt.bytes); } public function match( s : String ) : Bool { var p = regexp_match(r,s.bytes,0,s.length); if( p ) last = s; else last = null; return p; } public function matched( n : Int ) : String { var len = 0; var m = regexp_matched_pos(r,n,len); return m < 0 ? null : last.substr(m, len); } public function matchedLeft() : String { var p = regexp_matched_pos(r,0,null); return last.substr(0,p); } public function matchedRight() : String { var len = 0; var p = regexp_matched_pos(r,0,len); return last.substr(p + len); } public function matchedPos() : { pos : Int, len : Int } { var len = 0; var p = regexp_matched_pos(r, 0, len); if( p < 0 ) return null; return { pos : p, len : len }; } public function matchSub( s : String, pos : Int, len : Int = -1):Bool { var p = regexp_match(r, s.bytes, pos, len < 0 ? s.length - pos : len); if( p ) last = s; else last = null; return p; } public function split( s : String ) : Array { var pos = 0; var len = s.length; var a = new Array(); var first = true; do { if( !regexp_match(r,s.bytes,pos,len) ) break; var plen = 0; var p = regexp_matched_pos(r,0,plen); if( plen == 0 && !first ) { if( p == s.length ) break; p++; } a.push(s.substr(pos,p - pos)); var tot = p + plen - pos; pos += tot; len -= tot; first = false; } while( global ); a.push(s.substr(pos,len)); return a; } public function replace( s : String, by : String ) : String { var b = new StringBuf(); var pos = 0; var len = s.length; var a = by.split("$"); var first = true; do { if( !regexp_match(r,s.bytes,pos,len) ) break; var plen = 0; var p = regexp_matched_pos(r,0, plen); if( plen == 0 && !first ) { if( p == s.length ) break; p++; } b.addSub(s,pos,p-pos); if( a.length > 0 ) b.add(a[0]); var i = 1; while( i < a.length ) { var k = a[i]; var c = StringTools.fastCodeAt(k, 0); // 1...9 if( c >= 49 && c <= 57 ) { var plen = 0; var p = try regexp_matched_pos(r,Std.int(c)-48,plen) catch( e : String ) -1; if( p < 0 ){ b.add("$"); b.add(k); } else { if( p >= 0 ) b.addSub(s,p,plen); b.addSub(k,1,k.length - 1); } } else if( c == 0 ) { b.add("$"); i++; var k2 = a[i]; if( k2 != null && k2.length > 0 ) b.add(k2); } else b.add("$"+k); i++; } var tot = p + plen - pos; pos += tot; len -= tot; first = false; } while( global ); b.addSub(s,pos,len); return b.toString(); } public function map( s : String, f : EReg -> String ) : String { var offset = 0; var buf = new StringBuf(); do { if (offset >= s.length) break; else if (!matchSub(s, offset)) { buf.add(s.substr(offset)); break; } var plen = 0; var p = regexp_matched_pos(r,0,plen); buf.add(s.substr(offset, p - offset)); buf.add(f(this)); if (plen == 0) { buf.add(s.substr(p, 1)); offset = p + 1; } else offset = p + plen; } while (global); if (!global && offset > 0 && offset < s.length) buf.add(s.substr(offset)); return buf.toString(); } @:hlNative("std", "regexp_new_options") static function regexp_new_options( bytes : hl.Bytes, options : hl.Bytes ) : ERegValue { return null; } @:hlNative("std", "regexp_match") static function regexp_match( r : ERegValue, str : hl.Bytes, pos : Int, size : Int ) : Bool { return false; } @:hlNative("std", "regexp_matched_pos") static function regexp_matched_pos( r : ERegValue, n : Int, size : hl.Ref ) : Int { return 0; } } haxe_3.4.4.orig/std/hl/_std/Math.hx0000664000175000017500000000720413166552354016777 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi class Math { @:hlNative("std","math_sqrt") public static function sqrt( v : Float ) : Float return 0.; @:hlNative("std","math_abs") public static function abs( v : Float ) : Float return 0.; @:hlNative("std","math_floor") public static function floor( v : Float ) : Int return 0; @:hlNative("std","math_round") public static function round( v : Float ) : Int return 0; @:hlNative("std","math_ceil") public static function ceil( v : Float ) : Int return 0; @:hlNative("std","math_isfinite") public static function isFinite( f : Float ) : Bool return true; @:hlNative("std","math_isnan") public static function isNaN( f : Float ) : Bool return false; @:hlNative("std","math_ffloor") public static function ffloor( v : Float ) : Float return 0.; @:hlNative("std","math_fround") public static function fround( v : Float ) : Float return 0.; @:hlNative("std","math_fceil") public static function fceil( v : Float ) : Float return 0.; @:hlNative("std","math_cos") public static function cos( v : Float ) : Float return 0.; @:hlNative("std","math_sin") public static function sin( v : Float ) : Float return 0.; @:hlNative("std","math_exp") public static function exp( v : Float ) : Float return 0.; @:hlNative("std","math_log") public static function log( v : Float ) : Float return 0.; @:hlNative("std","math_tan") public static function tan( v : Float ) : Float return 0.; @:hlNative("std","math_atan") public static function atan( v : Float ) : Float return 0.; @:hlNative("std","math_acos") public static function acos( v : Float ) : Float return 0.; @:hlNative("std","math_asin") public static function asin( v : Float ) : Float return 0.; @:hlNative("std","math_pow") public static function pow( v : Float, exp : Float ) : Float return 0.; @:hlNative("std","math_atan2") public static function atan2( y : Float, x : Float ) : Float return 0.; public static function random() : Float return @:privateAccess Std.rnd_float(Std.rnd); public static function min( a : Float, b : Float ) : Float return a < b || isNaN(a) ? a : b; public static function max( a : Float, b : Float ) : Float return a < b || isNaN(b) ? b : a; public static var PI(default,null) : Float; public static var NaN(default,null) : Float; public static var POSITIVE_INFINITY(default,null) : Float; public static var NEGATIVE_INFINITY(default,null) : Float; static function __init__() : Void { PI = 3.1415926535897932384626433832795; NaN = 0. / 0.; POSITIVE_INFINITY = 1. / 0.; NEGATIVE_INFINITY = -1. / 0.; } }haxe_3.4.4.orig/std/hl/_std/Reflect.hx0000664000175000017500000001113313166552354017466 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi class Reflect { public static function hasField( o : Dynamic, field : String ) : Bool { if( field == null ) return false; var hash = @:privateAccess field.bytes.hash(); return hl.Api.hasField(o,hash); } public static function field( o : Dynamic, field : String ) : Dynamic { if( field == null ) return null; var hash = @:privateAccess field.bytes.hash(); return hl.Api.getField(o,hash); } public static function setField( o : Dynamic, field : String, value : Dynamic ) : Void { var hash = @:privateAccess field.bytes.hash(); hl.Api.setField(o,hash,value); } public static function getProperty( o : Dynamic, field : String ) : Dynamic { var f : Dynamic = Reflect.field(o, "get_" + field); if( f != null ) return f(); return Reflect.field(o,field); } public static function setProperty( o : Dynamic, field : String, value : Dynamic ) : Void { var f : Dynamic = Reflect.field(o, "set_" + field); if( f != null ) f(value); else setField(o, field, value); } public static function callMethod( o : Dynamic, func : haxe.Constraints.Function, args : Array ) : Dynamic { var args : hl.types.ArrayDyn = cast args; var count = args.length; var ft = hl.Type.getDynamic(func); if( ft.kind != HFun ) throw "Invalid function " + func; var need = ft.getArgsCount(); var cval = hl.Api.getClosureValue(func); var isClosure = cval != null && need >= 0; if( o == null ) o = cval; else if( !isClosure && count == need ) o = null; var nargs = o == null ? count : count + 1; if( isClosure ) need++; if( nargs < need ) nargs = need; var a = new hl.NativeArray(nargs); if( o == null || need < 0 ) { for( i in 0...count ) a[i] = args.getDyn(i); } else { func = hl.Api.noClosure(func); a[0] = o; for( i in 0...count ) a[i+1] = args.getDyn(i); } return hl.Api.callMethod(func,a); } @:hlNative("std","obj_fields") static function getObjectFields( v : Dynamic ) : hl.NativeArray { return null; } public static function fields( o : Dynamic ) : Array { var fields = getObjectFields(o); if( fields == null ) return []; return [for( f in fields ) @:privateAccess String.fromUCS2(f)]; } public static inline function isFunction( f : Dynamic ) : Bool { return hl.Type.getDynamic(f).kind == HFun; } @:hlNative("std","dyn_compare") public static function compare( a : T, b : T ) : Int { return 0; } @:hlNative("std","fun_compare") public static function compareMethods( f1 : Dynamic, f2 : Dynamic ) : Bool { return false; } public static function isObject( v : Dynamic ) : Bool { var t = hl.Type.getDynamic(v); return switch( t.kind ) { case HObj, HDynObj, HVirtual: true; default: false; } } public static function isEnumValue( v : Dynamic ) : Bool { var t = hl.Type.getDynamic(v); return t.kind == HEnum; } public static function deleteField( o : Dynamic, field : String ) : Bool { return hl.Api.deleteField(o,@:privateAccess field.bytes.hash()); } @:hlNative("std","obj_copy") public static function copy( o : T ) : T { return null; } @:overload(function( f : Array -> Void ) : Dynamic {}) @:extern public inline static function makeVarArgs( f : Array -> Dynamic ) : Dynamic { return _makeVarArgs(f); } static function _makeVarArgs( f : Array -> Dynamic ) : Dynamic { return hl.Api.makeVarArgs(function(args:hl.NativeArray) { var arr = hl.types.ArrayDyn.alloc(hl.types.ArrayObj.alloc(args), true); return f(cast arr); }); } } haxe_3.4.4.orig/std/hl/_std/Std.hx0000664000175000017500000000706413166552354016644 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import hl.Boot; private typedef Rand = hl.Abstract<"hl_random">; @:coreApi class Std { static var rnd : Rand; static function __init__() : Void { rnd = rnd_sys(); } @:hlNative("std","rnd_init_system") static function rnd_sys() : Rand { return null; } @:hlNative("std","rnd_int") static function rnd_int( r : Rand ) : Int { return 0; } @:hlNative("std","rnd_float") static function rnd_float( r : Rand ) : Float { return 0.; } public static function random( x : Int ) : Int { return x <= 0 ? 0 : (rnd_int(rnd) & 0x3FFFFFFF) % x; } public static function is( v : Dynamic, t : Dynamic ) : Bool { var t : hl.BaseType = t; if( t == null ) return false; switch( t.__type__.kind ) { case HDyn: return true; case HF64: switch( hl.Type.getDynamic(v).kind ) { case HUI8, HUI16, HI32: return true; default: } case HI32: switch( hl.Type.getDynamic(v).kind ) { case HF32, HF64: var v : Float = v; return Std.int(v) == v; default: } default: } return t.check(v); } @:extern public inline static function instance( value : T, c : Class ) : S { var t : hl.BaseType = cast c; return t.check(value) ? cast value : null; } @:extern public static inline function int( x : Float ) : Int { return untyped $int(x); } @:keep public static function string( s : Dynamic ) : String { var len = 0; var bytes = hl.Bytes.fromValue(s,new hl.Ref(len)); return @:privateAccess String.__alloc__(bytes,len); } public static function parseInt( x : String ) : Null { if( x == null ) return null; return @:privateAccess x.bytes.parseInt(0, x.length<<1); } public static function parseFloat( x : String ) : Float { if( x == null ) return Math.NaN; return @:privateAccess x.bytes.parseFloat(0, x.length<<1); } @:keep static function __add__( a : Dynamic, b : Dynamic ) : Dynamic { var ta = hl.Type.getDynamic(a); var tb = hl.Type.getDynamic(b); if( ta == hl.Type.get("") ) return (a : String) + b; if( tb == hl.Type.get("") ) return a + (b : String); switch(ta.kind) { case HUI8, HUI16, HI32: var a : Int = a; switch( tb.kind ) { case HUI8, HUI16, HI32: return a + (b:Int); case HF32, HF64: return a + (b:Float); default: } case HF32, HF64: var a : Float = a; switch( tb.kind ) { case HUI8, HUI16, HI32: return a + (b:Int); case HF32, HF64: return a + (b:Float); default: } default: } throw "Can't add "+a+"("+ta+") and "+b+"("+tb+")"; return null; } } haxe_3.4.4.orig/std/hl/_std/String.hx0000664000175000017500000001415313166552354017355 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi class String { var bytes : hl.Bytes; public var length(default,null) : Int; public function new(string:String) : Void { bytes = string.bytes; length = string.length; } public function toUpperCase() : String { return __alloc__(@:privateAccess bytes.ucs2Upper(0,length), length); } public function toLowerCase() : String { return __alloc__(@:privateAccess bytes.ucs2Lower(0,length), length); } public function charAt(index : Int) : String { if( (index:UInt) >= (length:UInt) ) return ""; var b = new hl.Bytes(4); b.setUI16(0, bytes.getUI16(index<<1)); b.setUI16(2,0); return __alloc__(b,1); } public function charCodeAt( index : Int) : Null { var idx : UInt = index; if( idx >= (length:UInt) ) return null; return bytes.getUI16(index << 1); } public function indexOf( str : String, ?startIndex : Int ) : Int { var startByte = 0; if( startIndex != null && startIndex > 0 ) { if( startIndex >= length ) return -1; startByte = startIndex << 1; } var p = bytes.find(startByte, (length << 1) - startByte, str.bytes, 0, str.length << 1); if( p > 0 ) p >>= 1; return p; } public function lastIndexOf( str : String, ?startIndex : Int ) : Int { var last = 0; var start = this.length; if( startIndex != null ) start = startIndex; start <<= 1; while( true ) { var p = bytes.find(last, (length << 1) - last, str.bytes, 0, str.length << 1); if( p < 0 || p > start ) return (last >> 1) - 1; last = p + 2; } return -1; } public function split( delimiter : String ) : Array { var out = []; if( length == 0 ) { out.push(""); return out; } if( delimiter.length == 0 ) { for( i in 0...length ) out.push(substr(i,1)); return out; } var pos = 0; var dlen = delimiter.length; while( true ) { var p = bytes.find(pos << 1, (length - pos) << 1, delimiter.bytes, 0, dlen << 1); if( p < 0 ) { out.push(substr(pos, length-pos)); break; } p >>= 1; out.push(substr(pos, p - pos)); pos = p + dlen; } return out; } public function substr( pos : Int, ?len : Int ) : String @:privateAccess { var sl = length; var len : Int = if( len == null ) sl else len; if( len == 0 ) return ""; if( pos != 0 && len < 0 ) return ""; if( pos < 0 ) { pos = sl + pos; if( pos < 0 ) pos = 0; } else if( len < 0 ) { len = sl + len - pos; if( len < 0 ) return ""; } if( ((pos + len) : UInt) > (sl:UInt) ) len = sl - pos; if( pos < 0 || len <= 0 ) return ""; var b = new hl.Bytes((len + 1) << 1); b.blit(0, bytes, pos<<1, len << 1); b.setUI16(len<<1,0); return __alloc__(b, len); } public function substring( startIndex : Int, ?endIndex : Int ) : String { var end : Int; if( endIndex == null ) end = length; else { end = endIndex; if( end < 0 ) end = 0; else if ( end > length ) end = length; } if( startIndex < 0 ) startIndex = 0; else if ( startIndex > length ) startIndex = length; if( startIndex > end ) { var tmp = startIndex; startIndex = end; end = tmp; } return substr( startIndex, end - startIndex ); } public function toString() : String { return this; } public static function fromCharCode( code : Int ) : String { if( code >= 0 && code < 0x10000 ) { if( code >= 0xD800 && code <= 0xDFFF ) throw "Invalid unicode char " + code; var b = new hl.Bytes(4); b.setUI16(0, code); b.setUI16(2, 0); return __alloc__(b, 1); } else if( code < 0x110000 ) { var b = new hl.Bytes(6); code -= 0x10000; b.setUI16(0, (code >> 10) + 0xD800); b.setUI16(2, (code & 1023) + 0xDC00); b.setUI16(4, 0); return __alloc__(b, 2); // UTF16 encoding but UCS2 API (same as JS) } else throw "Invalid unicode char " + code; } function toUtf8() : hl.Bytes { return bytes.utf16ToUtf8(0, null); } @:keep function __string() : hl.Bytes { return bytes; } @:keep function __compare( s : String ) : Int { var v = bytes.compare(0, s.bytes, 0, (length < s.length ? length : s.length) << 1); return v == 0 ? length - s.length : v; } @:keep static inline function __alloc__( b : hl.Bytes, length : Int ) : String { var s : String = untyped $new(String); s.bytes = b; s.length = length; return s; } @:keep static function call_toString( v : Dynamic ) : hl.Bytes { var s : String = v.toString(); return s.bytes; } inline static function fromUCS2( b : hl.Bytes ) : String { var s : String = untyped $new(String); s.bytes = b; s.length = @:privateAccess b.ucs2Length(0); return s; } @:keep static function fromUTF8( b : hl.Bytes ) : String { var outLen = 0; var b2 = @:privateAccess b.utf8ToUtf16(0, outLen); return __alloc__(b2, outLen>>1); } @:keep static function __add__( a : String, b : String ) : String { if( a == null ) a = "null"; if( b == null ) b = "null"; var asize = a.length << 1, bsize = b.length << 1, tot = asize + bsize; var bytes = new hl.Bytes(tot+2); bytes.blit(0, a.bytes, 0, asize); bytes.blit(asize,b.bytes,0,bsize); bytes.setUI16(tot, 0); return __alloc__(bytes, tot>>1); } } haxe_3.4.4.orig/std/hl/_std/StringBuf.hx0000664000175000017500000000554413166552354020016 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi class StringBuf { var b : hl.Bytes; var size : Int; var pos : Int; public var length(get,never) : Int; public function new() : Void { pos = 0; size = 8; // ensure 4 bytes expand for addChar() b = new hl.Bytes(size); } inline function get_length() : Int { return pos >> 1; } inline function __expand( need : Int ) : Void { var nsize = (size * 3) >> 1; if( need > nsize ) nsize = need; var b2 = new hl.Bytes(nsize); b2.blit(0, b, 0, pos); b = b2; size = nsize; } inline function __add( bytes : hl.Bytes, spos : Int, ssize : Int ) : Void { if( pos + ssize > size ) __expand(pos + ssize); b.blit(pos, bytes, spos, ssize); pos += ssize; } public function add( x : T ) : Void { var slen = 0; var sbytes = hl.Bytes.fromValue(x, new hl.Ref(slen)); __add(sbytes, 0, slen<<1); } public function addSub( s : String, pos : Int, ?len : Int ) : Void @:privateAccess { if( pos < 0 ) pos = 0; if( pos >= s.length ) return; var slen : Int; if( len == null ) slen = s.length - pos else { slen = len; if( pos + slen > s.length ) slen = s.length - pos; if( slen <= 0 ) return; } __add(s.bytes, pos << 1, slen << 1); } public function addChar( c : Int ) : Void { if( c >= 0 && c < 0x10000 ) { if( c >= 0xD800 && c <= 0xDFFF ) throw "Invalid unicode char " + c; if( pos + 2 > size ) __expand(0); b.setUI16(pos, c); pos += 2; } else if( c < 0x110000 ) { if( pos + 4 > size ) __expand(0); c -= 0x10000; b.setUI16(pos, (c >> 10) + 0xD800); b.setUI16(pos + 2, (c & 1023) + 0xDC00); pos += 4; } else throw "Invalid unicode char " + c; } public function toString() : String { if( pos+2 > size ) __expand(0); b.setUI16(pos,0); return @:privateAccess String.__alloc__(b, pos>>1); } } haxe_3.4.4.orig/std/hl/_std/Sys.hx0000664000175000017500000001430313166552354016662 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ class SysError { public var msg : String; public function new(msg) { this.msg = msg; } @:keep public function toString() { return "SysError("+msg+")"; } } @:coreApi @:keepInit @:access(String) class Sys { static var utf8Path : Bool; static function __init__() : Void { utf8Path = sys_utf8_path(); } static function getPath( s : String ) : hl.Bytes { return utf8Path ? s.bytes.utf16ToUtf8(0, null) : s.bytes; } static function makePath( b : hl.Bytes ) : String { if( b == null ) return null; return utf8Path ? String.fromUTF8(b) : String.fromUCS2(b); } public static function print( v : Dynamic ) : Void { sys_print(Std.string(v).bytes); } public static function println( v : Dynamic ) : Void { sys_print(Std.string(v).bytes); sys_print("\n".bytes); } public static function args() : Array { return [for( a in sys_args() ) makePath(a)]; } public static function stdin() : haxe.io.Input { return @:privateAccess new sys.io.FileInput(file_stdin()); } public static function stdout() : haxe.io.Output { return @:privateAccess new sys.io.FileOutput(file_stdout()); } public static function stderr() : haxe.io.Output { return @:privateAccess new sys.io.FileOutput(file_stderr()); } public static function getEnv( s : String ) : String { var v = get_env(getPath(s)); if( v == null ) return null; return makePath(v); } public static function putEnv( s : String, v : String ) : Void { if( !put_env(getPath(s), if( v == null ) null else getPath(v)) ) throw "putEnv() failure"; } public static function environment() : Map { var env = sys_env(); var h = new haxe.ds.StringMap(); for( i in 0...env.length >> 1 ) { var p = i << 1; h.set(makePath(env[p]), makePath(env[p + 1])); } return h; } @:hlNative("std","sys_sleep") public static function sleep( seconds : Float ) : Void { } public static function setTimeLocale( loc : String ) : Bool { return set_time_locale(loc.bytes.utf16ToUtf8(0,null)); } public static function getCwd() : String { return makePath(get_cwd()); } public static function setCwd( s : String ) : Void { if( !set_cwd(getPath(s)) ) throw new SysError("Failed to set path to " + s); } public static function systemName() : String { return String.fromUCS2(sys_string()); } public static function command( cmd : String, ?args : Array ) : Int { var code = 0; if (args == null) { code = sys_command(getPath(cmd)); } else { switch (systemName()) { case "Windows": cmd = [ for (a in [StringTools.replace(cmd, "/", "\\")].concat(args)) StringTools.quoteWinArg(a, true) ].join(" "); code = sys_command(getPath(cmd)); case _: cmd = [cmd].concat(args).map(StringTools.quoteUnixArg).join(" "); code = sys_command(getPath(cmd)); } } return code; } @:deprecated("Use programPath instead") public static function executablePath() : String { return makePath(sys_exe_path()); } public static function programPath() : String { return sys_program_path; } private static var sys_program_path = { var hlFile = sys_hl_file(); if( hlFile == null ) makePath( sys_exe_path() ); else sys.FileSystem.fullPath( makePath(hlFile) ); } @:hlNative("std", "sys_utf8_path") static function sys_utf8_path() : Bool { return false; } @:hlNative("std","sys_time") public static function time() : Float { return 0.; }; @:hlNative("std","sys_exit") public static function exit( code : Int ) : Void {}; @:hlNative("std", "sys_cpu_time") public static function cpuTime() : Float { return 0.; }; @:hlNative("std", "sys_get_char") public static function getChar( echo : Bool ) : Int { return 0; } @:hlNative("std","sys_print") static function sys_print( v : hl.Bytes ) : Void {}; @:hlNative("std", "file_stdin") static function file_stdin() : sys.io.File.FileHandle { return null; } @:hlNative("std", "file_stdout") static function file_stdout() : sys.io.File.FileHandle { return null; } @:hlNative("std", "file_stderr") static function file_stderr() : sys.io.File.FileHandle { return null; } @:hlNative("std", "sys_args") static function sys_args() : hl.NativeArray { return null; } @:hlNative("std", "sys_get_env") static function get_env( key : hl.Bytes ) : hl.Bytes { return null; } @:hlNative("std", "sys_put_env") static function put_env( key : hl.Bytes, val : hl.Bytes ) : Bool { return false; } @:hlNative("std", "sys_env") static function sys_env() : hl.NativeArray { return null; } @:hlNative("std", "sys_set_time_locale") static function set_time_locale( loc : hl.Bytes ) : Bool { return true; } @:hlNative("std", "sys_get_cwd") static function get_cwd() : hl.Bytes { return null; } @:hlNative("std", "sys_set_cwd") static function set_cwd( path : hl.Bytes ) : Bool { return true; } @:hlNative("std", "sys_command") static function sys_command( cmd : hl.Bytes ) : Int { return 0; } @:hlNative("std", "sys_exe_path") static function sys_exe_path() : hl.Bytes { return null; } @:hlNative("std", "sys_hl_file") static function sys_hl_file() : hl.Bytes { return null; } @:hlNative("std", "sys_string") static function sys_string() : hl.Bytes { return null; } }haxe_3.4.4.orig/std/hl/_std/Type.hx0000664000175000017500000001757113166552354017037 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ enum ValueType { TNull; TInt; TFloat; TBool; TObject; TFunction; TClass( c : Class ); TEnum( e : Enum ); TUnknown; } @:coreApi class Type { static var allTypes(get,never) : hl.types.BytesMap; static inline function get_allTypes() : hl.types.BytesMap return untyped $allTypes(); @:keep static function init() : Void { untyped $allTypes(new hl.types.BytesMap()); } @:keep static function initClass( ct : hl.Type, t : hl.Type, name : hl.Bytes ) : hl.BaseType.Class @:privateAccess { var c : hl.BaseType.Class = ct.allocObject(); t.setGlobal(c); c.__type__ = t; c.__name__ = String.fromUCS2(name); register(name, c); return c; } @:keep static function initEnum( et : hl.Type, t : hl.Type ) : hl.BaseType.Enum @:privateAccess { var e : hl.BaseType.Enum = et.allocObject(); e.__type__ = t; e.__evalues__ = t.getEnumValues(); e.__ename__ = t.getName(); e.__emap__ = new hl.types.BytesMap(); e.__constructs__ = new Array(); var cl = t.getEnumFields(); for( i in 0...cl.length ) { var name = cl[i]; e.__emap__.set(name, i); e.__constructs__.push(String.fromUCS2(name)); } register(e.__ename__.bytes,e); t.setGlobal(e); return e; } @:keep static function register( b : hl.Bytes, t : hl.BaseType ) : Void { allTypes.set(b, t); } public static function getClass( o : T ) : Class { var t = hl.Type.getDynamic(o); if( t.kind == HObj ) return t.getGlobal(); return null; } public static function getEnum( o : EnumValue ) : Enum { var t = hl.Type.getDynamic(o); if( t.kind == HEnum ) return t.getGlobal(); return null; } public static function getSuperClass( c : Class ) : Class @:privateAccess { var c : hl.BaseType.Class = cast c; var t = c.__type__.getSuper(); return t == hl.Type.get((null : Void)) ? null : t.getGlobal(); } public static function getClassName( c : Class ) : String { var c : hl.BaseType.Class = cast c; return c.__name__; } public static function getEnumName( e : Enum ) : String { var e : hl.BaseType.Enum = cast e; return e.__ename__; } public static function resolveClass( name : String ) : Class { var t : hl.BaseType = allTypes.get(@:privateAccess name.bytes); if( t == null || !Std.is(t, hl.BaseType.Class) ) return null; return cast t; } public static function resolveEnum( name : String ) : Enum { var t : hl.BaseType = allTypes.get(@:privateAccess name.bytes); if( t == null || !Std.is(t, hl.BaseType.Enum) ) return null; return cast t; } public static function createInstance( cl : Class, args : Array ) : T { var c : hl.BaseType.Class = cast cl; var t = c.__type__; if( t == hl.Type.get((null : hl.types.ArrayBase.ArrayAccess)) ) return cast new Array(); var o = t.allocObject(); if( c.__constructor__ != null ) Reflect.callMethod(o, c.__constructor__, args); return o; } public static function createEmptyInstance( cl : Class ) : T { var c : hl.BaseType.Class = cast cl; return c.__type__.allocObject(); } public static function createEnum( e : Enum, constr : String, ?params : Array ) : T { var en : hl.BaseType.Enum = cast e; var idx : Null = en.__emap__.get(@:privateAccess constr.bytes); if( idx == null ) throw "Unknown enum constructor " + en.__ename__ +"." + constr; return createEnumIndex(e,idx,params); } public static function createEnumIndex( e : Enum, index : Int, ?params : Array ) : T { var e : hl.BaseType.Enum = cast e; if( index < 0 || index >= e.__constructs__.length ) throw "Invalid enum index " + e.__ename__ +"." + index; if( params == null || params.length == 0 ) { var v = index >= e.__evalues__.length ? null : e.__evalues__[index]; if( v == null ) throw "Constructor " + e.__ename__ +"." + e.__constructs__[index] + " takes parameters"; return v; } var a : hl.types.ArrayDyn = cast params; var narr; if( @:privateAccess !a.array.isArrayObj() ) { narr = new hl.NativeArray(a.length); for( i in 0...a.length ) narr[i] = @:privateAccess a.array.getDyn(i); } else { var aobj : hl.types.ArrayObj = cast @:privateAccess a.array; narr = @:privateAccess aobj.array; } var v = @:privateAccess e.__type__.allocEnum(index, narr, a.length); if( v == null ) throw "Constructor " + e.__ename__ +"." + e.__constructs__[index] + " does not takes " + narr.length + " parameters"; return v; } public static function getInstanceFields( c : Class ) : Array @:privateAccess { var c : hl.BaseType.Class = cast c; var fields = c.__type__.getInstanceFields(); return [for( f in fields ) String.fromUCS2(f)]; } public static function getClassFields( c : Class ) : Array { var c : hl.BaseType.Class = cast c; var fields = @:privateAccess Reflect.getObjectFields(c); var fields = [for( f in fields ) @:privateAccess String.fromUCS2(f)]; fields.remove("__constructor__"); fields.remove("__meta__"); fields.remove("__name__"); fields.remove("__type__"); fields.remove("__implementedBy__"); return fields; } public static function getEnumConstructs( e : Enum ) : Array { var e : hl.BaseType.Enum = cast e; return e.__constructs__.copy(); } public static function typeof( v : Dynamic ) : ValueType { var t = hl.Type.getDynamic(v); switch( t.kind ) { case HVoid: return TNull; case HUI8, HUI16, HI32: return TInt; case HF32, HF64: return TFloat; case HBool: return TBool; case HDynObj: return TObject; case HObj: var c : Dynamic = Type.getClass(v); if( c == Class || c == null ) return TObject; return TClass(c); case HEnum: return TEnum(Type.getEnum(v)); case HFun: return TFunction; case HVirtual: var v = hl.Api.getVirtualValue(v); if( v == null ) return TObject; return typeof(v); default: return TUnknown; } } @:hlNative("std","type_enum_eq") public static function enumEq( a : T, b : T ) : Bool { return false; } public static function enumConstructor( e : EnumValue ) : String { var en : hl.BaseType.Enum = cast getEnum(e); return en.__constructs__[Type.enumIndex(e)]; } @:hlNative("std","enum_parameters") static function _enumParameters( e : EnumValue ) : hl.NativeArray { return null; } public static function enumParameters( e : EnumValue ) : Array { var arr = _enumParameters(e); return cast hl.types.ArrayObj.alloc(arr); } @:extern public inline static function enumIndex( e : EnumValue ) : Int { return untyped $enumIndex(e); } public static function allEnums( e : Enum ) : Array { var en : hl.BaseType.Enum = cast e; var out = []; for( i in 0...en.__evalues__.length ) { var v = en.__evalues__[i]; if( v != null ) out.push(v); } return out; } }haxe_3.4.4.orig/std/hl/_std/UInt.hx0000664000175000017500000001264113166552354016766 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi abstract UInt(Int) from Int to Int { @:op(A + B) private static inline function add(a:UInt, b:UInt):UInt { return a.toInt() + b.toInt(); } @:op(A / B) private static inline function div(a:UInt, b:UInt):Float { return a.toFloat() / b.toFloat(); } @:op(A * B) private static inline function mul(a:UInt, b:UInt):UInt { return a.toInt() * b.toInt(); } @:op(A - B) private static inline function sub(a:UInt, b:UInt):UInt { return a.toInt() - b.toInt(); } @:op(A > B) private static function gt(a:UInt, b:UInt):Bool; @:op(A >= B) private static function gte(a:UInt, b:UInt):Bool; @:op(A < B) private static function lt(a:UInt, b:UInt):Bool; @:op(A <= B) private static function lte(a:UInt, b:UInt):Bool; @:op(A & B) private static inline function and(a:UInt, b:UInt):UInt { return a.toInt() & b.toInt(); } @:op(A | B) private static inline function or(a:UInt, b:UInt):UInt { return a.toInt() | b.toInt(); } @:op(A ^ B) private static inline function xor(a:UInt, b:UInt):UInt { return a.toInt() ^ b.toInt(); } @:op(A << B) private static inline function shl(a:UInt, b:Int):UInt { return a.toInt() << b; } @:op(A >> B) private static inline function shr(a:UInt, b:Int):UInt { return a.toInt() >>> b; } @:op(A >>> B) private static inline function ushr(a:UInt, b:Int):UInt { return a.toInt() >>> b; } @:op(A % B) private static function mod(a:UInt, b:UInt):UInt; @:commutative @:op(A + B) private static inline function addWithFloat(a:UInt, b:Float):Float { return a.toFloat() + b; } @:commutative @:op(A * B) private static inline function mulWithFloat(a:UInt, b:Float):Float { return a.toFloat() * b; } @:op(A / B) private static inline function divFloat(a:UInt, b:Float):Float { return a.toFloat() / b; } @:op(A / B) private static inline function floatDiv(a:Float, b:UInt):Float { return a / b.toFloat(); } @:op(A - B) private static inline function subFloat(a:UInt, b:Float):Float { return a.toFloat() - b; } @:op(A - B) private static inline function floatSub(a:Float, b:UInt):Float { return a - b.toFloat(); } @:op(A > B) private static inline function gtFloat(a:UInt, b:Float):Bool { return a.toFloat() > b; } @:commutative @:op(A == B) private static inline function equalsInt(a:UInt, b:T):Bool { return a.toInt() == b; } @:commutative @:op(A != B) private static inline function notEqualsInt(a:UInt, b:T):Bool { return a.toInt() != b; } @:commutative @:op(A == B) private static inline function equalsFloat(a:UInt, b:T):Bool { return a.toFloat() == b; } @:commutative @:op(A != B) private static inline function notEqualsFloat(a:UInt, b:T):Bool { return a.toFloat() != b; } @:op(A >= B) private static inline function gteFloat(a:UInt, b:Float):Bool { return a.toFloat() >= b; } @:op(A > B) private static inline function floatGt(a:Float, b:UInt):Bool { return a > b.toFloat(); } @:op(A >= B) private static inline function floatGte(a:Float, b:UInt):Bool { return a >= b.toFloat(); } @:op(A < B) private static inline function ltFloat(a:UInt, b:Float):Bool { return a.toFloat() < b; } @:op(A <= B) private static inline function lteFloat(a:UInt, b:Float):Bool { return a.toFloat() <= b; } @:op(A < B) private static inline function floatLt(a:Float, b:UInt):Bool { return a < b.toFloat(); } @:op(A <= B) private static inline function floatLte(a:Float, b:UInt):Bool { return a <= b.toFloat(); } @:op(A % B) private static inline function modFloat(a:UInt, b:Float):Float { return a.toFloat() % b; } @:op(A % B) private static inline function floatMod(a:Float, b:UInt):Float { return a % b.toFloat(); } @:op(~A) private inline function negBits():UInt { return ~this; } @:op(++A) private inline function prefixIncrement():UInt { return ++this; } @:op(A++) private inline function postfixIncrement():UInt { return this++; } @:op(--A) private inline function prefixDecrement():UInt { return --this; } @:op(A--) private inline function postfixDecrement():UInt { return this--; } // TODO: radix is just defined to deal with doc_gen issues private inline function toString(?radix:Int):String { return Std.string(toFloat()); } private inline function toInt():Int { return this; } @:to private inline function toFloat():Float { return cast (this:UInt); } } haxe_3.4.4.orig/std/hl/_std/haxe/Resource.hx0000664000175000017500000000376613166552354020633 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; private class ResourceContent { public var name : hl.Bytes; public var data : hl.Bytes; public var dataLen : Int; } @:coreApi class Resource { static var content : hl.NativeArray; public static function listNames() : Array { return [for (x in content) @:privateAccess String.fromUCS2(x.name)]; } public static function getString( name : String ) : String { for( x in content ) if( x.name.compare(0,@:privateAccess name.bytes,0,(name.length+1)<<1) == 0 ) return @:privateAccess String.fromUTF8(x.data); return null; } public static function getBytes( name : String ) : haxe.io.Bytes { for( x in content ) if( x.name.compare(0,@:privateAccess name.bytes,0,(name.length+1)<<1) == 0 ) return @:privateAccess new haxe.io.Bytes(x.data, x.dataLen); return null; } static function __init__() : Void { content = untyped $resources(); } } haxe_3.4.4.orig/std/hl/_std/haxe/ds/IntMap.hx0000664000175000017500000000420213166552354020624 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:coreApi class IntMap implements haxe.Constraints.IMap { var h : hl.types.IntMap; public function new() : Void { h = new hl.types.IntMap(); } public function set( key : Int, value : T ) : Void { @:privateAccess h.set(key,value); } public function get( key : Int ) : Null { return @:privateAccess h.get(key); } public function exists( key : Int ) : Bool { return @:privateAccess h.exists(key); } public function remove( key : Int ) : Bool { return @:privateAccess h.remove(key); } public function keys() : Iterator { return new hl.NativeArray.NativeArrayIterator(h.keysArray()); } public function iterator() : Iterator { return h.iterator(); } public function toString() : String { var s = new StringBuf(); var keys = h.keysArray(); var values = h.valuesArray(); s.addChar('{'.code); for( i in 0...keys.length ) { if( i > 0 ) s.add(", "); s.add(keys[i]); s.add(" => "); s.add(values[i]); } s.addChar('}'.code); return s.toString(); } } haxe_3.4.4.orig/std/hl/_std/haxe/ds/ObjectMap.hx0000664000175000017500000000420713166552354021305 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:coreApi class ObjectMap implements haxe.Constraints.IMap { var h : hl.types.ObjectMap; public function new() : Void { h = new hl.types.ObjectMap(); } public function set( key : K, value : T ) : Void { @:privateAccess h.set(key,value); } public function get( key : K ) : Null { return @:privateAccess h.get(key); } public function exists( key : K ) : Bool { return @:privateAccess h.exists(key); } public function remove( key : K ) : Bool { return @:privateAccess h.remove(key); } public function keys() : Iterator { return new hl.NativeArray.NativeArrayIterator(cast h.keysArray()); } public function iterator() : Iterator { return h.iterator(); } public function toString() : String { var s = new StringBuf(); var keys = h.keysArray(); var values = h.valuesArray(); s.addChar('{'.code); for( i in 0...keys.length ) { if( i > 0 ) s.add(", "); s.add(keys[i]); s.add(" => "); s.add(values[i]); } s.addChar('}'.code); return s.toString(); } } haxe_3.4.4.orig/std/hl/_std/haxe/ds/StringMap.hx0000664000175000017500000000532113166552354021343 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; private class StringMapKeysIterator { var arr : hl.NativeArray; var pos : Int; var length : Int; public inline function new(h:hl.types.BytesMap) { this.arr = h.keysArray(); pos = 0; length = arr.length; } public inline function hasNext() { return pos < length; } public inline function next() @:privateAccess { var b = arr[pos++]; return String.fromUCS2(b); } } @:coreApi class StringMap implements haxe.Constraints.IMap { var h : hl.types.BytesMap; public function new() : Void { h = new hl.types.BytesMap(); } public function set( key : String, value : T ) : Void { @:privateAccess h.set(key.bytes,value); } public function get( key : String ) : Null { if( key == null ) return null; return @:privateAccess h.get(key.bytes); } public function exists( key : String ) : Bool { if( key == null ) return false; return @:privateAccess h.exists(key.bytes); } public function remove( key : String ) : Bool { if( key == null ) return false; return @:privateAccess h.remove(key.bytes); } public function keys() : Iterator { return new StringMapKeysIterator(h); } public function iterator() : Iterator { return h.iterator(); } public function toString() : String { var s = new StringBuf(); var keys = h.keysArray(); var values = h.valuesArray(); s.addChar('{'.code); for( i in 0...keys.length ) { if( i > 0 ) s.add(", "); var k = keys[i]; @:privateAccess s.__add(k,0,(@:privateAccess k.ucs2Length(0)) << 1); s.add(" => "); s.add(values[i]); } s.addChar('}'.code); return s.toString(); } } haxe_3.4.4.orig/std/hl/_std/haxe/ds/Vector.hx0000664000175000017500000000510113166552354020675 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; private typedef VectorData = Array @:coreApi abstract Vector(VectorData) { public inline function new(length:Int) { this = []; if( length > 0 ) this[length-1] = cast null; } @:op([]) public inline function get(index:Int):T { return this[index]; } @:op([]) public inline function set(index:Int, val:T):T { return this[index] = val; } public var length(get, never):Int; inline function get_length():Int { return this.length; } public static inline function blit(src:Vector, srcPos:Int, dest:Vector, destPos:Int, len:Int):Void { (cast dest : hl.types.ArrayBase.ArrayAccess).blit(destPos,(cast src : hl.types.ArrayBase.ArrayAccess),srcPos,len); } public inline function toArray():Array { return this.copy(); } public inline function toData():VectorData return this; static public inline function fromData(data:VectorData):Vector return cast data; static public inline function fromArrayCopy(array:Array):Vector { return cast array.copy(); } public inline function copy():Vector { return cast this.copy(); } public inline function join(sep:String):String { return this.join(sep); } public inline function sort(f:T->T->Int):Void { this.sort(f); } public inline function map(f:T->S):Vector { var length = length; var r = new Vector(length); var i = 0; var len = length; for(i in 0...len) { var v = f(get(i)); r.set(i, v); } return r; } } haxe_3.4.4.orig/std/hl/_std/haxe/io/Bytes.hx0000664000175000017500000001174113166552354020531 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; @:coreApi class Bytes { public var length(default,null) : Int; var b : hl.Bytes; function new(b:hl.Bytes,length:Int) : Void { this.b = b; this.length = length; } inline function out(pos:Int) : Bool { return (pos:UInt) >= (length : UInt); } inline function outRange(pos:Int,len:Int) : Bool { return pos < 0 || len < 0 || ((pos+len):UInt) > (length : UInt); } public function get( pos : Int ) : Int { return if( out(pos) ) 0 else b[pos]; } public function set( pos : Int, v : Int ) : Void { if( out(pos) ) throw Error.OutsideBounds; b[pos] = v; } public function blit( pos : Int, src : Bytes, srcpos : Int, len : Int ) : Void { if( outRange(pos, len) || src.outRange(srcpos,len) ) throw Error.OutsideBounds; b.blit(pos, src.b, srcpos, len); } public function fill( pos : Int, len : Int, value : Int ) : Void { if( outRange(pos,len) ) throw Error.OutsideBounds; b.fill(pos, len, value); } public function sub( pos : Int, len : Int ) : Bytes { if( outRange(pos,len) ) throw Error.OutsideBounds; return new Bytes(b.sub(pos, len), len); } public function compare( other : Bytes ) : Int { var len = length < other.length ? length : other.length; var r = b.compare(0, other.b, 0, len); if( r == 0 ) r = length - other.length; return r; } public function getDouble( pos : Int ) : Float { return if( out(pos + 7) ) 0. else b.getF64(pos); } public function getFloat( pos : Int ) : Float { return if( out(pos + 3) ) 0. else b.getF32(pos); } public function setDouble( pos : Int, v : Float ) : Void { if( out(pos + 7) ) throw Error.OutsideBounds; b.setF64(pos, v); } public function setFloat( pos : Int, v : Float ) : Void { if( out(pos + 3) ) throw Error.OutsideBounds; b.setF32(pos, v); } public inline function getUInt16( pos : Int ) : Int { return if( out(pos + 1) ) 0 else b.getUI16(pos); } public inline function setUInt16( pos : Int, v : Int ) : Void { if( out(pos + 1) ) throw Error.OutsideBounds; b.setUI16(pos, v); } public function getInt32( pos : Int ) : Int { return if( out(pos + 3) ) 0 else b.getI32(pos); } public function getInt64( pos : Int ) : haxe.Int64 { if( out(pos + 7) ) return haxe.Int64.ofInt(0); return haxe.Int64.make(b.getI32(pos+4), b.getI32(pos)); } public function setInt32( pos : Int, v : Int ) : Void { if( out(pos + 3) ) throw Error.OutsideBounds; b.setI32(pos, v); } public inline function setInt64( pos : Int, v : haxe.Int64 ) : Void { setInt32(pos + 4, v.high); setInt32(pos, v.low); } public function getString( pos : Int, len : Int ) : String { if( outRange(pos,len) ) throw Error.OutsideBounds; var b = new hl.Bytes(len + 1); b.blit(0, this.b, pos, len); b[len] = 0; return @:privateAccess String.fromUTF8(b); } @:deprecated("readString is deprecated, use getString instead") @:noCompletion public inline function readString(pos:Int, len:Int):String { return getString(pos, len); } public function toString() : String { return getString(0,length); } public function toHex() : String { var s = new StringBuf(); var chars = []; var str = "0123456789abcdef"; for( i in 0...str.length ) chars.push(str.charCodeAt(i)); for( i in 0...length ) { var c = get(i); s.addChar(chars[c >> 4]); s.addChar(chars[c & 15]); } return s.toString(); } public inline function getData() : BytesData { return new haxe.io.BytesData(b,length); } public static function alloc( length : Int ) : Bytes { var b = new hl.Bytes(length); b.fill(0, length, 0); return new Bytes(b,length); } public static function ofString( s : String ) : Bytes @:privateAccess { var size = 0; var b = s.bytes.utf16ToUtf8(0, size); return new Bytes(b,size); } public static function ofData( b : BytesData ) : Bytes { return new Bytes(b.bytes,b.length); } public inline static function fastGet( b : BytesData, pos : Int ) : Int { return b[pos]; } } haxe_3.4.4.orig/std/hl/_std/haxe/io/BytesBuffer.hx0000664000175000017500000000564313166552354021667 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; @:coreApi class BytesBuffer { var b : hl.Bytes; var pos : Int; var size : Int; public var length(get,never) : Int; public function new() { pos = 0; size = 16; // ensure increment of 8 b = new hl.Bytes(size); } inline function get_length() : Int { return pos; } public inline function addByte( byte : Int ) : Void { if( pos == size ) __expand(0); b[pos++] = byte; } function __expand( req : Int ) : Void { var nsize = (size * 3) >> 1; if( nsize < req ) nsize = req; var b2 = new hl.Bytes(nsize); b2.blit(0, b, 0, pos); b = b2; size = nsize; } function __add( b : hl.Bytes, bpos : Int, blen : Int ) : Void { if( pos + blen > size ) __expand(pos+blen); this.b.blit(pos, b, bpos, blen); pos += blen; } public inline function add( src : Bytes ) : Void { __add(@:privateAccess src.b, 0, src.length); } public inline function addString( v : String ) : Void { var len = 0; @:privateAccess __add(v.bytes.utf16ToUtf8(0, len), 0, len); } public inline function addInt32( v : Int ) : Void { if( pos + 4 > size ) __expand(0); b.setI32(pos, v); pos += 4; } public inline function addInt64( v : haxe.Int64 ) : Void { if( pos + 8 > size ) __expand(0); b.setI32(pos, v.low); b.setI32(pos + 4, v.high); pos += 8; } public inline function addFloat( v : Float ) : Void { if( pos + 4 > size ) __expand(0); b.setF32(pos, v); pos += 4; } public inline function addDouble( v : Float ) : Void { if( pos + 8 > size ) __expand(0); b.setF64(pos, v); pos += 8; } public inline function addBytes( src : Bytes, pos : Int, len : Int ) : Void { if( pos < 0 || len < 0 || pos + len > src.length ) throw Error.OutsideBounds; __add(@:privateAccess src.b, pos, len); } public function getBytes() : Bytes { return @:privateAccess new haxe.io.Bytes(b, pos); } } haxe_3.4.4.orig/std/hl/_std/haxe/io/FPHelper.hx0000664000175000017500000000353013166552354021105 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; class FPHelper { // note : this is not thread safe, use TLS when available static var i64tmp = Int64.ofInt(0); static var helper = new hl.Bytes(8); public static function i32ToFloat( i : Int ) : Single { helper.setI32(0,i); return helper.getF32(0); } public static function floatToI32( f : Single ) : Int { helper.setF32(0,f); return helper.getI32(0); } public static function i64ToDouble( low : Int, high : Int ) : Float { helper.setI32(0,low); helper.setI32(4,high); return helper.getF64(0); } public static function doubleToI64( v : Float ) : Int64 { helper.setF64(0,v); var i64 = i64tmp; @:privateAccess { i64.set_low(helper.getI32(0)); i64.set_high(helper.getI32(4)); } return i64; } } haxe_3.4.4.orig/std/hl/_std/haxe/zip/Compress.hx0000664000175000017500000000520613166552354021430 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; private typedef Deflater = hl.Abstract<"fmt_zip">; @:coreApi @:hlNative("fmt") class Compress { var s : Deflater; public function new( level : Int ) : Void { s = deflate_init(level); } public function execute( src : haxe.io.Bytes, srcPos : Int, dst : haxe.io.Bytes, dstPos : Int ) : { done : Bool, read : Int, write : Int } { var read = 0, write = 0; var done = deflate_buffer(s,src.getData(),srcPos,src.length,dst.getData(),dstPos,dst.length,read,write); return { done : done, read : read, write : write }; } public function setFlushMode( f : FlushMode ) : Void { @:privateAccess Uncompress.zip_flush_mode(cast s,f.getIndex()); } public function close() : Void { @:privateAccess Uncompress.zip_end(cast s); } public static function run( s : haxe.io.Bytes, level : Int ) : haxe.io.Bytes { var c = new Compress(level); c.setFlushMode(FlushMode.FINISH); var out = haxe.io.Bytes.alloc(deflate_bound(c.s,s.length)); var r = c.execute(s,0,out,0); c.close(); if( !r.done || r.read != s.length ) throw "Compression failed"; if( r.write < out.length*0.66 ) return out.sub(0, r.write); @:privateAccess out.length = r.write; return out; } static function deflate_init( level : Int ) : Deflater { return null; } static function deflate_buffer( i : Deflater, bytes : hl.Bytes, bytesPos : Int, bytesLen : Int, dst : hl.Bytes, dstPos : Int, dstLen : Int, read : hl.Ref, write : hl.Ref) : Bool { return false; } static function deflate_bound( i : Deflater, length : Int ) : Int { return 0; } } haxe_3.4.4.orig/std/hl/_std/haxe/zip/Uncompress.hx0000664000175000017500000000522313166552354021772 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; private typedef Inflater = hl.Abstract<"fmt_zip">; @:coreApi @:hlNative("fmt") class Uncompress { var s : Inflater; public function new( ?windowBits : Int ) : Void { s = inflate_init(windowBits); } public function execute( src : haxe.io.Bytes, srcPos : Int, dst : haxe.io.Bytes, dstPos : Int ) : { done : Bool, read : Int, write : Int } { var read = 0, write = 0; var done = inflate_buffer(s,src.getData(),srcPos,src.length,dst.getData(),dstPos,dst.length,read,write); return { done : done, read : read, write : write }; } public function setFlushMode( f : FlushMode ) : Void { zip_flush_mode(s,f.getIndex()); } public function close() : Void { zip_end(s); } public static function run( src : haxe.io.Bytes, ?bufsize : Int ) : haxe.io.Bytes { var u = new Uncompress(null); if( bufsize == null ) bufsize = 1 << 16; // 64K var tmp = haxe.io.Bytes.alloc(bufsize); var b = new haxe.io.BytesBuffer(); var pos = 0; u.setFlushMode(FlushMode.SYNC); while( true ) { var r = u.execute(src,pos,tmp,0); b.addBytes(tmp,0,r.write); pos += r.read; if( r.done ) break; } u.close(); return b.getBytes(); } static function inflate_init( bits : Int ) : Inflater { return null; } static function inflate_buffer( i : Inflater, bytes : hl.Bytes, bytesPos : Int, bytesLen : Int, dst : hl.Bytes, dstPos : Int, dstLen : Int, read : hl.Ref, write : hl.Ref) : Bool { return false; } static function zip_end( i : Inflater ) : Void { } static function zip_flush_mode( i : Inflater, flush : Int ) : Void {} } haxe_3.4.4.orig/std/hl/_std/sys/FileSystem.hx0000664000175000017500000001132413166552354021006 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys; @:coreApi @:access(Sys) class FileSystem { public static function exists( path : String ) : Bool { return sys_exists( Sys.getPath(makeCompatiblePath(path)) ); } public static function rename( path : String, newPath : String ) : Void { if( !sys_rename( Sys.getPath(path), Sys.getPath(newPath) ) ) throw new Sys.SysError("Failed to rename " + path + " to " + newPath); } public static function stat( path : String ) : FileStat { var values = sys_stat( Sys.getPath(makeCompatiblePath(path)) ); if( values == null ) throw new Sys.SysError("Failed to stat " + path); return { gid : values[0], uid : values[1], atime : @:privateAccess Date.fromInt(values[2]), mtime : @:privateAccess Date.fromInt(values[3]), ctime : @:privateAccess Date.fromInt(values[4]), size : values[5], dev : values[6], ino : values[7], nlink : values[8], rdev : values[9], mode : values[10], }; } public static function fullPath( relPath : String ) : String { return Sys.makePath( sys_full_path(Sys.getPath(relPath)) ); } public static function absolutePath ( relPath : String ) : String { if (haxe.io.Path.isAbsolute(relPath)) return relPath; return haxe.io.Path.join([Sys.getCwd(), relPath]); } public static function isDirectory( path : String ) : Bool { return sys_is_dir(Sys.getPath(makeCompatiblePath(path))); } public static function createDirectory( path : String ) : Void { var path = haxe.io.Path.addTrailingSlash(path); var _p = null; var parts = []; while (path != (_p = haxe.io.Path.directory(path))) { parts.unshift(path); path = _p; } for (part in parts) { if (part.charCodeAt(part.length - 1) != ":".code && !exists(part)) if( !sys_create_dir(Sys.getPath(part), 493) ) throw new Sys.SysError("Failed to create directory " + part); } } public static function deleteFile( path : String ) : Void { if( !sys_delete(Sys.getPath(path)) ) throw new Sys.SysError("Can't delete file " + path); } public static function deleteDirectory( path : String ) : Void { if( !sys_remove_dir(Sys.getPath(path)) ) throw new Sys.SysError("Can't delete directory " + path); } public static function readDirectory( path : String ) : Array { var content = sys_read_dir(Sys.getPath(path)); if( content == null ) throw new Sys.SysError("Failed to read directory " + path); return [for( c in content ) Sys.makePath(c)]; } private static inline function makeCompatiblePath(path:String):String { return if (path.charCodeAt(1) == ":".code && path.length <= 3) { haxe.io.Path.addTrailingSlash(path); } else { haxe.io.Path.removeTrailingSlashes(path); } } @:hlNative("std", "sys_read_dir") static function sys_read_dir( path : hl.Bytes ) : hl.NativeArray { return null; } @:hlNative("std", "sys_create_dir") static function sys_create_dir( path : hl.Bytes, rights : Int ) : Bool { return false; } @:hlNative("std", "sys_is_dir") static function sys_is_dir( path : hl.Bytes ) : Bool { return false; } @:hlNative("std", "sys_stat") static function sys_stat( path : hl.Bytes ) : hl.NativeArray { return null; } @:hlNative("std", "sys_rename") static function sys_rename( path : hl.Bytes, to : hl.Bytes ) : Bool { return true; } @:hlNative("std", "sys_delete") static function sys_delete( path : hl.Bytes ) : Bool { return true; }; @:hlNative("std", "sys_full_path") static function sys_full_path( path : hl.Bytes ) : hl.Bytes { return null; } @:hlNative("std", "sys_remove_dir") static function sys_remove_dir( path : hl.Bytes ) : Bool { return true; } @:hlNative("std", "sys_exists") static function sys_exists( path : hl.Bytes ) : Bool { return true; } } haxe_3.4.4.orig/std/hl/_std/sys/db/Sqlite.hx0000664000175000017500000001430513166552354020552 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.db; import haxe.crypto.BaseCode; private typedef SqliteConnectionHandle = hl.Abstract<"sqlite_database">; private typedef SqliteResultHandle = hl.Abstract<"sqlite_result">; @:hlNative("sqlite") private class SqliteLib { public static function connect( path : hl.Bytes ) : SqliteConnectionHandle { return null; } public static function close( c : SqliteConnectionHandle ) : Void { } public static function request( c : SqliteConnectionHandle, sql : hl.Bytes ) : SqliteResultHandle { return null; } public static function last_id( c : SqliteConnectionHandle ) : Int { return 0; } public static function result_next( c : SqliteResultHandle ) : hl.NativeArray { return null; } public static function result_get( c : SqliteResultHandle, n : Int ) : Null { return null; } public static function result_get_int( c : SqliteResultHandle, n : Int ) : Null { return 0; } public static function result_get_float( c : SqliteResultHandle, n : Int ) : Null { return .0; } public static function result_get_length( c : SqliteResultHandle ) : Null { return 0; } public static function result_get_nfields( c : SqliteResultHandle ) : Int { return 0; } public static function result_get_fields( c : SqliteResultHandle ) : hl.NativeArray { return null; } } @:access(Sys) @:access(String) private class SqliteConnection implements Connection { var c : SqliteConnectionHandle; public function new( file : String ) { c = SqliteLib.connect(Sys.getPath(file)); } public function close( ) : Void { SqliteLib.close(c); } public function request( s : String ) : ResultSet { try { var r : SqliteResultHandle = SqliteLib.request(c, s.bytes); return new SqliteResultSet(r); } catch ( e : String ) { throw 'Error while executing $s ($e)'; } return null; } public function escape( s : String ) : String { return s.split("'").join("''"); } public function quote( s : String ) : String { if( s.indexOf("\000") >= 0 ) return "x'" + BaseCode.encode(s, "0123456789ABCDEF") + "'"; return "'" + s.split("'").join("''") + "'"; } public function addValue( s : StringBuf, v : Dynamic ) : Void { switch( Type.typeof(v) ) { case TNull, TInt: s.add(v); case TBool: s.add( v ? 1 : 0); case _: s.add(quote(Std.string(v))); } } public function lastInsertId( ) : Int { return SqliteLib.last_id(c); } public function dbName( ) : String { return "SQLite"; } public function startTransaction( ) : Void { request("BEGIN TRANSACTION"); } public function commit( ) : Void { request("COMMIT"); startTransaction(); // match mysql usage } public function rollback( ) : Void { request("ROLLBACK"); startTransaction(); // match mysql usage } } @:access(String) private class SqliteResultSet implements ResultSet { public var length(get,null) : Int; public var nfields(get,null) : Int; var names : Array; var cache : List; var r : SqliteResultHandle; public function new( r : SqliteResultHandle ) { cache = new List(); this.r = r; hasNext(); // execute the request } function get_length( ) : Int { if ( nfields != 0 ) { while ( true ) { var c = doNext(); if( c == null ) break; cache.add(c); } return cache.length; } return SqliteLib.result_get_length(r); } function get_nfields( ) : Int { return SqliteLib.result_get_nfields(r); } public function hasNext( ) : Bool { var c = next(); if( c == null ) return false; cache.push(c); return true; } public function next( ) : Dynamic { var c = cache.pop(); if( c != null ) return c; return doNext(); } private function doNext( ) : Dynamic { var o : Dynamic = {}; var a = SqliteLib.result_next(r); if( a == null ) return null; var names = getFieldsNames(); var i = 0 ; var l = names.length; while ( i < l ) { var n : String = names[i]; var v : Dynamic = a[i]; if ( hl.Type.getDynamic(v).kind == hl.Type.TypeKind.HBytes ) Reflect.setField(o, n, String.fromUCS2(v)); else Reflect.setField(o, n, v); i++; } return o; } public function results( ) : List { var l = new List(); while ( true ) { var c = next(); if( c == null ) break; l.add(c); } return l; } public function getResult( n : Int ) : String { var bytes = SqliteLib.result_get(r, n); if ( bytes == null ) return null; return String.fromUCS2(bytes); } public function getIntResult( n : Int ) : Int { return SqliteLib.result_get_int(r,n); } public function getFloatResult( n : Int ) : Float { return SqliteLib.result_get_float(r,n); } public function getFieldsNames( ) : Array { if ( this.names != null ) return this.names; this.names = []; var names = SqliteLib.result_get_fields(r); var i = 0; var l = names.length; while ( i < l ) { var name = String.fromUCS2(names[i]); this.names.push(name); i++; } return this.names; } } @:coreApi class Sqlite { public static function open( file : String ) : Connection { return new SqliteConnection(file); } }haxe_3.4.4.orig/std/hl/_std/sys/io/File.hx0000664000175000017500000000630513166552354020213 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; #if doc_gen enum FileHandle { } #else typedef FileHandle = hl.Abstract<"hl_fdesc">; #end @:access(Sys) @:coreApi class File { public static function getContent( path : String ) : String { var bytes = file_contents(Sys.getPath(path), null); if( bytes == null ) throw new Sys.SysError("Can't read "+path); return @:privateAccess String.fromUTF8(bytes); } public static function getBytes( path : String ) : haxe.io.Bytes { var size = 0; var bytes = file_contents(Sys.getPath(path), size); if( bytes == null ) throw new Sys.SysError("Can't read "+path); return @:privateAccess new haxe.io.Bytes(bytes, size); } public static function saveContent( path : String, content : String ) : Void { var f = write(path); f.writeString(content); f.close(); } public static function saveBytes( path : String, bytes : haxe.io.Bytes ) : Void { var f = write(path); f.write(bytes); f.close(); } public static function read( path : String, binary : Bool = true ) : FileInput { var f = file_open(Sys.getPath(path),0,binary); if( f == null ) throw new Sys.SysError("Can't open "+path); return @:privateAccess new FileInput(f); } public static function write( path : String, binary : Bool = true ) : FileOutput { var f = file_open(Sys.getPath(path),1,binary); if( f == null ) throw new Sys.SysError("Can't open "+path+" for writing"); return @:privateAccess new FileOutput(f); } public static function append( path : String, binary : Bool = true ) : FileOutput { var f = file_open(Sys.getPath(path),2,binary); if( f == null ) throw new Sys.SysError("Can't open "+path+" for append"); return @:privateAccess new FileOutput(f); } public static function copy( srcPath : String, dstPath : String ) : Void { var s = read(srcPath,true); var d = write(dstPath,true); d.writeInput(s); s.close(); d.close(); } @:hlNative("std", "file_open") static function file_open( path : hl.Bytes, mode : Int, binary : Bool ) : FileHandle { return null; } @:hlNative("std", "file_contents") static function file_contents( path : hl.Bytes, size : hl.Ref ) : hl.Bytes { return null; } } haxe_3.4.4.orig/std/hl/_std/sys/io/FileInput.hx0000664000175000017500000000543113166552354021232 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; import sys.io.File; @:coreApi class FileInput extends haxe.io.Input { private var __f : FileHandle; function new(f:FileHandle) : Void { __f = f; } public override function readByte() : Int { var c = file_read_char(__f); if( c < 0 ) throw new haxe.io.Eof(); return c; } public override function readBytes( s : haxe.io.Bytes, p : Int, l : Int ) : Int { if( p < 0 || l < 0 || p + l > s.length ) throw haxe.io.Error.OutsideBounds; var v = file_read(__f, s.getData(), p, l); if( v <= 0 ) throw new haxe.io.Eof(); return v; } public override function close() : Void { super.close(); file_close(__f); __f = null; } public function seek( p : Int, pos : FileSeek ) : Void { if( !file_seek(__f,p,switch( pos ) { case SeekBegin: 0; case SeekCur: 1; case SeekEnd: 2; }) ) throw haxe.io.Error.Custom("seek() failure"); } public function tell() : Int { var p = file_tell(__f); if( p < 0 ) throw haxe.io.Error.Custom("tell() failure"); return p; } public function eof() : Bool { return file_eof(__f); } @:hlNative("std", "file_eof") static function file_eof( f : FileHandle ) : Bool { return false; } @:hlNative("std", "file_read") static function file_read( f : FileHandle, bytes : hl.Bytes, pos : Int, len : Int ) : Int { return 0; } @:hlNative("std", "file_read_char") static function file_read_char( f : FileHandle ) : Int { return 0; } @:hlNative("std", "file_close") static function file_close( f : FileHandle ) : Void { } @:hlNative("std", "file_seek") static function file_seek( f : FileHandle, pos : Int, from : Int ) : Bool { return true; } @:hlNative("std", "file_tell") static function file_tell( f : FileHandle ) : Int { return 0; } } haxe_3.4.4.orig/std/hl/_std/sys/io/FileOutput.hx0000664000175000017500000000517013166552354021433 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; import sys.io.File; @:coreApi class FileOutput extends haxe.io.Output { private var __f : FileHandle; function new(f:FileHandle) : Void { __f = f; } public override function writeByte( c : Int ) : Void { if( !file_write_char(__f, c) ) throw new haxe.io.Eof(); } public override function writeBytes( s : haxe.io.Bytes, p : Int, l : Int ) : Int { if( p < 0 || l < 0 || p + l > s.length ) throw haxe.io.Error.OutsideBounds; var v = file_write(__f, s.getData(), p, l); if( v <= 0 ) throw new haxe.io.Eof(); return v; } public override function flush() : Void { if( !file_flush(__f) ) throw haxe.io.Error.Custom("flush() failure"); } public override function close() : Void { super.close(); @:privateAccess FileInput.file_close(__f); __f = null; } public function seek( p : Int, pos : FileSeek ) : Void { if( @:privateAccess !FileInput.file_seek(__f,p,switch( pos ) { case SeekBegin: 0; case SeekCur: 1; case SeekEnd: 2; }) ) throw haxe.io.Error.Custom("seek() failure"); } public function tell() : Int { var p = @:privateAccess FileInput.file_tell(__f); if( p < 0 ) throw haxe.io.Error.Custom("tell() failure"); return p; } @:hlNative("std","file_flush") static function file_flush( f : FileHandle ) : Bool { return true; } @:hlNative("std", "file_write") static function file_write( f : FileHandle, bytes : hl.Bytes, pos : Int, len : Int ) : Int { return 0; } @:hlNative("std", "file_write_char") static function file_write_char( f : FileHandle, v : Int ) : Bool { return true; } } haxe_3.4.4.orig/std/hl/_std/sys/io/Process.hx0000664000175000017500000001264313166552354020754 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; private typedef ProcessHandle = hl.Abstract<"hl_process">; private class Stdin extends haxe.io.Output { var p : Dynamic; var buf : haxe.io.Bytes; public function new(p) { this.p = p; buf = haxe.io.Bytes.alloc(1); } public override function close() { super.close(); _stdin_close(p); } public override function writeByte(c) { buf.set(0,c); writeBytes(buf,0,1); } public override function writeBytes( buf : haxe.io.Bytes, pos : Int, len : Int ) : Int { var v = _stdin_write(p, buf.getData().bytes, pos, len); if( v < 0 ) throw new haxe.io.Eof(); return v; } @:hlNative("std","process_stdin_write") static function _stdin_write( p : ProcessHandle, bytes : hl.Bytes, pos : Int, len : Int ) : Int { return 0; } @:hlNative("std", "process_stdin_close") static function _stdin_close( p : ProcessHandle ) : Bool { return false; } } private class Stdout extends haxe.io.Input { var p : ProcessHandle; var out : Bool; var buf : haxe.io.Bytes; public function new(p,out) { this.p = p; this.out = out; buf = haxe.io.Bytes.alloc(1); } public override function readByte() { if( readBytes(buf,0,1) == 0 ) throw haxe.io.Error.Blocked; return buf.get(0); } public override function readBytes( str : haxe.io.Bytes, pos : Int, len : Int ) : Int { var v = out ? _stdout_read(p,str.getData().bytes,pos,len) : _stderr_read(p,str.getData().bytes,pos,len); if( v < 0 ) throw new haxe.io.Eof(); return v; } @:hlNative("std","process_stdout_read") static function _stdout_read( p : ProcessHandle, bytes : hl.Bytes, pos : Int, len : Int ) : Int { return 0; } @:hlNative("std","process_stderr_read") static function _stderr_read( p : ProcessHandle, bytes : hl.Bytes, pos : Int, len : Int ) : Int { return 0; } } @:access(Sys) @:coreApi class Process { var p : ProcessHandle; public var stdout(default,null) : haxe.io.Input; public var stderr(default,null) : haxe.io.Input; public var stdin(default, null) : haxe.io.Output; static var isWin = Sys.systemName() == "Windows"; public function new( cmd : String, ?args : Array ) : Void { var runCmd = cmd; if( isWin ) { var b = new StringBuf(); if( args == null ) { var exe = Sys.getEnv("COMSPEC"); if( exe == null ) exe = "cmd.exe"; b.add("\""); b.add(exe); b.add("\" /C \""); b.add(cmd); b.addChar('"'.code); } else { b.addChar('"'.code); b.add(cmd); b.addChar('"'.code); for( a in args ) { b.add(" \""); var bsCount = 0; for( i in 0...a.length ) { switch( StringTools.fastCodeAt(a, i) ) { case '"'.code: for( i in 0...bsCount * 2 ) b.addChar('\\'.code); bsCount = 0; b.add("\\\""); case '\\'.code: bsCount++; case c: for( i in 0...bsCount ) b.addChar('\\'.code); bsCount = 0; b.addChar(c); } } // Add remaining backslashes, if any. for( i in 0...bsCount * 2 ) b.addChar('\\'.code); b.addChar('"'.code); } args = null; } runCmd = b.toString(); } @:privateAccess { var aargs = null; if( args != null ) { aargs = new hl.NativeArray(args.length); for( i in 0...args.length ) aargs[i] = Sys.getPath(args[i]); } p = _run(Sys.getPath(runCmd), aargs); } if( p == null ) throw new Sys.SysError("Process creation failure : "+cmd); stdin = new Stdin(p); stdout = new Stdout(p,true); stderr = new Stdout(p,false); } public function getPid() : Int { return _pid(p); } public function exitCode( block : Bool = true ) : Null { var running = false; var code = _exit(p, block == false ? new hl.Ref(running) : null); if( block == false ) return running ? null : code; return code; } public function close() : Void { _close(p); } public function kill() : Void { _kill(p); } @:hlNative("std","process_run") static function _run( cmd : hl.Bytes, args : hl.NativeArray ) : ProcessHandle { return null; } @:hlNative("std", "process_exit") static function _exit( p : ProcessHandle, running : hl.Ref ) : Int { return 0; } @:hlNative("std", "process_pid") static function _pid( p : ProcessHandle ) : Int { return 0; } @:hlNative("std","process_close") static function _close( p : ProcessHandle ) : Void { } @:hlNative("std","process_kill") static function _kill( p : ProcessHandle ) : Void { } }haxe_3.4.4.orig/std/hl/_std/sys/net/Host.hx0000664000175000017500000000417213166552354020430 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.net; @:coreApi class Host { public var host(default,null) : String; public var ip(default,null) : Int; public function new( name : String ) : Void { host = name; ip = host_resolve(@:privateAccess name.bytes.utf16ToUtf8(0,null)); if( ip == -1 ) throw new Sys.SysError("Unresolved host " + name); } public function toString() : String { return @:privateAccess String.fromUTF8(host_to_string(ip)); } public function reverse() : String { return @:privateAccess String.fromUTF8(host_reverse(ip)); } public static function localhost() : String { return @:privateAccess String.fromUTF8(host_local()); } @:hlNative("std","host_resolve") static function host_resolve( name : hl.Bytes ) : Int { return 0; } @:hlNative("std","host_reverse") static function host_reverse( host : Int ) : hl.Bytes { return null; } @:hlNative("std","host_to_string") static function host_to_string( host : Int ) : hl.Bytes { return null; } @:hlNative("std","host_local") static function host_local() : hl.Bytes { return null; } } haxe_3.4.4.orig/std/hl/_std/sys/net/Socket.hx0000664000175000017500000002216613166552354020746 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.net; import haxe.io.Error; #if doc_gen @:noDoc enum SocketHandle { } #else @:noDoc typedef SocketHandle = hl.Abstract<"hl_socket">; #end private class SocketOutput extends haxe.io.Output { var sock : Socket; public function new(s) { this.sock = s; } public override function writeByte( c : Int ) { var k = socket_send_char(@:privateAccess sock.__s, c); if( k < 0 ) { if( k == -1 ) throw Blocked; throw new haxe.io.Eof(); } } public override function writeBytes( buf : haxe.io.Bytes, pos : Int, len : Int) : Int { if( pos < 0 || len < 0 || pos + len > buf.length ) throw haxe.io.Error.OutsideBounds; var n = socket_send(@:privateAccess sock.__s, buf.getData().bytes, pos, len); if( n < 0 ) { if( n == -1 ) throw Blocked; throw new haxe.io.Eof(); } return n; } public override function close() { sock.close(); } @:hlNative("std","socket_send_char") static function socket_send_char( s : SocketHandle, c : Int ) : Int { return 0; } @:hlNative("std","socket_send") static function socket_send( s : SocketHandle, bytes : hl.Bytes, pos : Int, len : Int ) : Int { return 0; } } private class SocketInput extends haxe.io.Input { var sock : Socket; public function new(s) { sock = s; } public override function readByte() : Int { var c = socket_recv_char(@:privateAccess sock.__s); if( c < 0 ) { if( c == -1 ) throw Blocked; throw new haxe.io.Eof(); } return c; } public override function readBytes( buf : haxe.io.Bytes, pos : Int, len : Int ) : Int { if( pos < 0 || len < 0 || pos + len > buf.length ) throw haxe.io.Error.OutsideBounds; var r = socket_recv(@:privateAccess sock.__s,buf.getData().bytes,pos,len); if( r < 0 ) { if( r == -1 ) throw Blocked; throw new haxe.io.Eof(); } return r; } public override function close() { sock.close(); } @:hlNative("std","socket_recv") static function socket_recv( s : SocketHandle, bytes : hl.Bytes, pos : Int, len : Int ) : Int { return 0; } @:hlNative("std","socket_recv_char") static function socket_recv_char( s : SocketHandle ) : Int { return 0; } } @:coreApi @:keepInit class Socket { private var __s : SocketHandle; public var input(default,null) : haxe.io.Input; public var output(default,null) : haxe.io.Output; public var custom : Dynamic; static function __init__() : Void { socket_init(); } public function new() : Void { init(); } function init() : Void { __s = socket_new(false); input = new SocketInput(this); output = new SocketOutput(this); } public function close() : Void { if( __s != null ) { socket_close(__s); __s = null; } } public function read() : String { return input.readAll().toString(); } public function write( content : String ) : Void { output.writeString(content); } public function connect(host : Host, port : Int) : Void { if( !socket_connect(__s, host.ip, port) ) throw new Sys.SysError("Failed to connect on "+host.toString()+":"+port); } public function listen( connections : Int ) : Void { if( !socket_listen(__s, connections) ) throw new Sys.SysError("listen() failure"); } public function shutdown( read : Bool, write : Bool ) : Void { if( !socket_shutdown(__s, read, write) ) throw new Sys.SysError("shutdown() failure"); } public function bind(host : Host, port : Int) : Void { if( !socket_bind(__s, host.ip, port) ) throw new Sys.SysError("Cannot bind socket on " + host + ":" + port); } public function accept() : Socket { var c = socket_accept(__s); if( c == null ) return null; var s : Socket = untyped $new(Socket); s.__s = c; s.input = new SocketInput(s); s.output = new SocketOutput(s); return s; } public function peer() : { host : Host, port : Int } { var ip = 0, port = 0; if( !socket_peer(__s, ip, port) ) return null; var h : Host = untyped $new(Host); @:privateAccess h.ip = ip; return { host : h, port : port }; } public function host() : { host : Host, port : Int } { var ip = 0, port = 0; if( !socket_host(__s, ip, port) ) return null; var h : Host = untyped $new(Host); @:privateAccess h.ip = ip; return { host : h, port : port }; } public function setTimeout( timeout : Float ) : Void { if( !socket_set_timeout(__s, timeout) ) throw new Sys.SysError("setTimeout() failure"); } public function waitForRead() : Void { select([this],null,null,null); } public function setBlocking( b : Bool ) : Void { if( !socket_set_blocking(__s, b) ) throw new Sys.SysError("setBlocking() failure"); } public function setFastSend( b : Bool ) : Void { if( !socket_set_fast_send(__s,b) ) throw new Sys.SysError("setFastSend() failure"); } // TODO : use TLS when multithread added static var tmp : hl.Bytes = null; static var curTmpSize = 0; static function makeArray( a : Array ) : hl.NativeArray { if( a == null ) return null; var arr = new hl.NativeArray(a.length); for( i in 0...a.length ) arr[i] = a[i].__s; return arr; } static function outArray( a : hl.NativeArray, original : Array ) : Array { var out = []; if( a == null ) return out; var i = 0, p = 0; var max = original.length; while( i < max ) { var sh = a[i++]; if( sh == null ) break; while( original[p].__s != sh ) p++; out.push(original[p++]); } return out; } public static function select(read : Array, write : Array, others : Array, ?timeout : Float) : {read: Array, write: Array, others: Array} { var sread = makeArray(read); var swrite = makeArray(write); var sothers = makeArray(others); var tmpSize = 0; if( sread != null ) tmpSize += socket_fd_size(sread.length); if( swrite != null ) tmpSize += socket_fd_size(swrite.length); if( sothers != null ) tmpSize += socket_fd_size(sothers.length); if( tmpSize > curTmpSize ) { tmp = new hl.Bytes(tmpSize); curTmpSize = tmpSize; } if( !socket_select(sread, swrite, sothers, tmp, curTmpSize, timeout == null ? -1 : timeout) ) throw "Error while waiting on socket"; return { read : outArray(sread,read), write : outArray(swrite,write), others : outArray(sothers,others), }; } @:hlNative("std", "socket_init") static function socket_init() : Void {} @:hlNative("std", "socket_new") static function socket_new( udp : Bool ) : SocketHandle { return null; } @:hlNative("std", "socket_close") static function socket_close( s : SocketHandle ) : Void { } @:hlNative("std", "socket_connect") static function socket_connect( s : SocketHandle, host : Int, port : Int ) : Bool { return true; } @:hlNative("std", "socket_listen") static function socket_listen( s : SocketHandle, count : Int ) : Bool { return true; } @:hlNative("std", "socket_bind") static function socket_bind( s : SocketHandle, host : Int, port : Int ) : Bool { return true; } @:hlNative("std", "socket_accept") static function socket_accept( s : SocketHandle ) : SocketHandle { return null; } @:hlNative("std", "socket_peer") static function socket_peer( s : SocketHandle, host : hl.Ref, port : hl.Ref ) : Bool { return true; } @:hlNative("std", "socket_host") static function socket_host( s : SocketHandle, host : hl.Ref, port : hl.Ref ) : Bool { return true; } @:hlNative("std", "socket_set_timeout") static function socket_set_timeout( s : SocketHandle, timeout : Float ) : Bool { return true; } @:hlNative("std", "socket_shutdown") static function socket_shutdown( s : SocketHandle, read : Bool, write : Bool ) : Bool { return true; } @:hlNative("std", "socket_set_blocking") static function socket_set_blocking( s : SocketHandle, b : Bool ) : Bool { return true; } @:hlNative("std", "socket_set_fast_send") static function socket_set_fast_send( s : SocketHandle, b : Bool ) : Bool { return true; } @:hlNative("std", "socket_fd_size") static function socket_fd_size( count : Int) : Int { return 0; } @:hlNative("std", "socket_select") static function socket_select( read : hl.NativeArray, write : hl.NativeArray, other : hl.NativeArray, tmpData : hl.Bytes, tmpSize : Int, timeout : Float ) : Bool { return false; } } haxe_3.4.4.orig/std/hl/_std/sys/ssl/Certificate.hx0000664000175000017500000001124413166552354021746 0ustar andyandy00000000000000package sys.ssl; import sys.ssl.Lib; @:noDoc typedef CertificatePtr = hl.Abstract<"hl_ssl_cert">; @:coreApi class Certificate { var __h : Null; var __x : CertificatePtr; @:allow(sys.ssl.Socket) function new( x : CertificatePtr, ?h: Null ){ __x = x; __h = h; } public static function loadFile( file : String ) : Certificate { return new Certificate( cert_load_file( @:privateAccess file.toUtf8() ) ); } public static function loadPath( path : String ) : Certificate { return new Certificate( cert_load_path( @:privateAccess path.toUtf8() ) ); } public static function fromString( str : String ) : Certificate { return new Certificate( cert_add_pem(null, @:privateAccess str.toUtf8() ) ); } public static function loadDefaults() : Certificate { var x = cert_load_defaults(); if ( x != null ) return new Certificate( x ); var defPaths = null; switch( Sys.systemName() ){ case "Linux": defPaths = [ "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL "/etc/ssl/ca-bundle.pem", // OpenSUSE "/etc/pki/tls/cacert.pem", // OpenELEC "/etc/ssl/certs", // SLES10/SLES11 "/system/etc/security/cacerts" // Android ]; case "BSD": defPaths = [ "/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly "/etc/ssl/cert.pem", // OpenBSD "/etc/openssl/certs/ca-certificates.crt", // NetBSD ]; case "Android": defPaths = ["/system/etc/security/cacerts"]; default: } if( defPaths != null ){ for( path in defPaths ){ if( sys.FileSystem.exists(path) ){ if( sys.FileSystem.isDirectory(path) ) return loadPath(path); else return loadFile(path); } } } return null; } public var commonName(get,null) : Null; public var altNames(get, null) : Array; public var notBefore(get,null) : Date; public var notAfter(get,null) : Date; function get_commonName() : Null { return subject("CN"); } function get_altNames() : Array { var a = cert_get_altnames(__x); return [for( e in a ) @:privateAccess String.fromUTF8(e)]; } public function subject( field : String ) : Null { var s = cert_get_subject(__x, @:privateAccess field.toUtf8() ); return s==null ? null : new String( cast s ); } public function issuer( field : String ) : Null { var s = cert_get_issuer(__x, @:privateAccess field.toUtf8()); return s==null ? null : new String( cast s ); } function get_notBefore() : Date { var a = cert_get_notbefore( __x ); return new Date( a[0], a[1] - 1, a[2], a[3], a[4], a[5] ); } function get_notAfter() : Date { var a = cert_get_notafter( __x ); return new Date( a[0], a[1] - 1, a[2], a[3], a[4], a[5] ); } public function next() : Null { var n = cert_get_next(__x); return n == null ? null : new Certificate( n, __h==null ? this : __h ); } public function add( pem : String ) : Void { cert_add_pem(__x, @:privateAccess pem.toUtf8()); } public function addDER( der : haxe.io.Bytes ) : Void { cert_add_der(__x, @:privateAccess der.b, @:privateAccess der.length); } @:hlNative("ssl","cert_load_defaults") static function cert_load_defaults() : CertificatePtr { return null; } @:hlNative("ssl","cert_load_file") static function cert_load_file( file : hl.Bytes ) : CertificatePtr { return null; } @:hlNative("ssl","cert_load_path") static function cert_load_path( path : hl.Bytes ) : CertificatePtr { return null; } @:hlNative("ssl","cert_get_subject") static function cert_get_subject( cert : CertificatePtr, obj : hl.Bytes ) : hl.Bytes { return null; } @:hlNative("ssl","cert_get_issuer") static function cert_get_issuer( cert : CertificatePtr, obj : hl.Bytes ) : hl.Bytes { return null; } @:hlNative("ssl","cert_get_altnames") static function cert_get_altnames( cert : CertificatePtr ) : hl.NativeArray { return null; } @:hlNative("ssl","cert_get_notbefore") static function cert_get_notbefore( cert : CertificatePtr ) : hl.NativeArray { return null; } @:hlNative("ssl","cert_get_notafter") static function cert_get_notafter( cert : CertificatePtr ) : hl.NativeArray { return null; } @:hlNative("ssl","cert_get_next") static function cert_get_next( cert : CertificatePtr ) : Null { return null; } @:hlNative("ssl","cert_add_pem") static function cert_add_pem( cert : Null, data : hl.Bytes ) : CertificatePtr { return null; } @:hlNative("ssl","cert_add_der") static function cert_add_der( cert : Null, data : hl.Bytes, len : Int ) : CertificatePtr { return null; } } haxe_3.4.4.orig/std/hl/_std/sys/ssl/Digest.hx0000664000175000017500000000254713166552354020751 0ustar andyandy00000000000000package sys.ssl; import sys.ssl.Lib; @:coreApi class Digest { public static function make( data : haxe.io.Bytes, alg : DigestAlgorithm ) : haxe.io.Bytes { var size = 0; var b = @:privateAccess dgst_make( data.b, data.length, (alg:String).toUtf8(), size ); return @:privateAccess new haxe.io.Bytes(b,size); } public static function sign( data : haxe.io.Bytes, privKey : Key, alg : DigestAlgorithm ) : haxe.io.Bytes { var size = 0; var b = @:privateAccess dgst_sign( data.b, data.length, privKey.__k, (alg:String).toUtf8(), size ); return @:privateAccess new haxe.io.Bytes(b,size); } public static function verify( data : haxe.io.Bytes, signature : haxe.io.Bytes, pubKey : Key, alg : DigestAlgorithm ) : Bool{ return @:privateAccess dgst_verify( data.b, data.length, signature.b, signature.length, pubKey.__k, (alg:String).toUtf8() ); } @:hlNative("ssl","dgst_make") static function dgst_make( data : hl.Bytes, len : Int, alg : hl.Bytes, size : hl.Ref ) : hl.Bytes { return null; } @:hlNative("ssl","dgst_sign") static function dgst_sign( data : hl.Bytes, len : Int, key : sys.ssl.Key.KeyPtr, alg : hl.Bytes, size : hl.Ref ) : hl.Bytes { return null; } @:hlNative("ssl","dgst_verify") static function dgst_verify( data : hl.Bytes, dlen : Int, sign : hl.Bytes, slen : Int, key : sys.ssl.Key.KeyPtr, alg : hl.Bytes ) : Bool { return false; } } haxe_3.4.4.orig/std/hl/_std/sys/ssl/Key.hx0000664000175000017500000000225713166552354020260 0ustar andyandy00000000000000package sys.ssl; import sys.ssl.Lib; @:noDoc typedef KeyPtr = hl.Abstract<"hl_ssl_pkey">; @:coreApi class Key { private var __k : KeyPtr; private function new( k : KeyPtr ){ __k = k; } public static function loadFile( file : String, ?isPublic : Bool, ?pass : String ) : Key { var data = sys.io.File.getBytes( file ); var start = data.getString(0,11); if( start == "-----BEGIN " ) return readPEM( data.toString(), isPublic==true, pass ); else return readDER( data, isPublic==true ); } public static function readPEM( data : String, isPublic : Bool, ?pass : String ) : Key { return new Key( key_from_pem( @:privateAccess data.toUtf8(), isPublic, pass == null ? null : @:privateAccess pass.toUtf8() ) ); } public static function readDER( data : haxe.io.Bytes, isPublic : Bool ) : Key { return new Key( key_from_der( @:privateAccess data.b, @:privateAccess data.length, isPublic ) ); } @:hlNative("ssl","key_from_pem") static function key_from_pem( data : hl.Bytes, pub : Bool, pass : Null ) : KeyPtr { return null; } @:hlNative("ssl","key_from_der") static function key_from_der( data : hl.Bytes, len : Int, pub : Bool ) : KeyPtr { return null; } } haxe_3.4.4.orig/std/hl/_std/sys/ssl/Lib.hx0000664000175000017500000000024213166552354020226 0ustar andyandy00000000000000package sys.ssl; @:noDoc @:keep class Lib { static function __init__() : Void{ ssl_init(); } @:hlNative("ssl","ssl_init") static function ssl_init(){}; } haxe_3.4.4.orig/std/hl/_std/sys/ssl/Socket.hx0000664000175000017500000001762313166552354020763 0ustar andyandy00000000000000package sys.ssl; import sys.ssl.Lib; import sys.ssl.Key.KeyPtr; import sys.ssl.Certificate.CertificatePtr; import sys.net.Socket.SocketHandle; private typedef ConfigPtr = hl.Abstract<"mbedtls_ssl_config">; private typedef ContextPtr = hl.Abstract<"mbedtls_ssl_context">; @:keep private class SNICbResult { public var cert : CertificatePtr; public var key : KeyPtr; public function new( cert : Certificate, key : Key ){ this.cert = @:privateAccess cert.__x; this.key = @:privateAccess key.__k; } } private class SocketInput extends haxe.io.Input { @:allow(sys.ssl.Socket) private var __s : Socket; public function new( s : Socket ) { this.__s = s; } public override function readByte() { __s.handshake(); var r = ssl_recv_char( @:privateAccess __s.ssl ); if( r == -1 ) throw haxe.io.Error.Blocked; else if( r < 0 ) throw new haxe.io.Eof(); return r; } public override function readBytes( buf : haxe.io.Bytes, pos : Int, len : Int ) : Int { __s.handshake(); var r = ssl_recv( @:privateAccess __s.ssl, @:privateAccess buf.b, pos, len ); if( r == -1 ) throw haxe.io.Error.Blocked; else if( r < 0 ) throw new haxe.io.Eof(); return r; } public override function close() { super.close(); if( __s != null ) __s.close(); } @:hlNative("ssl","ssl_recv") static function ssl_recv( ssl : ContextPtr, bytes : hl.Bytes, pos : Int, len : Int ) : Int { return -1; } @:hlNative("ssl","ssl_recv_char") static function ssl_recv_char( ssl : ContextPtr ) : Int { return -1; } } private class SocketOutput extends haxe.io.Output { @:allow(sys.ssl.Socket) private var __s : Socket; public function new( s : Socket ) { this.__s = s; } public override function writeByte( c : Int ) { __s.handshake(); var r = ssl_send_char( @:privateAccess __s.ssl, c); if( r == -1 ) throw haxe.io.Error.Blocked; else if( r < 0 ) throw new haxe.io.Eof(); } public override function writeBytes( buf : haxe.io.Bytes, pos : Int, len : Int) : Int { __s.handshake(); var r = ssl_send( @:privateAccess __s.ssl, @:privateAccess buf.b, pos, len); if( r == -1 ) throw haxe.io.Error.Blocked; else if( r < 0 ) throw new haxe.io.Eof(); return r; } public override function close() { super.close(); if( __s != null ) __s.close(); } @:hlNative("ssl","ssl_send") static function ssl_send( ssl : ContextPtr, bytes : hl.Bytes, pos : Int, len : Int ) : Int { return -1; } @:hlNative("ssl","ssl_send_char") static function ssl_send_char( ssl : ContextPtr, c : Int ) : Int { return -1; } } @:coreApi @:access(sys.net.Socket) class Socket extends sys.net.Socket { public static var DEFAULT_VERIFY_CERT : Null = true; public static var DEFAULT_CA : Null; private var conf : ConfigPtr; private var ssl : ContextPtr; public var verifyCert : Null; private var caCert : Null; private var hostname : String; private var ownCert : Null; private var ownKey : Null; private var altSNIContexts : NullBool, key: Key, cert: Certificate}>>; private var sniCallback : hl.Bytes -> SNICbResult; private var handshakeDone : Bool; private override function init() : Void { __s = sys.net.Socket.socket_new( false ); input = new SocketInput( this ); output = new SocketOutput( this ); if( DEFAULT_VERIFY_CERT && DEFAULT_CA == null ){ try { DEFAULT_CA = Certificate.loadDefaults(); }catch( e : Dynamic ){} } verifyCert = DEFAULT_VERIFY_CERT; caCert = DEFAULT_CA; } public override function connect(host : sys.net.Host, port : Int) : Void { conf = buildConfig( false ); ssl = ssl_new( conf ); ssl_set_socket( ssl, __s ); handshakeDone = false; if( hostname == null ) hostname = host.host; if( hostname != null ) ssl_set_hostname( ssl, @:privateAccess hostname.toUtf8() ); if( !sys.net.Socket.socket_connect( __s, host.ip, port ) ) throw new Sys.SysError("Failed to connect on "+host.toString()+":"+port); handshake(); } public function handshake() : Void { if( !handshakeDone ){ var r = ssl_handshake( ssl ); if( r == 0 ) handshakeDone = true; else if( r == -1 ) throw haxe.io.Error.Blocked; else throw new haxe.io.Eof(); } } public function setCA( cert : Certificate ) : Void { caCert = cert; } public function setHostname( name : String ) : Void { hostname = name; } public function setCertificate( cert : Certificate, key : Key ) : Void { ownCert = cert; ownKey = key; } public override function close() : Void { if( ssl != null ) ssl_close( ssl ); if( conf != null ) conf_close( conf ); if( altSNIContexts != null ) sniCallback = null; sys.net.Socket.socket_close( __s ); var input : SocketInput = cast input; var output : SocketOutput = cast output; @:privateAccess input.__s = output.__s = null; input.close(); output.close(); } public function addSNICertificate( cbServernameMatch : String->Bool, cert : Certificate, key : Key ) : Void { if( altSNIContexts == null ) altSNIContexts = []; altSNIContexts.push( {match: cbServernameMatch, cert: cert, key: key} ); } public override function bind( host : sys.net.Host, port : Int ) : Void { conf = buildConfig( true ); sys.net.Socket.socket_bind( __s, host.ip, port ); } public override function accept() : Socket { var c = sys.net.Socket.socket_accept( __s ); var cssl = ssl_new( conf ); ssl_set_socket( cssl, c ); var s = Type.createEmptyInstance( sys.ssl.Socket ); s.__s = c; s.ssl = cssl; s.input = new SocketInput(s); s.output = new SocketOutput(s); s.handshakeDone = false; return s; } public function peerCertificate() : sys.ssl.Certificate { var x = ssl_get_peer_certificate( ssl ); return x==null ? null : new sys.ssl.Certificate( x ); } private function buildConfig( server : Bool ) : ConfigPtr { var conf = conf_new( server ); if( ownCert != null && ownKey != null ) conf_set_cert( conf, @:privateAccess ownCert.__x, @:privateAccess ownKey.__k ); if ( altSNIContexts != null ) { sniCallback = function(servername:hl.Bytes) : SNICbResult { var servername = @:privateAccess String.fromUTF8(servername); for( c in altSNIContexts ){ if( c.match(servername) ) return new SNICbResult(c.cert, c.key); } if( ownKey != null && ownCert != null ) return new SNICbResult(ownCert, ownKey); return null; } conf_set_servername_callback( conf, sniCallback ); } if ( caCert != null ) conf_set_ca( conf, caCert == null ? null : @:privateAccess caCert.__x ); conf_set_verify( conf, if( verifyCert ) 1 else if( verifyCert==null ) 2 else 0 ); return conf; } @:hlNative("ssl","ssl_new") static function ssl_new( conf : ConfigPtr ) : ContextPtr { return null; } @:hlNative("ssl","ssl_close") static function ssl_close( ssl : ContextPtr ) : Void {} @:hlNative("ssl","ssl_handshake") static function ssl_handshake( ssl : ContextPtr ) : Int { return -1; } @:hlNative("ssl","ssl_set_socket") static function ssl_set_socket( ssl : ContextPtr, socket : SocketHandle ) : Void { } @:hlNative("ssl","ssl_set_hostname") static function ssl_set_hostname( ssl : ContextPtr, name : hl.Bytes ) : Void { } @:hlNative("ssl","ssl_get_peer_certificate") static function ssl_get_peer_certificate( ssl : ContextPtr ) : CertificatePtr { return null; } @:hlNative("ssl","conf_new") static function conf_new( server : Bool ) : ConfigPtr { return null; } @:hlNative("ssl","conf_close") static function conf_close( conf : ConfigPtr ) : Void { } @:hlNative("ssl","conf_set_ca") static function conf_set_ca( conf : ConfigPtr, ca : CertificatePtr ) : Void { } @:hlNative("ssl","conf_set_verify") static function conf_set_verify( conf : ConfigPtr, mode : Int ) : Void { } @:hlNative("ssl","conf_set_cert") static function conf_set_cert( conf : ConfigPtr, cert : CertificatePtr, pkey : KeyPtr ) : Void { } @:hlNative("ssl","conf_set_servername_callback") static function conf_set_servername_callback( conf : ConfigPtr, cb : hl.Bytes -> SNICbResult ) : Void { } } haxe_3.4.4.orig/std/hl/types/ArrayBase.hx0000664000175000017500000000731113166552354020171 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl.types; @:keep class ArrayAccess { public function getDyn( pos : Int ) : Dynamic { throw "Not implemented"; return 0; } public function setDyn( pos : Int, v : Dynamic ) { throw "Not implemented"; } public function blit( pos : Int, src : ArrayAccess, srcpos : Int, len : Int ) : Void { throw "Not implemented"; } } @:keep class ArrayBase extends ArrayAccess { public var length(default,null) : Int; public function pushDyn( v : Dynamic ) : Int { throw "Not implemented"; return 0; } public function popDyn() : Null { throw "Not implemented"; return null; } public function shiftDyn() : Null { throw "Not implemented"; return null; } public function unshiftDyn( v : Dynamic ) : Void { throw "Not implemented"; } public function insertDyn( pos : Int, v : Dynamic ) : Void { throw "Not implemented"; } public function removeDyn( v : Dynamic ) : Bool { throw "Not implemented"; return false; } public function sortDyn( f : Dynamic -> Dynamic -> Int ) : Void { throw "Not implemented"; } public function slice( pos : Int, ?end : Int ) : ArrayBase{ throw "Not implemented"; return null; } public function splice( pos : Int, len : Int ) : ArrayBase{ throw "Not implemented"; return null; } public function join( sep : String ) : String { throw "Not implemented"; return null; } public function reverse() { throw "Not implemented"; } public function toString() : String { throw "Not implemented"; return null; } function __cast( t : Type ) : Dynamic { if( t == Type.get(new ArrayDyn()) ) return ArrayDyn.alloc(this, false); return null; } function isArrayObj() { return false; } public static function allocI32( bytes : BytesAccess, length : Int ) @:privateAccess { var a : ArrayBytes.ArrayI32 = untyped $new(ArrayBytes.ArrayI32); a.length = length; a.bytes = bytes; a.size = length; return a; } public static function allocUI16( bytes : BytesAccess, length : Int ) @:privateAccess { var a : ArrayBytes.ArrayUI16 = untyped $new(ArrayBytes.ArrayUI16); a.length = length; a.bytes = bytes; a.size = length; return a; } public static function allocF32( bytes : BytesAccess, length : Int ) @:privateAccess { var a : ArrayBytes.ArrayF32 = untyped $new(ArrayBytes.ArrayF32); a.length = length; a.bytes = bytes; a.size = length; return a; } public static function allocF64( bytes : BytesAccess, length : Int ) @:privateAccess { var a : ArrayBytes.ArrayF64 = untyped $new(ArrayBytes.ArrayF64); a.length = length; a.bytes = bytes; a.size = length; return a; } } haxe_3.4.4.orig/std/hl/types/ArrayBytes.hx0000664000175000017500000002020213166552354020377 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl.types; @:keep @:generic class BytesIterator { var pos : Int; var a : ArrayBytes; public function new(a) { this.a = a; } public function hasNext() { return pos < a.length; } public function next() : T { return @:privateAccess a.bytes.get(pos++); } } @:keep @:generic class ArrayBytes extends ArrayBase { var bytes : hl.BytesAccess; var size : Int; public function new() { size = length = 0; bytes = null; } public function concat( a : ArrayBytes ) : ArrayBytes { var ac = new ArrayBytes(); ac.length = ac.size = length + a.length; ac.bytes = new Bytes(ac.length << bytes.sizeBits); var offset = length << bytes.sizeBits; (ac.bytes:Bytes).blit(0, this.bytes, 0, offset); (ac.bytes:Bytes).blit(offset, a.bytes, 0, a.length << bytes.sizeBits); return ac; } override function join( sep : String ) : String { var s = new StringBuf(); for( i in 0...length ) { if( i > 0 ) s.add(sep); s.add(bytes[i]); } return s.toString(); } public function pop() : Null { if( length == 0 ) return null; length--; return bytes[length]; } public function push(x : T) : Int { var len = length; if( size == len ) __expand(len); else length++; bytes[len] = x; return length; } override function reverse() : Void { for( i in 0...length >> 1 ) { var k = length - 1 - i; var tmp = bytes[i]; bytes[i] = bytes[k]; bytes[k] = tmp; } } public function shift() : Null { if( length == 0 ) return null; var v = bytes[0]; length--; (bytes:Bytes).blit(0, bytes, 1 << bytes.sizeBits, length << bytes.sizeBits); return v; } override function blit( pos : Int, src : ArrayBase.ArrayAccess, srcpos : Int, len : Int ) : Void { var src = (cast src : ArrayBytes); if( pos < 0 || srcpos < 0 || len < 0 || pos + len > length || srcpos + len > src.length ) throw haxe.io.Error.OutsideBounds; (bytes:Bytes).blit(pos << bytes.sizeBits,src.bytes,srcpos< { if( pos < 0 ) { pos = this.length + pos; if( pos < 0 ) pos = 0; } var pend : Int; if( end == null ) pend = this.length; else { pend = end; if( pend < 0 ) pend += this.length; if( pend > this.length ) pend = this.length; } var len = pend - pos; if( len < 0 ) return new ArrayBytes(); var a = new ArrayBytes(); a.length = a.size = len; a.bytes = (bytes:Bytes).sub(pos << bytes.sizeBits, len << bytes.sizeBits); return a; } public function sort( f : T -> T -> Int ) : Void { if( Type.get((cast null : T)) == Type.get(0) ) (bytes:Bytes).sortI32(0, length, cast f); else (bytes:Bytes).sortF64(0, length, cast f); } override function splice( pos : Int, len : Int ) : ArrayBytes { if( len < 0 ) return new ArrayBytes(); if( pos < 0 ){ pos = this.length + pos; if( pos < 0 ) pos = 0; } if( pos > this.length ) { pos = 0; len = 0; } else if( pos + len > this.length ) { len = this.length - pos; if( len < 0 ) len = 0; } if( len == 0 ) return new ArrayBytes(); var ret = new ArrayBytes(); ret.bytes = (bytes:Bytes).sub(pos << bytes.sizeBits, len << bytes.sizeBits); ret.size = ret.length = len; var end = pos + len; (bytes:Bytes).blit(pos << bytes.sizeBits, bytes, end << bytes.sizeBits, (length - end) << bytes.sizeBits); length -= len; return ret; } override function toString() : String { var b = new StringBuf(); b.addChar("[".code); for( i in 0...length ) { if( i > 0 ) b.addChar(",".code); b.add(bytes[i]); } b.addChar("]".code); return b.toString(); } public function unshift( x : T ) : Void { if( length == size ) __expand(length) else length++; (bytes:Bytes).blit(1< length ) pos = length; if( length == size ) __expand(length) else length++; (bytes:Bytes).blit((pos + 1)<= len ) i = len - 1; else if( i < 0 ) i += len; while( i >= 0 ) { if( bytes[i] == x ) return i; i--; } return -1; } public function copy() : ArrayBytes { var a = new ArrayBytes(); a.length = a.size = length; a.bytes = new Bytes(length << bytes.sizeBits); (a.bytes:Bytes).blit(0, bytes, 0, length << bytes.sizeBits); return a; } public function iterator() : Iterator { return new BytesIterator(this); } public function map( f : T -> S ) : ArrayDyn @:privateAccess { var a = new ArrayObj(); if( length > 0 ) a.__expand(length - 1); for( i in 0...length ) a.array[i] = f(bytes[i]); return ArrayDyn.alloc(a,true); } public function filter( f : T -> Bool ) : ArrayBytes { var a = new ArrayBytes(); for( i in 0...length ) { var v = bytes[i]; if( f(v) ) a.push(v); } return a; } override function getDyn( pos : Int ) : Dynamic { var pos : UInt = pos; if( pos >= length ) return bytes.nullValue; return bytes[pos]; } override function setDyn( pos : Int, v : Dynamic ) { var pos : UInt = pos; if( pos >= length ) __expand(pos); bytes[pos] = v; } override function pushDyn( v : Dynamic ) return push(v); override function popDyn() : Null return pop(); override function shiftDyn() : Null return shift(); override function unshiftDyn( v : Dynamic ) unshift(v); override function insertDyn( pos : Int, v : Dynamic ) insert(pos, v); override function removeDyn( v : Dynamic ) return remove(v); override function sortDyn( f : Dynamic -> Dynamic -> Int ) sort(f); // called by compiler when accessing the array outside of its bounds, might trigger resize function __expand( index : Int ) { if( index < 0 ) throw "Invalid array index "+index; var newlen = index + 1; if( newlen > size ) { var next = (size * 3) >> 1; if( next < newlen ) next = newlen; var bytes2 = new hl.Bytes(next << bytes.sizeBits); var bsize = length << bytes.sizeBits; bytes2.blit(0, bytes, 0, bsize); bytes2.fill(bsize, (next << bytes.sizeBits) - bsize, 0); bytes = bytes2; size = next; } length = newlen; } } typedef ArrayI32 = ArrayBytes; typedef ArrayUI16 = ArrayBytes; typedef ArrayF32 = ArrayBytes; typedef ArrayF64 = ArrayBytes; haxe_3.4.4.orig/std/hl/types/ArrayDyn.hx0000664000175000017500000001276513166552354020062 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl.types; import hl.types.ArrayBase; class ArrayDynIterator { var a : ArrayBase; var len : Int; var pos : Int; public function new(a) { this.a = a; this.len = a.length; this.pos = 0; } public function hasNext() { return pos < len; } public function next() { return a.getDyn(pos++); } } @:keep class ArrayDyn extends ArrayAccess { public var length(get,never) : Int; var array : ArrayBase; var allowReinterpret : Bool; public function new() { array = new ArrayObj(); allowReinterpret = true; } inline function get_length() return array.length; override function getDyn(i) { return array.getDyn(i); } override function setDyn(pos:Int, value:Dynamic) { array.setDyn(pos, value); } override function blit( pos : Int, src : ArrayAccess, srcpos : Int, len : Int ) : Void { array.blit(pos, src, srcpos, len); } public function concat( a : ArrayDyn ) : ArrayDyn { var a1 = array; var a2 = a.array; var alen = a1.length; var anew = new NativeArray(alen + a2.length); for( i in 0...alen ) anew[i] = a1.getDyn(i); for( i in 0...a2.length ) anew[i+alen] = a2.getDyn(i); return alloc(ArrayObj.alloc(anew),true); } public function join( sep : String ) : String { return array.join(sep); } public function pop() : Null { return array.popDyn(); } public function push(x : Dynamic) : Int { return array.pushDyn(x); } public function reverse() : Void { array.reverse(); } public function shift() : Null { return array.shiftDyn(); } public function slice( pos : Int, ?end : Int ) : ArrayDyn { return alloc(array.slice(pos,end),true); } public function sort( f : Dynamic -> Dynamic -> Int ) : Void { array.sortDyn(f); } public function splice( pos : Int, len : Int ) : ArrayDyn { return alloc(array.splice(pos,len),true); } public function toString() : String { return array.toString(); } public function unshift( x : Dynamic ) : Void { array.unshiftDyn(x); } public function insert( pos : Int, x : Dynamic ) : Void { array.insertDyn(pos,x); } public function remove( x : Dynamic ) : Bool { return array.removeDyn(x); } public function indexOf( x : Dynamic, ?fromIndex:Int ) : Int { var i : Int = fromIndex; var length = length; var array = array; while( i < length ) { if( array.getDyn(i) == x ) return i; i++; } return -1; } public function lastIndexOf( x : Dynamic, ?fromIndex:Int ) : Int { var len = length; var i:Int = fromIndex != null ? fromIndex : len - 1; if( i >= len ) i = len - 1; else if( i < 0 ) i += len; while( i >= 0 ) { if( array.getDyn(i) == x ) return i; i--; } return -1; } public function copy() : ArrayDyn { var a = new NativeArray(length); for( i in 0...length ) a[i] = array.getDyn(i); return alloc(ArrayObj.alloc(a),true); } public function iterator() : Iterator { return new ArrayDynIterator(array); } public function map( f : Dynamic -> Dynamic ) : ArrayDyn { var a = new NativeArray(length); for( i in 0...length ) a[i] = f(array.getDyn(i)); return alloc(ArrayObj.alloc(a),true); } public function filter( f : Dynamic -> Bool ) : ArrayDyn { var a = new ArrayObj(); for( i in 0...length ) { var v = array.getDyn(i); if( f(v) ) a.push(v); } return alloc(a,true); } function __get_field( fid : Int ) : Dynamic { if( fid == untyped $hash("length") ) return length; return null; } function __cast( t : Type ) : Dynamic { if( t == Type.getDynamic(array) ) return array; if( !allowReinterpret ) return null; if( t == Type.get(new ArrayBytes.ArrayI32()) ) { var a : BytesAccess = null; a = new Bytes(array.length << a.sizeBits); for( i in 0...array.length ) a[i] = array.getDyn(i); var arr = ArrayBase.allocI32(a, array.length); array = arr; allowReinterpret = false; return arr; } if( t == Type.get(new ArrayBytes.ArrayF64()) ) { var a : BytesAccess = null; a = new Bytes(array.length << a.sizeBits); for( i in 0...array.length ) a[i] = array.getDyn(i); var arr = ArrayBase.allocF64(a, array.length); array = arr; allowReinterpret = false; return arr; } return null; } public static function alloc( a : ArrayBase, allowReinterpret = false ) : ArrayDyn { var arr : ArrayDyn = untyped $new(ArrayDyn); arr.array = a; arr.allowReinterpret = allowReinterpret; return arr; } } haxe_3.4.4.orig/std/hl/types/ArrayObj.hx0000664000175000017500000001632213166552354020033 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl.types; @:keep class ArrayObj extends ArrayBase { var array : hl.NativeArray; public function new() { length = 0; array = new NativeArray(0); } public function concat( a : ArrayObj ) : ArrayObj { var arr = new hl.NativeArray(length + a.length); arr.blit(0, array, 0, length); arr.blit(length, a.array, 0, a.length); return alloc(cast arr); } override function join( sep : String ) : String { var b = new StringBuf(); for( i in 0...length ) { if( i > 0 ) b.add(sep); b.add(array[i]); } return b.toString(); } override function isArrayObj() { return true; } public function pop() : Null { if( length == 0 ) return null; length--; var v = array[length]; array[length] = null; return v; } public function push(x : T) : Int { var len = length; if( array.length == len ) __expand(len); else length++; array[len] = x; return length; } override function reverse() : Void { for( i in 0...length >> 1 ) { var k = length - 1 - i; var tmp = array[i]; array[i] = array[k]; array[k] = tmp; } } public function shift() : Null { if( length == 0 ) return null; length--; var v = array[0]; array.blit(0, array, 1, length); array[length] = null; return v; } override function slice( pos : Int, ?end : Int ) : ArrayObj { if( pos < 0 ) { pos = this.length + pos; if( pos < 0 ) pos = 0; } var pend : Int; if( end == null ) pend = this.length; else { pend = end; if( pend < 0 ) pend += this.length; if( pend > this.length ) pend = this.length; } var len = pend - pos; if( len < 0 ) return new ArrayObj(); return alloc(array.sub(pos,len)); } public function sort( f : T -> T -> Int ) : Void { // TODO : use native call ? haxe.ds.ArraySort.sort(cast this, f); } override function splice( pos : Int, len : Int ) : ArrayObj { if( len < 0 ) return new ArrayObj(); if( pos < 0 ){ pos = this.length + pos; if( pos < 0 ) pos = 0; } if( pos > this.length ) { pos = 0; len = 0; } else if( pos + len > this.length ) { len = this.length - pos; if( len < 0 ) len = 0; } var a = this.array; var ret : ArrayObj = alloc(cast a.sub(pos,len)); var end = pos + len; a.blit(pos,a,end,this.length-end); this.length -= len; while( --len >= 0 ) a[this.length + len] = null; return ret; } override function toString() : String { var b = new StringBuf(); b.addChar("[".code); for( i in 0...length ) { if( i > 0 ) b.addChar(",".code); b.add(array[i]); } b.addChar("]".code); return b.toString(); } public function unshift( x : T ) : Void { if( length == array.length ) __expand(length) else length++; array.blit(1, array, 0, length - 1); array[0] = x; } public function insert( pos : Int, x : T ) : Void { if( pos < 0 ) { pos = length + pos; if( pos < 0 ) pos = 0; } else if( pos > length ) pos = length; if( length == array.length ) __expand(length) else length++; array.blit(pos + 1, array, pos, length - pos - 1); array[pos] = x; } public function remove( x : T ) : Bool { var i = indexOf(x); if( i < 0 ) return false; length--; array.blit(i,array,i+1,length - i); array[length] = null; return true; } public function indexOf( x : T, ?fromIndex:Int ) : Int { var i : Int = fromIndex; if( i < 0 ) { i += length; if( i < 0 ) i = 0; } var length = length; var array = array; while( i < length ) { if( array[i] == x ) return i; i++; } return -1; } override function blit( pos : Int, src : ArrayBase.ArrayAccess, srcpos : Int, len : Int ) : Void { var src = (cast src : ArrayObj); if( pos < 0 || srcpos < 0 || len < 0 || pos + len > length || srcpos + len > src.length ) throw haxe.io.Error.OutsideBounds; array.blit(pos, src.array, srcpos, len); } public function lastIndexOf( x : T, ?fromIndex:Int ) : Int { var len = length; var i:Int = fromIndex != null ? fromIndex : len - 1; if( i >= len ) i = len - 1; else if( i < 0 ) i += len; while( i >= 0 ) { if( array[i] == x ) return i; i--; } return -1; } public function copy() : ArrayObj { var n = new NativeArray(length); n.blit(0, array, 0, length); return alloc(n); } public function iterator() : Iterator { var n = new NativeArray.NativeArrayIterator(cast array); @:privateAccess n.length = length; return n; } public function map( f : T -> S ) : ArrayDyn { var a = new ArrayObj(); if( length > 0 ) a.__expand(length - 1); for( i in 0...length ) a.array[i] = f(array[i]); return ArrayDyn.alloc(a,true); } public function filter( f : T -> Bool ) : ArrayObj { var a = new ArrayObj(); for( i in 0...length ) { var v = array[i]; if( f(v) ) a.push(v); } return a; } // called by compiler when accessing the array outside of its bounds, might trigger resize function __expand( index : Int ) { if( index < 0 ) throw "Invalid array index " + index; var newlen = index + 1; var size : Int = array.length; if( newlen > size ) { var next = (size * 3) >> 1; if( next < newlen ) next = newlen; var arr2 = new hl.NativeArray(next); arr2.blit(0,array,0,length); array = arr2; } length = newlen; } override function getDyn( pos : Int ) : Dynamic { var pos : UInt = pos; if( pos >= length ) return null; return array[pos]; } override function setDyn( pos : Int, v : Dynamic ) { var pos : UInt = pos; if( pos >= length ) __expand(pos); array[pos] = Api.safeCast(v,array.getType()); } override function pushDyn( v : Dynamic ) return push(v); override function popDyn() : Null return pop(); override function shiftDyn() : Null return shift(); override function unshiftDyn( v : Dynamic ) unshift(v); override function insertDyn( pos : Int, v : Dynamic ) insert(pos, v); override function removeDyn( v : Dynamic ) return remove(v); override function sortDyn( f : Dynamic -> Dynamic -> Int ) sort(f); public static function alloc( a : hl.NativeArray ) : ArrayObj { var arr : ArrayObj = untyped $new(ArrayObj); arr.array = a; arr.length = a.length; return arr; } } haxe_3.4.4.orig/std/hl/types/BytesMap.hx0000664000175000017500000000404113166552354020041 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl.types; typedef BytesMapData = Abstract<"hl_bytes_map">; abstract BytesMap(BytesMapData) { @:extern public inline function new() { this = alloc(); } @:hlNative("std","hballoc") static function alloc() : BytesMapData { return null; } @:hlNative("std","hbset") public function set( key : Bytes, value : Dynamic ) { } @:hlNative("std","hbexists") public function exists( key : Bytes ) : Bool { return false; } @:hlNative("std","hbget") public function get( key : Bytes ) : Dynamic { return null; } @:hlNative("std","hbremove") public function remove( key : Bytes ) : Bool { return false; } @:hlNative("std","hbkeys") public function keysArray() : NativeArray { return null; } @:hlNative("std","hbvalues") public function valuesArray() : NativeArray { return null; } @:extern public inline function iterator() { return new NativeArray.NativeArrayIterator(valuesArray()); } }haxe_3.4.4.orig/std/hl/types/IntMap.hx0000664000175000017500000000401513166552354017506 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl.types; typedef IntMapData = Abstract<"hl_int_map">; abstract IntMap(IntMapData) { @:extern public inline function new() { this = alloc(); } @:hlNative("std","hialloc") static function alloc() : IntMapData { return null; } @:hlNative("std","hiset") public function set( key : Int, value : Dynamic ) { } @:hlNative("std","hiexists") public function exists( key : Int ) : Bool { return false; } @:hlNative("std","higet") public function get( key : Int ) : Dynamic { return null; } @:hlNative("std","hiremove") public function remove( key : Int ) : Bool { return false; } @:hlNative("std","hikeys") public function keysArray() : NativeArray { return null; } @:hlNative("std","hivalues") public function valuesArray() : NativeArray { return null; } @:extern public inline function iterator() { return new NativeArray.NativeArrayIterator(valuesArray()); } }haxe_3.4.4.orig/std/hl/types/ObjectMap.hx0000664000175000017500000000405513166552354020166 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package hl.types; typedef ObjectMapData = Abstract<"hl_obj_map">; abstract ObjectMap(ObjectMapData) { @:extern public inline function new() { this = alloc(); } @:hlNative("std","hoalloc") static function alloc() : ObjectMapData { return null; } @:hlNative("std","hoset") public function set( key : Dynamic, value : Dynamic ) { } @:hlNative("std","hoexists") public function exists( key : Dynamic ) : Bool { return false; } @:hlNative("std","hoget") public function get( key : Dynamic ) : Dynamic { return null; } @:hlNative("std","horemove") public function remove( key : Dynamic ) : Bool { return false; } @:hlNative("std","hokeys") public function keysArray() : NativeArray { return null; } @:hlNative("std","hovalues") public function valuesArray() : NativeArray { return null; } @:extern public inline function iterator() { return new NativeArray.NativeArrayIterator(valuesArray()); } }haxe_3.4.4.orig/std/java/Boot.hx0000664000175000017500000000347213166552354016401 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java; import java.internal.Exceptions; import java.internal.Function; import java.internal.HxObject; import java.internal.Runtime; // TODO (see Gencommon.IteratorsInterfaceModf) //import java.internal.Iterator; import java.Lib; //import java.internal.StringExt; import java.StdTypes; import Reflect; import Map; import haxe.ds.StringMap; import java.lang.Boolean; import java.lang.Character; import java.lang.Class; import java.lang.Number; import java.lang.Byte; import java.lang.Double; import java.lang.Float; import java.lang.Integer; import java.lang.Long; import java.lang.Short; import java.lang.Throwable; import java.internal.StringExt; import java.internal.FieldLookup; @:dox(hide) extern class Boot { } haxe_3.4.4.orig/std/java/Lib.hx0000664000175000017500000001251113166552354016176 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java; /** Platform-specific Java Library. Provides some platform-specific functions for the Java target, such as conversion from Haxe types to native types and vice-versa. **/ //we cannot use the java package for custom classes, so we're redefining it as "haxe.java.Lib" @:native('haxe.java.Lib') class Lib { /** Returns a native array from the supplied Array. This native array is unsafe to be written on, as it may or may not be linked to the actual Array implementation. If `equalLengthRequired` is true, the result might be a copy of an array with the correct size. **/ inline public static function nativeArray(arr:Array, equalLengthRequired:Bool):NativeArray { var ret = new NativeArray(arr.length); for (i in 0...arr.length) { ret[i] = arr[i]; } return ret; } /** Gets the native `java.lang.Class` from the supplied object. Will throw an exception in case of null being passed. [deprecated] - use `getNativeType` instead **/ @:deprecated('The function `nativeType` is deprecated and will be removed in later versions. Please use `getNativeType` instead') inline public static function nativeType(obj:T):java.lang.Class { return untyped obj.getClass(); } /** Gets the native `java.lang.Class` from the supplied object. Will throw an exception in case of null being passed. **/ inline public static function getNativeType(obj:T):java.lang.Class { return untyped obj.getClass(); } /** Returns a Class<> equivalent to the native java.lang.Class type. **/ public static inline function fromNativeType(t:java.lang.Class):Class { return untyped t; } /** Returns a java.lang.Class equivalent to the Haxe Class<> type. **/ public static inline function toNativeType(cl:Class):java.lang.Class { return untyped cl; } /** Returns a java.lang.Class equivalent to the Haxe Enum<> type. **/ public static inline function toNativeEnum(cl:Enum):java.lang.Class { return untyped cl; } /** Returns a Haxe Array of a native Array. Unless `copy` is true, it won't copy the contents of the native array, so unless any operation triggers an array resize, all changes made to the Haxe array will affect the native array argument. **/ @:generic public static function array(native:java.NativeArray):Array { return untyped Array.ofNative(native); } @:extern inline private static function doArray(native:java.NativeArray):Array { var ret:NativeArray = new NativeArray(native.length); for (i in 0...native.length) { ret[i] = native[i]; } return untyped Array.ofNative(ret); } public static function array_Int(native:java.NativeArray):Array { return doArray(native); } public static function array_Float(native:java.NativeArray):Array { return doArray(native); } public static function array_Bool(native:java.NativeArray):Array { return doArray(native); } public static function array_java_Int8(native:java.NativeArray):Array { return doArray(native); } public static function array_java_Int16(native:java.NativeArray):Array { return doArray(native); } public static function array_java_Char16(native:java.NativeArray):Array { return doArray(native); } public static function array_Single(native:java.NativeArray):Array { return doArray(native); } public static function array_haxe_Int64(native:java.NativeArray):Array { return doArray(native); } /** Allocates a new Haxe Array with a predetermined size **/ public static function arrayAlloc(size:Int):Array { return untyped Array.alloc(size); } /** Ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread attempts to enter a locked code, it will wait, block, until the object is released. This is the equivalent to "synchronized" in java code. This method only exists at compile-time, so it can't be called via reflection. **/ @:extern public static inline function lock(obj:Dynamic, block:T):Void { untyped __lock__(obj, block); } } haxe_3.4.4.orig/std/java/NativeArray.hx0000664000175000017500000000316613166552354017723 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java; import haxe.extern.Rest; /** Represents a java fixed-size Array (`T[]`) **/ @:nativeGen extern class NativeArray implements ArrayAccess { /** Creates a new array with the specified elements. Usage: ```haxe var elements = NativeArray.make(1,2,3,4,5,6); ``` **/ public static function make(elements:Rest):NativeArray; /** The length of the array **/ public var length(default, null):Int; /** Allocates a new array with size `len` **/ public function new(len:Int):Void; } haxe_3.4.4.orig/std/java/StdTypes.hx0000664000175000017500000000671213166552354017255 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java; @:notNull @:runtimeValue @:coreType extern abstract Int8 from Int {} @:notNull @:runtimeValue @:coreType extern abstract Int16 from Int {} @:notNull @:runtimeValue @:coreType extern abstract Char16 from Int {} @:notNull @:runtimeValue @:coreType extern abstract Int64 from Int from Float { @:op(A+B) public static function addI(lhs:Int64, rhs:Int):Int64; @:op(A+B) public static function add(lhs:Int64, rhs:Int64):Int64; @:op(A*B) public static function mulI(lhs:Int64, rhs:Int):Int64; @:op(A*B) public static function mul(lhs:Int64, rhs:Int64):Int64; @:op(A%B) public static function modI(lhs:Int64, rhs:Int):Int64; @:op(A%B) public static function mod(lhs:Int64, rhs:Int64):Int64; @:op(A-B) public static function subI(lhs:Int64, rhs:Int):Int64; @:op(A-B) public static function sub(lhs:Int64, rhs:Int64):Int64; @:op(A/B) public static function divI(lhs:Int64, rhs:Int):Int64; @:op(A/B) public static function div(lhs:Int64, rhs:Int64):Int64; @:op(A|B) public static function orI(lhs:Int64, rhs:Int):Int64; @:op(A|B) public static function or(lhs:Int64, rhs:Int64):Int64; @:op(A^B) public static function xorI(lhs:Int64, rhs:Int):Int64; @:op(A^B) public static function xor(lhs:Int64, rhs:Int64):Int64; @:op(A&B) public static function andI(lhs:Int64, rhs:Int):Int64; @:op(A&B) public static function and(lhs:Int64, rhs:Int64):Int64; @:op(A<>B) public static function shrI(lhs:Int64, rhs:Int):Int64; @:op(A>>B) public static function shr(lhs:Int64, rhs:Int64):Int64; @:op(A>>>B) public static function ushrI(lhs:Int64, rhs:Int):Int64; @:op(A>>>B) public static function ushr(lhs:Int64, rhs:Int64):Int64; @:op(A>B) public static function gt(lhs:Int64, rhs:Int64):Bool; @:op(A>=B) public static function gte(lhs:Int64, rhs:Int64):Bool; @:op(A implements ArrayAccess { public var length(default,null) : Int; private var __a:NativeArray; @:functionCode(' return new Array(_native); ') private static function ofNative(native:NativeArray):Array { return null; } @:functionCode(' return new Array((Y[]) ((java.lang.Object)new java.lang.Object[size])); ') private static function alloc(size:Int):Array { return null; } public function new() : Void { this.length = 0; this.__a = new NativeArray(0); } public function concat( a : Array ) : Array { var length = length; var len = length + a.length; var retarr = new NativeArray(len); System.arraycopy(__a, 0, retarr, 0, length); System.arraycopy(a.__a, 0, retarr, length, a.length); return ofNative(retarr); } private function concatNative( a : NativeArray ) : Void { var __a = __a; var length = length; var len = length + a.length; if (__a.length >= len) { System.arraycopy(a, 0, __a, length, length); } else { var newarr = new NativeArray(len); System.arraycopy(__a, 0, newarr, 0, length); System.arraycopy(a, 0, newarr, length, a.length); this.__a = newarr; } this.length = len; } public function join( sep : String ) : String { var buf = new StringBuf(); var i = -1; var first = true; var length = length; while (++i < length) { if (first) first = false; else buf.add(sep); buf.add(__a[i]); } return buf.toString(); } public function pop() : Null { var __a = __a; var length = length; if (length > 0) { var val = __a[--length]; __a[length] = null; this.length = length; return val; } else { return null; } } public function push(x : T) : Int { var length = length; if (length >= __a.length) { var newLen = (length << 1) + 1; var newarr = new NativeArray(newLen); System.arraycopy(__a, 0, newarr, 0, __a.length); this.__a = newarr; } __a[length] = x; return ++this.length; } public function reverse() : Void { var i = 0; var l = this.length; var a = this.__a; var half = l >> 1; l -= 1; while ( i < half ) { var tmp = a[i]; a[i] = a[l-i]; a[l-i] = tmp; i += 1; } } public function shift() : Null { var l = this.length; if( l == 0 ) return null; var a = this.__a; var x = a[0]; l -= 1; System.arraycopy(a, 1, a, 0, length-1); a[l] = null; this.length = l; return x; } public function slice( pos : Int, ?end : Int ) : Array { if( pos < 0 ){ pos = this.length + pos; if( pos < 0 ) pos = 0; } if( end == null ) end = this.length; else if( end < 0 ) end = this.length + end; if( end > this.length ) end = this.length; var len = end - pos; if ( len < 0 ) return new Array(); var newarr = new NativeArray(len); System.arraycopy(__a, pos, newarr, 0, len); return ofNative(newarr); } public function sort( f : T -> T -> Int ) : Void { if (length == 0) return; quicksort(0, length - 1, f); } private function quicksort( lo : Int, hi : Int, f : T -> T -> Int ) : Void { var buf = __a; var i = lo, j = hi; var p = buf[(i + j) >> 1]; while ( i <= j ) { while ( i < hi && f(buf[i], p) < 0 ) i++; while ( j > lo && f(buf[j], p) > 0 ) j--; if ( i <= j ) { var t = buf[i]; buf[i++] = buf[j]; buf[j--] = t; } } if( lo < j ) quicksort( lo, j, f ); if( i < hi ) quicksort( i, hi, f ); } public function splice( pos : Int, len : Int ) : Array { if( len < 0 ) return new Array(); if( pos < 0 ) { pos = this.length + pos; if( pos < 0 ) pos = 0; } if( pos > this.length ) { pos = 0; len = 0; } else if( pos + len > this.length ) { len = this.length - pos; if( len < 0 ) len = 0; } var a = this.__a; var ret = new NativeArray(len); System.arraycopy(a, pos, ret, 0, len); var ret = ofNative(ret); var end = pos + len; System.arraycopy(a, end, a, pos, this.length - end); this.length -= len; while( --len >= 0 ) a[this.length + len] = null; return ret; } private function spliceVoid( pos : Int, len : Int ) : Void { if( len < 0 ) return; if( pos < 0 ) { pos = this.length + pos; if( pos < 0 ) pos = 0; } if( pos > this.length ) { pos = 0; len = 0; } else if( pos + len > this.length ) { len = this.length - pos; if( len < 0 ) len = 0; } var a = this.__a; var end = pos + len; System.arraycopy(a, end, a, pos, this.length - end); this.length -= len; while( --len >= 0 ) a[this.length + len] = null; } public function toString() : String { var ret = new StringBuf(); var a = __a; ret.add("["); var first = true; for (i in 0...length) { if (first) first = false; else ret.add(","); ret.add(a[i]); } ret.add("]"); return ret.toString(); } public function unshift( x : T ) : Void { var __a = __a; var length = length; if (length >= __a.length) { var newLen = (length << 1) + 1; var newarr = new NativeArray(newLen); System.arraycopy(__a, 0, newarr, 1, length); this.__a = newarr; } else { System.arraycopy(__a, 0, __a, 1, length); } this.__a[0] = x; ++this.length; } public function insert( pos : Int, x : T ) : Void { var l = this.length; if( pos < 0 ) { pos = l + pos; if( pos < 0 ) pos = 0; } if ( pos >= l ) { this.push(x); return; } else if (pos == 0) { this.unshift(x); return; } if (l >= __a.length) { var newLen = (length << 1) + 1; var newarr = new NativeArray(newLen); System.arraycopy(__a, 0, newarr, 0, pos); newarr[pos] = x; System.arraycopy(__a, pos, newarr, pos + 1, l - pos); this.__a = newarr; ++this.length; } else { var __a = __a; System.arraycopy(__a, pos, __a, pos + 1, l - pos); System.arraycopy(__a, 0, __a, 0, pos); __a[pos] = x; ++this.length; } } public function remove( x : T ) : Bool { var __a = __a; var i = -1; var length = length; while (++i < length) { if (__a[i] == x) { System.arraycopy(__a, i + 1, __a, i, length - i - 1); __a[--this.length] = null; return true; } } return false; } public function indexOf(x : T, ?fromIndex:Int) : Int { var len = length, a = __a, i:Int = (fromIndex == null) ? 0 : fromIndex; if (i < 0) { i += len; if (i < 0) i = 0; } while (i < len) { if (a[i] == x) return i; i++; } return -1; } public function lastIndexOf(x : T, ?fromIndex:Int) : Int { var len = length, a = __a, i:Int = (fromIndex == null) ? len - 1 : fromIndex; if (i >= len) i = len - 1; else if (i < 0) i += len; while (i >= 0) { if (a[i] == x) return i; i--; } return -1; } public function copy() : Array { var len = length; var __a = __a; var newarr = new NativeArray(len); System.arraycopy(__a, 0, newarr, 0, len); return ofNative(newarr); } public inline function iterator() : Iterator { return new ArrayIterator(this); } public function map( f : T -> S ) : Array { var ret = []; for (elt in this) ret.push(f(elt)); return ret; } public function filter( f : T -> Bool ) : Array { var ret = []; for (elt in this) if (f(elt)) ret.push(elt); return ret; } private function __get(idx:Int):T { var __a = __a; if (idx >= __a.length || idx < 0) return null; return __a[idx]; } private function __set(idx:Int, v:T):T { var __a = __a; if (idx >= __a.length) { var newl = idx + 1; if (idx == __a.length) newl = (idx << 1) + 1; var newArr = new NativeArray(newl); if (length > 0) System.arraycopy(__a, 0, newArr, 0, length); this.__a = __a = newArr; } if (idx >= length) this.length = idx + 1; return __a[idx] = v; } private inline function __unsafe_get(idx:Int):T { return __a[idx]; } private inline function __unsafe_set(idx:Int, val:T):T { return __a[idx] = val; } } @:final private class ArrayIterator { var arr:Array; var len:Int; var i:Int; public inline function new(a:Array) { arr = a; len = a.length; i = 0; } public inline function hasNext():Bool return i < len; public inline function next():T return arr[i++]; } haxe_3.4.4.orig/std/java/_std/Date.hx0000664000175000017500000000663313166552354017306 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package; import haxe.Int64; @:SuppressWarnings("deprecation") @:coreApi class Date { private var date:java.util.Date; public function new(year : Int, month : Int, day : Int, hour : Int, min : Int, sec : Int ) : Void { //issue #1769 year = year != 0 ? year - 1900 : 0; date = new java.util.Date(year, month, day, hour, min, sec); } public inline function getTime() : Float { return cast date.getTime(); } public inline function getHours() : Int { return date.getHours(); } public inline function getMinutes() : Int { return date.getMinutes(); } public inline function getSeconds() : Int { return date.getSeconds(); } public inline function getFullYear() : Int { return date.getYear() + 1900; } public inline function getMonth() : Int { return date.getMonth(); } public inline function getDate() : Int { return date.getDate(); } public inline function getDay() : Int { return date.getDay(); } public function toString():String { var m = date.getMonth() + 1; var d = date.getDate(); var h = date.getHours(); var mi = date.getMinutes(); var s = date.getSeconds(); return (date.getYear() + 1900) +"-"+(if( m < 10 ) "0"+m else ""+m) +"-"+(if( d < 10 ) "0"+d else ""+d) +" "+(if( h < 10 ) "0"+h else ""+h) +":"+(if( mi < 10 ) "0"+mi else ""+mi) +":"+(if( s < 10 ) "0"+s else ""+s); } static public function now() : Date { var d = new Date(0, 0, 0, 0, 0, 0); d.date = new java.util.Date(); return d; } static public function fromTime( t : Float ) : Date { var d = new Date(0, 0, 0, 0, 0, 0); d.date = new java.util.Date(cast(t, Int64)); return d; } static public function fromString( s : String ) : Date { switch( s.length ) { case 8: // hh:mm:ss var k = s.split(":"); var d : Date = new Date(0, 0, 0, Std.parseInt(k[0]), Std.parseInt(k[1]), Std.parseInt(k[2])); return d; case 10: // YYYY-MM-DD var k = s.split("-"); return new Date(Std.parseInt(k[0]),Std.parseInt(k[1]) - 1,Std.parseInt(k[2]),0,0,0); case 19: // YYYY-MM-DD hh:mm:ss var k = s.split(" "); var y = k[0].split("-"); var t = k[1].split(":"); return new Date(Std.parseInt(y[0]),Std.parseInt(y[1]) - 1,Std.parseInt(y[2]),Std.parseInt(t[0]),Std.parseInt(t[1]),Std.parseInt(t[2])); default: throw "Invalid date format : " + s; } } } haxe_3.4.4.orig/std/java/_std/EReg.hx0000664000175000017500000001060113166552354017241 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import java.util.regex.*; @:coreApi class EReg { private var pattern:String; private var matcher:Matcher; private var cur:String; private var isGlobal:Bool; public function new( r : String, opt : String ) { var flags = 0; for (i in 0...opt.length) { switch(StringTools.fastCodeAt(opt, i)) { case 'i'.code: flags |= Pattern.CASE_INSENSITIVE; case 'm'.code: flags |= Pattern.MULTILINE; case 's'.code: flags |= Pattern.DOTALL; case 'g'.code: isGlobal = true; } } matcher = Pattern.compile(convert(r), flags).matcher(""); pattern = r; } private static function convert(r:String):String { //some references of the implementation: //http://stackoverflow.com/questions/809647/java-vs-javascript-regex-problem //http://stackoverflow.com/questions/4788413/how-to-convert-javascript-regex-to-safe-java-regex //Some necessary changes: // // \0 -> \x00 // \v -> \x0b // [^] -> [\s\S] // unescaped ', " -> \', \" /* FIXME var pat = new StringBuf(); var len = r.length; var i = 0; while (i < len) { var c = StringTools.fastCodeAt(r, i++); switch(c) { case '\\'.code: //escape-sequence } } */ return r; } public function match( s : String ) : Bool { cur = s; matcher = matcher.reset(s); return matcher.find(); } public function matched( n : Int ) : String { if (n == 0) return matcher.group(); else return matcher.group(n); } public function matchedLeft() : String { return untyped cur.substring(0, matcher.start()); } public function matchedRight() : String { return untyped cur.substring(matcher.end(), cur.length); } public function matchedPos() : { pos : Int, len : Int } { var start = matcher.start(); return { pos : start, len : matcher.end() - start }; } public function matchSub( s : String, pos : Int, len : Int = -1):Bool { matcher = matcher.reset(len < 0 ? s : s.substr(0,pos + len)); cur = s; return matcher.find(pos); } public function split( s : String ) : Array { if (isGlobal) { var ret = []; while(this.match(s)) { ret.push(matchedLeft()); s = matchedRight(); } ret.push(s); return ret; } else { var m = matcher; m.reset(s); if (m.find()) { return untyped [s.substring(0, m.start()), s.substring(m.end(), s.length)]; } else { return [s]; } } } inline function start(group:Int) : Int { return matcher.start(group); } inline function len(group:Int) : Int { return matcher.end(group) - matcher.start(group); } public function replace( s : String, by : String ) : String { matcher.reset(s); by = by.split("$$").join("\\$"); return isGlobal ? matcher.replaceAll(by) : matcher.replaceFirst(by); } public function map( s : String, f : EReg -> String ) : String { var offset = 0; var buf = new StringBuf(); do { if (offset >= s.length) break; else if (!matchSub(s, offset)) { buf.add(s.substr(offset)); break; } var p = matchedPos(); buf.add(s.substr(offset, p.pos - offset)); buf.add(f(this)); if (p.len == 0) { buf.add(s.substr(p.pos, 1)); offset = p.pos + 1; } else offset = p.pos + p.len; } while (isGlobal); if (!isGlobal && offset > 0 && offset < s.length) buf.add(s.substr(offset)); return buf.toString(); } } haxe_3.4.4.orig/std/java/_std/Math.hx0000664000175000017500000000442113166552354017313 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi @:native("java.lang.Math") extern class Math { static var PI(default,null) : Float; static var NaN(default,null) : Float; static var NEGATIVE_INFINITY(default,null) : Float; static var POSITIVE_INFINITY(default,null) : Float; static function abs(v:Float):Float; static function min(a:Float,b:Float):Float; static function max(a:Float,b:Float):Float; static function sin(v:Float):Float; static function cos(v:Float):Float; static function atan2(y:Float,x:Float):Float; static function tan(v:Float):Float; static function exp(v:Float):Float; static function log(v:Float):Float; static function sqrt(v:Float):Float; static function round(v:Float):Int; static function floor(v:Float):Int; static function ceil(v:Float):Int; static function atan(v:Float):Float; inline static function fround(v:Float):Float { return ffloor(v + 0.5); } static function ffloor(v:Float):Float; static function fceil(v:Float):Float; static function asin(v:Float):Float; static function acos(v:Float):Float; static function pow(v:Float,exp:Float):Float; static function random() : Float; static function isFinite( f : Float ) : Bool; static function isNaN( f : Float ) : Bool; } haxe_3.4.4.orig/std/java/_std/Reflect.hx0000664000175000017500000001106213166552354020005 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import java.internal.Function; import java.internal.HxObject; import java.internal.Runtime; import java.Boot; @:coreApi class Reflect { public static function hasField( o : Dynamic, field : String ) : Bool { if (Std.is(o, IHxObject)) { return untyped (o : IHxObject).__hx_getField(field, false, true, false) != Runtime.undefined; } return Runtime.slowHasField(o, field); } @:keep public static function field( o : Dynamic, field : String ) : Dynamic { if (Std.is(o, IHxObject)) { return untyped (o : IHxObject).__hx_getField(field, false, false, false); } return Runtime.slowGetField(o, field, false); } @:keep public static function setField( o : Dynamic, field : String, value : Dynamic ) : Void { if (Std.is(o, IHxObject)) { untyped (o : IHxObject).__hx_setField(field, value, false); } else { Runtime.slowSetField(o, field, value); } } public static function getProperty( o : Dynamic, field : String ) : Dynamic { if (Std.is(o, IHxObject)) { return untyped (o : IHxObject).__hx_getField(field, false, false, true); } if (Runtime.slowHasField(o, "get_" + field)) { return Runtime.slowCallField(o, "get_" + field, null); } return Runtime.slowGetField(o, field, false); } public static function setProperty( o : Dynamic, field : String, value : Dynamic ) : Void { if (Std.is(o, IHxObject)) { untyped (o : IHxObject).__hx_setField(field, value, true); } else if (Runtime.slowHasField(o, "set_" + field)) { Runtime.slowCallField(o, "set_" + field, [value]); } else { Runtime.slowSetField(o, field, value); } } public static function callMethod( o : Dynamic, func : haxe.Constraints.Function, args : Array ) : Dynamic { return untyped (func : Function).__hx_invokeDynamic(args); } @:keep public static function fields( o : Dynamic ) : Array { if (Std.is(o, IHxObject)) { var ret:Array = []; untyped (o : IHxObject).__hx_getFields(ret); return ret; } else if (Std.is(o, java.lang.Class)) { return Type.getClassFields(cast o); } else { return []; } } public static function isFunction( f : Dynamic ) : Bool { return Std.is(f, Function); } public static function compare( a : T, b : T ) : Int { return Runtime.compare(a, b); } @:access(java.internal.Closure) public static function compareMethods( f1 : Dynamic, f2 : Dynamic ) : Bool { if (f1 == f2) { return true; } if (Std.is(f1, Closure) && Std.is(f2, Closure)) { var f1c:Closure = cast f1; var f2c:Closure = cast f2; return Runtime.refEq(f1c.obj, f2c.obj) && f1c.field == f2c.field; } return false; } public static function isObject( v : Dynamic ) : Bool { return v != null && !(Std.is(v, HxEnum) || Std.is(v, Function) || Std.is(v, java.lang.Enum) || Std.is(v, java.lang.Number) || Std.is(v, java.lang.Boolean.BooleanClass)); } public static function isEnumValue( v : Dynamic ) : Bool { return v != null && (Std.is(v, HxEnum) || Std.is(v, java.lang.Enum)); } public static function deleteField( o : Dynamic, field : String ) : Bool { return (Std.is(o, DynamicObject) && (o : DynamicObject).__hx_deleteField(field)); } public static function copy( o : T ) : T { var o2 : Dynamic = {}; for( f in Reflect.fields(o) ) Reflect.setField(o2,f,Reflect.field(o,f)); return cast o2; } @:overload(function( f : Array -> Void ) : Dynamic {}) public static function makeVarArgs( f : Array -> Dynamic ) : Dynamic { return new VarArgsFunction(f); } } haxe_3.4.4.orig/std/java/_std/Std.hx0000664000175000017500000001113713166552354017156 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import java.Boot; import java.Lib; import java.internal.Exceptions; @:coreApi @:nativeGen class Std { public static function is( v : Dynamic, t : Dynamic ) : Bool { if (v == null) return t == Dynamic; if (t == null) return false; var clt:java.lang.Class = cast t; if (clt == null) return false; var name:String = clt.getName(); switch(name) { case "double", "java.lang.Double": return untyped __java__('haxe.lang.Runtime.isDouble(v)'); case "int", "java.lang.Integer": return untyped __java__('haxe.lang.Runtime.isInt(v)'); case "boolean", "java.lang.Boolean": return untyped __java__('v instanceof java.lang.Boolean'); case "java.lang.Object": return true; } var clv:java.lang.Class = untyped __java__('v.getClass()'); return clt.isAssignableFrom(clv); } public static function string( s : Dynamic ) : String { return cast(s, String) + ""; } public static function int( x : Float ) : Int { return cast x; } @:functionCode(' if (x == null) return null; int ret = 0; int base = 10; int i = 0; int len = x.length(); if (x.startsWith("0") && len > 2) { char c = x.charAt(1); if (c == \'x\' || c == \'X\') { i = 2; base = 16; } } boolean foundAny = i != 0; boolean isNeg = false; for (; i < len; i++) { char c = x.charAt(i); if (!foundAny) { switch(c) { case \'-\': isNeg = true; continue; case \'+\': case \'\\n\': case \'\\t\': case \'\\r\': case \' \': if (isNeg) return null; continue; } } if (c >= \'0\' && c <= \'9\') { if (!foundAny && c == \'0\') { foundAny = true; continue; } ret *= base; foundAny = true; ret += ((int) (c - \'0\')); } else if (base == 16) { if (c >= \'a\' && c <= \'f\') { ret *= base; foundAny = true; ret += ((int) (c - \'a\')) + 10; } else if (c >= \'A\' && c <= \'F\') { ret *= base; foundAny = true; ret += ((int) (c - \'A\')) + 10; } else { break; } } else { break; } } if (foundAny) return isNeg ? -ret : ret; else return null; ') public static function parseInt( x : String ) : Null { return null; } public static function parseFloat( x : String ) : Float { if (x == null) return Math.NaN; x = StringTools.ltrim(x); var found = false, hasDot = false, hasSign = false, hasE = false, hasESign = false, hasEData = false; var i = -1; inline function getch(i:Int):Int return cast (untyped x._charAt(i) : java.StdTypes.Char16); while (++i < x.length) { var chr = getch(i); if (chr >= '0'.code && chr <= '9'.code) { if (hasE) { hasEData = true; } found = true; } else switch (chr) { case 'e'.code | 'E'.code if(!hasE): hasE = true; case '.'.code if (!hasDot): hasDot = true; case '-'.code, '+'.code if (!found && !hasSign): hasSign = true; case '-'.code | '+'.code if (found && !hasESign && hasE && !hasEData): hasESign = true; case _: break; } } if (hasE && !hasEData) { i--; if (hasESign) i--; } if (i != x.length) { x = x.substr(0,i); } return try java.lang.Double.DoubleClass.parseDouble(x) catch(e:Dynamic) Math.NaN; } inline public static function instance( value : T, c : Class ) : S { return Std.is(value, c) ? cast value : null; } public static function random( x : Int ) : Int { if (x <= 0) return 0; return Std.int(Math.random() * x); } } haxe_3.4.4.orig/std/java/_std/String.hx0000664000175000017500000000425013166552354017670 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi extern class String implements java.lang.CharSequence { var length(default,null) : Int; @:overload(function(b:haxe.io.BytesData, offset:Int, length:Int, charsetName:String):Void { }) @:overload(function(b:haxe.io.BytesData, offset:Int, length:Int):Void { }) function new(string:String) : Void; function toUpperCase() : String; function toLowerCase() : String; function charAt( index : Int) : String; function charCodeAt( index : Int) : Null; function indexOf( str : String, ?startIndex : Int ) : Int; function lastIndexOf( str : String, ?startIndex : Int ) : Int; function split( delimiter : String ) : Array; function substr( pos : Int, ?len : Int ) : String; function substring( startIndex : Int, ?endIndex : Int ) : String; function toString() : String; private function compareTo( anotherString : String ) : Int; private function codePointAt( idx : Int ) : Int; @:overload(function() : haxe.io.BytesData { }) private function getBytes(encoding:String) : haxe.io.BytesData; static function fromCharCode( code : Int ) : String; } haxe_3.4.4.orig/std/java/_std/StringBuf.hx0000664000175000017500000000350413166552354020326 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi class StringBuf { private var b : java.lang.StringBuilder; public var length(get,never) : Int; public function new() : Void { b = new java.lang.StringBuilder(); } inline function get_length() : Int { return b.length(); } public function add( x : T ) : Void { if (Std.is(x, Int)) { var x:Int = cast x; var xd:Dynamic = x; b.append(xd); } else { b.append(x); } } public function addSub( s : String, pos : Int, ?len : Int ) : Void { var l:Int = (len == null) ? s.length - pos : len; b.append(s, pos, pos + l); } public function addChar( c : Int ) : Void untyped { b.append(cast(c, java.StdTypes.Char16)); } public function toString() : String { return b.toString(); } } haxe_3.4.4.orig/std/java/_std/Sys.hx0000664000175000017500000001131113166552354017174 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import java.lang.System; import sys.io.Process; using haxe.Int64; @:coreApi class Sys { private static var _args:java.NativeArray; private static var _env:haxe.ds.StringMap; private static var _sysName:String; public static inline function print( v : Dynamic ) : Void { java.lang.System.out.print(v); } public static inline function println( v : Dynamic ) : Void { java.lang.System.out.println(v); } public static function args() : Array { if (_args == null) return []; return java.Lib.array(_args); } public static function getEnv( s : String ) : String { return java.lang.System.getenv(s); } public static function putEnv( s : String, v : String ) : Void { //java offers no support for it (!) throw "Not implemented in this platform"; } public static function environment() : Map { if (_env != null) return _env; var _env = _env = new haxe.ds.StringMap(); for (mv in java.lang.System.getenv().entrySet()) { _env.set(mv.getKey(), mv.getValue()); } return _env; } public static function sleep( seconds : Float ) : Void { try java.lang.Thread.sleep(cast seconds * 1000) catch (e:Dynamic) throw e; } public static function setTimeLocale( loc : String ) : Bool { return false; } public static function getCwd() : String { return new java.io.File(".").getAbsolutePath().substr(0,-1); } public static function setCwd( s : String ) : Void { //java offers no support for it (!) throw "not implemented"; } public static function systemName() : String { if (_sysName != null) return _sysName; var sname = System.getProperty("os.name").toLowerCase(); if (sname.indexOf("win") >= 0) return _sysName = "Windows"; if (sname.indexOf("mac") >= 0) return _sysName = "Mac"; if (sname.indexOf("nux") >= 0) return _sysName = "Linux"; if (sname.indexOf("nix") >= 0) return _sysName = "BSD"; return _sysName = System.getProperty("os.name"); } public static function command( cmd : String, ?args : Array ) : Int { var pb = Process.createProcessBuilder(cmd, args); #if java6 pb.redirectErrorStream(true); #else pb.redirectOutput(java.lang.ProcessBuilder.ProcessBuilder_Redirect.INHERIT); pb.redirectError(java.lang.ProcessBuilder.ProcessBuilder_Redirect.INHERIT); #end var proc = pb.start(); #if java6 var reader = new java.io.NativeInput(proc.getInputStream()); try { while(true) { var ln = reader.readLine(); Sys.println(ln); } } catch(e:haxe.io.Eof) {} #end proc.waitFor(); var exitCode = proc.exitValue(); proc.destroy(); return exitCode; } public static function exit( code : Int ) : Void { System.exit(code); } public static function time() : Float { return cast(System.currentTimeMillis(), Float) / 1000; } public static function cpuTime() : Float { return cast(System.nanoTime(), Float) / 1000000000; } @:deprecated("Use programPath instead") public static function executablePath() : String { return getCwd(); } public static function programPath() : String { return java.Lib.toNativeType(Sys) .getProtectionDomain() .getCodeSource() .getLocation().toURI().getPath(); } public static function getChar( echo : Bool ) : Int { //TODO return throw "Not implemented"; } public static function stdin() : haxe.io.Input { var _in:java.io.InputStream = Reflect.field(System, "in"); return new java.io.NativeInput(_in); } public static function stdout() : haxe.io.Output { return new java.io.NativeOutput(System.out); } public static function stderr() : haxe.io.Output { return new java.io.NativeOutput(System.err); } } haxe_3.4.4.orig/std/java/_std/Type.hx0000664000175000017500000002742213166552354017351 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import java.internal.HxObject; using StringTools; enum ValueType { TNull; TInt; TFloat; TBool; TObject; TFunction; TClass( c : Class ); TEnum( e : Enum ); TUnknown; } @:coreApi class Type { public static function getClass( o : T ) : Class { if (o == null || Std.is(o, DynamicObject) || Std.is(o, java.lang.Class)) { return null; } return cast java.Lib.getNativeType(o); } public static function getEnum( o : EnumValue ) : Enum { if (Std.is(o, java.lang.Enum) || Std.is(o, HxEnum)) { return untyped o.getClass(); } return null; } public static function getSuperClass( c : Class ) : Class { var c = java.Lib.toNativeType(c); var cl:java.lang.Class = c == null ? null : untyped c.getSuperclass(); if (cl != null && cl.getName() != "haxe.lang.HxObject" && cl.getName() != "java.lang.Object") { return cast cl; } return null; } public static function getClassName( c : Class ) : String { var c : java.lang.Class = cast c; var name:String = c.getName(); if (name.startsWith("haxe.root.")) return name.substr(10); if (name.startsWith("java.lang")) name = name.substr(10); return switch(name) { case "int", "Integer": "Int"; case "double", "Double": "Float"; case "Object": "Dynamic"; default: name; } } public static function getEnumName( e : Enum ) : String { var c : java.lang.Class = cast e; var ret:String = c.getName(); if (ret.startsWith("haxe.root.")) return ret.substr(10); else if (ret == "boolean" || ret == "java.lang.Boolean") return "Bool"; return ret; } public static function resolveClass( name : String ) : Class { try { if (name.indexOf(".") == -1) { name = "haxe.root." +name; } return cast java.lang.Class.forName(name); } catch (e:java.lang.ClassNotFoundException) { return untyped switch (name) { case "haxe.root.Int": Int; case "haxe.root.Float": Float; case "haxe.root.String": String; case "haxe.root.Math": java.lang.Math; case "haxe.root.Class": java.lang.Class; case "haxe.root.Dynamic": java.lang.Object; case _: null; } } } @:functionCode(' if ("Bool".equals(name)) return boolean.class; Class r = resolveClass(name); if (r != null && (r.getSuperclass() == java.lang.Enum.class || haxe.lang.Enum.class.isAssignableFrom(r))) return r; return null; ') public static function resolveEnum( name : String ) : Enum untyped { if (name == "Bool") return Bool; return resolveClass(name); } @:functionCode(' int len = args.length; java.lang.Class[] cls = new java.lang.Class[len]; java.lang.Object[] objs = new java.lang.Object[len]; java.lang.reflect.Constructor[] ms = cl.getConstructors(); int msl = ms.length; int realMsl = 0; for(int i =0; i < msl; i++) { if (!ms[i].isVarArgs() && ms[i].getParameterTypes().length != len) { ms[i] = null; } else { ms[realMsl] = ms[i]; if (realMsl != i) ms[i] = null; realMsl++; } } boolean hasNumber = false; for (int i = 0; i < len; i++) { Object o = args.__get(i); objs[i]= o; cls[i] = o.getClass(); boolean isNum = false; if (o instanceof java.lang.Number) { cls[i] = java.lang.Number.class; isNum = hasNumber = true; } msl = realMsl; realMsl = 0; for (int j = 0; j < msl; j++) { java.lang.Class[] allcls = ms[j].getParameterTypes(); if (i < allcls.length) { if (! ((isNum && allcls[i].isPrimitive()) || allcls[i].isAssignableFrom(cls[i])) ) { ms[j] = null; } else { ms[realMsl] = ms[j]; if (realMsl != j) ms[j] = null; realMsl++; } } } } java.lang.reflect.Constructor found = ms[0]; if (hasNumber) { java.lang.Class[] allcls = found.getParameterTypes(); for (int i = 0; i < len; i++) { java.lang.Object o = objs[i]; if (o instanceof java.lang.Number) { java.lang.Class curCls = null; if (i < allcls.length) { curCls = allcls[i]; if (!curCls.isAssignableFrom(o.getClass())) { String name = curCls.getName(); if (name.equals("double") || name.equals("java.lang.Double")) { objs[i] = ((java.lang.Number)o).doubleValue(); } else if (name.equals("int") || name.equals("java.lang.Integer")) { objs[i] = ((java.lang.Number)o).intValue(); } else if (name.equals("float") || name.equals("java.lang.Float")) { objs[i] = ((java.lang.Number)o).floatValue(); } else if (name.equals("byte") || name.equals("java.lang.Byte")) { objs[i] = ((java.lang.Number)o).byteValue(); } else if (name.equals("short") || name.equals("java.lang.Short")) { objs[i] = ((java.lang.Number)o).shortValue(); } } } //else varargs not handled TODO } } } try { found.setAccessible(true); return (T) found.newInstance(objs); } catch (java.lang.reflect.InvocationTargetException e) { throw haxe.lang.HaxeException.wrap(e.getCause()); } catch (Throwable t) { throw haxe.lang.HaxeException.wrap(t); } ') public static function createInstance( cl : Class, args : Array ) : T untyped { return null; } // cache empty constructor arguments so we don't allocate it on each createEmptyInstance call @:protected @:readOnly static var __createEmptyInstance_EMPTY_TYPES = java.NativeArray.make(java.Lib.toNativeEnum(java.internal.Runtime.EmptyObject)); @:protected @:readOnly static var __createEmptyInstance_EMPTY_ARGS = java.NativeArray.make(java.internal.Runtime.EmptyObject.EMPTY); public static function createEmptyInstance( cl : Class ) : T { var t = java.Lib.toNativeType(cl); try { var ctor = t.getConstructor(__createEmptyInstance_EMPTY_TYPES); return ctor.newInstance(__createEmptyInstance_EMPTY_ARGS); } catch (_:java.lang.NoSuchMethodException) { return t.newInstance(); } } @:functionCode(' if (params == null || params.length == 0) { java.lang.Object ret = haxe.lang.Runtime.slowGetField(e, constr, true); if (ret instanceof haxe.lang.Function) throw haxe.lang.HaxeException.wrap("Constructor " + constr + " needs parameters"); return (T) ret; } else { return (T) haxe.lang.Runtime.slowCallField(e, constr, params); } ') public static function createEnum( e : Enum, constr : String, ?params : Array ) : T { return null; } public static function createEnumIndex( e : Enum, index : Int, ?params : Array ) : T { var constr = getEnumConstructs(e); return createEnum(e, constr[index], params); } @:functionCode(' if (c == java.lang.String.class) { return haxe.lang.StringRefl.fields; } Array ret = new Array(); for (java.lang.reflect.Field f : c.getFields()) { java.lang.String fname = f.getName(); if (!java.lang.reflect.Modifier.isStatic(f.getModifiers()) && !fname.startsWith("__hx_")) ret.push(fname); } for (java.lang.reflect.Method m : c.getMethods()) { if (m.getDeclaringClass() == java.lang.Object.class) continue; java.lang.String mname = m.getName(); if (!java.lang.reflect.Modifier.isStatic(m.getModifiers()) && !mname.startsWith("__hx_")) ret.push(mname); } return ret; ') public static function getInstanceFields( c : Class ) : Array { return null; } @:functionCode(' Array ret = new Array(); if (c == java.lang.String.class) { ret.push("fromCharCode"); return ret; } for (java.lang.reflect.Field f : c.getDeclaredFields()) { java.lang.String fname = f.getName(); if (java.lang.reflect.Modifier.isStatic(f.getModifiers()) && !fname.startsWith("__hx_")) ret.push(fname); } for (java.lang.reflect.Method m : c.getDeclaredMethods()) { if (m.getDeclaringClass() == java.lang.Object.class) continue; java.lang.String mname = m.getName(); if (java.lang.reflect.Modifier.isStatic(m.getModifiers()) && !mname.startsWith("__hx_")) ret.push(mname); } return ret; ') public static function getClassFields( c : Class ) : Array { return null; } public static function getEnumConstructs( e : Enum ) : Array { if (Reflect.hasField(e, "__hx_constructs")) { var ret:Array = java.Lib.array(untyped e.__hx_constructs); return ret.copy(); } var vals:java.NativeArray> = untyped e.values(), ret = []; for (i in 0...vals.length) ret[i] = vals[i].name(); return ret; } @:functionCode(' if (v == null) return ValueType.TNull; if (v instanceof haxe.lang.IHxObject) { haxe.lang.IHxObject vobj = (haxe.lang.IHxObject) v; java.lang.Class cl = vobj.getClass(); if (v instanceof haxe.lang.DynamicObject) return ValueType.TObject; else return ValueType.TClass(cl); } else if (v instanceof java.lang.Number) { java.lang.Number n = (java.lang.Number) v; if (n.intValue() == n.doubleValue()) return ValueType.TInt; else return ValueType.TFloat; } else if (v instanceof haxe.lang.Function) { return ValueType.TFunction; } else if (v instanceof java.lang.Enum || v instanceof haxe.lang.Enum) { return ValueType.TEnum(v.getClass()); } else if (v instanceof java.lang.Boolean) { return ValueType.TBool; } else if (v instanceof java.lang.Class) { return ValueType.TObject; } else { return ValueType.TClass(v.getClass()); } ') public static function typeof( v : Dynamic ) : ValueType untyped { return null; } @:functionCode(' if (a instanceof haxe.lang.Enum) return a.equals(b); else return haxe.lang.Runtime.eq(a, b); ') public static function enumEq( a : T, b : T ) : Bool untyped { return a == b; } @:functionCode(' if (e instanceof java.lang.Enum) return ((java.lang.Enum) e).name(); else return ((haxe.lang.Enum) e).getTag(); ') public static function enumConstructor( e : EnumValue ) : String untyped { return null; } @:functionCode(' return ( e instanceof java.lang.Enum ) ? new haxe.root.Array() : ((haxe.lang.Enum) e).getParams(); ') public static function enumParameters( e : EnumValue ) : Array untyped { return null; } @:functionCode(' if (e instanceof java.lang.Enum) return ((java.lang.Enum) e).ordinal(); else return ((haxe.lang.Enum) e).index; ') public static function enumIndex( e : EnumValue ) : Int untyped { return e.index; } public static function allEnums( e : Enum ) : Array { var ctors = getEnumConstructs(e); var ret = []; for (ctor in ctors) { var v = Reflect.field(e, ctor); if (Std.is(v, e)) ret.push(v); } return ret; } } haxe_3.4.4.orig/std/java/_std/haxe/Int64.hx0000664000175000017500000001706713166552354020265 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; using haxe.Int64; import haxe.Int64Helper; private typedef __Int64 = java.StdTypes.Int64; @:coreApi abstract Int64(__Int64) from __Int64 to __Int64 { public static inline function make( high : Int32, low : Int32 ) : Int64 return new Int64( (cast(high, __Int64) << 32) | (cast(low, __Int64)& (untyped __java__('0xffffffffL') : Int64)) ); private inline function new(x : __Int64) this = x; private var val( get, set ) : __Int64; inline function get_val() : __Int64 return this; inline function set_val( x : __Int64 ) : __Int64 return this = x; public var high( get, never ):Int32; public inline function get_high():Int32 return cast(this >> 32); public var low( get, never ):Int32; public inline function get_low():Int32 return cast this; public inline function copy():Int64 return new Int64( this ); @:from public static inline function ofInt( x : Int ) : Int64 return cast x; inline public static function is( val : Dynamic ) : Bool return Std.is(val,java.lang.Long.LongClass); public static inline function toInt( x : Int64 ) : Int { if( x.val < 0x80000000 || x.val > 0x7FFFFFFF ) throw "Overflow"; return cast x.val; } public static inline function getHigh( x : Int64 ) : Int32 return cast( x.val >> 32 ); public static inline function getLow( x : Int64 ) : Int32 return cast( x.val ); public static inline function isNeg( x : Int64 ) : Bool return x.val < 0; public static inline function isZero( x : Int64 ) : Bool return x.val == 0; public static inline function compare( a : Int64, b : Int64 ) : Int { if( a.val < b.val ) return -1; if( a.val > b.val ) return 1; return 0; } public static inline function ucompare( a : Int64, b : Int64 ) : Int { if( a.val < 0 ) return ( b.val < 0 ) ? compare( a, b ) : 1; return ( b.val < 0 ) ? -1 : compare( a, b ); } public static inline function toStr( x : Int64 ) : String return '${x.val}'; public static inline function divMod( dividend : Int64, divisor : Int64 ) : { quotient : Int64, modulus : Int64 } return { quotient: dividend / divisor, modulus: dividend % divisor }; private inline function toString() : String return '$this'; public static function parseString( sParam : String ) : Int64 { // can this be done?: return new Int64( java.lang.Long.LongClass.parseLong( sParam ) ); return Int64Helper.parseString( sParam ); } public static function fromFloat( f : Float ) : Int64 { return Int64Helper.fromFloat( f ); } @:op(-A) public static function neg( x : Int64 ) : Int64 return -x.val; @:op(++A) private inline function preIncrement() : Int64 return ++this; @:op(A++) private inline function postIncrement() : Int64 return this++; @:op(--A) private inline function preDecrement() : Int64 return --this; @:op(A--) private inline function postDecrement() : Int64 return this--; @:op(A + B) public static inline function add( a : Int64, b : Int64 ) : Int64 return a.val + b.val; @:op(A + B) @:commutative private static inline function addInt( a : Int64, b : Int ) : Int64 return a.val + b; @:op(A - B) public static inline function sub( a : Int64, b : Int64 ) : Int64 return a.val - b.val; @:op(A - B) private static inline function subInt( a : Int64, b : Int ) : Int64 return a.val - b; @:op(A - B) private static inline function intSub( a : Int, b : Int64 ) : Int64 return a - b.val; @:op(A * B) public static inline function mul( a : Int64, b : Int64 ) : Int64 return a.val * b.val; @:op(A * B) @:commutative private static inline function mulInt( a : Int64, b : Int ) : Int64 return a.val * b; @:op(A / B) public static inline function div( a : Int64, b : Int64 ) : Int64 return a.val / b.val; @:op(A / B) private static inline function divInt( a : Int64, b : Int ) : Int64 return a.val / b; @:op(A / B) private static inline function intDiv( a : Int, b : Int64 ) : Int64 return a / b.val; @:op(A % B) public static inline function mod( a : Int64, b : Int64 ) : Int64 return a.val % b.val; @:op(A % B) private static inline function modInt( a : Int64, b : Int ) : Int64 return a.val % b; @:op(A % B) private static inline function intMod( a : Int, b : Int64 ) : Int64 return a % b.val; @:op(A == B) public static inline function eq( a : Int64, b : Int64 ) : Bool return a.val == b.val; @:op(A == B) @:commutative private static inline function eqInt( a : Int64, b : Int ) : Bool return a.val == b; @:op(A != B) public static inline function neq( a : Int64, b : Int64 ) : Bool return a.val != b.val; @:op(A != B) @:commutative private static inline function neqInt( a : Int64, b : Int ) : Bool return a.val != b; @:op(A < B) private static inline function lt( a : Int64, b : Int64 ) : Bool return a.val < b.val; @:op(A < B) private static inline function ltInt( a : Int64, b : Int ) : Bool return a.val < b; @:op(A < B) private static inline function intLt( a : Int, b : Int64 ) : Bool return a < b.val; @:op(A <= B) private static inline function lte( a : Int64, b : Int64 ) : Bool return a.val <= b.val; @:op(A <= B) private static inline function lteInt( a : Int64, b : Int ) : Bool return a.val <= b; @:op(A <= B) private static inline function intLte( a : Int, b : Int64 ) : Bool return a <= b.val; @:op(A > B) private static inline function gt( a : Int64, b : Int64 ) : Bool return a.val > b.val; @:op(A > B) private static inline function gtInt( a : Int64, b : Int ) : Bool return a.val > b; @:op(A > B) private static inline function intGt( a : Int, b : Int64 ) : Bool return a > b.val; @:op(A >= B) private static inline function gte( a : Int64, b : Int64 ) : Bool return a.val >= b.val; @:op(A >= B) private static inline function gteInt( a : Int64, b : Int ) : Bool return a.val >= b; @:op(A >= B) private static inline function intGte( a : Int, b : Int64 ) : Bool return a >= b.val; @:op(~A) private static inline function complement( x : Int64 ) : Int64 return ~x.val; @:op(A & B) public static inline function and( a : Int64, b : Int64 ) : Int64 return a.val & b.val; @:op(A | B) public static inline function or( a : Int64, b : Int64 ) : Int64 return a.val | b.val; @:op(A ^ B) public static inline function xor( a : Int64, b : Int64 ) : Int64 return a.val ^ b.val; @:op(A << B) public static inline function shl( a : Int64, b : Int ) : Int64 return a.val << b; @:op(A >> B) public static inline function shr( a : Int64, b : Int ) : Int64 return a.val >> b; @:op(A >>> B) public static inline function ushr( a : Int64, b : Int ) : Int64 return a.val >>> b; } haxe_3.4.4.orig/std/java/_std/haxe/Resource.hx0000664000175000017500000000372213166552354021141 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; @:coreApi class Resource { @:keep static var content : Array; public static inline function listNames() : Array { return content.copy(); } @:access(haxe.io.Path.escape) public static function getString( name : String ) : String { name = haxe.io.Path.escape(name, true); var stream = cast(Resource, java.lang.Class).getResourceAsStream("/" + name); if (stream == null) return null; var stream = new java.io.NativeInput(stream); return stream.readAll().toString(); } @:access(haxe.io.Path.escape) public static function getBytes( name : String ) : haxe.io.Bytes { name = haxe.io.Path.escape(name, true); var stream = cast(Resource, java.lang.Class).getResourceAsStream("/" + name); if (stream == null) return null; var stream = new java.io.NativeInput(stream); return stream.readAll(); } } haxe_3.4.4.orig/std/java/_std/haxe/ds/IntMap.hx0000664000175000017500000002456313166552354021156 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; import java.NativeArray; /* * This IntMap implementation is based on khash (https://github.com/attractivechaos/klib/blob/master/khash.h) * Copyright goes to Attractive Chaos and his contributors * * Thanks also to Jonas Malaco Filho for his Haxe-written IntMap code inspired by Python tables. * (https://jonasmalaco.com/fossil/test/jonas-haxe/artifact/887b53126e237d6c68951111d594033403889304) */ @:coreApi class IntMap implements haxe.Constraints.IMap { private static inline var HASH_UPPER = 0.7; private var flags:NativeArray; private var _keys:NativeArray; private var vals:NativeArray; private var nBuckets:Int; private var size:Int; private var nOccupied:Int; private var upperBound:Int; private var cachedKey:Int; private var cachedIndex:Int; public function new() : Void { cachedIndex = -1; } public function set( key : Int, value : T ) : Void { var x:Int; if (nOccupied >= upperBound) { if (nBuckets > (size << 1)) resize(nBuckets - 1); //clear "deleted" elements else resize(nBuckets + 1); } var flags = flags, _keys = _keys; { var mask = nBuckets - 1; var site = x = nBuckets; var k = hash(key); var i = k & mask; var delKey = -1; //for speed up if (flagIsEmpty(flags, i)) { x = i; } else { var inc = getInc(k, mask); var last = i; while (! (flagIsEmpty(flags, i) || _keys[i] == key) ) { if (flagIsDel(flags,i) && delKey == -1) delKey = i; i = (i + inc) & mask; #if DEBUG_HASHTBL if (i == last) { throw "assert"; } #end } if (flagIsEmpty(flags, i) && delKey != -1) x = delKey; else x = i; } } if (flagIsEmpty(flags, x)) { _keys[x] = key; vals[x] = value; setIsBothFalse(flags, x); size++; nOccupied++; } else if (flagIsDel(flags, x)) { _keys[x] = key; vals[x] = value; setIsBothFalse(flags, x); size++; } else { assert(_keys[x] == key); vals[x] = value; } } @:final private function lookup( key : Int ) : Int { if (nBuckets != 0) { var flags = flags, _keys = _keys; var mask = nBuckets - 1, k = hash(key); var i = k & mask; var inc = getInc(k, mask); /* inc == 1 for linear probing */ var last = i; while (!flagIsEmpty(flags, i) && (flagIsDel(flags, i) || _keys[i] != key)) { i = (i + inc) & mask; if (i == last) return -1; } return isEither(flags, i) ? -1 : i; } return -1; } public function get( key : Int ) : Null { var idx = -1; if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } idx = lookup(key); if (idx != -1) { cachedKey = key; cachedIndex = idx; return vals[idx]; } return null; } private function getDefault( key : Int, def : T ) : T { var idx = -1; if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } idx = lookup(key); if (idx != -1) { cachedKey = key; cachedIndex = idx; return vals[idx]; } return def; } public function exists( key : Int ) : Bool { var idx = -1; if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return true; } idx = lookup(key); if (idx != -1) { cachedKey = key; cachedIndex = idx; return true; } return false; } public function remove( key : Int ) : Bool { var idx = -1; if (! (cachedKey == key && ( (idx = cachedIndex) != -1 ))) { idx = lookup(key); } if (idx == -1) { return false; } else { if (cachedKey == key) cachedIndex = -1; if (!isEither(flags, idx)) { setIsDelTrue(flags, idx); --size; vals[idx] = null; _keys[idx] = 0; } return true; } } @:final private function resize(newNBuckets:Int) : Void { //This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. var newFlags = null; var j = 1; { newNBuckets = roundUp(newNBuckets); if (newNBuckets < 4) newNBuckets = 4; if (size >= (newNBuckets * HASH_UPPER + 0.5)) /* requested size is too small */ { j = 0; } else { /* hash table size to be changed (shrink or expand); rehash */ var nfSize = flagsSize(newNBuckets); newFlags = new NativeArray( nfSize ); for (i in 0...nfSize) newFlags[i] = 0xaaaaaaaa; if (nBuckets < newNBuckets) //expand { var k = new NativeArray(newNBuckets); if (_keys != null) arrayCopy(_keys, 0, k, 0, nBuckets); _keys = k; var v = new NativeArray(newNBuckets); if (vals != null) arrayCopy(vals, 0, v, 0, nBuckets); vals = v; } //otherwise shrink } } if (j != 0) { //rehashing is required //resetting cache cachedKey = 0; cachedIndex = -1; j = -1; var nBuckets = nBuckets, _keys = _keys, vals = vals, flags = flags; var newMask = newNBuckets - 1; while (++j < nBuckets) { if (!isEither(flags, j)) { var key = _keys[j]; var val = vals[j]; setIsDelTrue(flags, j); while (true) /* kick-out process; sort of like in Cuckoo hashing */ { var k = hash(key); var inc = getInc(k, newMask); var i = k & newMask; while (!flagIsEmpty(newFlags, i)) i = (i + inc) & newMask; setIsEmptyFalse(newFlags, i); if (i < nBuckets && !isEither(flags, i)) /* kick out the existing element */ { { var tmp = _keys[i]; _keys[i] = key; key = tmp; } { var tmp = vals[i]; vals[i] = val; val = tmp; } setIsDelTrue(flags, i); /* mark it as deleted in the old hash table */ } else { /* write the element and jump out of the loop */ _keys[i] = key; vals[i] = val; break; } } } } if (nBuckets > newNBuckets) /* shrink the hash table */ { { var k = new NativeArray(newNBuckets); arrayCopy(_keys, 0, k, 0, newNBuckets); this._keys = k; } { var v = new NativeArray(newNBuckets); arrayCopy(vals, 0, v, 0, newNBuckets); this.vals = v; } } this.flags = newFlags; this.nBuckets = newNBuckets; this.nOccupied = size; this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5); } } /** Returns an iterator of all keys in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function keys() : Iterator { var i = 0; var len = nBuckets; return { hasNext: function() { for (j in i...len) { if (!isEither(flags, j)) { i = j; return true; } } return false; }, next: function() { var ret = _keys[i]; cachedIndex = i; cachedKey = ret; i = i + 1; return ret; } }; } /** Returns an iterator of all values in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function iterator() : Iterator { var i = 0; var len = nBuckets; return { hasNext: function() { for (j in i...len) { if (!isEither(flags, j)) { i = j; return true; } } return false; }, next: function() { var ret = vals[i]; i = i + 1; return ret; } }; } /** Returns an displayable representation of the hashtable content. **/ public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(i); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } private static inline function assert(x:Bool):Void { #if debug if (!x) throw "assert failed"; #end } private static inline function defaultK():Int return 0; private static inline function arrayCopy(sourceArray:Dynamic, sourceIndex:Int, destinationArray:Dynamic, destinationIndex:Int, length:Int):Void java.lang.System.arraycopy(sourceArray, sourceIndex, destinationArray, destinationIndex, length); private static inline function getInc(k:Int, mask:Int):Int return (((k) >> 3 ^ (k) << 3) | 1) & (mask); private static inline function hash(i:Int):Int return i; private static inline function flagIsEmpty(flag:NativeArray, i:Int):Bool return ( (flag[i >> 4] >>> ((i & 0xf) << 1)) & 2 ) != 0; private static inline function flagIsDel(flag:NativeArray, i:Int):Bool return ((flag[i >> 4] >>> ((i & 0xf) << 1)) & 1) != 0; private static inline function isEither(flag:NativeArray, i:Int):Bool return ((flag[i >> 4] >>> ((i & 0xf) << 1)) & 3) != 0; private static inline function setIsDelFalse(flag:NativeArray, i:Int):Void flag[i >> 4] &= ~(1 << ((i & 0xf) << 1)); private static inline function setIsEmptyFalse(flag:NativeArray, i:Int):Void flag[i >> 4] &= ~(2 << ((i & 0xf) << 1)); private static inline function setIsBothFalse(flag:NativeArray, i:Int):Void flag[i >> 4] &= ~(3 << ((i & 0xf) << 1)); private static inline function setIsDelTrue(flag:NativeArray, i:Int):Void flag[i >> 4] |= 1 << ((i & 0xf) << 1); private static inline function roundUp(x:Int):Int { --x; x |= (x) >>> 1; x |= (x) >>> 2; x |= (x) >>> 4; x |= (x) >>> 8; x |= (x) >>> 16; return ++x; } private static inline function flagsSize(m:Int):Int return ((m) < 16? 1 : (m) >> 4); } haxe_3.4.4.orig/std/java/_std/haxe/ds/ObjectMap.hx0000664000175000017500000002535513166552354021632 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; import java.NativeArray; @:coreApi class ObjectMap implements haxe.Constraints.IMap { @:extern private static inline var HASH_UPPER = 0.77; @:extern private static inline var FLAG_EMPTY = 0; @:extern private static inline var FLAG_DEL = 1; /** * This is the most important structure here and the reason why it's so fast. * It's an array of all the hashes contained in the table. These hashes cannot be 0 nor 1, * which stand for "empty" and "deleted" states. * * The lookup algorithm will keep looking until a 0 or the key wanted is found; * The insertion algorithm will do the same but will also break when FLAG_DEL is found; */ private var hashes:NativeArray; private var _keys:NativeArray; private var vals:NativeArray; private var nBuckets:Int; private var size:Int; private var nOccupied:Int; private var upperBound:Int; private var cachedKey:K; private var cachedIndex:Int; #if DEBUG_HASHTBL private var totalProbes:Int; private var probeTimes:Int; private var sameHash:Int; private var maxProbe:Int; #end public function new() : Void { cachedIndex = -1; } public function set( key : K, value : V ) : Void { var x:Int, k:Int; if (nOccupied >= upperBound) { if (nBuckets > (size << 1)) resize(nBuckets - 1); //clear "deleted" elements else resize(nBuckets + 2); } var hashes = hashes, keys = _keys, hashes = hashes; { var mask = (nBuckets == 0) ? 0 : nBuckets - 1; var site = x = nBuckets; k = hash(key); var i = k & mask, nProbes = 0; var delKey = -1; //for speed up if (isEmpty(hashes[i])) { x = i; } else { //var inc = getInc(k, mask); var last = i, flag; while(! (isEmpty(flag = hashes[i]) || (flag == k && untyped keys[i].equals(key))) ) { if (isDel(flag) && delKey == -1) delKey = i; i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } if (isEmpty(flag) && delKey != -1) x = delKey; else x = i; } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end } var flag = hashes[x]; if (isEmpty(flag)) { keys[x] = key; vals[x] = value; hashes[x] = k; size++; nOccupied++; } else if (isDel(flag)) { keys[x] = key; vals[x] = value; hashes[x] = k; size++; } else { assert(keys[x] == key); vals[x] = value; } cachedIndex = x; cachedKey = key; } @:final private function lookup( key : K ) : Int { if (nBuckets != 0) { var hashes = hashes, keys = _keys; var mask = nBuckets - 1, hash = hash(key), k = hash, nProbes = 0; var i = k & mask; var last = i, flag; //var inc = getInc(k, mask); while (!isEmpty(flag = hashes[i]) && (isDel(flag) || flag != k || !(untyped keys[i].equals(key)))) { i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end return isEither(flag) ? -1 : i; } return -1; } @:final @:private function resize(newNBuckets:Int) : Void { //This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. var newHash = null; var j = 1; { newNBuckets = roundUp(newNBuckets); if (newNBuckets < 4) newNBuckets = 4; if (size >= (newNBuckets * HASH_UPPER + 0.5)) /* requested size is too small */ { j = 0; } else { /* hash table size to be changed (shrink or expand); rehash */ var nfSize = newNBuckets; newHash = new NativeArray( nfSize ); if (nBuckets < newNBuckets) //expand { var k = new NativeArray(newNBuckets); if (_keys != null) arrayCopy(_keys, 0, k, 0, nBuckets); _keys = k; var v = new NativeArray(newNBuckets); if (vals != null) arrayCopy(vals, 0, v, 0, nBuckets); vals = v; } //otherwise shrink } } if (j != 0) { //rehashing is required //resetting cache cachedKey = null; cachedIndex = -1; j = -1; var nBuckets = nBuckets, _keys = _keys, vals = vals, hashes = hashes; var newMask = newNBuckets - 1; while (++j < nBuckets) { var k; if (!isEither(k = hashes[j])) { var key = _keys[j]; var val = vals[j]; hashes[j] = FLAG_DEL; while (true) /* kick-out process; sort of like in Cuckoo hashing */ { var nProbes = 0; //var inc = getInc(k, newMask); var i = k & newMask; while (!isEmpty(newHash[i])) i = (i + ++nProbes) & newMask; newHash[i] = k; if (i < nBuckets && !isEither(k = hashes[i])) /* kick out the existing element */ { { var tmp = _keys[i]; _keys[i] = key; key = tmp; } { var tmp = vals[i]; vals[i] = val; val = tmp; } hashes[i] = FLAG_DEL; /* mark it as deleted in the old hash table */ } else { /* write the element and jump out of the loop */ _keys[i] = key; vals[i] = val; break; } } } } if (nBuckets > newNBuckets) /* shrink the hash table */ { { var k = new NativeArray(newNBuckets); arrayCopy(_keys, 0, k, 0, newNBuckets); this._keys = k; } { var v = new NativeArray(newNBuckets); arrayCopy(vals, 0, v, 0, newNBuckets); this.vals = v; } } this.hashes = newHash; this.nBuckets = newNBuckets; this.nOccupied = size; this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5); } } public function get( key : K ) : Null { var idx = -1; if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } idx = lookup(key); if (idx != -1) { cachedKey = key; cachedIndex = idx; return vals[idx]; } return null; } private function getDefault( key : K, def : V ) : V { var idx = -1; if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } idx = lookup(key); if (idx != -1) { cachedKey = key; cachedIndex = idx; return vals[idx]; } return def; } public function exists( key : K ) : Bool { var idx = -1; if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return true; } idx = lookup(key); if (idx != -1) { cachedKey = key; cachedIndex = idx; return true; } return false; } public function remove( key : K ) : Bool { var idx = -1; if (! (cachedKey == key && ( (idx = cachedIndex) != -1 ))) { idx = lookup(key); } if (idx == -1) { return false; } else { if (cachedKey == key) cachedIndex = -1; hashes[idx] = FLAG_DEL; _keys[idx] = null; vals[idx] = null; --size; return true; } } /** Returns an iterator of all keys in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function keys() : Iterator { var i = 0; var len = nBuckets; return { hasNext: function() { for (j in i...len) { if (!isEither(hashes[j])) { i = j; return true; } } return false; }, next: function() { var ret = _keys[i]; cachedIndex = i; cachedKey = ret; i = i + 1; return ret; } }; } /** Returns an iterator of all values in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function iterator() : Iterator { var i = 0; var len = nBuckets; return { hasNext: function() { for (j in i...len) { if (!isEither(hashes[j])) { i = j; return true; } } return false; }, next: function() { var ret = vals[i]; i = i + 1; return ret; } }; } /** Returns an displayable representation of the hashtable content. **/ public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(Std.string(i)); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } @:extern private static inline function roundUp(x:Int):Int { --x; x |= (x) >>> 1; x |= (x) >>> 2; x |= (x) >>> 4; x |= (x) >>> 8; x |= (x) >>> 16; return ++x; } @:extern private static inline function getInc(k:Int, mask:Int):Int //return 1 for linear probing return (((k) >> 3 ^ (k) << 3) | 1) & (mask); @:extern private static inline function isEither(v:HashType):Bool return (v & 0xFFFFFFFE) == 0; @:extern private static inline function isEmpty(v:HashType):Bool return v == FLAG_EMPTY; @:extern private static inline function isDel(v:HashType):Bool return v == FLAG_DEL; //guarantee: Whatever this function is, it will never return 0 nor 1 @:extern private static inline function hash(s:Dynamic):HashType { var k:Int = untyped s.hashCode(); //k *= 357913941; //k ^= k << 24; //k += ~357913941; //k ^= k >> 31; //k ^= k << 31; k = (k+0x7ed55d16) + (k<<12); k = (k^0xc761c23c) ^ (k>>19); k = (k+0x165667b1) + (k<<5); k = (k+0xd3a2646c) ^ (k<<9); k = (k+0xfd7046c5) + (k<<3); k = (k^0xb55a4f09) ^ (k>>16); var ret = k; if (isEither(ret)) { if (ret == 0) ret = 2; else ret = 0xFFFFFFFF; } return ret; } @:extern private static inline function arrayCopy(sourceArray:Dynamic, sourceIndex:Int, destinationArray:Dynamic, destinationIndex:Int, length:Int):Void java.lang.System.arraycopy(sourceArray, sourceIndex, destinationArray, destinationIndex, length); @:extern private static inline function assert(x:Bool):Void { #if DEBUG_HASHTBL if (!x) throw "assert failed"; #end } } private typedef HashType = Int; haxe_3.4.4.orig/std/java/_std/haxe/ds/StringMap.hx0000664000175000017500000002536113166552354021667 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; import java.NativeArray; @:coreApi class StringMap implements haxe.Constraints.IMap { @:extern private static inline var HASH_UPPER = 0.77; @:extern private static inline var FLAG_EMPTY = 0; @:extern private static inline var FLAG_DEL = 1; /** * This is the most important structure here and the reason why it's so fast. * It's an array of all the hashes contained in the table. These hashes cannot be 0 nor 1, * which stand for "empty" and "deleted" states. * * The lookup algorithm will keep looking until a 0 or the key wanted is found; * The insertion algorithm will do the same but will also break when FLAG_DEL is found; */ private var hashes:NativeArray; private var _keys:NativeArray; private var vals:NativeArray; private var nBuckets:Int; private var size:Int; private var nOccupied:Int; private var upperBound:Int; private var cachedKey:String; private var cachedIndex:Int; #if DEBUG_HASHTBL private var totalProbes:Int; private var probeTimes:Int; private var sameHash:Int; private var maxProbe:Int; #end public function new() : Void { cachedIndex = -1; } public function set( key : String, value : T ) : Void { var x:Int, k:Int; if (nOccupied >= upperBound) { if (nBuckets > (size << 1)) resize(nBuckets - 1); //clear "deleted" elements else resize(nBuckets + 2); } var hashes = hashes, keys = _keys, hashes = hashes; { var mask = (nBuckets == 0) ? 0 : nBuckets - 1; var site = x = nBuckets; k = hash(key); var i = k & mask, nProbes = 0; var delKey = -1; //for speed up if (isEmpty(hashes[i])) { x = i; } else { //var inc = getInc(k, mask); var last = i, flag; while(! (isEmpty(flag = hashes[i]) || (flag == k && _keys[i] == key)) ) { if (isDel(flag) && delKey == -1) delKey = i; i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } if (isEmpty(flag) && delKey != -1) x = delKey; else x = i; } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end } var flag = hashes[x]; if (isEmpty(flag)) { keys[x] = key; vals[x] = value; hashes[x] = k; size++; nOccupied++; } else if (isDel(flag)) { keys[x] = key; vals[x] = value; hashes[x] = k; size++; } else { assert(_keys[x] == key); vals[x] = value; } cachedIndex = x; cachedKey = key; } @:final private function lookup( key : String ) : Int { if (nBuckets != 0) { var hashes = hashes, keys = _keys; var mask = nBuckets - 1, hash = hash(key), k = hash, nProbes = 0; var i = k & mask; var last = i, flag; //var inc = getInc(k, mask); while (!isEmpty(flag = hashes[i]) && (isDel(flag) || flag != k || keys[i] != key)) { i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end return isEither(flag) ? -1 : i; } return -1; } @:final @:private function resize(newNBuckets:Int) : Void { //This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. var newHash = null; var j = 1; { newNBuckets = roundUp(newNBuckets); if (newNBuckets < 4) newNBuckets = 4; if (size >= (newNBuckets * HASH_UPPER + 0.5)) /* requested size is too small */ { j = 0; } else { /* hash table size to be changed (shrink or expand); rehash */ var nfSize = newNBuckets; newHash = new NativeArray( nfSize ); if (nBuckets < newNBuckets) //expand { var k = new NativeArray(newNBuckets); if (_keys != null) arrayCopy(_keys, 0, k, 0, nBuckets); _keys = k; var v = new NativeArray(newNBuckets); if (vals != null) arrayCopy(vals, 0, v, 0, nBuckets); vals = v; } //otherwise shrink } } if (j != 0) { //rehashing is required //resetting cache cachedKey = null; cachedIndex = -1; j = -1; var nBuckets = nBuckets, _keys = _keys, vals = vals, hashes = hashes; var newMask = newNBuckets - 1; while (++j < nBuckets) { var k; if (!isEither(k = hashes[j])) { var key = _keys[j]; var val = vals[j]; hashes[j] = FLAG_DEL; while (true) /* kick-out process; sort of like in Cuckoo hashing */ { var nProbes = 0; //var inc = getInc(k, newMask); var i = k & newMask; while (!isEmpty(newHash[i])) i = (i + ++nProbes) & newMask; newHash[i] = k; if (i < nBuckets && !isEither(k = hashes[i])) /* kick out the existing element */ { { var tmp = _keys[i]; _keys[i] = key; key = tmp; } { var tmp = vals[i]; vals[i] = val; val = tmp; } hashes[i] = FLAG_DEL; /* mark it as deleted in the old hash table */ } else { /* write the element and jump out of the loop */ _keys[i] = key; vals[i] = val; break; } } } } if (nBuckets > newNBuckets) /* shrink the hash table */ { { var k = new NativeArray(newNBuckets); arrayCopy(_keys, 0, k, 0, newNBuckets); this._keys = k; } { var v = new NativeArray(newNBuckets); arrayCopy(vals, 0, v, 0, newNBuckets); this.vals = v; } } this.hashes = newHash; this.nBuckets = newNBuckets; this.nOccupied = size; this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5); } } public function get( key : String ) : Null { var idx = -1; if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } idx = lookup(key); if (idx != -1) { cachedKey = key; cachedIndex = idx; return vals[idx]; } return null; } private function getDefault( key : String, def : T ) : T { var idx = -1; if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return vals[idx]; } idx = lookup(key); if (idx != -1) { cachedKey = key; cachedIndex = idx; return vals[idx]; } return def; } public function exists( key : String ) : Bool { var idx = -1; if (cachedKey == key && ( (idx = cachedIndex) != -1 )) { return true; } idx = lookup(key); if (idx != -1) { cachedKey = key; cachedIndex = idx; return true; } return false; } public function remove( key : String ) : Bool { var idx = -1; if (! (cachedKey == key && ( (idx = cachedIndex) != -1 ))) { idx = lookup(key); } if (idx == -1) { return false; } else { if (cachedKey == key) cachedIndex = -1; hashes[idx] = FLAG_DEL; _keys[idx] = null; vals[idx] = null; --size; return true; } } /** Returns an iterator of all keys in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function keys() : Iterator { var i = 0; var len = nBuckets; return { hasNext: function() { for (j in i...len) { if (!isEither(hashes[j])) { i = j; return true; } } return false; }, next: function() { var ret = _keys[i]; cachedIndex = i; cachedKey = ret; i = i + 1; return ret; } }; } /** Returns an iterator of all values in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function iterator() : Iterator { var i = 0; var len = nBuckets; return { hasNext: function() { for (j in i...len) { if (!isEither(hashes[j])) { i = j; return true; } } return false; }, next: function() { var ret = vals[i]; i = i + 1; return ret; } }; } /** Returns an displayable representation of the hashtable content. **/ public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(i); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } @:extern private static inline function roundUp(x:Int):Int { --x; x |= (x) >>> 1; x |= (x) >>> 2; x |= (x) >>> 4; x |= (x) >>> 8; x |= (x) >>> 16; return ++x; } @:extern private static inline function getInc(k:Int, mask:Int):Int //return 1 for linear probing return (((k) >> 3 ^ (k) << 3) | 1) & (mask); @:extern private static inline function isEither(v:HashType):Bool return (v & 0xFFFFFFFE) == 0; @:extern private static inline function isEmpty(v:HashType):Bool return v == FLAG_EMPTY; @:extern private static inline function isDel(v:HashType):Bool return v == FLAG_DEL; //guarantee: Whatever this function is, it will never return 0 nor 1 @:extern private static inline function hash(s:String):HashType { var k:Int = untyped s.hashCode(); //k *= 357913941; //k ^= k << 24; //k += ~357913941; //k ^= k >> 31; //k ^= k << 31; k = (k+0x7ed55d16) + (k<<12); k = (k^0xc761c23c) ^ (k>>19); k = (k+0x165667b1) + (k<<5); k = (k+0xd3a2646c) ^ (k<<9); k = (k+0xfd7046c5) + (k<<3); k = (k^0xb55a4f09) ^ (k>>16); var ret = k; if (isEither(ret)) { if (ret == 0) ret = 2; else ret = 0xFFFFFFFF; } return ret; } @:extern private static inline function arrayCopy(sourceArray:Dynamic, sourceIndex:Int, destinationArray:Dynamic, destinationIndex:Int, length:Int):Void java.lang.System.arraycopy(sourceArray, sourceIndex, destinationArray, destinationIndex, length); @:extern private static inline function assert(x:Bool):Void { #if DEBUG_HASHTBL if (!x) throw "assert failed"; #end } } private typedef HashType = Int; haxe_3.4.4.orig/std/java/_std/haxe/ds/WeakMap.hx0000664000175000017500000003037313166552354021307 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; import java.NativeArray; import java.lang.ref.WeakReference; import java.lang.ref.ReferenceQueue; @:coreApi class WeakMap implements haxe.Constraints.IMap { @:extern private static inline var HASH_UPPER = 0.77; @:extern private static inline var FLAG_EMPTY = 0; @:extern private static inline var FLAG_DEL = 1; /** * This is the most important structure here and the reason why it's so fast. * It's an array of all the hashes contained in the table. These hashes cannot be 0 nor 1, * which stand for "empty" and "deleted" states. * * The lookup algorithm will keep looking until a 0 or the key wanted is found; * The insertion algorithm will do the same but will also break when FLAG_DEL is found; */ private var hashes:NativeArray; private var entries:NativeArray>; //weak map specific private var queue:ReferenceQueue; private var nBuckets:Int; private var size:Int; private var nOccupied:Int; private var upperBound:Int; private var cachedEntry:Entry; private var cachedIndex:Int; #if DEBUG_HASHTBL private var totalProbes:Int; private var probeTimes:Int; private var sameHash:Int; private var maxProbe:Int; #end public function new() : Void { cachedIndex = -1; queue = new ReferenceQueue(); } @:analyzer(ignore) private function cleanupRefs():Void { var x:Dynamic = null, nOccupied = nOccupied; while (( x = queue.poll()) != null) { //even if not found on hashtable (already removed), release value var x:Entry = cast x; x.value = null; //lookup index if (nOccupied != 0) { var mask = nBuckets - 1, hash = x.hash, nProbes = 0; var i = hash & mask; var last = i, flag; while(!isEmpty(flag = hashes[i]) && (isDel(flag) || flag != hash || entries[i] != x)) { i = (i + ++nProbes) & mask; } if (entries[i] == x) { if (cachedIndex == i) { cachedIndex = -1; cachedEntry = null; } entries[i] = null; hashes[i] = FLAG_DEL; --size; } } } } public function set( key : K, value : V ) : Void { cleanupRefs(); var x:Int, k:Int; if (nOccupied >= upperBound) { if (nBuckets > (size << 1)) resize(nBuckets - 1); //clear "deleted" elements else resize(nBuckets + 2); } k = hash(key); var hashes = hashes, entries = entries; { var mask = (nBuckets == 0) ? 0 : nBuckets - 1; var site = x = nBuckets; var i = k & mask, nProbes = 0; var delKey = -1; //for speed up if (isEmpty(hashes[i])) { x = i; } else { //var inc = getInc(k, mask); var last = i, flag; while(! (isEmpty(flag = hashes[i]) || (flag == k && entries[i].keyEquals(key) )) ) { if (delKey == -1 && isDel(flag)) delKey = i; i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } if (isEmpty(flag) && delKey != -1) x = delKey; else x = i; } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end } var flag = hashes[x], entry = new Entry(key,value,k,queue); if (isEmpty(flag)) { entries[x] = entry; hashes[x] = k; size++; nOccupied++; } else if (isDel(flag)) { entries[x] = entry; hashes[x] = k; size++; } else { assert(entries[x].keyEquals(key)); entries[x] = entry; } cachedIndex = x; cachedEntry = entry; } @:final private function lookup( key : K ) : Int { if (nBuckets != 0) { var hashes = hashes, entries = entries; var mask = nBuckets - 1, hash = hash(key), k = hash, nProbes = 0; var i = k & mask; var last = i, flag; //var inc = getInc(k, mask); while (!isEmpty(flag = hashes[i]) && (isDel(flag) || flag != k || !entries[i].keyEquals(key))) { i = (i + ++nProbes) & mask; #if DEBUG_HASHTBL probeTimes++; if (i == last) throw "assert"; #end } #if DEBUG_HASHTBL if (nProbes > maxProbe) maxProbe = nProbes; totalProbes++; #end return isEither(flag) ? -1 : i; } return -1; } @:final @:private function resize(newNBuckets:Int) : Void { //This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. var newHash = null; var j = 1; { newNBuckets = roundUp(newNBuckets); if (newNBuckets < 4) newNBuckets = 4; if (size >= (newNBuckets * HASH_UPPER + 0.5)) /* requested size is too small */ { j = 0; } else { /* hash table size to be changed (shrink or expand); rehash */ var nfSize = newNBuckets; newHash = new NativeArray( nfSize ); if (nBuckets < newNBuckets) //expand { var e = new NativeArray(newNBuckets); if (entries != null) arrayCopy(entries, 0, e, 0, nBuckets); entries = e; } //otherwise shrink } } if (j != 0) { //rehashing is required //resetting cache cachedEntry = null; cachedIndex = -1; j = -1; var nBuckets = nBuckets, entries = entries, hashes = hashes; var newMask = newNBuckets - 1; while (++j < nBuckets) { var k; if (!isEither(k = hashes[j])) { var entry = entries[j]; hashes[j] = FLAG_DEL; while (true) /* kick-out process; sort of like in Cuckoo hashing */ { var nProbes = 0; var i = k & newMask; while (!isEmpty(newHash[i])) i = (i + ++nProbes) & newMask; newHash[i] = k; if (i < nBuckets && !isEither(k = hashes[i])) /* kick out the existing element */ { { var tmp = entries[i]; entries[i] = entry; entry = tmp; } hashes[i] = FLAG_DEL; /* mark it as deleted in the old hash table */ } else { /* write the element and jump out of the loop */ entries[i] = entry; break; } } } } if (nBuckets > newNBuckets) /* shrink the hash table */ { { var e = new NativeArray(newNBuckets); arrayCopy(entries, 0, e, 0, newNBuckets); this.entries = e; } } this.hashes = newHash; this.nBuckets = newNBuckets; this.nOccupied = size; this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5); } } public function get( key : K ) : Null { cleanupRefs(); var idx = -1; if (cachedEntry != null && cachedEntry.keyEquals(key) && ( (idx = cachedIndex) != -1 )) { return cachedEntry.value; } idx = lookup(key); if (idx != -1) { var entry = entries[idx]; cachedEntry = entry; cachedIndex = idx; return entry.value; } return null; } private function getDefault( key : K, def : V ) : V { cleanupRefs(); var idx = -1; if (cachedEntry != null && cachedEntry.keyEquals(key) && ( (idx = cachedIndex) != -1 )) { return cachedEntry.value; } idx = lookup(key); if (idx != -1) { var entry = entries[idx]; cachedEntry = entry; cachedIndex = idx; return entry.value; } return def; } public function exists( key : K ) : Bool { cleanupRefs(); var idx = -1; if (cachedEntry != null && cachedEntry.keyEquals(key) && ( (idx = cachedIndex) != -1 )) { return true; } idx = lookup(key); if (idx != -1) { var entry = entries[idx]; cachedEntry = entry; cachedIndex = idx; return true; } return false; } public function remove( key : K ) : Bool { cleanupRefs(); var idx = -1; if ( !(cachedEntry != null && cachedEntry.keyEquals(key) && ( (idx = cachedIndex) != -1 )) ) { idx = lookup(key); } if (idx == -1) { return false; } else { if (cachedEntry != null && cachedEntry.keyEquals(key)) { cachedIndex = -1; cachedEntry = null; } hashes[idx] = FLAG_DEL; entries[idx] = null; --size; return true; } } /** Returns an iterator of all keys in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function keys() : Iterator { cleanupRefs(); var i = 0; var len = nBuckets; var lastKey = null; //keep a strong reference to the key while iterating, so it can't be collected while iterating return { hasNext: function() { for (j in i...len) { if (!isEither(hashes[j])) { var entry = entries[j]; var last = entry.get(); if (last != null) { lastKey = last; cachedIndex = i; cachedEntry = entry; i = j; return true; } } } return false; }, next: function() { i = i + 1; return lastKey; } }; } /** Returns an iterator of all values in the hashtable. Implementation detail: Do not set() any new value while iterating, as it may cause a resize, which will break iteration **/ public function iterator() : Iterator { cleanupRefs(); var i = 0; var len = nBuckets; return { hasNext: function() { for (j in i...len) { if (!isEither(hashes[j])) { i = j; return true; } } return false; }, next: function() { var ret = entries[i].value; i = i + 1; return ret; } }; } /** Returns an displayable representation of the hashtable content. **/ public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(Std.string(i)); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } @:extern private static inline function roundUp(x:Int):Int { --x; x |= (x) >>> 1; x |= (x) >>> 2; x |= (x) >>> 4; x |= (x) >>> 8; x |= (x) >>> 16; return ++x; } @:extern private static inline function getInc(k:Int, mask:Int):Int //return 1 for linear probing return (((k) >> 3 ^ (k) << 3) | 1) & (mask); @:extern private static inline function isEither(v:HashType):Bool return (v & 0xFFFFFFFE) == 0; @:extern private static inline function isEmpty(v:HashType):Bool return v == FLAG_EMPTY; @:extern private static inline function isDel(v:HashType):Bool return v == FLAG_DEL; //guarantee: Whatever this function is, it will never return 0 nor 1 @:extern private static inline function hash(s:Dynamic):HashType { var k:Int = untyped s.hashCode(); //k *= 357913941; //k ^= k << 24; //k += ~357913941; //k ^= k >> 31; //k ^= k << 31; k = (k+0x7ed55d16) + (k<<12); k = (k^0xc761c23c) ^ (k>>19); k = (k+0x165667b1) + (k<<5); k = (k+0xd3a2646c) ^ (k<<9); k = (k+0xfd7046c5) + (k<<3); k = (k^0xb55a4f09) ^ (k>>16); var ret = k; if (isEither(ret)) { if (ret == 0) ret = 2; else ret = 0xFFFFFFFF; } return ret; } @:extern private static inline function arrayCopy(sourceArray:Dynamic, sourceIndex:Int, destinationArray:Dynamic, destinationIndex:Int, length:Int):Void java.lang.System.arraycopy(sourceArray, sourceIndex, destinationArray, destinationIndex, length); @:extern private static inline function assert(x:Bool):Void { #if DEBUG_HASHTBL if (!x) throw "assert failed"; #end } } private class Entry extends WeakReference { public var value:V; public var hash(default, null):Int; public function new(key:K, value:V, hash:Int, queue:ReferenceQueue) { super(key, queue); this.value = value; this.hash = hash; } @:final inline public function keyEquals(k:K):Bool { return k != null && untyped k.equals(get()); } } private typedef HashType = Int; haxe_3.4.4.orig/std/java/_std/haxe/zip/Compress.hx0000664000175000017500000000540113166552354021743 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; import java.util.zip.Deflater; class Compress { var deflater:Deflater; var mode:Int; var finish:Bool = false; public function new( level : Int ) { throw "Not implemented for this platform"; //FIXME: Add unit tests for Compress/Uncompress and check current implementation this.deflater = new Deflater(level); this.mode = Deflater.NO_FLUSH; } public function execute( src : haxe.io.Bytes, srcPos : Int, dst : haxe.io.Bytes, dstPos : Int ) : { done : Bool, read : Int, write : Int } { deflater.setInput(src.getData(), srcPos, src.length - srcPos); if (finish) deflater.finish(); finish = false; var written = deflater.deflate(dst.getData(), dstPos, dst.length - dstPos); var read = deflater.getTotalIn(); return { done: deflater.finished(), read: read, write: written }; } public function setFlushMode( f : FlushMode ) { this.mode = switch (f) { case NO: Deflater.NO_FLUSH; case SYNC: Deflater.SYNC_FLUSH; case FULL: Deflater.FULL_FLUSH; case FINISH: this.finish = true; Deflater.FULL_FLUSH; case BLOCK: throw "Not Implemented"; } } public function close() { deflater.end(); } public static function run( s : haxe.io.Bytes, level : Int ) : haxe.io.Bytes { var deflater = new java.util.zip.Deflater(level); deflater.setInput(s.getData()); var outputStream = new java.io.ByteArrayOutputStream(s.length); deflater.finish(); var buffer = haxe.io.Bytes.alloc(1024).getData(); while (!deflater.finished()) { var count = deflater.deflate(buffer); outputStream.write(buffer, 0, count); } outputStream.close(); return haxe.io.Bytes.ofData(outputStream.toByteArray()); } } haxe_3.4.4.orig/std/java/_std/haxe/zip/Uncompress.hx0000664000175000017500000000374613166552354022320 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.zip; class Uncompress { public function new( ?windowBits : Int ) { throw "Not implemented for this platform"; } public function execute( src : haxe.io.Bytes, srcPos : Int, dst : haxe.io.Bytes, dstPos : Int ) : { done : Bool, read : Int, write : Int } { return null; } public function setFlushMode( f : FlushMode ) { } public function close() { } public static function run( src : haxe.io.Bytes, ?bufsize : Int ) : haxe.io.Bytes { var decompresser = new java.util.zip.Inflater(); var buf = haxe.io.Bytes.alloc(bufsize == null ? src.length : bufsize).getData(); var out = new java.io.ByteArrayOutputStream(src.length); decompresser.setInput(src.getData(), 0, src.length); while (!decompresser.finished()) { var count = decompresser.inflate(buf); out.write(buf, 0, count); } out.close(); return haxe.io.Bytes.ofData(out.toByteArray()); } } haxe_3.4.4.orig/std/java/_std/sys/FileSystem.hx0000664000175000017500000000644313166552354021332 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys; import java.io.File; import java.Lib; @:coreApi class FileSystem { public static function exists( path : String ) : Bool { return new File(path).exists(); } public static function rename( path : String, newPath : String ) : Void { if (!new File(path).renameTo(new File(newPath))) { throw "Cannot rename " + path + " to " + newPath; } } public static function stat( path : String ) : FileStat { var f = new File(path); if (!f.exists()) throw "Path " + path + " doesn't exist"; return { gid: 0, //java doesn't let you get this info uid: 0, //same atime: Date.now(), //same mtime: Date.fromTime(cast(f.lastModified(), Float)), ctime: Date.fromTime(cast(f.lastModified(), Float)), //same size: cast(f.length(), Int), //TODO: maybe change to Int64 for Haxe 3? dev: 0, //FIXME: not sure what that is ino: 0, //FIXME: not sure what that is nlink: 0, //FIXME: not sure what that is rdev: 0, //FIXME: not sure what that is mode: 0 //FIXME: not sure what that is }; } public static function fullPath( relPath : String ) : String { try { return new File(relPath).getCanonicalPath(); } catch (e: java.io.IOException) { throw new java.lang.RuntimeException(e); } } public static function absolutePath ( relPath : String ) : String { if (haxe.io.Path.isAbsolute(relPath)) return relPath; return haxe.io.Path.join([Sys.getCwd(), relPath]); } public static function isDirectory( path : String ) : Bool { var f = new File(path); if (!f.exists()) throw "Path " + path + " doesn't exist"; return f.isDirectory(); } public static function createDirectory( path : String ) : Void { if (!new File(path).mkdirs()) throw "Cannot create dir " + path; } public static function deleteFile( path : String ) : Void { if (!new File(path).delete()) throw "Cannot delete file " + path; } public static function deleteDirectory( path : String ) : Void { if (!new File(path).delete()) throw "Cannot delete directory " + path; } public static function readDirectory( path : String ) : Array { var f = new File(path); if (!f.exists()) throw "Path " + path + " doesn't exist"; return Lib.array( f.list() ); } } haxe_3.4.4.orig/std/java/_std/sys/db/Mysql.hx0000664000175000017500000000347213166552354020737 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.db; class Mysql { static var init = false; public static function connect( params : { host : String, ?port : Int, user : String, pass : String, ?socket : String, database : String } ) : sys.db.Connection { if (!init) { java.lang.Class.forName("com.mysql.jdbc.Driver"); init = true; } var url = new StringBuf(); url.add('jdbc:mysql:'); if (params.socket != null) { url.add(params.socket); } else { url.add('//'); url.add(params.host); if (params.port != null) url.add(':${params.port}'); } url.add('/${params.database}'); var cnx = java.sql.DriverManager.getConnection(url.toString(), params.user, params.pass); return java.db.Jdbc.create(cnx); } } haxe_3.4.4.orig/std/java/_std/sys/db/Sqlite.hx0000664000175000017500000000321313166552354021064 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.db; class Sqlite { static var init = false; /** Opens a new SQLite connection on the specified path. Note that you will need a SQLite JDBC driver (like https://bitbucket.org/xerial/sqlite-jdbc). **/ public static function open(file:String):sys.db.Connection { if (!init) { try java.lang.Class.forName("org.sqlite.JDBC") catch(e:Dynamic) throw e; init = true; } try { var cnx = java.sql.DriverManager.getConnection("jdbc:sqlite:" + file); return java.db.Jdbc.create(cnx); } catch(e:Dynamic) throw e; } } haxe_3.4.4.orig/std/java/_std/sys/io/File.hx0000664000175000017500000000576213166552354020537 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; @:coreApi class File { public static function getContent( path : String ) : String { var f = read(path, false); var ret = f.readAll().toString(); f.close(); return ret; } public static function saveContent( path : String, content : String ) : Void { var f = write(path, false); f.writeString(content); f.close(); } public static function getBytes( path : String ) : haxe.io.Bytes { var f = read(path, true); var ret = f.readAll(); f.close(); return ret; } public static function saveBytes( path : String, bytes : haxe.io.Bytes ) : Void { var f = write(path, true); f.writeBytes(bytes, 0, bytes.length); f.close(); } public static function read( path : String, binary : Bool = true ) : FileInput { try { return new FileInput( new java.io.RandomAccessFile(new java.io.File(path), "r") ); } catch (e:Dynamic) //swallow checked exceptions { throw e; } } public static function write( path : String, binary : Bool = true ) : FileOutput { var f = new java.io.File(path); if (f.exists()) { f.delete(); } try { return new FileOutput( new java.io.RandomAccessFile(f, "rw") ); } catch (e:Dynamic) //swallow checked exceptions { throw e; } } public static function append( path : String, binary : Bool = true ) : FileOutput { var f = new java.io.File(path); try { var ra = new java.io.RandomAccessFile(f, "rw"); if (f.exists()) { ra.seek(f.length()); } return new FileOutput( ra ); } catch (e:Dynamic) //swallow checked exceptions { throw e; } } public static function copy( srcPath : String, dstPath : String ) : Void { var r:FileInput = null; var w:FileOutput = null; try { r = read(srcPath); w = write(dstPath); w.writeInput(r); r.close(); w.close(); } catch (e:Dynamic) { if (r != null) r.close(); if (w != null) w.close(); throw e; } } }haxe_3.4.4.orig/std/java/_std/sys/io/FileInput.hx0000664000175000017500000000524713166552354021555 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; import haxe.Int64; import haxe.io.Bytes; import haxe.io.Eof; import haxe.io.Input; import java.io.EOFException; import java.io.IOException; class FileInput extends Input { var f:java.io.RandomAccessFile; var _eof:Bool; public function new(f) { this.f = f; this._eof = false; } override public function close() { try f.close() catch(e:Dynamic) throw e; } override public function readByte():Int { try { return f.readUnsignedByte(); } catch (e:EOFException) { _eof = true; throw new Eof(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } override public function readBytes(s:Bytes, pos:Int, len:Int):Int { var ret = 0; try { ret = f.read(s.getData(), pos, len); } catch (e:EOFException) { _eof = true; throw new Eof(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } if (ret == -1) { _eof = true; throw new Eof(); } return ret; } public function seek( p : Int, pos : FileSeek ) : Void { _eof = false; try { switch(pos) { case SeekBegin: f.seek(cast p); case SeekCur: f.seek(haxe.Int64.add(f.getFilePointer(), cast(p, Int64))); case SeekEnd: f.seek(haxe.Int64.add(f.length(), cast p)); } } catch (e:EOFException) { _eof = true; throw new Eof(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } public function tell() : Int { try { return cast f.getFilePointer(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } public inline function eof() : Bool { return _eof; } } haxe_3.4.4.orig/std/java/_std/sys/io/FileOutput.hx0000664000175000017500000000474613166552354021761 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; import haxe.io.Bytes; import haxe.io.Eof; import haxe.io.Output; import java.io.EOFException; import java.io.IOException; class FileOutput extends Output { var f:java.io.RandomAccessFile; public function new(f) { this.f = f; } override public function close() { try f.close() catch(e:Dynamic) throw e; } override public function writeByte(c:Int):Void { try { this.f.write(c); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } override public function write(s:Bytes):Void { try { this.f.write(s.getData()); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } override public function writeBytes(s:Bytes, pos:Int, len:Int):Int { try { this.f.write(s.getData(), pos, len); return len; } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } public function seek( p : Int, pos : FileSeek ) : Void { try { switch(pos) { case SeekBegin: f.seek(cast p); case SeekCur: f.seek(haxe.Int64.add(f.getFilePointer(), cast(p, haxe.Int64))); case SeekEnd: f.seek(haxe.Int64.add(f.length(), cast p)); } } catch (e:EOFException) { throw new Eof(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } public function tell() : Int { try { return cast f.getFilePointer(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } } haxe_3.4.4.orig/std/java/_std/sys/io/Process.hx0000664000175000017500000001061613166552354021270 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.io; import haxe.io.Bytes; import haxe.io.BytesInput; import haxe.io.Eof; import java.io.IOException; import java.io.EOFException; import java.NativeArray; @:coreApi class Process { public var stdout(default,null) : haxe.io.Input; public var stderr(default,null) : haxe.io.Input; public var stdin(default, null) : haxe.io.Output; private var proc:java.lang.Process; @:allow(Sys) private static function createProcessBuilder(cmd:String, ?args:Array):java.lang.ProcessBuilder { var sysName = Sys.systemName(); var pargs; if (args == null) { var cmdStr = cmd; switch (sysName) { case "Windows": pargs = new NativeArray(3); pargs[0] = cmd = switch (Sys.getEnv("COMSPEC")) { case null: "cmd.exe"; case comspec: comspec; } pargs[1] = '/C'; pargs[2] = '"$cmdStr"'; case _: pargs = new NativeArray(3); pargs[0] = cmd = "/bin/sh"; pargs[1] = "-c"; pargs[2] = cmdStr; } } else { pargs = new NativeArray(args.length + 1); switch (sysName) { case "Windows": pargs[0] = StringTools.quoteWinArg(cmd, false); for (i in 0...args.length) { pargs[i + 1] = StringTools.quoteWinArg(args[i], false); } case _: pargs[0] = cmd; for (i in 0...args.length) { pargs[i + 1] = args[i]; } } } return new java.lang.ProcessBuilder(pargs); } public function new( cmd : String, ?args : Array ) : Void { var p = proc = createProcessBuilder(cmd, args).start(); stderr = new ProcessInput(p.getErrorStream()); stdout = new ProcessInput(p.getInputStream()); stdin = new java.io.NativeOutput(p.getOutputStream()); } public function getPid() : Int { if (Reflect.hasField(proc, "pid")) return Reflect.field(proc, "pid"); return -1; } public function exitCode( block : Bool = true ) : Null { if( block == false ) { try { return proc.exitValue(); } catch( e : Dynamic ) { return null; } } cast(stdout, ProcessInput).bufferContents(); cast(stderr, ProcessInput).bufferContents(); try { proc.waitFor(); } catch (e:Dynamic) { throw e; } return proc.exitValue(); } public function close() : Void { proc.destroy(); } public function kill() : Void { proc.destroy(); } } private class ProcessInput extends java.io.NativeInput { private var chained:BytesInput; public function bufferContents():Void { if (chained != null) return; var b = this.readAll(); chained = new BytesInput(b); } override public function readByte():Int { if (chained != null) return chained.readByte(); var ret = 0; try { ret = stream.read(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } if ( ret == -1 ) throw new Eof(); return ret; } override public function readBytes(s:Bytes, pos:Int, len:Int):Int { if (chained != null) return chained.readBytes(s, pos, len); var ret = -1; try { ret = stream.read(s.getData(), pos, len); } catch (e:EOFException) { throw new Eof(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } if (ret == -1) throw new Eof(); return ret; } override public function close():Void { if (chained != null) chained.close(); try { stream.close(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } } haxe_3.4.4.orig/std/java/_std/sys/net/Host.hx0000664000175000017500000000364013166552354020745 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.net; import java.net.InetAddress; class Host { public var host(default,null) : String; public var ip(default,null) : Int; @:allow(sys.net) private var wrapped:InetAddress; public function new( name : String ) : Void { host = name; try this.wrapped = InetAddress.getByName(name) catch(e:Dynamic) throw e; var rawIp = wrapped.getAddress(); //network byte order assumed this.ip = cast(rawIp[3], Int) | (cast(rawIp[2], Int) << 8) | (cast(rawIp[1], Int) << 16) | (cast(rawIp[0], Int) << 24); } public function toString() : String { return wrapped.getHostAddress(); } public function reverse() : String { return wrapped.getHostName(); } public static function localhost() : String { try { return InetAddress.getLocalHost().getHostName(); } catch(e:Dynamic) throw e; } } haxe_3.4.4.orig/std/java/_std/sys/net/Socket.hx0000664000175000017500000001041613166552354021257 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package sys.net; import java.net.InetSocketAddress; @:coreApi class Socket { public var input(default,null) : haxe.io.Input; public var output(default,null) : haxe.io.Output; public var custom : Dynamic; private var sock:java.net.Socket; private var server:java.net.ServerSocket; private var boundAddr:java.net.SocketAddress; public function new() : Void { create(); } private function create():Void { this.sock = new java.net.Socket(); try { this.server = new java.net.ServerSocket(); } catch(e:Dynamic) throw e; } public function close() : Void { try { if (sock != null) this.sock.close(); if (server != null) this.server.close(); } catch(e:Dynamic) throw e; } public function read() : String { return input.readAll().toString(); } public function write( content : String ) : Void { output.writeString(content); } public function connect( host : Host, port : Int ) : Void { try { sock.connect(new InetSocketAddress( host.wrapped, port)); this.output = new java.io.NativeOutput(sock.getOutputStream()); this.input = new java.io.NativeInput(sock.getInputStream()); } catch(e:Dynamic) throw e; } public function listen( connections : Int ) : Void { if (boundAddr == null) throw "You must bind the Socket to an address!"; try server.bind(boundAddr,connections) catch(e:Dynamic) throw e; } public function shutdown( read : Bool, write : Bool ) : Void { try { if (read) sock.shutdownInput(); if (write) sock.shutdownOutput(); } catch(e:Dynamic) throw e; } public function bind( host : Host, port : Int ) : Void { if (boundAddr != null) { if (server.isBound()) throw "Already bound"; } this.boundAddr = new java.net.InetSocketAddress(host.wrapped, port); } public function accept() : Socket { var ret = try server.accept() catch(e:Dynamic) throw e; var s = new Socket(); s.sock = ret; s.output = new java.io.NativeOutput(ret.getOutputStream()); s.input = new java.io.NativeInput(ret.getInputStream()); return s; } public function peer() : { host : Host, port : Int } { var rem = sock.getInetAddress(); if (rem == null) return null; var host = new Host(null); host.wrapped = rem; return { host: host, port: sock.getPort() }; } public function host() : { host : Host, port : Int } { var local = sock.getLocalAddress(); var host = new Host(null); host.wrapped = local; if (boundAddr != null) { return { host: host, port: server.getLocalPort() }; } return { host: host, port: sock.getLocalPort() }; } public function setTimeout( timeout : Float ) : Void { try sock.setSoTimeout( Std.int(timeout * 1000) ) catch(e:Dynamic) throw e; } public function waitForRead() : Void { throw "Not implemented"; } public function setBlocking( b : Bool ) : Void { throw "Not implemented"; } public function setFastSend( b : Bool ) : Void { try sock.setTcpNoDelay(b) catch(e:Dynamic) throw e; } public static function select(read : Array, write : Array, others : Array, ?timeout : Float) : { read: Array,write: Array,others: Array } { throw "Not implemented"; return null; } } haxe_3.4.4.orig/std/java/db/Jdbc.hx0000664000175000017500000001721613166552354016726 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.db; import java.util.concurrent.atomic.AtomicInteger; import haxe.io.Bytes; import java.sql.Types; @:native('haxe.java.db.Jdbc') class Jdbc { public static function create(cnx:java.sql.Connection):sys.db.Connection { return new JdbcConnection(cnx); } } @:native('haxe.java.db.JdbcConnection') private class JdbcConnection implements sys.db.Connection { private static var ids = new AtomicInteger(0); private var id:Int; private var cnx:java.sql.Connection; private var _lastInsertId:Int; //escape handling private var escapeRegex:EReg; private var escapes:Array; public function new(cnx) { this.id = ids.getAndIncrement(); this.cnx = cnx; this.escapes = []; this.escapeRegex = ~/@@HX_ESCAPE(\d+)_(\d+)@@/; } public function close() { try this.cnx.close() catch(e:Dynamic) throw e; } public function escape(s:String):String { return "@@HX_ESCAPE" + id + "_" +escapes.push(s) + "@@"; } public function quote(s:String):String { return "@@HX_ESCAPE" + id + "_" +escapes.push(s) + "@@"; } public function addValue(s:StringBuf, v:Dynamic) { if (Std.is(v, Date)) { v = Std.string(v); } else if (Std.is(v, Bytes)) { var bt:Bytes = v; v = bt.getData(); } s.add("@@HX_ESCAPE"); s.add(id); s.add("_"); s.add(escapes.push(v)); s.add("@@"); } public function lastInsertId():Int { return _lastInsertId; } public function dbName():String { try { var ret = cnx.getMetaData().getDriverName(); var retc = ret.toLowerCase(); if (retc.indexOf("mysql") != -1) return "MySQL"; else if (retc.indexOf("sqlite") != -1) return "SQLite"; return ret; } catch(e:Dynamic) { throw e; } } public function startTransaction() { try { cnx.setAutoCommit(false); } catch(e:Dynamic) throw e; } public function commit() { try { cnx.commit(); } catch(e:Dynamic) { throw e; } } public function rollback() { try cnx.rollback() catch(e:Dynamic) throw e; } public function request(s:String):sys.db.ResultSet { var newst = new StringBuf(); var sentArray = []; //cycle through the request string, adding any @@HX_ESCAPE@@ reference to the sentArray var r = escapeRegex; var myid = id + "", escapes = escapes, elen = escapes.length; try { while (r.match(s)) { var id = r.matched(1); if (id != myid) throw "Request quotes are only valid for one single request; They can't be cached."; newst.add(r.matchedLeft()); var eid = Std.parseInt(r.matched(2)); if (eid == null || eid > elen) throw "Invalid request quote ID " + eid; sentArray.push(escapes[eid - 1]); newst.add("?"); s = r.matchedRight(); } newst.add(s); var stmt = cnx.prepareStatement(newst.toString(), java.sql.Statement.Statement_Statics.RETURN_GENERATED_KEYS); for (i in 0...sentArray.length) { stmt.setObject(i + 1, sentArray[i]); } var ret = null, dbName = dbName(); if (stmt.execute()) { //is a result set var rs = stmt.getResultSet(); ret = new JdbcResultSet(rs, dbName, stmt.getMetaData()); } else { //is an update var affected = stmt.getUpdateCount(); if (affected == 1) { var autogen = stmt.getGeneratedKeys(); if (autogen.next()) { this._lastInsertId = autogen.getInt(1); } } ret = new JdbcResultSet(null, dbName,null); } if (escapes.length != 0) escapes = []; this.id = ids.getAndIncrement(); return ret; } catch(e:Dynamic) { if (escapes.length != 0) escapes = []; this.id = ids.getAndIncrement(); throw e; } } } @:native('haxe.java.db.JdbcResultSet') private class JdbcResultSet implements sys.db.ResultSet { @:isVar public var length(get,null) : Int; public var nfields(get,null) : Int; private var rs:java.sql.ResultSet; private var names:Array; private var types:java.NativeArray; private var dbName:String; private var didNext:Bool; public function new(rs, dbName, meta:java.sql.ResultSetMetaData) { this.dbName = dbName; this.rs = rs; if (meta != null) { try { var count = meta.getColumnCount(); var names = [], types = new NativeArray(count); for (i in 0...count) { names.push(meta.getColumnName(i+1)); types[i] = meta.getColumnType(i+1); } this.types = types; this.names = names; } catch(e:Dynamic) throw e; } } private function get_length():Int { if (length == 0) { try { var cur = rs.getRow(); rs.last(); this.length = rs.getRow(); rs.absolute(cur); } catch(e:Dynamic) throw e; } return length; } private function get_nfields():Int { return names == null ? 0 : names.length; } public function hasNext() : Bool { try { didNext = true; return rs != null && rs.next(); } catch(e:Dynamic) { return throw e; } } public function next() : Dynamic { try { if (rs == null) return null; if (didNext) { didNext = false; } else { if (!rs.next()) { return null; } } var ret = {}, names = names, types = types; for (i in 0...names.length) { var name = names[i], t = types[i], val:Dynamic = null; if (t == Types.FLOAT) { val = rs.getDouble(i+1); } else if (t == Types.DATE || t == Types.TIME) { if (dbName == "SQLite") { var str = rs.getString(i+1); if (str != null) { var d:Date = Date.fromString(str); val = d; } } else { var d:java.sql.Date = rs.getDate(i+1); if (d != null) val = Date.fromTime(cast d.getTime()); } } else if (t == Types.LONGVARBINARY || t == Types.VARBINARY || t == Types.BINARY || t == Types.BLOB) { var b = rs.getBytes(i+1); if (b != null) val = Bytes.ofData(b); } else { untyped __java__("val = rs.getObject(i + 1)"); //type parameter constraint + overloads } Reflect.setField(ret, name, val); } return ret; } catch(e:Dynamic) throw e; } public function results() : List { var l = new List(); if (rs == null) return l; try { while(hasNext()) l.add(next()); } catch(e:Dynamic) throw e; return l; } public function getResult( n : Int ) : String { try { return rs.getString(n); } catch(e:Dynamic) throw e; } public function getIntResult( n : Int ) : Int { try { return rs.getInt(n); } catch(e:Dynamic) { return throw e; }; } public function getFloatResult( n : Int ) : Float { try { return rs.getFloat(n); } catch(e:Dynamic) { return throw e; }; } public function getFieldsNames() : Null> { return this.names; } } haxe_3.4.4.orig/std/java/internal/Exceptions.hx0000664000175000017500000000536113166552354021432 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.internal; import java.lang.Throwable; import java.lang.RuntimeException; import java.lang.Exception; @:native("haxe.lang.Exceptions") class Exceptions { private static var exception = new java.lang.ThreadLocal(); @:keep private static function setException(exc:Throwable) { exception.set(exc); } public static function currentException() { return exception.get(); } } @:classCode("public static final long serialVersionUID = 5956463319488556322L;") @:nativeGen @:keep @:native("haxe.lang.HaxeException") private class HaxeException extends RuntimeException { private var obj:Dynamic; public function new(obj:Dynamic, msg:String, cause:Throwable) { super(msg, cause); if (Std.is(obj, HaxeException)) { var _obj:HaxeException = cast obj; obj = _obj.getObject(); } this.obj = obj; } public function getObject():Dynamic { return obj; } #if !debug @:overload override public function fillInStackTrace():Throwable { return this; } #end @:overload override public function toString():String { return "Haxe Exception: " + obj; } @:overload override public function getMessage():String { return switch (super.getMessage()) { case null: Std.string(obj); case message: message; } } public static function wrap(obj:Dynamic):RuntimeException { var ret:RuntimeException = null; if (Std.is(obj, RuntimeException)) ret = obj; else if (Std.is(obj, String)) ret = new HaxeException(obj, obj, null); else if (Std.is(obj, Throwable)) ret = new HaxeException(obj, Std.string(obj), obj); else ret = new HaxeException(obj, Std.string(obj), null); return ret; } } haxe_3.4.4.orig/std/java/internal/FieldLookup.hx0000664000175000017500000000722713166552354021531 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.internal; import java.lang.System; @:native('haxe.lang.FieldLookup') @:keep @:static private class FieldLookup { @:functionCode(' return s.hashCode(); ') public static function hash(s:String):Int { return 0; } public static function findHash(hash:String, hashs:java.NativeArray, length:Int):Int { var min = 0; var max = length; while (min < max) { var mid = Std.int((max + min) / 2); //overflow safe var classify = untyped hash.compareTo(hashs[mid]); if (classify < 0) { max = mid; } else if (classify > 0) { min = mid + 1; } else { return mid; } } //if not found, return a negative value of where it should be inserted return ~min; } static function removeString(a:java.NativeArray, length:Int, pos:Int) { System.arraycopy(a, pos + 1, a, pos, length - pos - 1); a[length - 1] = null; } static function removeFloat(a:java.NativeArray, length:Int, pos:Int) { System.arraycopy(a, pos + 1, a, pos, length - pos - 1); a[length - 1] = 0; } static function removeDynamic(a:java.NativeArray, length:Int, pos:Int) { System.arraycopy(a, pos + 1, a, pos, length - pos - 1); a[length - 1] = null; } @:extern static inline function __insert(a:java.NativeArray, length:Int, pos:Int, x:T):java.NativeArray { var capacity = a.length; if (pos == length) { if (capacity == length) { var newarr = new NativeArray((length << 1) + 1); System.arraycopy(a, 0, newarr, 0, a.length); a = newarr; } } else if (pos == 0) { if (capacity == length) { var newarr = new NativeArray((length << 1) + 1); System.arraycopy(a, 0, newarr, 1, length); a = newarr; } else { System.arraycopy(a, 0, a, 1, length); } } else { if (capacity == length) { var newarr = new NativeArray((length << 1) + 1); System.arraycopy(a, 0, newarr, 0, pos); System.arraycopy(a, pos, newarr, pos + 1, length - pos); a = newarr; } else { System.arraycopy(a, pos, a, pos + 1, length - pos); System.arraycopy(a, 0, a, 0, pos); } } a[pos] = x; return a; } static function insertString(a:java.NativeArray, length:Int, pos:Int, x:String):java.NativeArray return __insert(a, length, pos, x); static function insertFloat(a:java.NativeArray, length:Int, pos:Int, x:Float):java.NativeArray return __insert(a, length, pos, x); static function insertDynamic(a:java.NativeArray, length:Int, pos:Int, x:Dynamic):java.NativeArray return __insert(a, length, pos, x); } haxe_3.4.4.orig/std/java/internal/Function.hx0000664000175000017500000000517513166552354021101 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.internal; import java.internal.Runtime; /** * These classes are automatically generated by the compiler. They are only * here so there is an option for e.g. defining them as externs if you are compiling * in modules (untested) * * @author waneck */ @:abstract @:nativeGen @:native("haxe.lang.Function") @:keep class Function { function new(arity:Int, type:Int) { } } @:nativeGen @:native("haxe.lang.VarArgsBase") @:keep private class VarArgsBase extends Function { public function __hx_invokeDynamic(dynArgs:Array):Dynamic { throw "Abstract implementation"; } } @:nativeGen @:native('haxe.lang.VarArgsFunction') @:keep class VarArgsFunction extends VarArgsBase { private var fun:Array->Dynamic; public function new(fun) { super(-1, -1); this.fun = fun; } override public function __hx_invokeDynamic(dynArgs:Array):Dynamic { return fun(dynArgs); } } @:nativeGen @:native('haxe.lang.Closure') @:keep class Closure extends VarArgsBase { private var obj:Dynamic; private var field:String; public function new(obj:Dynamic, field) { super(-1, -1); this.obj = obj; this.field = field; } override public function __hx_invokeDynamic(dynArgs:Array):Dynamic { return Runtime.callField(obj, field, dynArgs); } public function equals(obj:Dynamic):Bool { if (obj == null) return false; var c:Closure = cast obj; return (c.obj == this.obj && c.field == this.field); } public function hashCode():Int { return obj.hashCode() ^ untyped field.hashCode(); } } haxe_3.4.4.orig/std/java/internal/HxObject.hx0000664000175000017500000000736413166552354021024 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.internal; import java.internal.IEquatable; import haxe.ds.Vector; private typedef StdType = Type; @:native('haxe.lang.HxObject') @:keep private class HxObject implements IHxObject { } @:native('haxe.lang.IHxObject') @:keep interface IHxObject { } @:native('haxe.lang.DynamicObject') @:keep class DynamicObject extends HxObject implements Dynamic { @:skipReflection public function toString():String { var ts = Reflect.field(this, "toString"); if (ts != null) return ts(); var ret = new StringBuf(); ret.add("{"); var first = true; for (f in Reflect.fields(this)) { if( first ) first = false; else ret.add(","); ret.add(" "); ret.add(f); ret.add(" : "); ret.add(Reflect.field(this, f)); } if (!first) ret.add(" "); ret.add("}"); return ret.toString(); } } @:keep @:native('haxe.lang.Enum') @:nativeGen class HxEnum { @:readOnly private var index(default,never):Int; public function new(index:Int) { untyped this.index = index; } public function getTag():String { return throw 'Not Implemented'; } public function getParams():Array<{}> { return []; } public function toString():String { return getTag(); } } @:keep @:native('haxe.lang.ParamEnum') @:nativeGen private class ParamEnum extends HxEnum { @:readOnly private var params(default,never):Vector; public function new(index:Int, params:Vector) { super(index); untyped this.params = params; } override public function getParams():Array<{}> { return params == null ? [] : cast params.toArray(); } override public function toString():String { if (params == null || params.length == 0) return getTag(); var ret = new StringBuf(); ret.add(getTag()); ret.add("("); var first = true; for (p in params) { if (first) first = false; else ret.add(","); ret.add(p); } ret.add(")"); return ret.toString(); } public function equals(obj:Dynamic) { if (obj == this) //we cannot use == as .Equals ! return true; var obj:ParamEnum = Std.is(obj,ParamEnum) ? cast obj : null; var ret = obj != null && Std.is(obj, StdType.getEnum(cast this)) && obj.index == this.index; if (!ret) return false; if (obj.params == this.params) return true; var len = 0; if (obj.params == null || this.params == null || (len = this.params.length) != obj.params.length) return false; for (i in 0...len) { if (!StdType.enumEq(obj.params[i], this.params[i])) return false; } return true; } public function hashCode():Int { var h = 19; if (params != null) for (p in params) { h = h * 31; if (p != null) untyped h += p.hashCode(); } h += index; return h; } } haxe_3.4.4.orig/std/java/internal/IEquatable.hx0000664000175000017500000000236513166552354021326 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.internal; @:native('haxe.lang.IEquatable') @:keep @:nativeGen interface IEquatable { public function equals(to:Dynamic):Bool; } haxe_3.4.4.orig/std/java/internal/Iterator.hx0000664000175000017500000000262613166552354021103 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.internal; /* TODO (see Gencommon.IteratorsInterfaceModf) @:native('haxe.lang.Iterator') @:keep interface Iterator { public function hasNext():Bool; public function next():T; } @:native('haxe.lang.Iterable') @:keep interface Iterable { public function iterator():Iterator; }*/haxe_3.4.4.orig/std/java/internal/Runtime.hx0000664000175000017500000003456113166552354020740 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.internal; /** This class is meant for internal compiler use only. It provides the Haxe runtime compatibility to the host language. Do not access it directly. **/ @:native('haxe.lang.Runtime') @:nativeGen @:classCode(' public static java.lang.Object getField(haxe.lang.IHxObject obj, java.lang.String field, boolean throwErrors) { if (obj == null && !throwErrors) return null; return obj.__hx_getField(field, throwErrors, false, false); } public static double getField_f(haxe.lang.IHxObject obj, java.lang.String field, boolean throwErrors) { if (obj == null && !throwErrors) return 0.0; return obj.__hx_getField_f(field, throwErrors, false); } public static java.lang.Object setField(haxe.lang.IHxObject obj, java.lang.String field, java.lang.Object value) { return obj.__hx_setField(field, value, false); } public static double setField_f(haxe.lang.IHxObject obj, java.lang.String field, double value) { return obj.__hx_setField_f(field, value, false); } public static java.lang.Object callField(haxe.lang.IHxObject obj, java.lang.String field, Array args) { return obj.__hx_invokeField(field, args); } ') @:keep class Runtime { public static var undefined:Dynamic = { }; @:functionCode(' return new haxe.lang.Closure(obj, field); ') public static function closure(obj:Dynamic, field:String):Dynamic { return null; } @:functionCode(' if (v1 == v2) return true; if (v1 == null || v2 == null) return false; if (v1 instanceof java.lang.Number) { if (!(v2 instanceof java.lang.Number)) return false; java.lang.Number v1c = (java.lang.Number) v1; java.lang.Number v2c = (java.lang.Number) v2; if (v1 instanceof java.lang.Long || v2 instanceof java.lang.Long) return v1c.longValue() == v2c.longValue(); return v1c.doubleValue() == v2c.doubleValue(); } else if (v1 instanceof java.lang.String || v1 instanceof haxe.lang.IEquatable) { //TODO see what happens with Boolean cases return v1.equals(v2); } return false; ') public static function eq(v1:Dynamic, v2:Dynamic):Bool { return false; } @:functionCode(' if (v1 == v2) return true; if (v1 instanceof java.lang.String || v1 instanceof haxe.lang.IEquatable) { return v1 != null && v1.equals(v2); } else { return v1 == v2; } ') public static function refEq(v1: { }, v2: { } ):Bool { return false; } @:functionCode(' return v1 == v2 || (v1 != null && v1.equals(v2)); ') public static function valEq(v1: { }, v2: { } ):Bool { return false; } @:functionCode(' return (obj == null) ? 0.0 : ((java.lang.Number) obj).doubleValue(); ') public static function toDouble(obj:Dynamic):Float { return 0.0; } @:functionCode(' return (obj == null) ? false : ((java.lang.Boolean) obj).booleanValue(); ') public static function toBool(obj:Dynamic):Bool { return false; } @:functionCode(' return (obj == null) ? 0 : ((java.lang.Number) obj).intValue(); ') public static function toInt(obj:Dynamic):Int { return 0; } public static function toLong(obj:Dynamic):haxe.Int64 { return obj == null ? 0 : (obj : java.lang.Number).longValue(); } @:functionCode(' if (obj != null && obj instanceof java.lang.Number) { return true; } else { return false; } ') public static function isDouble(obj:Dynamic):Bool { return false; } @:overload public static function isInt(obj:Dynamic):Bool { if (Std.is(obj, java.lang.Number)) { var n:java.lang.Number = obj; return n.doubleValue() == n.intValue(); } else { return false; } } @:overload public static function isInt(num:java.lang.Number):Bool { return num != null && num.doubleValue() == num.intValue(); } @:functionCode(' java.lang.Class cl = null; if (o instanceof java.lang.Class) { if (o == java.lang.String.class) return field.equals("fromCharCode"); cl = (java.lang.Class) o; } else if (o instanceof java.lang.String) { return haxe.lang.StringRefl.handleGetField( (java.lang.String) o, field, false) != null; } else { cl = o.getClass(); } try { java.lang.reflect.Field f = cl.getField(field); return true; } catch(Throwable t) { java.lang.reflect.Method[] ms = cl.getMethods(); for (int i = 0; i < ms.length; i++) { if (ms[i].getName().equals(field)) { return true; } } } return false; ') public static function slowHasField(o:Dynamic, field:String):Bool { return false; } @:functionCode(' if (v1 == v2) return 0; if (v1 == null) return -1; if (v2 == null) return 1; if (v1 instanceof java.lang.Number || v2 instanceof java.lang.Number) { java.lang.Number v1c = (java.lang.Number) v1; java.lang.Number v2c = (java.lang.Number) v2; if (v1 instanceof java.lang.Long || v2 instanceof java.lang.Long) { long l1 = (v1 == null) ? 0L : v1c.longValue(); long l2 = (v2 == null) ? 0L : v2c.longValue(); return (l1 < l2) ? -1 : (l1 > l2) ? 1 : 0; } else { double d1 = (v1 == null) ? 0.0 : v1c.doubleValue(); double d2 = (v2 == null) ? 0.0 : v2c.doubleValue(); return (d1 < d2) ? -1 : (d1 > d2) ? 1 : 0; } } //if it\'s not a number it must be a String return ((java.lang.String) v1).compareTo((java.lang.String) v2); ') public static function compare(v1:Dynamic, v2:Dynamic):Int { return 0; } @:functionCode(' if (v1 instanceof java.lang.String || v2 instanceof java.lang.String) return toString(v1) + toString(v2); if (v1 instanceof java.lang.Number || v2 instanceof java.lang.Number) { java.lang.Number v1c = (java.lang.Number) v1; java.lang.Number v2c = (java.lang.Number) v2; double d1 = (v1 == null) ? 0.0 : v1c.doubleValue(); double d2 = (v2 == null) ? 0.0 : v2c.doubleValue(); return d1 + d2; } throw new java.lang.IllegalArgumentException("Cannot dynamically add " + v1 + " and " + v2); ') public static function plus(v1:Dynamic, v2:Dynamic):Dynamic { return null; } @:functionCode(' if (obj == null) if (throwErrors) throw new java.lang.NullPointerException("Cannot access field \'" + field + "\' of null."); else return null; java.lang.Class cl = null; try { if (obj instanceof java.lang.Class) { if (obj == java.lang.String.class && field.equals("fromCharCode")) return new haxe.lang.Closure(haxe.lang.StringExt.class, field); cl = (java.lang.Class) obj; obj = null; } else if (obj instanceof java.lang.String) { return haxe.lang.StringRefl.handleGetField((java.lang.String) obj, field, throwErrors); } else { cl = obj.getClass(); } java.lang.reflect.Field f = cl.getField(field); f.setAccessible(true); return f.get(obj); } catch (Throwable t) { try { java.lang.reflect.Method[] ms = cl.getMethods(); for (int i = 0; i < ms.length; i++) { if (ms[i].getName().equals(field)) { return new haxe.lang.Closure(obj != null ? obj : cl, field); } } } catch (Throwable t2) { } if (throwErrors) throw HaxeException.wrap(t); return null; } ') public static function slowGetField(obj:Dynamic, field:String, throwErrors:Bool):Dynamic { return null; } @:functionCode(' java.lang.Class cl = null; if (obj instanceof java.lang.Class) { cl = (java.lang.Class) obj; obj = null; } else { cl = obj.getClass(); } try { java.lang.reflect.Field f = cl.getField(field); f.setAccessible(true); //FIXME we must evaluate if field to be set receives either int or double if (isInt(value)) { f.setInt(obj, toInt(value)); } else if (isDouble(value)) { f.setDouble(obj, toDouble(value)); } else { f.set(obj, value); } return value; } catch (Throwable t) { throw HaxeException.wrap(t); } ') public static function slowSetField(obj:Dynamic, field:String, value:Dynamic):Dynamic { return null; } @:functionCode(' java.lang.Class cl = null; if (obj instanceof java.lang.Class) { if (obj == java.lang.String.class && field.equals("fromCharCode")) return haxe.lang.StringExt.fromCharCode(toInt(args.__get(0))); cl = (java.lang.Class) obj; obj = null; } else if (obj instanceof java.lang.String) { return haxe.lang.StringRefl.handleCallField((java.lang.String) obj, field, args); } else { cl = obj.getClass(); } if (args == null) args = new Array(); int len = args.length; java.lang.Class[] cls = new java.lang.Class[len]; java.lang.Object[] objs = new java.lang.Object[len]; java.lang.reflect.Method[] ms = cl.getMethods(); int msl = ms.length; int realMsl = 0; for(int i =0; i < msl; i++) { if (!ms[i].getName().equals(field) || (!ms[i].isVarArgs() && ms[i].getParameterTypes().length != len)) { ms[i] = null; } else { ms[realMsl] = ms[i]; if (realMsl != i) ms[i] = null; realMsl++; } } boolean hasNumber = false; for (int i = 0; i < len; i++) { Object o = args.__get(i); if (o == null) { continue; //can be anything } objs[i]= o; cls[i] = o.getClass(); boolean isNum = false; if (o instanceof java.lang.Number) { cls[i] = java.lang.Number.class; isNum = hasNumber = true; } else if (o instanceof java.lang.Boolean) { cls[i] = java.lang.Boolean.class; isNum = true; } msl = realMsl; realMsl = 0; for (int j = 0; j < msl; j++) { java.lang.Class[] allcls = ms[j].getParameterTypes(); if (i < allcls.length) { if (! ((isNum && allcls[i].isPrimitive()) || allcls[i].isAssignableFrom(cls[i])) ) { ms[j] = null; } else { ms[realMsl] = ms[j]; if (realMsl != j) ms[j] = null; realMsl++; } } } } java.lang.reflect.Method found; if (ms.length == 0 || (found = ms[0]) == null) throw haxe.lang.HaxeException.wrap("No compatible method found for: " + field); if (hasNumber) { java.lang.Class[] allcls = found.getParameterTypes(); for (int i = 0; i < len; i++) { java.lang.Object o = objs[i]; if (o instanceof java.lang.Number) { java.lang.Class curCls = null; if (i < allcls.length) { curCls = allcls[i]; if (!curCls.isAssignableFrom(o.getClass())) { String name = curCls.getName(); if (name.equals("double") || name.equals("java.lang.Double")) { objs[i] = ((java.lang.Number)o).doubleValue(); } else if (name.equals("int") || name.equals("java.lang.Integer")) { objs[i] = ((java.lang.Number)o).intValue(); } else if (name.equals("float") || name.equals("java.lang.Float")) { objs[i] = ((java.lang.Number)o).floatValue(); } else if (name.equals("byte") || name.equals("java.lang.Byte")) { objs[i] = ((java.lang.Number)o).byteValue(); } else if (name.equals("short") || name.equals("java.lang.Short")) { objs[i] = ((java.lang.Number)o).shortValue(); } else if (name.equals("long") || name.equals("java.lang.Long")) { objs[i] = ((java.lang.Number)o).longValue(); } } } //else varargs not handled TODO } } } try { found.setAccessible(true); return found.invoke(obj, objs); } catch (java.lang.reflect.InvocationTargetException e) { throw haxe.lang.HaxeException.wrap(e.getCause()); } catch (Throwable t) { throw haxe.lang.HaxeException.wrap(t); } ') public static function slowCallField(obj:Dynamic, field:String, args:Array):Dynamic { return null; } @:functionCode(' if (obj instanceof haxe.lang.IHxObject) { return ((haxe.lang.IHxObject) obj).__hx_invokeField(field, args); } return slowCallField(obj, field, args); ') public static function callField(obj:Dynamic, field:String, args:Array):Dynamic { return null; } @:functionCode(' if (obj instanceof haxe.lang.IHxObject) return ((haxe.lang.IHxObject) obj).__hx_getField(field, throwErrors, false, false); return slowGetField(obj, field, throwErrors); ') public static function getField(obj:Dynamic, field:String, throwErrors:Bool):Dynamic { return null; } @:functionCode(' if (obj instanceof haxe.lang.IHxObject) return ((haxe.lang.IHxObject) obj).__hx_getField_f(field, throwErrors, false); return toDouble(slowGetField(obj, field, throwErrors)); ') public static function getField_f(obj:Dynamic, field:String, throwErrors:Bool):Float { return 0.0; } @:functionCode(' if (obj instanceof haxe.lang.IHxObject) return ((haxe.lang.IHxObject) obj).__hx_setField(field, value, false); return slowSetField(obj, field, value); ') public static function setField(obj:Dynamic, field:String, value:Dynamic):Dynamic { return null; } @:functionCode(' if (obj instanceof haxe.lang.IHxObject) return ((haxe.lang.IHxObject) obj).__hx_setField_f(field, value, false); return toDouble(slowSetField(obj, field, value)); ') public static function setField_f(obj:Dynamic, field:String, value:Float):Float { return 0.0; } public static function toString(obj:Dynamic):String { if (obj == null) return null; if (Std.is(obj, java.lang.Number) && !Std.is(obj, java.lang.Integer.IntegerClass) && isInt( (obj : java.lang.Number) )) return java.lang.Integer._toString(toInt(obj)); return untyped obj.toString(); } public static function isFinite(v:Float):Bool { return (v == v) && !java.lang.Double.DoubleClass._isInfinite(v); } } @:keep @:native("haxe.lang.EmptyObject") enum EmptyObject { EMPTY; } haxe_3.4.4.orig/std/java/internal/StringExt.hx0000664000175000017500000001511713166552354021240 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.internal; import java.internal.Function; private typedef NativeString = String; @:keep @:nativeGen @:native("haxe.lang.StringExt") private class StringExt { @:functionCode(' if ( index >= me.length() || index < 0 ) return ""; else return java.lang.Character.toString(me.charAt(index)); ') public static function charAt(me:NativeString, index:Int):NativeString { return null; } @:functionCode(' if ( index >= me.length() || index < 0 ) return null; else return (int) me.charAt(index); ') public static function charCodeAt(me:NativeString, index:Int):Null { return null; } @:functionCode(' int sIndex = (startIndex != null ) ? (haxe.lang.Runtime.toInt(startIndex)) : 0; if (sIndex >= me.length() || sIndex < 0) return -1; return me.indexOf(str, sIndex); ') public static function indexOf(me:NativeString, str:NativeString, ?startIndex:Int):Int { return -1; } @:functionCode(' int sIndex = (startIndex != null ) ? (haxe.lang.Runtime.toInt(startIndex)) : (me.length() - 1); if (sIndex > me.length() || sIndex < 0) sIndex = me.length() - 1; else if (sIndex < 0) return -1; return me.lastIndexOf(str, sIndex); ') public static function lastIndexOf(me:NativeString, str:NativeString, ?startIndex:Int):Int { return -1; } @:functionCode(' Array ret = new Array(); int slen = delimiter.length(); if (slen == 0) { int len = me.length(); for (int i = 0; i < len; i++) { ret.push(me.substring(i, i + 1)); } } else { int start = 0; int pos = me.indexOf(delimiter, start); while (pos >= 0) { ret.push(me.substring(start, pos)); start = pos + slen; pos = me.indexOf(delimiter, start); } ret.push(me.substring(start)); } return ret; ') public static function split(me:NativeString, delimiter:NativeString):Array { return null; } @:functionCode(' int meLen = me.length(); int targetLen = meLen; if (len != null) { targetLen = haxe.lang.Runtime.toInt(len); if (targetLen == 0) return ""; if( pos != 0 && targetLen < 0 ){ return ""; } } if( pos < 0 ){ pos = meLen + pos; if( pos < 0 ) pos = 0; } else if( targetLen < 0 ){ targetLen = meLen + targetLen - pos; } if( pos + targetLen > meLen ){ targetLen = meLen - pos; } if ( pos < 0 || targetLen <= 0 ) return ""; return me.substring(pos, pos + targetLen); ') public static function substr(me:NativeString, pos:Int, ?len:Int):NativeString { return null; } @:functionCode(' int endIdx; int len = me.length(); if ( endIndex == null) { endIdx = len; } else if ( (endIdx = haxe.lang.Runtime.toInt(endIndex)) < 0 ) { endIdx = 0; } else if ( endIdx > len ) { endIdx = len; } if ( startIndex < 0 ) { startIndex = 0; } else if ( startIndex > len ) { startIndex = len; } if ( startIndex > endIdx ) { int tmp = startIndex; startIndex = endIdx; endIdx = tmp; } return me.substring(startIndex, endIdx); ') public static function substring(me:NativeString, startIndex:Int, ?endIndex:Int):NativeString { return null; } public static function toString(me:NativeString):NativeString { return me; } @:functionCode(' return me.toLowerCase(); ') public static function toLowerCase(me:NativeString):NativeString { return null; } @:functionCode(' return me.toUpperCase(); ') public static function toUpperCase(me:NativeString):NativeString { return null; } public static function toNativeString(me:NativeString):NativeString { return me; } @:functionCode(' return java.lang.Character.toString( (char) code ); ') public static function fromCharCode(code:Int):NativeString { return null; } } @:keep @:nativeGen @:native('haxe.lang.StringRefl') private class StringRefl { public static var fields = ["length", "toUpperCase", "toLowerCase", "charAt", "charCodeAt", "indexOf", "lastIndexOf", "split", "substr", "substring"]; public static function handleGetField(str:NativeString, f:NativeString, throwErrors:Bool):Dynamic { switch(f) { case "length": return str.length; case "toUpperCase", "toLowerCase", "charAt", "charCodeAt", "indexOf", "lastIndexOf", "split", "substr", "substring": return new Closure(str, f); default: if (throwErrors) throw "Field not found: '" + f + "' in String"; else return null; } } public static function handleCallField(str:NativeString, f:NativeString, args:Array):Dynamic { var _args:Array = [str]; if (args == null) args = _args; else args = _args.concat(args); return Runtime.slowCallField(StringExt, f, args); } } @:keep @:native('haxe.lang.NativeString') private extern class JavaString { //name collides with Haxe's function _charAt(idx:Int):java.StdTypes.Char16; function codePointAt(idx:Int):Int; function codePointBefore(idx:Int):Int; function codePointCount(begin:Int, end:Int):Int; function offsetByCodePoints(index:Int, codePointOffset:Int):Int; function getChars(srcBegin:Int, srcEnd:Int, dst:java.NativeArray, dstBegin:Int):Void; function startsWith(prefix:String):Bool; function endsWith(suffix:String):Bool; function _indexOf(str:String, fromIndex:Int):Int; function _lastIndexOf(str:String, fromIndex:Int):Int; function _substring(begin:Int, end:Int):String; function replace(old:String, nw:String):String; function _split(regex:String):java.NativeArray; function trim():String; } haxe_3.4.4.orig/std/java/io/NativeInput.hx0000664000175000017500000000411613166552354020347 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.io; import haxe.Int64; import haxe.io.Bytes; import haxe.io.Eof; import haxe.io.Input; import java.io.IOException; import java.io.EOFException; @:native('haxe.java.io.NativeInput') class NativeInput extends Input { var stream:java.io.InputStream; public function new(stream) { this.stream = stream; } override public function readByte():Int { var ret = 0; try { ret = stream.read(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } if ( ret == -1 ) throw new Eof(); return ret; } override public function readBytes(s:Bytes, pos:Int, len:Int):Int { var ret = 0; try { ret = stream.read(s.getData(), pos, len); } catch (e:EOFException) { throw new Eof(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } if (ret == -1) throw new Eof(); return ret; } override public function close():Void { try { stream.close(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } } haxe_3.4.4.orig/std/java/io/NativeOutput.hx0000664000175000017500000000363213166552354020552 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.io; import haxe.Int64; import haxe.io.Bytes; import haxe.io.Eof; import haxe.io.Output; import java.io.IOException; import java.io.EOFException; @:native('haxe.java.io.NativeOutput') class NativeOutput extends Output { var stream:java.io.OutputStream; public function new(stream) { this.stream = stream; } override public function writeByte(c:Int):Void { try { stream.write(c); } catch (e:EOFException) { throw new Eof(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } override public function close():Void { try { stream.close(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } override public function flush():Void { try { stream.flush(); } catch (e:IOException) { throw haxe.io.Error.Custom(e); } } } haxe_3.4.4.orig/std/java/lang/Boolean.hx0000664000175000017500000000507213166552354017774 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.lang; @:native("") // make sure the generator won't see this @:forward @:forwardStatics abstract Boolean(BooleanClass) from BooleanClass to BooleanClass { @:to @:extern inline public function toBool():Bool return this.booleanValue(); @:from @:extern inline public static function fromBool(b:Bool):Boolean return BooleanClass.valueOf(b); } @:native("java.lang.Boolean") extern class BooleanClass extends Number implements Comparable { @:overload public function new(bool:Bool):Void; @:overload public function new(string:String):Void; @:overload public function booleanValue() : Bool; @:overload public function compareTo(param1 : Boolean) : Int; @:overload public function compareTo(param1 : Dynamic) : Int; @:overload public function equals(param1 : Dynamic) : Bool; @:overload public function hashCode() : Int; @:overload public function toString() : String; @:final public static var FALSE : Boolean; @:final public static var TRUE : Boolean; @:final public static var TYPE : Class; @:overload public static function compare(param1 : Bool, param2 : Bool) : Int; @:overload public static function getBoolean(param1 : String) : Bool; @:overload public static function parseBoolean(param1 : String) : Bool; @:native("toString") @:overload public static function _toString(param1 : Bool) : String; @:overload public static function valueOf(param1 : Bool) : Boolean; @:overload public static function valueOf(param1 : String) : Boolean; } haxe_3.4.4.orig/std/java/lang/Byte.hx0000664000175000017500000000617613166552354017326 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.lang; @:native("") // make sure the generator won't see this @:forwardStatics @:forward abstract Byte(ByteClass) from ByteClass to ByteClass { @:to @:extern inline public function toByte():java.types.Int8 return this.byteValue(); @:from @:extern inline public static function fromByte(b:java.types.Int8):Byte return ByteClass.valueOf(b); } @:native("java.lang.Byte") extern class ByteClass extends Number implements Comparable { @:overload function new(param1 : java.types.Int8) : Void; @:overload @:throws("java.lang.NumberFormatException") function new(param1 : String) : Void; @:overload function compareTo(param1 : Byte) : Int; @:overload function compareTo(param1 : Dynamic) : Int; @:overload function equals(param1 : Dynamic) : Bool; @:overload function hashCode() : Int; @:overload function toString() : String; @:final static var MAX_VALUE(default,null) : java.types.Int8; @:final static var MIN_VALUE(default,null) : java.types.Int8; @:final static var SIZE(default,null) : Int; @:final static var TYPE : Class; @:overload static function compare(param1 : java.types.Int8, param2 : java.types.Int8) : Int; @:overload @:throws("java.lang.NumberFormatException") static function decode(param1 : String) : Byte; @:overload @:throws("java.lang.NumberFormatException") static function parseByte(param1 : String, param2 : Int) : java.types.Int8; @:overload @:throws("java.lang.NumberFormatException") static function parseByte(param1 : String) : java.types.Int8; @:native("toString") @:overload static function _toString(param1 : java.types.Int8) : String; @:overload static function valueOf(param1 : java.types.Int8) : Byte; @:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String) : Byte; @:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String, param2 : Int) : Byte; } @:realPath("java.lang.Byte_ByteCache") @:javaNative @:native("java.lang.Byte$ByteCache") @:javaCanonical("java.lang","Byte.ByteCache") extern class Byte_ByteCache { } haxe_3.4.4.orig/std/java/lang/Character.hx0000664000175000017500000007013513166552354020313 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.lang; @:native("") // make sure the generator won't see this @:forwardStatics @:forward abstract Character(CharacterClass) from CharacterClass to CharacterClass { @:to @:extern inline public function toCharacter():java.types.Char16 return this.charValue(); @:from @:extern inline public static function fromCharacter(b:java.types.Char16):Character return CharacterClass.valueOf(b); } @:native("java.lang.Character") extern class CharacterClass implements Comparable { @:overload function new(param1 : java.types.Char16) : Void; @:overload function charValue() : java.types.Char16; @:overload function compareTo(param1 : Character) : Int; @:overload function compareTo(param1 : Dynamic) : Int; @:overload function equals(param1 : Dynamic) : Bool; @:overload function hashCode() : Int; @:overload function toString() : String; @:final static var COMBINING_SPACING_MARK(default,null) : java.types.Char16; @:final static var CONNECTOR_PUNCTUATION(default,null) : java.types.Char16; @:final static var CONTROL(default,null) : java.types.Char16; @:final static var CURRENCY_SYMBOL(default,null) : java.types.Char16; @:final static var DASH_PUNCTUATION(default,null) : java.types.Char16; @:final static var DECIMAL_DIGIT_NUMBER(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_ARABIC_NUMBER(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_BOUNDARY_NEUTRAL(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_COMMON_NUMBER_SEPARATOR(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_EUROPEAN_NUMBER(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_LEFT_TO_RIGHT(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_NONSPACING_MARK(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_OTHER_NEUTRALS(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_PARAGRAPH_SEPARATOR(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_POP_DIRECTIONAL_FORMAT(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_RIGHT_TO_LEFT(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_SEGMENT_SEPARATOR(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_UNDEFINED(default,null) : java.types.Char16; @:final static var DIRECTIONALITY_WHITESPACE(default,null) : java.types.Char16; @:final static var ENCLOSING_MARK(default,null) : java.types.Char16; @:final static var END_PUNCTUATION(default,null) : java.types.Char16; @:final static var FINAL_QUOTE_PUNCTUATION(default,null) : java.types.Char16; @:final static var FORMAT(default,null) : java.types.Char16; @:final static var INITIAL_QUOTE_PUNCTUATION(default,null) : java.types.Char16; @:final static var LETTER_NUMBER(default,null) : java.types.Char16; @:final static var LINE_SEPARATOR(default,null) : java.types.Char16; @:final static var LOWERCASE_LETTER(default,null) : java.types.Char16; @:final static var MATH_SYMBOL(default,null) : java.types.Char16; @:final static var MAX_CODE_POINT(default,null) : Int; @:final static var MAX_HIGH_SURROGATE(default,null) : java.types.Char16; @:final static var MAX_LOW_SURROGATE(default,null) : java.types.Char16; @:final static var MAX_RADIX(default,null) : Int; @:final static var MAX_SURROGATE(default,null) : java.types.Char16; @:final static var MAX_VALUE(default,null) : java.types.Char16; @:final static var MIN_CODE_POINT(default,null) : Int; @:final static var MIN_HIGH_SURROGATE(default,null) : java.types.Char16; @:final static var MIN_LOW_SURROGATE(default,null) : java.types.Char16; @:final static var MIN_RADIX(default,null) : Int; @:final static var MIN_SUPPLEMENTARY_CODE_POINT(default,null) : Int; @:final static var MIN_SURROGATE(default,null) : java.types.Char16; @:final static var MIN_VALUE(default,null) : java.types.Char16; @:final static var MODIFIER_LETTER(default,null) : java.types.Char16; @:final static var MODIFIER_SYMBOL(default,null) : java.types.Char16; @:final static var NON_SPACING_MARK(default,null) : java.types.Char16; @:final static var OTHER_LETTER(default,null) : java.types.Char16; @:final static var OTHER_NUMBER(default,null) : java.types.Char16; @:final static var OTHER_PUNCTUATION(default,null) : java.types.Char16; @:final static var OTHER_SYMBOL(default,null) : java.types.Char16; @:final static var PARAGRAPH_SEPARATOR(default,null) : java.types.Char16; @:final static var PRIVATE_USE(default,null) : java.types.Char16; @:final static var SIZE(default,null) : Int; @:final static var SPACE_SEPARATOR(default,null) : java.types.Char16; @:final static var START_PUNCTUATION(default,null) : java.types.Char16; @:final static var SURROGATE(default,null) : java.types.Char16; @:final static var TITLECASE_LETTER(default,null) : java.types.Char16; @:final static var TYPE : Class; @:final static var UNASSIGNED(default,null) : java.types.Char16; @:final static var UPPERCASE_LETTER(default,null) : java.types.Char16; @:overload static function charCount(param1 : Int) : Int; @:overload static function codePointAt(param1 : CharSequence, param2 : Int) : Int; @:overload static function codePointAt(param1 : java.NativeArray, param2 : Int, param3 : Int) : Int; @:overload static function codePointAt(param1 : java.NativeArray, param2 : Int) : Int; @:overload static function codePointBefore(param1 : CharSequence, param2 : Int) : Int; @:overload static function codePointBefore(param1 : java.NativeArray, param2 : Int, param3 : Int) : Int; @:overload static function codePointBefore(param1 : java.NativeArray, param2 : Int) : Int; @:overload static function codePointCount(param1 : CharSequence, param2 : Int, param3 : Int) : Int; @:overload static function codePointCount(param1 : java.NativeArray, param2 : Int, param3 : Int) : Int; @:overload static function compare(param1 : java.types.Char16, param2 : java.types.Char16) : Int; @:overload static function digit(param1 : java.types.Char16, param2 : Int) : Int; @:overload static function digit(param1 : Int, param2 : Int) : Int; @:overload static function forDigit(param1 : Int, param2 : Int) : java.types.Char16; @:overload static function getDirectionality(param1 : java.types.Char16) : java.types.Char16; @:overload static function getDirectionality(param1 : Int) : java.types.Char16; @:overload static function getName(param1 : Int) : String; @:overload static function getNumericValue(param1 : java.types.Char16) : Int; @:overload static function getNumericValue(param1 : Int) : Int; @:overload static function getType(param1 : java.types.Char16) : Int; @:overload static function getType(param1 : Int) : Int; @:overload static function highSurrogate(param1 : Int) : java.types.Char16; @:overload static function isAlphabetic(param1 : Int) : Bool; @:overload static function isBmpCodePoint(param1 : Int) : Bool; @:overload static function isDefined(param1 : java.types.Char16) : Bool; @:overload static function isDefined(param1 : Int) : Bool; @:overload static function isDigit(param1 : java.types.Char16) : Bool; @:overload static function isDigit(param1 : Int) : Bool; @:overload static function isHighSurrogate(param1 : java.types.Char16) : Bool; @:overload static function isISOControl(param1 : java.types.Char16) : Bool; @:overload static function isISOControl(param1 : Int) : Bool; @:overload static function isIdentifierIgnorable(param1 : java.types.Char16) : Bool; @:overload static function isIdentifierIgnorable(param1 : Int) : Bool; @:overload static function isIdeographic(param1 : Int) : Bool; @:overload static function isJavaIdentifierPart(param1 : java.types.Char16) : Bool; @:overload static function isJavaIdentifierPart(param1 : Int) : Bool; @:overload static function isJavaIdentifierStart(param1 : java.types.Char16) : Bool; @:overload static function isJavaIdentifierStart(param1 : Int) : Bool; @:overload @:deprecated static function isJavaLetter(param1 : java.types.Char16) : Bool; @:overload @:deprecated static function isJavaLetterOrDigit(param1 : java.types.Char16) : Bool; @:overload static function isLetter(param1 : java.types.Char16) : Bool; @:overload static function isLetter(param1 : Int) : Bool; @:overload static function isLetterOrDigit(param1 : java.types.Char16) : Bool; @:overload static function isLetterOrDigit(param1 : Int) : Bool; @:overload static function isLowSurrogate(param1 : java.types.Char16) : Bool; @:overload static function isLowerCase(param1 : java.types.Char16) : Bool; @:overload static function isLowerCase(param1 : Int) : Bool; @:overload static function isMirrored(param1 : java.types.Char16) : Bool; @:overload static function isMirrored(param1 : Int) : Bool; @:overload @:deprecated static function isSpace(param1 : java.types.Char16) : Bool; @:overload static function isSpaceChar(param1 : java.types.Char16) : Bool; @:overload static function isSpaceChar(param1 : Int) : Bool; @:overload static function isSupplementaryCodePoint(param1 : Int) : Bool; @:overload static function isSurrogate(param1 : java.types.Char16) : Bool; @:overload static function isSurrogatePair(param1 : java.types.Char16, param2 : java.types.Char16) : Bool; @:overload static function isTitleCase(param1 : java.types.Char16) : Bool; @:overload static function isTitleCase(param1 : Int) : Bool; @:overload static function isUnicodeIdentifierPart(param1 : java.types.Char16) : Bool; @:overload static function isUnicodeIdentifierPart(param1 : Int) : Bool; @:overload static function isUnicodeIdentifierStart(param1 : java.types.Char16) : Bool; @:overload static function isUnicodeIdentifierStart(param1 : Int) : Bool; @:overload static function isUpperCase(param1 : java.types.Char16) : Bool; @:overload static function isUpperCase(param1 : Int) : Bool; @:overload static function isValidCodePoint(param1 : Int) : Bool; @:overload static function isWhitespace(param1 : java.types.Char16) : Bool; @:overload static function isWhitespace(param1 : Int) : Bool; @:overload static function lowSurrogate(param1 : Int) : java.types.Char16; @:overload static function offsetByCodePoints(param1 : CharSequence, param2 : Int, param3 : Int) : Int; @:overload static function offsetByCodePoints(param1 : java.NativeArray, param2 : Int, param3 : Int, param4 : Int, param5 : Int) : Int; @:overload static function reverseBytes(param1 : java.types.Char16) : java.types.Char16; @:overload static function toChars(param1 : Int, param2 : java.NativeArray, param3 : Int) : Int; @:overload static function toChars(param1 : Int) : java.NativeArray; @:overload static function toCodePoint(param1 : java.types.Char16, param2 : java.types.Char16) : Int; @:overload static function toLowerCase(param1 : java.types.Char16) : java.types.Char16; @:overload static function toLowerCase(param1 : Int) : Int; @:native("toString") @:overload static function _toString(param1 : java.types.Char16) : String; @:overload static function toTitleCase(param1 : java.types.Char16) : java.types.Char16; @:overload static function toTitleCase(param1 : Int) : Int; @:overload static function toUpperCase(param1 : java.types.Char16) : java.types.Char16; @:overload static function toUpperCase(param1 : Int) : Int; @:overload static function valueOf(param1 : java.types.Char16) : Character; } @:realPath("java.lang.Character_CharacterCache") @:javaNative @:native("java.lang.Character$CharacterCache") @:javaCanonical("java.lang","Character.CharacterCache") extern class Character_CharacterCache { } @:realPath("java.lang.Character_Subset") @:javaNative @:native("java.lang.Character$Subset") @:javaCanonical("java.lang","Character.Subset") extern class Character_Subset { @:overload @:final function equals(param1 : Dynamic) : Bool; @:overload @:final function hashCode() : Int; @:overload @:final function toString() : String; } @:realPath("java.lang.Character_UnicodeBlock") @:final @:javaNative @:native("java.lang.Character$UnicodeBlock") @:javaCanonical("java.lang","Character.UnicodeBlock") extern class Character_UnicodeBlock extends Character_Subset { @:final static var AEGEAN_NUMBERS : Character_UnicodeBlock; @:final static var ALCHEMICAL_SYMBOLS : Character_UnicodeBlock; @:final static var ALPHABETIC_PRESENTATION_FORMS : Character_UnicodeBlock; @:final static var ANCIENT_GREEK_MUSICAL_NOTATION : Character_UnicodeBlock; @:final static var ANCIENT_GREEK_NUMBERS : Character_UnicodeBlock; @:final static var ANCIENT_SYMBOLS : Character_UnicodeBlock; @:final static var ARABIC : Character_UnicodeBlock; @:final static var ARABIC_PRESENTATION_FORMS_A : Character_UnicodeBlock; @:final static var ARABIC_PRESENTATION_FORMS_B : Character_UnicodeBlock; @:final static var ARABIC_SUPPLEMENT : Character_UnicodeBlock; @:final static var ARMENIAN : Character_UnicodeBlock; @:final static var ARROWS : Character_UnicodeBlock; @:final static var AVESTAN : Character_UnicodeBlock; @:final static var BALINESE : Character_UnicodeBlock; @:final static var BAMUM : Character_UnicodeBlock; @:final static var BAMUM_SUPPLEMENT : Character_UnicodeBlock; @:final static var BASIC_LATIN : Character_UnicodeBlock; @:final static var BATAK : Character_UnicodeBlock; @:final static var BENGALI : Character_UnicodeBlock; @:final static var BLOCK_ELEMENTS : Character_UnicodeBlock; @:final static var BOPOMOFO : Character_UnicodeBlock; @:final static var BOPOMOFO_EXTENDED : Character_UnicodeBlock; @:final static var BOX_DRAWING : Character_UnicodeBlock; @:final static var BRAHMI : Character_UnicodeBlock; @:final static var BRAILLE_PATTERNS : Character_UnicodeBlock; @:final static var BUGINESE : Character_UnicodeBlock; @:final static var BUHID : Character_UnicodeBlock; @:final static var BYZANTINE_MUSICAL_SYMBOLS : Character_UnicodeBlock; @:final static var CARIAN : Character_UnicodeBlock; @:final static var CHAM : Character_UnicodeBlock; @:final static var CHEROKEE : Character_UnicodeBlock; @:final static var CJK_COMPATIBILITY : Character_UnicodeBlock; @:final static var CJK_COMPATIBILITY_FORMS : Character_UnicodeBlock; @:final static var CJK_COMPATIBILITY_IDEOGRAPHS : Character_UnicodeBlock; @:final static var CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT : Character_UnicodeBlock; @:final static var CJK_RADICALS_SUPPLEMENT : Character_UnicodeBlock; @:final static var CJK_STROKES : Character_UnicodeBlock; @:final static var CJK_SYMBOLS_AND_PUNCTUATION : Character_UnicodeBlock; @:final static var CJK_UNIFIED_IDEOGRAPHS : Character_UnicodeBlock; @:final static var CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A : Character_UnicodeBlock; @:final static var CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B : Character_UnicodeBlock; @:final static var CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C : Character_UnicodeBlock; @:final static var CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D : Character_UnicodeBlock; @:final static var COMBINING_DIACRITICAL_MARKS : Character_UnicodeBlock; @:final static var COMBINING_DIACRITICAL_MARKS_SUPPLEMENT : Character_UnicodeBlock; @:final static var COMBINING_HALF_MARKS : Character_UnicodeBlock; @:final static var COMBINING_MARKS_FOR_SYMBOLS : Character_UnicodeBlock; @:final static var COMMON_INDIC_NUMBER_FORMS : Character_UnicodeBlock; @:final static var CONTROL_PICTURES : Character_UnicodeBlock; @:final static var COPTIC : Character_UnicodeBlock; @:final static var COUNTING_ROD_NUMERALS : Character_UnicodeBlock; @:final static var CUNEIFORM : Character_UnicodeBlock; @:final static var CUNEIFORM_NUMBERS_AND_PUNCTUATION : Character_UnicodeBlock; @:final static var CURRENCY_SYMBOLS : Character_UnicodeBlock; @:final static var CYPRIOT_SYLLABARY : Character_UnicodeBlock; @:final static var CYRILLIC : Character_UnicodeBlock; @:final static var CYRILLIC_EXTENDED_A : Character_UnicodeBlock; @:final static var CYRILLIC_EXTENDED_B : Character_UnicodeBlock; @:final static var CYRILLIC_SUPPLEMENTARY : Character_UnicodeBlock; @:final static var DESERET : Character_UnicodeBlock; @:final static var DEVANAGARI : Character_UnicodeBlock; @:final static var DEVANAGARI_EXTENDED : Character_UnicodeBlock; @:final static var DINGBATS : Character_UnicodeBlock; @:final static var DOMINO_TILES : Character_UnicodeBlock; @:final static var EGYPTIAN_HIEROGLYPHS : Character_UnicodeBlock; @:final static var EMOTICONS : Character_UnicodeBlock; @:final static var ENCLOSED_ALPHANUMERICS : Character_UnicodeBlock; @:final static var ENCLOSED_ALPHANUMERIC_SUPPLEMENT : Character_UnicodeBlock; @:final static var ENCLOSED_CJK_LETTERS_AND_MONTHS : Character_UnicodeBlock; @:final static var ENCLOSED_IDEOGRAPHIC_SUPPLEMENT : Character_UnicodeBlock; @:final static var ETHIOPIC : Character_UnicodeBlock; @:final static var ETHIOPIC_EXTENDED : Character_UnicodeBlock; @:final static var ETHIOPIC_EXTENDED_A : Character_UnicodeBlock; @:final static var ETHIOPIC_SUPPLEMENT : Character_UnicodeBlock; @:final static var GENERAL_PUNCTUATION : Character_UnicodeBlock; @:final static var GEOMETRIC_SHAPES : Character_UnicodeBlock; @:final static var GEORGIAN : Character_UnicodeBlock; @:final static var GEORGIAN_SUPPLEMENT : Character_UnicodeBlock; @:final static var GLAGOLITIC : Character_UnicodeBlock; @:final static var GOTHIC : Character_UnicodeBlock; @:final static var GREEK : Character_UnicodeBlock; @:final static var GREEK_EXTENDED : Character_UnicodeBlock; @:final static var GUJARATI : Character_UnicodeBlock; @:final static var GURMUKHI : Character_UnicodeBlock; @:final static var HALFWIDTH_AND_FULLWIDTH_FORMS : Character_UnicodeBlock; @:final static var HANGUL_COMPATIBILITY_JAMO : Character_UnicodeBlock; @:final static var HANGUL_JAMO : Character_UnicodeBlock; @:final static var HANGUL_JAMO_EXTENDED_A : Character_UnicodeBlock; @:final static var HANGUL_JAMO_EXTENDED_B : Character_UnicodeBlock; @:final static var HANGUL_SYLLABLES : Character_UnicodeBlock; @:final static var HANUNOO : Character_UnicodeBlock; @:final static var HEBREW : Character_UnicodeBlock; @:final static var HIGH_PRIVATE_USE_SURROGATES : Character_UnicodeBlock; @:final static var HIGH_SURROGATES : Character_UnicodeBlock; @:final static var HIRAGANA : Character_UnicodeBlock; @:final static var IDEOGRAPHIC_DESCRIPTION_CHARACTERS : Character_UnicodeBlock; @:final static var IMPERIAL_ARAMAIC : Character_UnicodeBlock; @:final static var INSCRIPTIONAL_PAHLAVI : Character_UnicodeBlock; @:final static var INSCRIPTIONAL_PARTHIAN : Character_UnicodeBlock; @:final static var IPA_EXTENSIONS : Character_UnicodeBlock; @:final static var JAVANESE : Character_UnicodeBlock; @:final static var KAITHI : Character_UnicodeBlock; @:final static var KANA_SUPPLEMENT : Character_UnicodeBlock; @:final static var KANBUN : Character_UnicodeBlock; @:final static var KANGXI_RADICALS : Character_UnicodeBlock; @:final static var KANNADA : Character_UnicodeBlock; @:final static var KATAKANA : Character_UnicodeBlock; @:final static var KATAKANA_PHONETIC_EXTENSIONS : Character_UnicodeBlock; @:final static var KAYAH_LI : Character_UnicodeBlock; @:final static var KHAROSHTHI : Character_UnicodeBlock; @:final static var KHMER : Character_UnicodeBlock; @:final static var KHMER_SYMBOLS : Character_UnicodeBlock; @:final static var LAO : Character_UnicodeBlock; @:final static var LATIN_1_SUPPLEMENT : Character_UnicodeBlock; @:final static var LATIN_EXTENDED_A : Character_UnicodeBlock; @:final static var LATIN_EXTENDED_ADDITIONAL : Character_UnicodeBlock; @:final static var LATIN_EXTENDED_B : Character_UnicodeBlock; @:final static var LATIN_EXTENDED_C : Character_UnicodeBlock; @:final static var LATIN_EXTENDED_D : Character_UnicodeBlock; @:final static var LEPCHA : Character_UnicodeBlock; @:final static var LETTERLIKE_SYMBOLS : Character_UnicodeBlock; @:final static var LIMBU : Character_UnicodeBlock; @:final static var LINEAR_B_IDEOGRAMS : Character_UnicodeBlock; @:final static var LINEAR_B_SYLLABARY : Character_UnicodeBlock; @:final static var LISU : Character_UnicodeBlock; @:final static var LOW_SURROGATES : Character_UnicodeBlock; @:final static var LYCIAN : Character_UnicodeBlock; @:final static var LYDIAN : Character_UnicodeBlock; @:final static var MAHJONG_TILES : Character_UnicodeBlock; @:final static var MALAYALAM : Character_UnicodeBlock; @:final static var MANDAIC : Character_UnicodeBlock; @:final static var MATHEMATICAL_ALPHANUMERIC_SYMBOLS : Character_UnicodeBlock; @:final static var MATHEMATICAL_OPERATORS : Character_UnicodeBlock; @:final static var MEETEI_MAYEK : Character_UnicodeBlock; @:final static var MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A : Character_UnicodeBlock; @:final static var MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B : Character_UnicodeBlock; @:final static var MISCELLANEOUS_SYMBOLS : Character_UnicodeBlock; @:final static var MISCELLANEOUS_SYMBOLS_AND_ARROWS : Character_UnicodeBlock; @:final static var MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS : Character_UnicodeBlock; @:final static var MISCELLANEOUS_TECHNICAL : Character_UnicodeBlock; @:final static var MODIFIER_TONE_LETTERS : Character_UnicodeBlock; @:final static var MONGOLIAN : Character_UnicodeBlock; @:final static var MUSICAL_SYMBOLS : Character_UnicodeBlock; @:final static var MYANMAR : Character_UnicodeBlock; @:final static var MYANMAR_EXTENDED_A : Character_UnicodeBlock; @:final static var NEW_TAI_LUE : Character_UnicodeBlock; @:final static var NKO : Character_UnicodeBlock; @:final static var NUMBER_FORMS : Character_UnicodeBlock; @:final static var OGHAM : Character_UnicodeBlock; @:final static var OLD_ITALIC : Character_UnicodeBlock; @:final static var OLD_PERSIAN : Character_UnicodeBlock; @:final static var OLD_SOUTH_ARABIAN : Character_UnicodeBlock; @:final static var OLD_TURKIC : Character_UnicodeBlock; @:final static var OL_CHIKI : Character_UnicodeBlock; @:final static var OPTICAL_CHARACTER_RECOGNITION : Character_UnicodeBlock; @:final static var ORIYA : Character_UnicodeBlock; @:final static var OSMANYA : Character_UnicodeBlock; @:final static var PHAGS_PA : Character_UnicodeBlock; @:final static var PHAISTOS_DISC : Character_UnicodeBlock; @:final static var PHOENICIAN : Character_UnicodeBlock; @:final static var PHONETIC_EXTENSIONS : Character_UnicodeBlock; @:final static var PHONETIC_EXTENSIONS_SUPPLEMENT : Character_UnicodeBlock; @:final static var PLAYING_CARDS : Character_UnicodeBlock; @:final static var PRIVATE_USE_AREA : Character_UnicodeBlock; @:final static var REJANG : Character_UnicodeBlock; @:final static var RUMI_NUMERAL_SYMBOLS : Character_UnicodeBlock; @:final static var RUNIC : Character_UnicodeBlock; @:final static var SAMARITAN : Character_UnicodeBlock; @:final static var SAURASHTRA : Character_UnicodeBlock; @:final static var SHAVIAN : Character_UnicodeBlock; @:final static var SINHALA : Character_UnicodeBlock; @:final static var SMALL_FORM_VARIANTS : Character_UnicodeBlock; @:final static var SPACING_MODIFIER_LETTERS : Character_UnicodeBlock; @:final static var SPECIALS : Character_UnicodeBlock; @:final static var SUNDANESE : Character_UnicodeBlock; @:final static var SUPERSCRIPTS_AND_SUBSCRIPTS : Character_UnicodeBlock; @:final static var SUPPLEMENTAL_ARROWS_A : Character_UnicodeBlock; @:final static var SUPPLEMENTAL_ARROWS_B : Character_UnicodeBlock; @:final static var SUPPLEMENTAL_MATHEMATICAL_OPERATORS : Character_UnicodeBlock; @:final static var SUPPLEMENTAL_PUNCTUATION : Character_UnicodeBlock; @:final static var SUPPLEMENTARY_PRIVATE_USE_AREA_A : Character_UnicodeBlock; @:final static var SUPPLEMENTARY_PRIVATE_USE_AREA_B : Character_UnicodeBlock; @:deprecated @:final static var SURROGATES_AREA : Character_UnicodeBlock; @:final static var SYLOTI_NAGRI : Character_UnicodeBlock; @:final static var SYRIAC : Character_UnicodeBlock; @:final static var TAGALOG : Character_UnicodeBlock; @:final static var TAGBANWA : Character_UnicodeBlock; @:final static var TAGS : Character_UnicodeBlock; @:final static var TAI_LE : Character_UnicodeBlock; @:final static var TAI_THAM : Character_UnicodeBlock; @:final static var TAI_VIET : Character_UnicodeBlock; @:final static var TAI_XUAN_JING_SYMBOLS : Character_UnicodeBlock; @:final static var TAMIL : Character_UnicodeBlock; @:final static var TELUGU : Character_UnicodeBlock; @:final static var THAANA : Character_UnicodeBlock; @:final static var THAI : Character_UnicodeBlock; @:final static var TIBETAN : Character_UnicodeBlock; @:final static var TIFINAGH : Character_UnicodeBlock; @:final static var TRANSPORT_AND_MAP_SYMBOLS : Character_UnicodeBlock; @:final static var UGARITIC : Character_UnicodeBlock; @:final static var UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS : Character_UnicodeBlock; @:final static var UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED : Character_UnicodeBlock; @:final static var VAI : Character_UnicodeBlock; @:final static var VARIATION_SELECTORS : Character_UnicodeBlock; @:final static var VARIATION_SELECTORS_SUPPLEMENT : Character_UnicodeBlock; @:final static var VEDIC_EXTENSIONS : Character_UnicodeBlock; @:final static var VERTICAL_FORMS : Character_UnicodeBlock; @:final static var YIJING_HEXAGRAM_SYMBOLS : Character_UnicodeBlock; @:final static var YI_RADICALS : Character_UnicodeBlock; @:final static var YI_SYLLABLES : Character_UnicodeBlock; @:overload @:final static function forName(param1 : String) : Character_UnicodeBlock; @:overload static function of(param1 : java.types.Char16) : Character_UnicodeBlock; @:overload static function of(param1 : Int) : Character_UnicodeBlock; } @:realPath("java.lang.Character_UnicodeScript") @:javaCanonical("java.lang","Character.UnicodeScript") @:native("java.lang.Character$UnicodeScript") extern enum Character_UnicodeScript { COMMON; LATIN; GREEK; CYRILLIC; ARMENIAN; HEBREW; ARABIC; SYRIAC; THAANA; DEVANAGARI; BENGALI; GURMUKHI; GUJARATI; ORIYA; TAMIL; TELUGU; KANNADA; MALAYALAM; SINHALA; THAI; LAO; TIBETAN; MYANMAR; GEORGIAN; HANGUL; ETHIOPIC; CHEROKEE; CANADIAN_ABORIGINAL; OGHAM; RUNIC; KHMER; MONGOLIAN; HIRAGANA; KATAKANA; BOPOMOFO; HAN; YI; OLD_ITALIC; GOTHIC; DESERET; INHERITED; TAGALOG; HANUNOO; BUHID; TAGBANWA; LIMBU; TAI_LE; LINEAR_B; UGARITIC; SHAVIAN; OSMANYA; CYPRIOT; BRAILLE; BUGINESE; COPTIC; NEW_TAI_LUE; GLAGOLITIC; TIFINAGH; SYLOTI_NAGRI; OLD_PERSIAN; KHAROSHTHI; BALINESE; CUNEIFORM; PHOENICIAN; PHAGS_PA; NKO; SUNDANESE; BATAK; LEPCHA; OL_CHIKI; VAI; SAURASHTRA; KAYAH_LI; REJANG; LYCIAN; CARIAN; LYDIAN; CHAM; TAI_THAM; TAI_VIET; AVESTAN; EGYPTIAN_HIEROGLYPHS; SAMARITAN; MANDAIC; LISU; BAMUM; JAVANESE; MEETEI_MAYEK; IMPERIAL_ARAMAIC; OLD_SOUTH_ARABIAN; INSCRIPTIONAL_PARTHIAN; INSCRIPTIONAL_PAHLAVI; OLD_TURKIC; BRAHMI; KAITHI; UNKNOWN; } haxe_3.4.4.orig/std/java/lang/Double.hx0000664000175000017500000000662313166552354017632 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.lang; @:native("") // make sure the generator won't see this @:forwardStatics @:forward abstract Double(DoubleClass) from DoubleClass to DoubleClass { @:to @:extern inline public function toFloat():Float return this.doubleValue(); @:from @:extern inline public static function fromFloat(b:Float):Double return DoubleClass.valueOf(b); } @:native("java.lang.Double") extern class DoubleClass extends Number implements Comparable { @:overload function new(param1 : Float) : Void; @:overload @:throws("java.lang.NumberFormatException") function new(param1 : String) : Void; @:overload function compareTo(param1 : Double) : Int; @:overload function compareTo(param1 : Dynamic) : Int; @:overload function equals(param1 : Dynamic) : Bool; @:overload function hashCode() : Int; @:overload function isInfinite() : Bool; @:overload function isNaN() : Bool; @:overload function toString() : String; @:final static var MAX_EXPONENT(default,null) : Int; @:final static var MAX_VALUE(default,null) : Float; @:final static var MIN_EXPONENT(default,null) : Int; @:final static var MIN_NORMAL(default,null) : Float; @:final static var MIN_VALUE(default,null) : Float; @:final static var NEGATIVE_INFINITY(default,null) : Float; @:final static var NaN(default,null) : Float; @:final static var POSITIVE_INFINITY(default,null) : Float; @:final static var SIZE(default,null) : Int; @:final static var TYPE : Class; @:overload static function compare(param1 : Float, param2 : Float) : Int; @:overload static function doubleToLongBits(param1 : Float) : haxe.Int64; @:overload static function doubleToRawLongBits(param1 : Float) : haxe.Int64; @:native("isInfinite") @:overload static function _isInfinite(param1 : Float) : Bool; @:native("isNaN") @:overload static function _isNaN(param1 : Float) : Bool; @:overload static function longBitsToDouble(param1 : haxe.Int64) : Float; @:overload @:throws("java.lang.NumberFormatException") static function parseDouble(param1 : String) : Float; @:overload static function toHexString(param1 : Float) : String; @:native("toString") @:overload static function _toString(param1 : Float) : String; @:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String) : Double; @:overload static function valueOf(param1 : Float) : Double; } haxe_3.4.4.orig/std/java/lang/Float.hx0000664000175000017500000000674313166552354017470 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.lang; @:native("") // make sure the generator won't see this @:forwardStatics @:forward abstract Float(FloatClass) from FloatClass to FloatClass { @:to @:extern inline public function toFloat():std.StdTypes.Float return this.floatValue(); @:from @:extern inline public static function fromFloat(b:std.StdTypes.Single):Float return FloatClass.valueOf(b); } @:native("java.lang.Float") extern class FloatClass extends Number implements Comparable { @:overload function new(param1 : Single) : Void; @:overload @:throws("java.lang.NumberFormatException") function new(param1 : String) : Void; @:overload function new(param1 : std.StdTypes.Float) : Void; @:overload function compareTo(param1 : Float) : Int; @:overload function compareTo(param1 : Dynamic) : Int; @:overload function equals(param1 : Dynamic) : Bool; @:overload function hashCode() : Int; @:overload function isInfinite() : Bool; @:overload function isNaN() : Bool; @:overload function toString() : String; @:final static var MAX_EXPONENT(default,null) : Int; @:final static var MAX_VALUE(default,null) : Single; @:final static var MIN_EXPONENT(default,null) : Int; @:final static var MIN_NORMAL(default,null) : Single; @:final static var MIN_VALUE(default,null) : Single; @:final static var NEGATIVE_INFINITY(default,null) : Single; @:final static var NaN(default,null) : Single; @:final static var POSITIVE_INFINITY(default,null) : Single; @:final static var SIZE(default,null) : Int; @:final static var TYPE : Class; @:overload static function compare(param1 : Single, param2 : Single) : Int; @:overload static function floatToIntBits(param1 : Single) : Int; @:overload static function floatToRawIntBits(param1 : Single) : Int; @:overload static function intBitsToFloat(param1 : Int) : Single; @:native("isInfinite") @:overload static function _isInfinite(param1 : Single) : Bool; @:native("isNaN") @:overload static function _isNaN(param1 : Single) : Bool; @:overload @:throws("java.lang.NumberFormatException") static function parseFloat(param1 : String) : Single; @:overload static function toHexString(param1 : Single) : String; @:native("toString") @:overload static function _toString(param1 : Single) : String; @:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String) : Float; @:overload static function valueOf(param1 : Single) : Float; } haxe_3.4.4.orig/std/java/lang/Integer.hx0000664000175000017500000001032113166552354020003 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.lang; @:native("") // make sure the generator won't see this @:forwardStatics @:forward abstract Integer(IntegerClass) from IntegerClass to IntegerClass { @:to @:extern inline public function toInt():Int return this.intValue(); @:from @:extern inline public static function fromInt(b:Int):Integer return IntegerClass.valueOf(b); } @:native("java.lang.Integer") extern class IntegerClass extends Number implements Comparable { @:overload function new(param1 : Int) : Void; @:overload @:throws("java.lang.NumberFormatException") function new(param1 : String) : Void; @:overload function compareTo(param1 : Integer) : Int; @:overload function compareTo(param1 : Dynamic) : Int; @:overload function equals(param1 : Dynamic) : Bool; @:overload function hashCode() : Int; @:overload function toString() : String; @:final static var MAX_VALUE(default,null) : Int; @:final static var MIN_VALUE(default,null) : Int; @:final static var SIZE(default,null) : Int; @:final static var TYPE : Class; @:overload static function bitCount(param1 : Int) : Int; @:overload static function compare(param1 : Int, param2 : Int) : Int; @:overload @:throws("java.lang.NumberFormatException") static function decode(param1 : String) : Integer; @:overload static function getInteger(param1 : String) : Integer; @:overload static function getInteger(param1 : String, param2 : Integer) : Integer; @:overload static function getInteger(param1 : String, param2 : Int) : Integer; @:overload static function highestOneBit(param1 : Int) : Int; @:overload static function lowestOneBit(param1 : Int) : Int; @:overload static function numberOfLeadingZeros(param1 : Int) : Int; @:overload static function numberOfTrailingZeros(param1 : Int) : Int; @:overload @:throws("java.lang.NumberFormatException") static function parseInt(param1 : String, param2 : Int) : Int; @:overload @:throws("java.lang.NumberFormatException") static function parseInt(param1 : String) : Int; @:overload static function reverse(param1 : Int) : Int; @:overload static function reverseBytes(param1 : Int) : Int; @:overload static function rotateLeft(param1 : Int, param2 : Int) : Int; @:overload static function rotateRight(param1 : Int, param2 : Int) : Int; @:overload static function signum(param1 : Int) : Int; @:overload static function toBinaryString(param1 : Int) : String; @:overload static function toHexString(param1 : Int) : String; @:overload static function toOctalString(param1 : Int) : String; @:native("toString") @:overload static function _toString(param1 : Int, param2 : Int) : String; @:native("toString") @:overload static function _toString(param1 : Int) : String; @:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String, param2 : Int) : Integer; @:overload static function valueOf(param1 : Int) : Integer; @:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String) : Integer; } @:realPath("java.lang.Integer_IntegerCache") @:javaNative @:native("java.lang.Integer$IntegerCache") @:javaCanonical("java.lang","Integer.IntegerCache") extern class Integer_IntegerCache { } haxe_3.4.4.orig/std/java/lang/Long.hx0000664000175000017500000001053413166552354017313 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.lang; @:native("") // make sure the generator won't see this @:forwardStatics @:forward abstract Long(LongClass) from LongClass to LongClass { @:to @:extern inline public function toLong():haxe.Int64 return this.longValue(); @:from @:extern inline public static function fromLong(b:haxe.Int64):Long return LongClass.valueOf(b); } @:native("java.lang.Long") extern class LongClass extends Number implements Comparable { @:overload @:throws("java.lang.NumberFormatException") function new(param1 : String) : Void; @:overload function new(param1 : haxe.Int64) : Void; @:overload function compareTo(param1 : Dynamic) : Int; @:overload function compareTo(param1 : Long) : Int; @:overload function equals(param1 : Dynamic) : Bool; @:overload function hashCode() : Int; @:overload function toString() : String; @:final static var MAX_VALUE(default,null) : haxe.Int64; @:final static var MIN_VALUE(default,null) : haxe.Int64; @:final static var SIZE(default,null) : Int; @:final static var TYPE : Class; @:overload static function bitCount(param1 : haxe.Int64) : Int; @:overload static function compare(param1 : haxe.Int64, param2 : haxe.Int64) : Int; @:overload @:throws("java.lang.NumberFormatException") static function decode(param1 : String) : Long; @:overload static function getLong(param1 : String, param2 : Long) : Long; @:overload static function getLong(param1 : String) : Long; @:overload static function getLong(param1 : String, param2 : haxe.Int64) : Long; @:overload static function highestOneBit(param1 : haxe.Int64) : haxe.Int64; @:overload static function lowestOneBit(param1 : haxe.Int64) : haxe.Int64; @:overload static function numberOfLeadingZeros(param1 : haxe.Int64) : Int; @:overload static function numberOfTrailingZeros(param1 : haxe.Int64) : Int; @:overload @:throws("java.lang.NumberFormatException") static function parseLong(param1 : String) : haxe.Int64; @:overload @:throws("java.lang.NumberFormatException") static function parseLong(param1 : String, param2 : Int) : haxe.Int64; @:overload static function reverse(param1 : haxe.Int64) : haxe.Int64; @:overload static function reverseBytes(param1 : haxe.Int64) : haxe.Int64; @:overload static function rotateLeft(param1 : haxe.Int64, param2 : Int) : haxe.Int64; @:overload static function rotateRight(param1 : haxe.Int64, param2 : Int) : haxe.Int64; @:overload static function signum(param1 : haxe.Int64) : Int; @:overload static function toBinaryString(param1 : haxe.Int64) : String; @:overload static function toHexString(param1 : haxe.Int64) : String; @:overload static function toOctalString(param1 : haxe.Int64) : String; @:native("toString") @:overload static function _toString(param1 : haxe.Int64) : String; @:native("toString") @:overload static function _toString(param1 : haxe.Int64, param2 : Int) : String; @:overload static function valueOf(param1 : haxe.Int64) : Long; @:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String, param2 : Int) : Long; @:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String) : Long; } @:realPath("java.lang.Long_LongCache") @:javaNative @:native("java.lang.Long$LongCache") @:javaCanonical("java.lang","Long.LongCache") extern class Long_LongCache { } haxe_3.4.4.orig/std/java/lang/Short.hx0000664000175000017500000000637513166552354017523 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.lang; @:native("") // make sure the generator won't see this @:forwardStatics @:forward abstract Short(ShortClass) from ShortClass to ShortClass { @:to @:extern inline public function toShort():java.types.Int16 return this.shortValue(); @:from @:extern inline public static function fromShort(b:java.types.Int16):Short return ShortClass.valueOf(b); } @:native("java.lang.Short") extern class ShortClass extends Number implements Comparable { @:overload function new(param1 : java.types.Int16) : Void; @:overload @:throws("java.lang.NumberFormatException") function new(param1 : String) : Void; @:overload function compareTo(param1 : Short) : Int; @:overload function compareTo(param1 : Dynamic) : Int; @:overload function equals(param1 : Dynamic) : Bool; @:overload function hashCode() : Int; @:overload function toString() : String; @:final static var MAX_VALUE(default,null) : java.types.Int16; @:final static var MIN_VALUE(default,null) : java.types.Int16; @:final static var SIZE(default,null) : Int; @:final static var TYPE : Class; @:overload static function compare(param1 : java.types.Int16, param2 : java.types.Int16) : Int; @:overload @:throws("java.lang.NumberFormatException") static function decode(param1 : String) : Short; @:overload @:throws("java.lang.NumberFormatException") static function parseShort(param1 : String, param2 : Int) : java.types.Int16; @:overload @:throws("java.lang.NumberFormatException") static function parseShort(param1 : String) : java.types.Int16; @:overload static function reverseBytes(param1 : java.types.Int16) : java.types.Int16; @:native("toString") @:overload static function _toString(param1 : java.types.Int16) : String; @:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String, param2 : Int) : Short; @:overload static function valueOf(param1 : java.types.Int16) : Short; @:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String) : Short; } @:realPath("java.lang.Short_ShortCache") @:javaNative @:native("java.lang.Short$ShortCache") @:javaCanonical("java.lang","Short.ShortCache") extern class Short_ShortCache { } haxe_3.4.4.orig/std/java/net/SslSocket.hx0000664000175000017500000000271713166552354020177 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.net; @:native('haxe.java.net.SslSocket') class SslSocket extends sys.net.Socket { override private function create() : Void { try { this.sock = java.javax.net.ssl.SSLSocketFactory.getDefault().createSocket(); this.server = java.javax.net.ssl.SSLServerSocketFactory.getDefault().createServerSocket(); } catch(e:Dynamic) throw e; } } haxe_3.4.4.orig/std/java/types/Char16.hx0000664000175000017500000000224113166552354017657 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.types; typedef Char16 = java.StdTypes.Char16; haxe_3.4.4.orig/std/java/types/Int16.hx0000664000175000017500000000223713166552354017541 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.types; typedef Int16 = java.StdTypes.Int16; haxe_3.4.4.orig/std/java/types/Int8.hx0000664000175000017500000000223513166552354017460 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.types; typedef Int8 = java.StdTypes.Int8; haxe_3.4.4.orig/std/java/vm/AtomicList.hx0000664000175000017500000000460213166552354020164 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.vm; import java.util.concurrent.atomic.AtomicReference; /** A lock-free queue implementation **/ @:native('haxe.java.vm.AtomicList') @:nativeGen class AtomicList { @:volatile @:private var head:AtomicNode; @:volatile @:private var tail:AtomicReference>; public function new() { this.head = new AtomicNode(null); this.head.set(new AtomicNode(null)); this.tail = new AtomicReference(head); } public function add(v:T) { var n = new AtomicNode(v), tail = this.tail; var p = null; while( !((p = tail.get()).compareAndSet(null, n)) ) { tail.compareAndSet(p, p.get()); } tail.compareAndSet(p, n); } public function pop():Null { var p = null, pget = null, head = head; do { p = head.get(); if ( (pget = p.get()) == null) return null; //empty } while(!head.compareAndSet(p, pget)); var ret = pget.value; pget.value = null; return ret; } public function peek() { var ret = head.get(); if (ret == null) return null; //empty return ret.value; } public function peekLast() { return tail.get().value; } } @:native('haxe.java.vm.AtomicNode') @:nativeGen class AtomicNode extends AtomicReference> { public var value:T; public function new(value) { super(); this.value = value; } } haxe_3.4.4.orig/std/java/vm/Deque.hx0000664000175000017500000000443213166552354017160 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.vm; import java.Lib; /** A Lock-free Queue implementation **/ @:native('haxe.java.vm.Deque') @:nativeGen class Deque { @:private var head:Node; @:private var tail:Node; public function new() { this.head = this.tail = new Node(null); } public function add(i : T) { var n = new Node(i); untyped __lock__(this, { tail.next = n; tail = n; try { untyped this.notify(); } catch(e:Dynamic) { throw e; } }); } public function push(i : T) { var n = new Node(i); untyped __lock__(this, { n.next = head.next; head.next = n; try { untyped this.notify(); } catch(e:Dynamic) { throw e; } }); } public function pop(block : Bool) : Null { var ret = null; untyped __lock__(this, { var n = null; do { n = head.next; if (n != null) { ret = n.value; n.value = null; head = n; } else if (block) { //block try { untyped this.wait(); } catch(e:Dynamic) { throw e; } } } while( block && n == null ); }); return ret; } } @:native('haxe.java.vm.DequeNode') @:nativeGen class Node { public var value:T; public var next:Node; public function new(val) { this.value = val; } } haxe_3.4.4.orig/std/java/vm/Gc.hx0000664000175000017500000000263713166552354016453 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.vm; @:native('haxe.java.vm.Gc') class Gc { public static function run( major : Bool ) { java.lang.System.gc(); } public static function stats() : { heap : Int, free : Int } { var r = java.lang.Runtime.getRuntime(); return { heap : cast r.totalMemory(), free : cast r.freeMemory() }; } } haxe_3.4.4.orig/std/java/vm/Lock.hx0000664000175000017500000000572213166552354017010 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.vm; import java.Lib; import java.lang.System; using haxe.Int64; @:native('haxe.java.vm.Lock') class Lock { @:private @:volatile var releasedCount = 0; /** Creates a new lock, which is initially locked **/ public function new() { } /** Waits for a lock to be released and acquire it. If `timeout` (in seconds) is not null and expires then the returned value is false **/ public function wait(?timeout : Float) : Bool { var ret = false; java.Lib.lock(this, { if (--releasedCount < 0) { if (timeout == null) { // since .notify() is asynchronous, this `while` is needed // because there is a very remote possibility of release() awaking a thread, // but before it releases, another thread calls wait - and since the release count // is still positive, it will get the lock. while( releasedCount < 0 ) { try { untyped __java__("this.wait()"); } catch(e:java.lang.InterruptedException) { } } } else { var timeout:haxe.Int64 = cast timeout * 1000; var cur = System.currentTimeMillis(), max = cur.add(timeout); // see above comment about this while loop while ( releasedCount < 0 && cur.compare(max) < 0 ) { try { var t = max.sub(cur); untyped __java__("this.wait({0})",t); cur = System.currentTimeMillis(); } catch(e:java.lang.InterruptedException) { } } } } ret = this.releasedCount >= 0; if (!ret) this.releasedCount++; //timed out }); return ret; } /** Release a lock. The thread does not need to own the lock to be able to release it. If a lock is released several times, it can be acquired as many times **/ public function release() { untyped __lock__(this, { if (++releasedCount >= 0) { untyped this.notify(); } }); } } haxe_3.4.4.orig/std/java/vm/Mutex.hx0000664000175000017500000000420113166552354017211 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.vm; import java.util.concurrent.locks.ReentrantLock; @:native('haxe.java.vm.Mutex') class Mutex { @:private var lock:ReentrantLock; /** Creates a mutex, which can be used to acquire a temporary lock to access some resource. The main difference with a lock is that a mutex must always be released by the owner thread **/ public function new() { this.lock = new ReentrantLock(); } /** Try to acquire the mutex, returns true if acquire or false if it's already locked by another thread. **/ public function tryAcquire():Bool { return this.lock.tryLock(); } /** The current thread acquire the mutex or wait if not available. The same thread can acquire several times the same mutex, but must release it as many times it has been acquired. **/ public function acquire():Void { this.lock.lock(); } /** Release a mutex that has been acquired by the current thread. If the current thread does not own the mutex, an exception will be thrown **/ public function release():Void { this.lock.unlock(); } } haxe_3.4.4.orig/std/java/vm/Thread.hx0000664000175000017500000000547013166552354017327 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.vm; import java.Lib; @:native('haxe.java.vm.Thread') class Thread { @:private static var javaThreadToHaxe = new haxe.ds.WeakMap(); @:private static var mainJavaThread = java.lang.Thread.currentThread(); @:private static var mainHaxeThread = { var ret = new Thread(); javaThreadToHaxe.set(mainJavaThread, ret); ret; }; private static function getThread(jt:java.lang.Thread):Thread { if (Std.is(jt, HaxeThread)) { var t:HaxeThread = cast jt; return t.threadObject; } else if (jt == mainJavaThread) { return mainHaxeThread; } else { var ret = null; untyped __lock__(javaThreadToHaxe, { ret = javaThreadToHaxe.get(jt); if (ret == null) { ret = new Thread(); javaThreadToHaxe.set(jt, ret); } }); return ret; } } private var messages:Deque; function new() { this.messages = new Deque(); } public function sendMessage(obj:Dynamic) { messages.add(obj); } public static function current():Thread { return getThread( java.lang.Thread.currentThread() ); } public static function readMessage(block : Bool) : Dynamic { return current().messages.pop(block); } public static function create(fn:Void->Void):Thread { var ret = new Thread(); var t = new HaxeThread(ret, fn); t.start(); return ret; } } @:native('haxe.java.vm.HaxeThread') private class HaxeThread extends java.lang.Thread { public var threadObject(default, null):Thread; private var runFunction:Void->Void; @:overload override public function run():Void { runFunction(); } public function new(hxThread:Thread, run:Void->Void) { super(); threadObject = hxThread; runFunction = run; setDaemon(true); } } haxe_3.4.4.orig/std/java/vm/Tls.hx0000664000175000017500000000274313166552354016662 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package java.vm; /** Thread-local Storage implementation **/ @:native('haxe.java.vm.Tls') class Tls { var t : java.lang.ThreadLocal; public var value(get,set):T; public function new() { this.t = new java.lang.ThreadLocal(); } inline private function get_value():T { return t.get(); } inline private function set_value(v:T):T { t.set(v); return v; } } haxe_3.4.4.orig/std/js/Boot.hx0000664000175000017500000001657713166552354016106 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package js; private class HaxeError extends js.Error { var val:Dynamic; public function new(val:Dynamic) untyped { super(); this.val = __define_feature__("js.Boot.HaxeError", val); this.message = String(val); if (js.Error.captureStackTrace) js.Error.captureStackTrace(this, HaxeError); } public static function wrap(val:Dynamic):Dynamic untyped { return if (__instanceof__(val, js.Error)) val else new HaxeError(val); } } @:dox(hide) class Boot { private static function __unhtml(s : String) { return s.split("&").join("&").split("<").join("<").split(">").join(">"); } private static function __trace(v,i : haxe.PosInfos) { untyped { var msg = if( i != null ) i.fileName+":"+i.lineNumber+": " else ""; #if jsfl msg += __string_rec(v,""); fl.trace(msg); #else msg += __string_rec(v, ""); if( i != null && i.customParams != null ) for( v in i.customParams ) msg += "," + __string_rec(v, ""); var d; if( __js__("typeof")(document) != "undefined" && (d = document.getElementById("haxe:trace")) != null ) d.innerHTML += __unhtml(msg)+"
"; else if( __js__("typeof console") != "undefined" && __js__("console").log != null ) __js__("console").log(msg); #end } } private static function __clear_trace() { untyped { #if jsfl fl.outputPanel.clear(); #else var d = document.getElementById("haxe:trace"); if( d != null ) d.innerHTML = ""; #end } } static inline function isClass(o:Dynamic) : Bool { return untyped __define_feature__("js.Boot.isClass", o.__name__); } static inline function isEnum(e:Dynamic) : Bool { return untyped __define_feature__("js.Boot.isEnum", e.__ename__); } static function getClass(o:Dynamic) : Dynamic { if (Std.is(o, Array)) return Array; else { var cl = untyped __define_feature__("js.Boot.getClass", o.__class__); if (cl != null) return cl; var name = __nativeClassName(o); if (name != null) return __resolveNativeClass(name); return null; } } @:ifFeature("has_enum") private static function __string_rec(o,s:String) { untyped { if( o == null ) return "null"; if( s.length >= 5 ) return "<...>"; // too much deep recursion var t = __js__("typeof(o)"); if( t == "function" && (isClass(o) || isEnum(o)) ) t = "object"; switch( t ) { case "object": if( __js__("o instanceof Array") ) { if( o.__enum__ ) { if( o.length == 2 ) return o[0]; var str = o[0]+"("; s += "\t"; for( i in 2...o.length ) { if( i != 2 ) str += "," + __string_rec(o[i],s); else str += __string_rec(o[i],s); } return str + ")"; } var l = o.length; var i; var str = "["; s += "\t"; for( i in 0...l ) str += (if (i > 0) "," else "")+__string_rec(o[i],s); str += "]"; return str; } var tostr; try { tostr = untyped o.toString; } catch( e : Dynamic ) { // strange error on IE return "???"; } if( tostr != null && tostr != __js__("Object.toString") && __typeof__(tostr) == "function" ) { var s2 = o.toString(); if( s2 != "[object Object]") return s2; } var k : String = null; var str = "{\n"; s += "\t"; var hasp = (o.hasOwnProperty != null); __js__("for( var k in o ) {"); if( hasp && !o.hasOwnProperty(k) ) __js__("continue"); if( k == "prototype" || k == "__class__" || k == "__super__" || k == "__interfaces__" || k == "__properties__" ) __js__("continue"); if( str.length != 2 ) str += ", \n"; str += s + k + " : "+__string_rec(o[k],s); __js__("}"); s = s.substring(1); str += "\n" + s + "}"; return str; case "function": return ""; case "string": return o; default: return String(o); } } } private static function __interfLoop(cc : Dynamic,cl : Dynamic) { if( cc == null ) return false; if( cc == cl ) return true; var intf : Dynamic = cc.__interfaces__; if( intf != null ) for( i in 0...intf.length ) { var i : Dynamic = intf[i]; if( i == cl || __interfLoop(i,cl) ) return true; } return __interfLoop(cc.__super__,cl); } @:ifFeature("typed_catch") private static function __instanceof(o : Dynamic,cl : Dynamic) { if( cl == null ) return false; switch( cl ) { case Int: return (untyped __js__("typeof"))(o) == "number" && untyped __js__("(o|0) === o"); case Float: return (untyped __js__("typeof"))(o) == "number"; case Bool: return (untyped __js__("typeof"))(o) == "boolean"; case String: return (untyped __js__("typeof"))(o) == "string"; case Array: return (untyped __js__("(o instanceof Array)")) && o.__enum__ == null; case Dynamic: return true; default: if( o != null ) { // Check if o is an instance of a Haxe class or a native JS object if( (untyped __js__("typeof"))(cl) == "function" ) { if( untyped __js__("o instanceof cl") ) return true; if( __interfLoop(getClass(o),cl) ) return true; } else if ( (untyped __js__("typeof"))(cl) == "object" && __isNativeObj(cl) ) { if( untyped __js__("o instanceof cl") ) return true; } } else { return false; } // do not use isClass/isEnum here untyped __feature__("Class.*",if( cl == Class && o.__name__ != null ) return true); untyped __feature__("Enum.*",if( cl == Enum && o.__ename__ != null ) return true); return o.__enum__ == cl; } } @:ifFeature("typed_cast") private static function __cast(o : Dynamic, t : Dynamic) { if (__instanceof(o, t)) return o; else throw "Cannot cast " +Std.string(o) + " to " +Std.string(t); } static var __toStr = untyped ({}).toString; // get native JS [[Class]] static function __nativeClassName(o:Dynamic):String { var name = untyped __toStr.call(o).slice(8, -1); // exclude general Object and Function // also exclude Math and JSON, because instanceof cannot be called on them if (name == "Object" || name == "Function" || name == "Math" || name == "JSON") return null; return name; } // check for usable native JS object static function __isNativeObj(o:Dynamic):Bool { return __nativeClassName(o) != null; } // resolve native JS class in the global scope: static function __resolveNativeClass(name:String) { return untyped js.Lib.global[name]; } } haxe_3.4.4.orig/std/js/Browser.hx0000664000175000017500000000713613166552354016615 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package js; import js.html.Storage; import js.html.XMLHttpRequest; class Browser { /** The global window object. */ public static var window(get, never):js.html.Window; inline static function get_window() return untyped __js__("window"); /** Shortcut to Window.document. */ public static var document(get, never):js.html.HTMLDocument; inline static function get_document() return untyped __js__("window.document"); /** Shortcut to Window.location. */ public static var location(get, never):js.html.Location; inline static function get_location() return untyped __js__("window.location"); /** Shortcut to Window.navigator. */ public static var navigator(get, never):js.html.Navigator; inline static function get_navigator() return untyped __js__("window.navigator"); /** Shortcut to Window.console. */ public static var console(get, never):js.html.Console; inline static function get_console() return untyped __js__("window.console"); /** * True if a window object exists, false otherwise. * * This can be used to check if the code is being executed in a non-browser * environment such as node.js. */ public static var supported(get, never):Bool; inline static function get_supported() return untyped __typeof__(window) != "undefined"; /** * Safely gets the browser's local storage, or returns null if localStorage is unsupported or * disabled. */ public static function getLocalStorage() : Storage { try { var s = window.localStorage; s.getItem(""); return s; } catch( e : Dynamic ) { return null; } } /** * Safely gets the browser's session storage, or returns null if sessionStorage is unsupported * or disabled. */ public static function getSessionStorage() : Storage { try { var s = window.sessionStorage; s.getItem(""); return s; } catch( e : Dynamic ) { return null; } } /** * Creates an XMLHttpRequest, with a fallback to ActiveXObject for ancient versions of Internet * Explorer. */ public static function createXMLHttpRequest() : XMLHttpRequest { if( untyped __js__("typeof XMLHttpRequest") != "undefined" ) { return new XMLHttpRequest(); } if( untyped __js__("typeof ActiveXObject") != "undefined" ) { return untyped __new__("ActiveXObject","Microsoft.XMLHTTP"); } throw "Unable to create XMLHttpRequest object."; } /** Display an alert message box containing the given message. See also `Window.alert()`. **/ public static function alert( v : Dynamic ) { @:privateAccess window.alert(Boot.__string_rec(v,"")); } } haxe_3.4.4.orig/std/js/Cookie.hx0000664000175000017500000000457413166552354016406 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package js; class Cookie { /** Create or update a cookie. @param expireDelay In seconds. If null, the cookie expires at end of session. **/ public static function set( name : String, value : String, ?expireDelay : Int, ?path : String, ?domain : String ){ var s = name+"="+StringTools.urlEncode(value); if( expireDelay != null ){ var d = DateTools.delta(Date.now(),expireDelay*1000); s += ";expires=" + untyped d.toGMTString(); } if( path != null ){ s += ";path="+path; } if( domain != null ){ s += ";domain="+domain; } Browser.document.cookie = s; } /** Returns all cookies. **/ public static function all(){ var h = new haxe.ds.StringMap(); var a = Browser.document.cookie.split(";"); for( e in a ){ e = StringTools.ltrim(e); var t = e.split("="); if( t.length < 2 ) continue; h.set(t[0],StringTools.urlDecode(t[1])); } return h; } /** Returns value of a cookie. **/ public static function get( name : String ){ return all().get(name); } /** Returns true if a cookie `name` exists. **/ public static function exists( name : String ){ return all().exists(name); } /** Remove a cookie. **/ public static function remove( name : String, ?path : String, ?domain : String ){ set(name,"",-10,path,domain); } } haxe_3.4.4.orig/std/js/Error.hx0000664000175000017500000000362613166552354016263 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package js; @:native("Error") extern class Error { var message : String; var name : String; var stack(default,null) : String; function new(?message : String) : Void; } @:native("EvalError") extern class EvalError extends Error { function new(?message : String) : Void; } @:native("RangeError") extern class RangeError extends Error { function new(?message : String) : Void; } @:native("ReferenceError") extern class ReferenceError extends Error { function new(?message : String) : Void; } @:native("SyntaxError") extern class SyntaxError extends Error { function new(?message : String) : Void; } @:native("TypeError") extern class TypeError extends Error { function new(?message : String) : Void; } @:native("URIError") extern class URIError extends Error { function new(?message : String) : Void; } haxe_3.4.4.orig/std/js/JQuery.hx0000664000175000017500000003624213166552354016411 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package js; import js.html.Window; import js.html.Element; @:deprecated("Use js.jquery.Event instead.") typedef JqEvent = { var target : Element; var currentTarget : Element; var relatedTarget : Element; var delegateTarget : Element; var type : String; var timeStamp : Int; //var data : Dynamic; //var namespace : String; //var result : Dynamic; // position var pageX : Int; var pageY : Int; var wheelDelta : Int; // keys var keyCode : Int; var charCode : Int; var shiftKey : Bool; var ctrlKey : Bool; var altKey : Bool; var metaKey : Bool; var which : Int; // propagation function isDefaultPrevented() : Bool; function isImmediatePropagationStopped() : Bool; function isPropagationStopped() : Bool; function preventDefault() : Void; function stopImmediatePropagation() : Void; function stopPropagation() : Void; } @:deprecated("Use js.jquery.Helper instead.") extern class JQueryHelper { @:overload(function(j:JQuery):JQuery{}) @:overload(function(j:Window):JQuery{}) @:overload(function(j:Element):JQuery { } ) public static inline function J( html : haxe.extern.EitherType>> ) : JQuery { return new JQuery(cast html); } public static var JTHIS(get, null) : JQuery; static inline function get_JTHIS() : JQuery { return new JQuery(js.Lib.nativeThis); } } @:deprecated("Use js.jquery.JQuery instead.") @:initPackage extern class JQuery implements ArrayAccess { var context(default,null) : Element; var length(default, null) : Int; @:selfCall @:overload(function(j:JQuery):Void{}) @:overload(function(j:Window):Void{}) @:overload(function(j:Element):Void{}) function new( html : String ) : Void; // attributes function addClass( className : String ) : JQuery; function removeClass( ?className : String ) : JQuery; function hasClass( className : String ) : Bool; function toggleClass( className : String, ?addRemove : Bool ) : JQuery; @:overload(function(name:String,value:String):JQuery{}) function attr( name : String ) : String; function removeAttr( attr : String ) : JQuery; @:overload(function(name:String,value:Dynamic):JQuery{}) function prop( name : String ) : Dynamic; @:overload(function(prop:String,value:String):JQuery{}) @:overload(function(map:{}):JQuery{}) function css( prop : String ) : String; @:overload(function(html:String):JQuery{}) @:overload(function(html:JQuery):JQuery{}) function html() : String; @:overload(function(value:String):JQuery{}) function val() : String; @:overload(function(text:String):JQuery{}) function text() : String; // Size & Position @:overload(function(value:Int):JQuery{}) function width() : Int; @:overload(function(value:Int):JQuery{}) function height() : Int; @:overload(function(value:Int):JQuery{}) function innerWidth() : Int; @:overload(function(value:Int):JQuery{}) function innerHeight() : Int; function outerWidth( ?includeMargin : Bool ) : Int; function outerHeight( ?includeMargin : Bool ) : Int; @:overload(function(value:Int):JQuery{}) function scrollLeft() : Int; @:overload(function(value:Int):JQuery{}) function scrollTop() : Int; @:overload(function(value: { left : Int, top : Int }):JQuery{}) function offset() : { left : Int, top : Int }; function offsetParent() : JQuery; @:overload(function(value: { left : Int, top : Int }):JQuery{}) function position() : { left : Int, top : Int }; // current group manipulation @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) @:overload(function(value:Array):JQuery{}) function add( selector : String, ?context : JQuery ) : JQuery; function andSelf() : JQuery; function children( ?selector : String ) : JQuery; function clone( ?withDataAndEvents : Bool ) : JQuery; function closest( selector : String, ?context : JQuery ) : JQuery; function contents() : JQuery; @:overload(function( f : Int -> Element -> Void ):JQuery{}) function each( f : Void -> Void ) : JQuery; function end() : JQuery; function eq( index : Int ) : JQuery; function filter( selector : String ) : JQuery; function find( selector : String ) : JQuery; function first() : JQuery; function index( ?selector : String ) : Int; function last( ?selector : String ) : JQuery; function has( selector : String ) : JQuery; function next( ?selector : String ) : JQuery; function nextAll( ?selector : String ) : JQuery; function nextUntil( ?selector : String ) : JQuery; function parent( ?selector : String ) : JQuery; function parents( ?selector : String ) : JQuery; function parentsUntil( ?selector : String ) : JQuery; @:overload(function(value:Element):JQuery{}) function not( selector : String ) : JQuery; function prev( ?selector : String ) : JQuery; function prevAll( ?selector : String ) : JQuery; function prevUntil( ?selector : String ) : JQuery; function pushStack( elements : Array ) : JQuery; function siblings( ?selector : String ) : JQuery; function size() : Int; function slice( start : Int, ?end : Int ) : JQuery; function toArray() : Array; // DOM changes @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function before( html : String ) : JQuery; @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function after( html : String ) : JQuery; @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function append( html : String ) : JQuery; @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function appendTo( html : String ) : JQuery; function detach( ?selector : String ) : JQuery; function empty() : JQuery; // remove all texts @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function insertBefore( html : String ) : JQuery; @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function insertAfter( html : String ) : JQuery; @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function prepend( html : String ) : JQuery; @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function prependTo( html : String ) : JQuery; function remove( ?selector : String ) : JQuery; function replaceAll( selector : String ) : JQuery; @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function replaceWith( html : String ) : JQuery; function unwrap() : JQuery; @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function wrap( html : String ) : JQuery; @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function wrapAll( html : String ) : JQuery; @:overload(function(value:JQuery):JQuery{}) @:overload(function(value:Element):JQuery{}) function wrapInner( html : String ) : JQuery; // animation @:overload(function(properties:{},?duration:Int,?easing:String,?call:Void->Void) : JQuery{}) function animate( properties : { }, ?duration : Int, ?callb : Void -> Void ) : JQuery; function delay( duration : Int, ?queueName : String ) : JQuery; @:overload(function(?duration:Int,?easing:String,?call:Void->Void) : JQuery{}) function hide( ?duration : Int, ?call : Void -> Void ) : JQuery; @:overload(function(?duration:Int,?easing:String,?call:Void->Void) : JQuery{}) function fadeIn( ?duration : Int, ?call : Void -> Void ) : JQuery; @:overload(function(?duration:Int,?easing:String,?call:Void->Void) : JQuery{}) function fadeOut( ?duration : Int, ?call : Void -> Void ) : JQuery; @:overload(function(duration:Int,opacity:Float,?easing:String,?call:Void->Void) : JQuery{}) function fadeTo( duration : Int, opacity : Float, ?call : Void -> Void ) : JQuery; @:overload(function(?duration:Int,?easing:String,?call:Void->Void) : JQuery{}) function fadeToggle( ?duration : Int, ?call : Void -> Void ) : JQuery; @:overload(function(?duration:Int,?easing:String,?call:Void->Void) : JQuery{}) function show( ?duration : Int, ?call : Void -> Void ) : JQuery; @:overload(function(?duration:Int,?easing:String,?call:Void->Void) : JQuery{}) function slideDown( ?duration : Int, ?call : Void -> Void ) : JQuery; @:overload(function(?duration:Int,?easing:String,?call:Void->Void) : JQuery{}) function slideToggle( ?duration : Int, ?call : Void -> Void ) : JQuery; @:overload(function(?duration:Int,?easing:String,?call:Void->Void) : JQuery{}) function slideUp( ?duration : Int, ?call : Void -> Void ) : JQuery; function stop( ?clearQueue : Bool, ?jumpToEnd : Bool ) : JQuery; @:overload(function(?duration:Int,?easing:String,?call:Void->Void) : JQuery{}) function toggle( ?duration : Int, ?call : Void -> Void ) : JQuery; // Events function blur( ?callb : JqEvent -> Void ) : JQuery; function change( ?callb : JqEvent -> Void ) : JQuery; @:overload(function(callb:Void->Void):JQuery { } ) @:overload(function(callb:JQuery.JqEvent->Void):JQuery{}) @:overload(function(callb:Void->Bool):JQuery{}) function click( ?callb : JqEvent -> Void ) : JQuery; function dblclick( ?callb : JqEvent -> Void ) : JQuery; function error( ?callb : JqEvent -> Void ) : JQuery; function focus( ?callb : JqEvent -> Void ) : JQuery; function focusin( ?callb : JqEvent -> Void ) : JQuery; function focusout( ?callb : JqEvent -> Void ) : JQuery; @:overload(function(onInOut:JqEvent->Void):JQuery{}) function hover( onIn : JqEvent -> Void, ?onOut : JqEvent -> Void ) : JQuery; @:overload(function( callb : JQuery.JqEvent -> Bool ) : JQuery {}) function keydown( ?callb : JqEvent -> Void ) : JQuery; @:overload(function( callb : JQuery.JqEvent -> Bool ) : JQuery {}) function keypress( ?callb : JqEvent -> Void ) : JQuery; @:overload(function( callb : JQuery.JqEvent -> Bool ) : JQuery {}) function keyup( ?callb : JqEvent -> Void ) : JQuery; function mousedown( ?callb : JqEvent -> Void ) : JQuery; function mouseenter( ?callb : JqEvent -> Void ) : JQuery; function mouseleave( ?callb : JqEvent -> Void ) : JQuery; function mouseout( ?callb : JqEvent -> Void ) : JQuery; function mouseover( ?callb : JqEvent -> Void ) : JQuery; function mousemove( ?callb : JqEvent -> Void ) : JQuery; function mouseup( ?callb : JqEvent -> Void ) : JQuery; // AJAX overloads @:overload(function( url:String, ?data : {}, ?callb : String -> String -> Void ) : JQuery {}) @:overload(function( url:String, ?data : {}, ?callb : String -> Void ) : JQuery {}) @:overload(function( url:String, ?data : {}, ?callb : Void -> Void ) : JQuery {}) function load( ?callb : JqEvent -> Void ) : JQuery; function ready( callb : JqEvent -> Void ) : JQuery; function resize( ?callb : JqEvent -> Void ) : JQuery; function scroll( ?callb : JqEvent -> Void ) : JQuery; function select( ?callb : JqEvent -> Void ) : JQuery; function submit( ?callb : JqEvent -> Void ) : JQuery; function unload( ?callb : JqEvent -> Void ) : JQuery; function bind( events : String, callb : JqEvent -> Void ) : JQuery; function delegate( selector : String, events : String, callb : JqEvent -> Void ) : JQuery; function die( ?events : String, ?callb : JqEvent -> Void ) : JQuery; function one( events : String, callb : JqEvent -> Void ) : JQuery; function live( events : String, callb : JqEvent -> Void ) : JQuery; function trigger( events : String ) : JQuery; function triggerHandler( events : String ) : JQuery; function unbind( ?events : String, ?callb : JqEvent -> Void ) : JQuery; function undelegate( ?selector : String, ?events : String, ?callb : JqEvent -> Void ) : JQuery; // JQuery 1.7+ @:overload(function(events:DynamicVoid>):JQuery{}) @:overload(function(events : String, selector : String, callb : JqEvent -> Void ):JQuery{}) function on( events : String, callb : JqEvent -> Void ) : JQuery; // queue function clearQueue( ?queueName : String ) : JQuery; function dequeue( ?queueName : String ) : JQuery; function queue( ?queueName : String, ?callb : (Void -> Void) -> Void ) : { length : Int }; // ajax // TODO // deferred // TODO // other tools @:overload(function(index:Int):Element{}) function get() : Array; @:overload(function(j:JQuery):Bool{}) function is( selector : String ) : Bool; @:overload(function() : Dynamic {}) @:overload(function( key : String ) : Dynamic {}) function data( key : String, value : Dynamic ) : JQuery; function removeData( ?key : String ) : JQuery; function serialize() : String; function serializeArray() : Array<{ name : String, value : String }>; //inline function map( f : JQuery -> T ) : Array { // return untyped this["map"](function() return f(cur)).get(); //} // Haxe addition @:runtime inline function iterator() : Iterator { return untyped __define_feature__('js.JQuery.iterator', this["iterator"])(); } /** Return the current JQuery element (in a callback), similar to $(this) in JS. **/ static var cur(get, null) : JQuery; static var fx(default, null) : { off : Bool, interval : Int }; static var browser(default, null) : { webkit : Bool, opera : Bool, msie : Bool, mozilla : Bool, version : String }; static function contains( parent : Element, child : Element ) : Bool; static function noConflict( ?removeAll : Bool ) : Void; static function parseJSON( json : String ) : Dynamic; static function globalEval( js : String ) : Void; //static function parseXML //static function get, post //static function getJSON, getScript, grep //static function is*, makeArray, map, merge, noop, now, param, proxy, sub, trim, type, unique private static inline function get_cur() : JQuery { return new js.JQuery(js.Lib.nativeThis); } private static function __init__() : Void untyped { #if embed_js #error "Haxe no longer bundle third-party JS libraries. Please remove `-D embed-js`. You may download the JS files and use `haxe.macro.Compiler.includeFile`." #end var q : Dynamic = (untyped js.Browser.window).jQuery; untyped __js__("var js = js || {}"); js.JQuery = q; __feature__('js.JQuery.iterator', q.fn.iterator = function() return { pos : 0, j : __this__, hasNext : function() return __this__.pos < __this__.j.length, next : function() return $(__this__.j[__this__.pos++]) } ); } } haxe_3.4.4.orig/std/js/Lib.hx0000664000175000017500000000766413166552354015706 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package js; /** Platform-specific JavaScript Library. Provides some platform-specific functions for the JavaScript target. **/ class Lib { /** Inserts a 'debugger' statement that will make a breakpoint if a debugger is available. **/ public static inline function debug() { untyped __js__("debugger"); } /** Display an alert message box containing the given message. @deprecated Use Browser.alert() instead. **/ @:deprecated("Lib.alert() is deprecated, use Browser.alert() instead") public static function alert( v : Dynamic ) { untyped __js__("alert")(js.Boot.__string_rec(v,"")); } public static inline function eval( code : String ) : Dynamic { return untyped __js__("eval")(code); } /** Inserts a `require` expression that loads JavaScript object from a module or file specified in the `module` argument. This is only supported in environments where `require` function is available, such as Node.js or RequireJS. **/ @:extern public static inline function require( module:String ) : Dynamic { return untyped __js__("require")(module); } /** Returns JavaScript `undefined` value. Note that this is only needed in very rare cases when working with external JavaScript code. In Haxe, `null` is used to represent the absence of a value. **/ public static var undefined(get,never) : Dynamic; static inline function get_undefined() : Dynamic { return untyped __js__("undefined"); } /** `nativeThis` is the JavaScript `this`, which is semantically different from the Haxe `this`. Use `nativeThis` only when working with external JavaScript code. In Haxe, `this` is always bound to a class instance. In JavaScript, `this` in a function can be bound to an arbitrary variable when the function is called using `func.call(thisObj, ...)` or `func.apply(thisObj, [...])`. Read more at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this **/ public static var nativeThis(get,never) : Dynamic; @:extern static inline function get_nativeThis() : Dynamic { return untyped __js__("this"); } /** An alias of the JS "global" object. Concretely, it is set as the first defined value in the list of `window`, `global`, `self`, and `this` in the top-level of the compiled output. **/ #if (haxe_ver >= 3.3) public #else // hide it since we should not add new feature in 3.2.1 @:allow(js) private #end static var global(get,never) : Dynamic; @:extern static inline function get_global() : Dynamic { return untyped __define_feature__("js.Lib.global", __js__("$global")); // $global is generated by the compiler } /** Re-throw last cathed exception, preserving original stack information. Calling this only makes sense inside a catch statement. **/ @:extern public static inline function rethrow() { untyped __define_feature__("js.Lib.rethrow", __rethrow__()); } } haxe_3.4.4.orig/std/js/Promise.hx0000664000175000017500000000422213166552354016601 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package js; import haxe.extern.EitherType; @:native("Promise") extern class Promise { @:overload(function(promise : Promise) : Promise {}) @:overload(function(thenable : Thenable) : Promise {}) static function resolve( ?value : T ) : Promise; static function reject( ?value : Dynamic ) : Promise; static function all( iterable : Array ) : Promise>; static function race( iterable : Array ) : Promise; /** @throws DOMError */ function new( init : (T -> Void) -> (Dynamic -> Void) -> Void ) : Void; function then( fulfillCallback : Null>, ?rejectCallback : EitherType Void, PromiseCallback> ) : Promise; @:native("catch") function catchError( rejectCallback : EitherType Void, PromiseCallback> ) : Promise; } typedef PromiseCallback = EitherType TOut, T -> Promise>; typedef Thenable = { function then(resolve:T->Void, ?reject:Dynamic->Void):Void; } haxe_3.4.4.orig/std/js/RegExp.hx0000664000175000017500000000340513166552354016357 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package js; /** Native JavaScript regular expressions. For cross-platform regular expressions, use Haxe `EReg` class or [regexp literals](https://haxe.org/manual/std-regex.html). **/ @:native("RegExp") extern class RegExp { var global(default,null):Bool; var ignoreCase(default,null):Bool; var multiline(default,null):Bool; var source(default,null):String; var lastIndex:Int; function new(pattern:String, ?flags:String); function exec(str:String):Null; function test(str:String):Bool; function toString():String; } extern class RegExpMatch extends Array { var index:Int; var input:String; } haxe_3.4.4.orig/std/js/SWFObject.hx0000664000175000017500000000354313166552354016756 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package js; @:deprecated("Use js.swfobject.SWFObject instead.") @:initPackage extern class SWFObject { function new( swf : String, id : String, width : Int, height : Int, ver : String, color : String /*...*/ ) : Void; function addParam( param : String, value : String ) : Void; function getSWFHTML() : String; function write( elementId : String ) : Bool; function addVariable( param : String, value : String ) : Void; function setAttribute( id : String, value : String ) : Void; private static function __init__() : Void untyped { #if embed_js #error "Haxe no longer bundle third-party JS libraries. Please remove `-D embed-js`. You may download the JS files and use `haxe.macro.Compiler.includeFile`." #end js.SWFObject = deconcept.SWFObject; } }haxe_3.4.4.orig/std/js/Selection.hx0000664000175000017500000000577313166552354017124 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package js; import js.html.TextAreaElement; class Selection { var doc : Dynamic; public function new( doc : TextAreaElement ) { this.doc = doc; } public function get() { // Mozilla if( doc.selectionStart != null ) return doc.value.substring(doc.selectionStart,doc.selectionEnd); // IE var range = untyped js.Lib.document.selection.createRange(); if( range.parentElement() != doc ) return ""; return range.text; } public function select( start : Int, end : Int ) { doc.focus(); // Mozilla if( doc.selectionStart != null ) { doc.selectionStart = start; doc.selectionEnd = end; return; } // FIX : IE count \r\n as one single char for selection // operations, we must then deal with it var value : String = doc.value; var p = 0, delta = 0; while( true ) { var i = value.indexOf("\r\n", p); if( i < 0 || i > start ) break; delta++; p = i + 2; } start -= delta; while( true ) { var i = value.indexOf("\r\n", p); if( i < 0 || i > end ) break; delta++; p = i + 2; } end -= delta; // IE var r = doc.createTextRange(); r.moveEnd('textedit',-1); r.moveStart('character',start); r.moveEnd('character',end - start); r.select(); } public function insert( left : String, text : String, right : String ) { doc.focus(); // Mozilla if( doc.selectionStart != null ) { var top = doc.scrollTop; var start = doc.selectionStart; var end = doc.selectionEnd; doc.value = doc.value.substr(0,start) + left + text + right + doc.value.substr(end); doc.selectionStart = start + left.length; doc.selectionEnd = start + left.length + text.length; doc.scrollTop = top; return; } // IE var range = untyped js.Lib.document.selection.createRange(); range.text = left + text + right; range.moveStart('character',-text.length-right.length); range.moveEnd('character',-right.length); range.select(); } } haxe_3.4.4.orig/std/js/XMLSocket.hx0000664000175000017500000000411613166552354016776 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package js; /** By compiling the `haxe.remoting.SocketWrapper` into a SWF, you can create and use XMLSockets directly from Javascript. **/ class XMLSocket { var cnx : haxe.remoting.ExternalConnection; public function new( flashObject : String ) { var ctx = new haxe.remoting.Context(); var cnx = haxe.remoting.ExternalConnection.flashConnect("SocketWrapper",flashObject,ctx); var sockId = cnx.api.create.call([flashObject]); cnx.close(); ctx.addObject("api",this,false); this.cnx = haxe.remoting.ExternalConnection.flashConnect(sockId,flashObject,ctx); } public function connect( host : String, port : Int ) { cnx.sock.connect.call([host,port]); } public function send( data : String ) { cnx.sock.send.call([data]); } public function close() { cnx.sock.close.call([]); cnx.api.destroy.call([]); cnx.close(); } public dynamic function onData( data : String ) { } public dynamic function onClose() { } public dynamic function onConnect( b : Bool ) { } } haxe_3.4.4.orig/std/js/_std/Array.hx0000664000175000017500000000472013166552354017175 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi extern class Array { var length(default,null) : Int; function new() : Void; function concat( a : Array ) : Array; function join( sep : String ) : String; function pop() : Null; function push(x : T) : Int; function reverse() : Void; function shift() : Null; function slice( pos : Int, ?end : Int ) : Array; function sort( f : T -> T -> Int ) : Void; function splice( pos : Int, len : Int ) : Array; function toString() : String; function unshift( x : T ) : Void; inline function insert( pos : Int, x : T ) : Void { (untyped this).splice(pos,0,x); } inline function remove( x : T ) : Bool { return @:privateAccess HxOverrides.remove(this,x); } #if (js_es >= 5) function indexOf( x : T, ?fromIndex:Int ) : Int; function lastIndexOf( x : T, ?fromIndex:Int ) : Int; #else inline function indexOf( x : T, ?fromIndex:Int ) : Int { return @:privateAccess HxOverrides.indexOf(this,x,(fromIndex!=null)?fromIndex:0); } inline function lastIndexOf( x : T, ?fromIndex:Int ) : Int { return @:privateAccess HxOverrides.lastIndexOf(this,x,(fromIndex!=null)?fromIndex:length-1); } #end inline function copy() : Array { return (untyped this).slice(); } function map(f:T->S):Array; function filter(f:T->Bool):Array; @:runtime inline function iterator() : Iterator { return untyped HxOverrides.iter(this); } } haxe_3.4.4.orig/std/js/_std/Date.hx0000664000175000017500000000361113166552354016772 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi extern class Date { @:pure function new(year : Int, month : Int, day : Int, hour : Int, min : Int, sec : Int ) : Void; @:pure function getTime() : Float; @:pure function getHours() : Int; @:pure function getMinutes() : Int; @:pure function getSeconds() : Int; @:pure function getFullYear() : Int; @:pure function getMonth() : Int; @:pure function getDate() : Int; @:pure function getDay() : Int; @:pure inline function toString() : String { return untyped HxOverrides.dateStr(this); } @:pure static inline function now() : Date { return untyped __new__(Date); } @:pure static inline function fromTime( t : Float ) : Date { return untyped __new__(Date, t); } @:pure static inline function fromString( s : String ) : Date { return untyped HxOverrides.strDate(s); } } haxe_3.4.4.orig/std/js/_std/EReg.hx0000664000175000017500000000665713166552354016754 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi class EReg { var r : HaxeRegExp; public inline function new( r : String, opt : String ) : Void { this.r = new HaxeRegExp(r, opt.split("u").join("")); // 'u' (utf8) depends on page encoding } public function match( s : String ) : Bool { if( r.global ) r.lastIndex = 0; r.m = r.exec(s); r.s = s; return (r.m != null); } public function matched( n : Int ) : String { return if( r.m != null && n >= 0 && n < r.m.length ) r.m[n] else throw "EReg::matched"; } public function matchedLeft() : String { if( r.m == null ) throw "No string matched"; return r.s.substr(0,r.m.index); } public function matchedRight() : String { if( r.m == null ) throw "No string matched"; var sz = r.m.index+r.m[0].length; return r.s.substr(sz,r.s.length-sz); } public function matchedPos() : { pos : Int, len : Int } { if( r.m == null ) throw "No string matched"; return { pos : r.m.index, len : r.m[0].length }; } public function matchSub( s : String, pos : Int, len : Int = -1):Bool { return if (r.global) { r.lastIndex = pos; r.m = r.exec(len < 0 ? s : s.substr(0, pos + len)); var b = r.m != null; if (b) { r.s = s; } b; } else { // TODO: check some ^/$ related corner cases var b = match( len < 0 ? s.substr(pos) : s.substr(pos,len) ); if (b) { r.s = s; r.m.index += pos; } b; } } public function split( s : String ) : Array { // we can't use directly s.split because it's ignoring the 'g' flag var d = "#__delim__#"; return untyped s.replace(r,d).split(d); } public inline function replace( s : String, by : String ) : String { return untyped s.replace(r,by); } public function map( s : String, f : EReg -> String ) : String { var offset = 0; var buf = new StringBuf(); do { if (offset >= s.length) break; else if (!matchSub(s, offset)) { buf.add(s.substr(offset)); break; } var p = matchedPos(); buf.add(s.substr(offset, p.pos - offset)); buf.add(f(this)); if (p.len == 0) { buf.add(s.substr(p.pos, 1)); offset = p.pos + 1; } else offset = p.pos + p.len; } while (r.global); if (!r.global && offset > 0 && offset < s.length) buf.add(s.substr(offset)); return buf.toString(); } } @:native("RegExp") private extern class HaxeRegExp extends js.RegExp { var m:js.RegExp.RegExpMatch; var s:String; } haxe_3.4.4.orig/std/js/_std/HxOverrides.hx0000664000175000017500000001004413166552354020355 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:noDoc class HxOverrides { static function dateStr( date :Date ) : String { var m = date.getMonth() + 1; var d = date.getDate(); var h = date.getHours(); var mi = date.getMinutes(); var s = date.getSeconds(); return date.getFullYear() +"-"+(if( m < 10 ) "0"+m else ""+m) +"-"+(if( d < 10 ) "0"+d else ""+d) +" "+(if( h < 10 ) "0"+h else ""+h) +":"+(if( mi < 10 ) "0"+mi else ""+mi) +":"+(if( s < 10 ) "0"+s else ""+s); } static function strDate( s : String ) : Date { switch( s.length ) { case 8: // hh:mm:ss var k = s.split(":"); var d : Date = untyped __new__(Date); untyped d["setTime"](0); untyped d["setUTCHours"](k[0]); untyped d["setUTCMinutes"](k[1]); untyped d["setUTCSeconds"](k[2]); return d; case 10: // YYYY-MM-DD var k = s.split("-"); return new Date(cast k[0],cast untyped k[1] - 1,cast k[2],0,0,0); case 19: // YYYY-MM-DD hh:mm:ss var k = s.split(" "); var y = k[0].split("-"); var t = k[1].split(":"); return new Date(cast y[0],cast untyped y[1] - 1,cast y[2],cast t[0],cast t[1],cast t[2]); default: throw "Invalid date format : " + s; } } static function cca( s : String, index : Int ) : Null { var x = (cast s).charCodeAt(index); if( x != x ) // fast isNaN return js.Lib.undefined; // isNaN will still return true return x; } static function substr( s : String, pos : Int, ?len : Int ) : String { if (len == null) { len = s.length; } else if (len < 0) { if (pos == 0) len = s.length + len; else return ""; } #if (js_es < 5) if (pos < 0) { pos = s.length + pos; if (pos < 0) pos = 0; } #end return (untyped s).substr(pos, len); } static function indexOf( a : Array, obj : T, i : Int) { var len = a.length; if (i < 0) { i += len; if (i < 0) i = 0; } while (i < len) { if (untyped __js__("a[i] === obj")) return i; i++; } return -1; } static function lastIndexOf( a : Array, obj : T, i : Int) { var len = a.length; if (i >= len) i = len - 1; else if (i < 0) i += len; while (i >= 0) { if (untyped __js__("a[i] === obj")) return i; i--; } return -1; } static function remove( a : Array, obj : T ) { var i = a.indexOf(obj); if( i == -1 ) return false; a.splice(i,1); return true; } static function iter( a : Array ) : Iterator untyped { return { cur : 0, arr : a, hasNext : function() { return __this__.cur < __this__.arr.length; }, next : function() { return __this__.arr[__this__.cur++]; } }; } static function __init__() untyped { #if (js_es < 5) __feature__('HxOverrides.indexOf', if( Array.prototype.indexOf ) __js__("HxOverrides").indexOf = function(a,o,i) return Array.prototype.indexOf.call(a, o, i)); __feature__('HxOverrides.lastIndexOf', if( Array.prototype.lastIndexOf ) __js__("HxOverrides").lastIndexOf = function(a,o,i) return Array.prototype.lastIndexOf.call(a, o, i)); #end } } haxe_3.4.4.orig/std/js/_std/Math.hx0000664000175000017500000000612213166552354017006 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package; // Can't enable @:coreApi because some fields are now inline getters // @:coreApi @:keepInit extern class Math { static var PI(default,null) : Float; static var NEGATIVE_INFINITY(get, null) : Float; @:pure private static inline function get_NEGATIVE_INFINITY () : Float { return -(untyped __js__("Infinity")); } static var POSITIVE_INFINITY(get,null) : Float; @:pure private static inline function get_POSITIVE_INFINITY () : Float { return (untyped __js__("Infinity")); } static var NaN(get, null) : Float; @:pure private static inline function get_NaN () : Float { return (untyped __js__("NaN")); } @:pure static function abs(v:Float):Float; @:pure static function acos(v:Float):Float; @:pure static function asin(v:Float):Float; @:pure static function atan(v:Float):Float; @:pure static function atan2(y:Float, x:Float):Float; @:pure static function ceil(v:Float):Int; @:pure static function cos(v:Float):Float; @:pure static function exp(v:Float):Float; @:pure static function floor(v:Float):Int; @:pure static function log(v:Float):Float; @:pure static function max(a:Float, b:Float):Float; @:pure static function min(a:Float, b:Float):Float; @:pure static function pow(v:Float, exp:Float):Float; static function random() : Float; @:pure static function round(v:Float):Int; @:pure static function sin(v:Float):Float; @:pure static function sqrt(v:Float):Float; @:pure static function tan(v:Float):Float; @:pure static inline function ffloor( v : Float ) : Float { return floor(v); } @:pure static inline function fceil( v : Float ) : Float { return ceil(v); } @:pure static inline function fround( v : Float ) : Float { return round(v); } @:pure static inline function isFinite( f : Float ) : Bool { return (untyped __js__("isFinite"))(f); } @:pure static inline function isNaN( f : Float ) : Bool { return (untyped __js__("isNaN"))(f); } static function __init__() : Void { untyped __feature__("Type.resolveClass", $hxClasses["Math"] = Math); } } haxe_3.4.4.orig/std/js/_std/Reflect.hx0000664000175000017500000001004613166552354017501 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi class Reflect { @:pure public inline static function hasField( o : Dynamic, field : String ) : Bool { return untyped __js__('Object').prototype.hasOwnProperty.call(o, field); } public static function field( o : Dynamic, field : String ) : Dynamic { try return untyped o[field] catch( e : Dynamic ) return null; } public inline static function setField( o : Dynamic, field : String, value : Dynamic ) : Void untyped { o[field] = value; } public static function getProperty( o : Dynamic, field : String ) : Dynamic untyped { var tmp; return if( o == null ) __define_feature__("Reflect.getProperty",null) else if( o.__properties__ && (tmp=o.__properties__["get_"+field]) ) o[tmp]() else o[field]; } public static function setProperty( o : Dynamic, field : String, value : Dynamic ) : Void untyped { var tmp; if( o.__properties__ && (tmp=o.__properties__["set_"+field]) ) o[tmp](value) else o[field] = __define_feature__("Reflect.setProperty",value); } public inline static function callMethod( o : Dynamic, func : haxe.Constraints.Function, args : Array ) : Dynamic untyped { return func.apply(o,args); } public static function fields( o : Dynamic ) : Array { var a = []; if (o != null) untyped { var hasOwnProperty = __js__('Object').prototype.hasOwnProperty; __js__("for( var f in o ) {"); if( f != "__id__" && f != "hx__closures__" && hasOwnProperty.call(o, f) ) a.push(f); __js__("}"); } return a; } public static function isFunction( f : Dynamic ) : Bool untyped { return __js__("typeof(f)") == "function" && !(js.Boot.isClass(f) || js.Boot.isEnum(f)); } public static function compare( a : T, b : T ) : Int { return ( a == b ) ? 0 : (((cast a) > (cast b)) ? 1 : -1); } public static function compareMethods( f1 : Dynamic, f2 : Dynamic ) : Bool { if( f1 == f2 ) return true; if( !isFunction(f1) || !isFunction(f2) ) return false; return f1.scope == f2.scope && f1.method == f2.method && f1.method != null; } public static function isObject( v : Dynamic ) : Bool untyped { if( v == null ) return false; var t = __js__("typeof(v)"); return (t == "string" || (t == "object" && v.__enum__ == null)) || (t == "function" && (js.Boot.isClass(v) || js.Boot.isEnum(v)) != null); } public static function isEnumValue( v : Dynamic ) : Bool { return v != null && v.__enum__ != null; } public static function deleteField( o : Dynamic, field : String ) : Bool untyped { if( !hasField(o,field) ) return false; __js__("delete")(o[field]); return true; } public static function copy( o : T ) : T { var o2 : Dynamic = {}; for( f in Reflect.fields(o) ) Reflect.setField(o2,f,Reflect.field(o,f)); return o2; } @:overload(function( f : Array -> Void ) : Dynamic {}) public static function makeVarArgs( f : Array -> Dynamic ) : Dynamic { return function() { var a = untyped Array.prototype.slice.call(__js__("arguments")); return f(a); }; } } haxe_3.4.4.orig/std/js/_std/Std.hx0000664000175000017500000001045213166552354016650 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ import js.Boot; @:keepInit @:coreApi class Std { public static inline function is( v : Dynamic, t : Dynamic ) : Bool { return untyped js.Boot.__instanceof(v,t); } public static inline function instance( value : T, c : Class ) : S { return untyped __instanceof__(value, c) ? cast value : null; } @:pure public static function string( s : Dynamic ) : String { return untyped js.Boot.__string_rec(s,""); } public static inline function int( x : Float ) : Int { return (cast x) | 0; } @:pure public static function parseInt( x : String ) : Null { var v = untyped __js__("parseInt")(x, 10); // parse again if hexadecimal if( v == 0 && (x.charCodeAt(1) == 'x'.code || x.charCodeAt(1) == 'X'.code) ) v = untyped __js__("parseInt")(x); if( untyped __js__("isNaN")(v) ) return null; return cast v; } public static inline function parseFloat( x : String ) : Float { return untyped __js__("parseFloat")(x); } public static function random( x : Int ) : Int { return x <= 0 ? 0 : Math.floor(Math.random()*x); } static function __init__() : Void untyped { __feature__("js.Boot.getClass",String.prototype.__class__ = __feature__("Type.resolveClass",$hxClasses["String"] = String,String)); __feature__("js.Boot.isClass",String.__name__ = __feature__("Type.getClassName",["String"],true)); __feature__("Type.resolveClass",$hxClasses["Array"] = Array); __feature__("js.Boot.isClass",Array.__name__ = __feature__("Type.getClassName",["Array"],true)); __feature__("Date.*", { __feature__("js.Boot.getClass",__js__('Date').prototype.__class__ = __feature__("Type.resolveClass",$hxClasses["Date"] = __js__('Date'),__js__('Date'))); __feature__("js.Boot.isClass",__js__('Date').__name__ = ["Date"]); }); __feature__("Int.*",{ var Int = __feature__("Type.resolveClass", $hxClasses["Int"] = { __name__ : ["Int"] }, { __name__ : ["Int"] }); }); __feature__("Dynamic.*",{ var Dynamic = __feature__("Type.resolveClass", $hxClasses["Dynamic"] = { __name__ : ["Dynamic"] }, { __name__ : ["Dynamic"] }); }); __feature__("Float.*",{ var Float = __feature__("Type.resolveClass", $hxClasses["Float"] = __js__("Number"), __js__("Number")); Float.__name__ = ["Float"]; }); __feature__("Bool.*",{ var Bool = __feature__("Type.resolveEnum",$hxClasses["Bool"] = __js__("Boolean"), __js__("Boolean")); Bool.__ename__ = ["Bool"]; }); __feature__("Class.*",{ var Class = __feature__("Type.resolveClass", $hxClasses["Class"] = { __name__ : ["Class"] }, { __name__ : ["Class"] }); }); __feature__("Enum.*",{ var Enum = {}; }); __feature__("Void.*",{ var Void = __feature__("Type.resolveEnum", $hxClasses["Void"] = { __ename__ : ["Void"] }, { __ename__ : ["Void"] }); }); #if (js_es < 5) __feature__("Array.map", if( Array.prototype.map == null ) Array.prototype.map = function(f) { var a = []; for( i in 0...__this__.length ) a[i] = f(__this__[i]); return a; } ); __feature__("Array.filter", if( Array.prototype.filter == null ) Array.prototype.filter = function(f) { var a = []; for( i in 0...__this__.length ) { var e = __this__[i]; if( f(e) ) a.push(e); } return a; } ); #end } } haxe_3.4.4.orig/std/js/_std/String.hx0000664000175000017500000000354613166552354017372 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ @:coreApi extern class String { var length(default,null) : Int; function new(string:String) : Void; function toUpperCase() : String; function toLowerCase() : String; function charAt( index : Int) : String; function indexOf( str : String, ?startIndex : Int ) : Int; function lastIndexOf( str : String, ?startIndex : Int ) : Int; function split( delimiter : String ) : Array; function toString() : String; function substring( startIndex : Int, ?endIndex : Int ) : String; inline function charCodeAt( index : Int) : Null { return untyped HxOverrides.cca(this, index); } inline function substr( pos : Int, ?len : Int ) : String { return untyped HxOverrides.substr(this, pos, len); } static function fromCharCode( code : Int ) : String; } haxe_3.4.4.orig/std/js/_std/Type.hx0000664000175000017500000001571713166552354017050 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ enum ValueType { TNull; TInt; TFloat; TBool; TObject; TFunction; TClass( c : Class ); TEnum( e : Enum ); TUnknown; } @:coreApi class Type { public static inline function getClass( o : T ) : Class { return if (o == null) null else @:privateAccess js.Boot.getClass(o); } public static function getEnum( o : EnumValue ) : Enum untyped { if( o == null ) return null; return o.__enum__; } public static function getSuperClass( c : Class ) : Class untyped { return c.__super__; } public static function getClassName( c : Class ) : String { var a : Array = untyped c.__name__; if (a == null) return null; return a.join("."); } public static function getEnumName( e : Enum ) : String { var a : Array = untyped e.__ename__; return a.join("."); } public static function resolveClass( name : String ) : Class untyped { var cl : Class = $hxClasses[name]; // ensure that this is a class if( cl == null || !js.Boot.isClass(cl) ) return null; return cl; } public static function resolveEnum( name : String ) : Enum untyped { var e : Dynamic = $hxClasses[name]; // ensure that this is an enum if( e == null || !js.Boot.isEnum(e) ) return null; return e; } public static function createInstance( cl : Class, args : Array ) : T untyped { switch( args.length ) { case 0: return __new__(cl); case 1: return __new__(cl,args[0]); case 2: return __new__(cl,args[0],args[1]); case 3: return __new__(cl,args[0],args[1],args[2]); case 4: return __new__(cl,args[0],args[1],args[2],args[3]); case 5: return __new__(cl,args[0],args[1],args[2],args[3],args[4]); case 6: return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5]); case 7: return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6]); case 8: return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]); case 9: return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]); case 10: return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]); case 11: return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]); case 12: return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11]); case 13: return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12]); case 14: return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13]); default: throw "Too many arguments"; } } public static function createEmptyInstance( cl : Class ) : T untyped { __js__("function empty() {}; empty.prototype = cl.prototype"); return __js__("new empty()"); } public static function createEnum( e : Enum, constr : String, ?params : Array ) : T { var f:Dynamic = Reflect.field(e,constr); if( f == null ) throw "No such constructor "+constr; if( Reflect.isFunction(f) ) { if( params == null ) throw "Constructor "+constr+" need parameters"; return Reflect.callMethod(e,f,params); } if( params != null && params.length != 0 ) throw "Constructor "+constr+" does not need parameters"; return f; } public static function createEnumIndex( e : Enum, index : Int, ?params : Array ) : T { var c : String = (untyped e.__constructs__)[index]; if( c == null ) throw index+" is not a valid enum constructor index"; return createEnum(e,c,params); } public static function getInstanceFields( c : Class ) : Array { var a = []; untyped __js__("for(var i in c.prototype) a.push(i)"); a.remove("__class__"); a.remove("__properties__"); return a; } public static function getClassFields( c : Class ) : Array { var a = Reflect.fields(c); a.remove("__name__"); a.remove("__interfaces__"); a.remove("__properties__"); a.remove("__super__"); a.remove("__meta__"); a.remove("prototype"); return a; } public static inline function getEnumConstructs( e : Enum ) : Array { return ((cast e).__constructs__ : Array).copy(); } public static function typeof( v : Dynamic ) : ValueType untyped { switch( __js__("typeof")(v) ) { case "boolean": return TBool; case "string": return TClass(String); case "number": // this should handle all cases : NaN, +/-Inf and Floats outside range if( Math.ceil(v) == v%2147483648.0 ) return TInt; return TFloat; case "object": if( v == null ) return TNull; var e = v.__enum__; if( e != null ) return TEnum(e); var c = js.Boot.getClass(v); if( c != null ) return TClass(c); return TObject; case "function": if( js.Boot.isClass(v) || js.Boot.isEnum(v) ) return TObject; return TFunction; case "undefined": return TNull; default: return TUnknown; } } public static function enumEq( a : T, b : T ) : Bool untyped { if( a == b ) return true; try { if( a[0] != b[0] ) return false; for( i in 2...a.length ) if( !enumEq(a[i],b[i]) ) return false; var e = a.__enum__; if( e != b.__enum__ || e == null ) return false; } catch( e : Dynamic ) { return false; } return true; } public inline static function enumConstructor( e : EnumValue ) : String { return untyped e[0]; } public inline static function enumParameters( e : EnumValue ) : Array { return untyped e.slice(2); } public inline static function enumIndex( e : EnumValue ) : Int { return untyped e[1]; } public inline static function allEnums( e : Enum ) : Array { return untyped __define_feature__("Type.allEnums", e.__empty_constructs__); } } haxe_3.4.4.orig/std/js/_std/haxe/Json.hx0000664000175000017500000000330313166552354017751 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe; @:coreApi #if (!haxeJSON && !old_browser) @:native("JSON") extern #end class Json { #if haxeJSON inline #end public static function parse( text : String ) : Dynamic { return haxe.format.JsonParser.parse(text); } #if haxeJSON inline #end public static function stringify( value : Dynamic, ?replacer:Dynamic -> Dynamic -> Dynamic, ?space:String ) : String { return haxe.format.JsonPrinter.print(value, replacer, space); } #if (!haxeJSON && old_browser) static function __init__():Void untyped { if( __js__('typeof(JSON)') != 'undefined' ) Json = __js__('JSON'); } #end } haxe_3.4.4.orig/std/js/_std/haxe/ds/IntMap.hx0000664000175000017500000000453113166552354020642 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:coreApi class IntMap implements haxe.Constraints.IMap { private var h : Dynamic; public inline function new() : Void { h = {}; } public inline function set( key : Int, value : T ) : Void { untyped h[key] = value; } public inline function get( key : Int ) : Null { return untyped h[key]; } public inline function exists( key : Int ) : Bool { return untyped h.hasOwnProperty(key); } public function remove( key : Int ) : Bool { if( untyped !h.hasOwnProperty(key) ) return false; untyped __js__("delete")(h[key]); return true; } public function keys() : Iterator { var a = []; untyped __js__("for( var key in {0} ) {1}", h, if( h.hasOwnProperty(key) ) a.push(key|0)); return a.iterator(); } public function iterator() : Iterator { return untyped { ref : h, it : keys(), hasNext : function() { return __this__.it.hasNext(); }, next : function() { var i = __this__.it.next(); return __this__.ref[i]; } }; } public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(i); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } } haxe_3.4.4.orig/std/js/_std/haxe/ds/ObjectMap.hx0000664000175000017500000000532413166552354021317 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of h 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 h permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; @:coreApi class ObjectMap implements haxe.Constraints.IMap { static var count = 0; static inline function assignId(obj: { } ):Int { return untyped obj.__id__ = ++count; } static inline function getId(obj: { } ):Int { return untyped obj.__id__; } var h : { }; public function new() : Void { h = { __keys__: {} }; } public function set(key:K, value:V):Void untyped { var id : Int = getId(key) || assignId(key); h[id] = value; h.__keys__[id] = key; } public inline function get(key:K):Null { return untyped h[getId(key)]; } public inline function exists(key:K):Bool { return untyped h.__keys__[getId(key)] != null; } public function remove( key : K ) : Bool { var id = getId(key); if ( untyped h.__keys__[id] == null ) return false; untyped __js__("delete")(h[id]); untyped __js__("delete")(h.__keys__[id]); return true; } public function keys() : Iterator { var a = []; untyped { __js__("for( var key in this.h.__keys__ ) {"); if( h.hasOwnProperty(key) ) a.push(h.__keys__[key]); __js__("}"); } return a.iterator(); } public function iterator() : Iterator { return untyped { ref : h, it : keys(), hasNext : function() { return __this__.it.hasNext(); }, next : function() { var i = __this__.it.next(); return __this__.ref[getId(i)]; } }; } public function toString() : String { var s = new StringBuf(); s.add("{"); var it = keys(); for( i in it ) { s.add(Std.string(i)); s.add(" => "); s.add(Std.string(get(i))); if( it.hasNext() ) s.add(", "); } s.add("}"); return s.toString(); } }haxe_3.4.4.orig/std/js/_std/haxe/ds/StringMap.hx0000664000175000017500000000750513166552354021362 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.ds; private class StringMapIterator { var map : StringMap; var keys : Array; var index : Int; var count : Int; public inline function new(map:StringMap, keys:Array) { this.map = map; this.keys = keys; this.index = 0; this.count = keys.length; } public inline function hasNext() { return index < count; } public inline function next() { return map.get(keys[index++]); } } @:coreApi class StringMap implements haxe.Constraints.IMap { private var h : Dynamic; private var rh : Dynamic; public inline function new() : Void { h = {}; } inline function isReserved(key:String) : Bool { return untyped __js__("__map_reserved")[key] != null; } public inline function set( key : String, value : T ) : Void { if( isReserved(key) ) setReserved(key, value); else h[cast key] = value; } public inline function get( key : String ) : Null { if( isReserved(key) ) return getReserved(key); return h[cast key]; } public inline function exists( key : String ) : Bool { if( isReserved(key) ) return existsReserved(key); return h.hasOwnProperty(key); } function setReserved( key : String, value : T ) : Void { if( rh == null ) rh = {}; rh[cast "$"+key] = value; } function getReserved( key : String ) : Null { return rh == null ? null : rh[cast "$"+key]; } function existsReserved( key : String ) : Bool { if( rh == null ) return false; return untyped rh.hasOwnProperty("$"+key); } public function remove( key : String ) : Bool { if( isReserved(key) ) { key = "$" + key; if( rh == null || !rh.hasOwnProperty(key) ) return false; untyped __js__("delete")(rh[key]); return true; } else { if( !h.hasOwnProperty(key) ) return false; untyped __js__("delete")(h[key]); return true; } } public function keys() : Iterator { return arrayKeys().iterator(); } function arrayKeys() : Array { var out = []; untyped { __js__("for( var key in this.h ) {"); if( h.hasOwnProperty(key) ) out.push(key); __js__("}"); } if( rh != null ) untyped { __js__("for( var key in this.rh ) {"); if( key.charCodeAt(0) == "$".code ) out.push(key.substr(1)); __js__("}"); } return out; } public inline function iterator() : Iterator { return new StringMapIterator(this, arrayKeys()); } public function toString() : String { var s = new StringBuf(); s.add("{"); var keys = arrayKeys(); for( i in 0...keys.length ) { var k = keys[i]; s.add(k); s.add(" => "); s.add(Std.string(get(k))); if( i < keys.length-1 ) s.add(", "); } s.add("}"); return s.toString(); } static function __init__() : Void { untyped __js__("var __map_reserved = {};"); } } haxe_3.4.4.orig/std/js/_std/haxe/io/ArrayBufferView.hx0000664000175000017500000000427713166552354022525 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef ArrayBufferViewData = js.html.ArrayBufferView; abstract ArrayBufferView(ArrayBufferViewData) { public static var EMULATED(get,never) : Bool; static inline function get_EMULATED() { #if nodejs return false; #else return (cast js.html.ArrayBuffer) == js.html.compat.ArrayBuffer; #end } public var buffer(get,never) : haxe.io.Bytes; public var byteOffset(get, never) : Int; public var byteLength(get, never) : Int; public inline function new( size : Int ) { this = new js.html.Uint8Array(size); } inline function get_byteOffset() return this.byteOffset; inline function get_byteLength() return this.byteLength; inline function get_buffer() : haxe.io.Bytes { return haxe.io.Bytes.ofData(this.buffer); } public inline function sub( begin : Int, ?length : Int ) { return fromData(new js.html.Uint8Array(this.buffer.slice(begin, length == null ? null : begin+length))); } public inline function getData() : ArrayBufferViewData { return this; } public static inline function fromData( a : ArrayBufferViewData ) : ArrayBufferView { return cast a; } }haxe_3.4.4.orig/std/js/_std/haxe/io/Bytes.hx0000664000175000017500000001500013166552354020532 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; #if !nodejs import js.html.compat.Uint8Array; import js.html.compat.DataView; #end @:coreApi class Bytes { public var length(default,null) : Int; var b : js.html.Uint8Array; var data : js.html.DataView; function new(data:BytesData) { this.length = data.byteLength; this.b = new js.html.Uint8Array(data); untyped { b.bufferValue = data; // some impl does not return the same instance in .buffer data.hxBytes = this; data.bytes = this.b; } } public inline function get( pos : Int ) : Int { return b[pos]; } public inline function set( pos : Int, v : Int ) : Void { b[pos] = v & 0xFF; // the &0xFF is necessary for js.html.compat support } public function blit( pos : Int, src : Bytes, srcpos : Int, len : Int ) : Void { if( pos < 0 || srcpos < 0 || len < 0 || pos + len > length || srcpos + len > src.length ) throw Error.OutsideBounds; if( srcpos == 0 && len == src.b.byteLength ) b.set(src.b,pos); else b.set(src.b.subarray(srcpos,srcpos+len),pos); } public function fill( pos : Int, len : Int, value : Int ) : Void { for( i in 0...len ) set(pos++, value); } public function sub( pos : Int, len : Int ) : Bytes { if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds; return new Bytes(b.buffer.slice(pos+b.byteOffset,pos+b.byteOffset+len)); } public function compare( other : Bytes ) : Int { var b1 = b; var b2 = other.b; var len = (length < other.length) ? length : other.length; for( i in 0...len ) if( b1[i] != b2[i] ) return b1[i] - b2[i]; return length - other.length; } inline function initData() : Void { if( data == null ) data = new js.html.DataView(b.buffer, b.byteOffset, b.byteLength); } public function getDouble( pos : Int ) : Float { initData(); return data.getFloat64(pos, true); } public function getFloat( pos : Int ) : Float { initData(); return data.getFloat32(pos, true); } public function setDouble( pos : Int, v : Float ) : Void { initData(); data.setFloat64(pos, v, true); } public function setFloat( pos : Int, v : Float ) : Void { initData(); data.setFloat32(pos, v, true); } public function getUInt16( pos : Int ) : Int { initData(); return data.getUint16(pos, true); } public function setUInt16( pos : Int, v : Int ) : Void { initData(); data.setUint16(pos, v, true); } public function getInt32( pos : Int ) : Int { initData(); return data.getInt32(pos, true); } public function setInt32( pos : Int, v : Int ) : Void { initData(); data.setInt32(pos, v, true); } public function getInt64( pos : Int ) : haxe.Int64 { return Int64.make(getInt32(pos + 4),getInt32(pos)); } public function setInt64( pos : Int, v : haxe.Int64 ) : Void { setInt32(pos, v.low); setInt32(pos + 4, v.high); } public function getString( pos : Int, len : Int ) : String { if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds; var s = ""; var b = b; var fcc = String.fromCharCode; var i = pos; var max = pos+len; // utf8-decode and utf16-encode while( i < max ) { var c = b[i++]; if( c < 0x80 ) { if( c == 0 ) break; s += fcc(c); } else if( c < 0xE0 ) s += fcc( ((c & 0x3F) << 6) | (b[i++] & 0x7F) ); else if( c < 0xF0 ) { var c2 = b[i++]; s += fcc( ((c & 0x1F) << 12) | ((c2 & 0x7F) << 6) | (b[i++] & 0x7F) ); } else { var c2 = b[i++]; var c3 = b[i++]; var u = ((c & 0x0F) << 18) | ((c2 & 0x7F) << 12) | ((c3 & 0x7F) << 6) | (b[i++] & 0x7F); // surrogate pair s += fcc( (u >> 10) + 0xD7C0 ); s += fcc( (u & 0x3FF) | 0xDC00 ); } } return s; } @:deprecated("readString is deprecated, use getString instead") @:noCompletion public inline function readString(pos:Int, len:Int):String { return getString(pos, len); } public function toString() : String { return getString(0,length); } public function toHex() : String { var s = new StringBuf(); var chars = []; var str = "0123456789abcdef"; for( i in 0...str.length ) chars.push(str.charCodeAt(i)); for( i in 0...length ) { var c = get(i); s.addChar(chars[c >> 4]); s.addChar(chars[c & 15]); } return s.toString(); } public inline function getData() : BytesData { return untyped b.bufferValue; } public static inline function alloc( length : Int ) : Bytes { return new Bytes(new BytesData(length)); } public static function ofString( s : String ) : Bytes { var a = new Array(); // utf16-decode and utf8-encode var i = 0; while( i < s.length ) { var c : Int = StringTools.fastCodeAt(s,i++); // surrogate pair if( 0xD800 <= c && c <= 0xDBFF ) c = (c - 0xD7C0 << 10) | (StringTools.fastCodeAt(s,i++) & 0x3FF); if( c <= 0x7F ) a.push(c); else if( c <= 0x7FF ) { a.push( 0xC0 | (c >> 6) ); a.push( 0x80 | (c & 63) ); } else if( c <= 0xFFFF ) { a.push( 0xE0 | (c >> 12) ); a.push( 0x80 | ((c >> 6) & 63) ); a.push( 0x80 | (c & 63) ); } else { a.push( 0xF0 | (c >> 18) ); a.push( 0x80 | ((c >> 12) & 63) ); a.push( 0x80 | ((c >> 6) & 63) ); a.push( 0x80 | (c & 63) ); } } return new Bytes(new js.html.Uint8Array(a).buffer); } public static function ofData( b : BytesData ) : Bytes { var hb = untyped b.hxBytes; if( hb != null ) return hb; return new Bytes(b); } public inline static function fastGet( b : BytesData, pos : Int ) : Int { // this requires that we have wrapped it with haxe.io.Bytes beforehand return untyped b.bytes[pos]; } } haxe_3.4.4.orig/std/js/_std/haxe/io/Float32Array.hx0000664000175000017500000000575513166552354021675 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; #if !nodejs import js.html.compat.Float32Array; #end typedef Float32ArrayData = js.html.Float32Array; @:coreApi abstract Float32Array(Float32ArrayData) { public static inline var BYTES_PER_ELEMENT = 4; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) : Void { this = new Float32ArrayData(elements); } inline function get_length() : Int { return this.length; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) : Float { return this[index]; } @:arrayAccess public inline function set( index : Int, value : Float ) : Float { return this[index] = value; } public inline function sub( begin : Int, ?length : Int ) : Float32Array { return fromData(this.subarray(begin, length == null ? this.length : begin+length)); } public inline function subarray( ?begin : Int, ?end : Int ) : Float32Array { return fromData(this.subarray(begin, end)); } public inline function getData() : Float32ArrayData { return this; } public inline static function fromData( d : Float32ArrayData ) : Float32Array { return cast d; } public static function fromArray( a : Array, pos : Int = 0, ?length : Int ) : Float32Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; if( pos == 0 && length == a.length ) return fromData(new Float32ArrayData(a)); var i = new Float32Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos : Int = 0, ?length : Int ) : Float32Array { if( length == null ) length = (bytes.length - bytePos) >> 2; return fromData(new Float32ArrayData(bytes.getData(), bytePos, length)); } } haxe_3.4.4.orig/std/js/_std/haxe/io/Float64Array.hx0000664000175000017500000000575513166552354021702 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; #if !nodejs import js.html.compat.Float64Array; #end typedef Float64ArrayData = js.html.Float64Array; @:coreApi abstract Float64Array(Float64ArrayData) { public static inline var BYTES_PER_ELEMENT = 4; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) : Void { this = new Float64ArrayData(elements); } inline function get_length() : Int { return this.length; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) : Float { return this[index]; } @:arrayAccess public inline function set( index : Int, value : Float ) : Float { return this[index] = value; } public inline function sub( begin : Int, ?length : Int ) : Float64Array { return fromData(this.subarray(begin, length == null ? this.length : begin+length)); } public inline function subarray( ?begin : Int, ?end : Int ) : Float64Array { return fromData(this.subarray(begin, end)); } public inline function getData() : Float64ArrayData { return this; } public static inline function fromData( d : Float64ArrayData ) : Float64Array { return cast d; } public static function fromArray( a : Array, pos : Int = 0, ?length : Int ) : Float64Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; if( pos == 0 && length == a.length ) return fromData(new Float64ArrayData(a)); var i = new Float64Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos : Int = 0, ?length : Int ) : Float64Array { if( length == null ) length = (bytes.length - bytePos) >> 3; return fromData(new Float64ArrayData(bytes.getData(), bytePos, length)); } } haxe_3.4.4.orig/std/js/_std/haxe/io/Int32Array.hx0000664000175000017500000000570013166552354021350 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef Int32ArrayData = js.html.Int32Array; @:coreApi abstract Int32Array(Int32ArrayData) { public static inline var BYTES_PER_ELEMENT = 1; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) { this = new Int32ArrayData(elements * BYTES_PER_ELEMENT); } inline function get_length() : Int { return this.length; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) : Int { return this[index]; } @:arrayAccess public inline function set( index : Int, value : Int ) : Int { return this[index] = value | 0; // necessary for html compat } public inline function sub( begin : Int, ?length : Int ) : Int32Array { return fromData(this.subarray(begin, length == null ? this.length : begin+length)); } public inline function subarray( ?begin : Int, ?end : Int ) : Int32Array { return fromData(this.subarray(begin, end)); } public inline function getData() : Int32ArrayData { return this; } public static inline function fromData( d : Int32ArrayData ) : Int32Array { return cast d; } public static function fromArray( a : Array, pos : Int = 0, ?length : Int ) : Int32Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; if( pos == 0 && length == a.length ) return fromData(new Int32ArrayData(a)); var i = new Int32Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos : Int = 0, ?length : Int ) : Int32Array { if( length == null ) length = (bytes.length - bytePos) >> 2; return fromData(new Int32ArrayData(bytes.getData(), bytePos, length)); } } haxe_3.4.4.orig/std/js/_std/haxe/io/UInt16Array.hx0000664000175000017500000000571013166552354021500 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef UInt16ArrayData = js.html.Uint16Array; @:coreApi abstract UInt16Array(UInt16ArrayData) { public static inline var BYTES_PER_ELEMENT = 2; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) { this = new UInt16ArrayData(elements); } inline function get_length() : Int { return this.length; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) : Int { return this[index]; } @:arrayAccess public inline function set( index : Int, value : Int ) : Int { return this[index] = value & 0xFFFF; // &0xFFFF necessary for html compat } public inline function sub( begin : Int, ?length : Int ) : UInt16Array { return fromData(this.subarray(begin, length == null ? this.length : begin+length)); } public inline function subarray( ?begin : Int, ?end : Int ) : UInt16Array { return fromData(this.subarray(begin, end)); } public inline function getData() : UInt16ArrayData { return this; } public static inline function fromData( d : UInt16ArrayData ) : UInt16Array { return cast d; } public static function fromArray( a : Array, pos : Int = 0, ?length : Int ) : UInt16Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; if( pos == 0 && length == a.length ) return fromData(new UInt16ArrayData(a)); var i = new UInt16Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos : Int = 0, ?length : Int ) : UInt16Array { if( length == null ) length = (bytes.length - bytePos) >> 1; return fromData(new UInt16ArrayData(bytes.getData(), bytePos, length)); } } haxe_3.4.4.orig/std/js/_std/haxe/io/UInt32Array.hx0000664000175000017500000000567713166552354021512 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef UInt32ArrayData = js.html.Uint32Array; @:coreApi abstract UInt32Array(UInt32ArrayData) { public static inline var BYTES_PER_ELEMENT = 4; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) { this = new UInt32ArrayData(elements); } inline function get_length() : Int { return this.length; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) : UInt { return this[index]; } @:arrayAccess public inline function set( index : Int, value : UInt ) : UInt { return this[index] = value | 0; // necessary for html compat } public inline function sub( begin : Int, ?length : Int ) : UInt32Array { return fromData(this.subarray(begin, length == null ? this.length : begin+length)); } public inline function subarray( ?begin : Int, ?end : Int ) : UInt32Array { return fromData(this.subarray(begin, end)); } public inline function getData() : UInt32ArrayData { return this; } public static inline function fromData( d : UInt32ArrayData ) : UInt32Array { return cast d; } public static function fromArray( a : Array, pos : Int = 0, ?length : Int ) : UInt32Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; if( pos == 0 && length == a.length ) return fromData(new UInt32ArrayData(a)); var i = new UInt32Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos : Int = 0, ?length : Int ) : UInt32Array { if( length == null ) length = (bytes.length - bytePos) >> 2; return fromData(new UInt32ArrayData(bytes.getData(), bytePos, length)); } } haxe_3.4.4.orig/std/js/_std/haxe/io/UInt8Array.hx0000664000175000017500000000565613166552354021432 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package haxe.io; typedef UInt8ArrayData = js.html.Uint8Array; @:coreApi abstract UInt8Array(UInt8ArrayData) { public static inline var BYTES_PER_ELEMENT = 1; public var length(get,never) : Int; public var view(get,never) : ArrayBufferView; public inline function new( elements : Int ) { this = new UInt8ArrayData(elements); } inline function get_length() : Int { return this.length; } public inline function get_view() : ArrayBufferView { return ArrayBufferView.fromData(this); } @:arrayAccess public inline function get( index : Int ) : Int { return this[index]; } @:arrayAccess public inline function set( index : Int, value : Int ) : Int { return this[index] = value & 0xFF; // &0xFF necessary for html compat } public inline function sub( begin : Int, ?length : Int ) : UInt8Array { return fromData(this.subarray(begin, length == null ? this.length : begin+length)); } public inline function subarray( ?begin : Int, ?end : Int ) : UInt8Array { return fromData(this.subarray(begin, end)); } public inline function getData() : UInt8ArrayData { return this; } public static inline function fromData( d : UInt8ArrayData ) : UInt8Array { return cast d; } public static function fromArray( a : Array, pos : Int = 0, ?length : Int ) : UInt8Array { if( length == null ) length = a.length - pos; if( pos < 0 || length < 0 || pos + length > a.length ) throw Error.OutsideBounds; if( pos == 0 && length == a.length ) return fromData(new UInt8ArrayData(a)); var i = new UInt8Array(a.length); for( idx in 0...length ) i[idx] = a[idx + pos]; return i; } public static function fromBytes( bytes : haxe.io.Bytes, bytePos : Int = 0, ?length : Int ) : UInt8Array { if( length == null ) length = bytes.length - bytePos; return fromData(new UInt8ArrayData(bytes.getData(), bytePos, length)); } } haxe_3.4.4.orig/std/js/html/AlignSetting.hx0000664000175000017500000000251513166552354020522 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\VTTCue.webidl. Do not edit! package js.html; @:enum abstract AlignSetting(String) { var START = "start"; var MIDDLE = "middle"; var END = "end"; var LEFT = "left"; var RIGHT = "right"; }haxe_3.4.4.orig/std/js/html/AnchorElement.hx0000664000175000017500000000770613166552354020665 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLAnchorElement.webidl. Do not edit! package js.html; /** The `HTMLAnchorElement` interface represents hyperlink elements and provides special properties and methods (beyond those of the regular `HTMLElement` object interface they also have available to them by inheritance) for manipulating the layout and presentation of such elements. Documentation [HTMLAnchorElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLAnchorElement") extern class AnchorElement extends Element { /** Is a `DOMString` that reflects the `target` HTML attribute, indicating where to display the linked resource. **/ var target : String; /** Is a `DOMString` indicating that the linked resource is intended to be downloaded rather than displayed in the browser. The value represent the proposed name of the file. If the name is not a valid filename of the underlying OS, browser will adapt it. The value is a URL with a scheme like `http:`, `file:`, `data:` or even `blob:` (created with `URL.createObjectURL`). **/ var download : String; var ping : String; /** Is a `DOMString` that reflects the `rel` HTML attribute, specifying the relationship of the target object to the linked object. **/ var rel : String; /** Returns a `DOMTokenList` that reflects the `rel` HTML attribute, as a list of tokens. **/ var relList(default,null) : DOMTokenList; /** Is a `DOMString` that reflects the `hreflang` HTML attribute, indicating the language of the linked resource. **/ var hreflang : String; /** Is a `DOMString` that reflects the `type` HTML attribute, indicating the MIME type of the linked resource. **/ var type : String; /** Is a `DOMString` being a synonym for the `Node.textContent` property. **/ var text : String; /** Is a `DOMString` representing a comma-separated list of coordinates. **/ var coords : String; /** Is a `DOMString` representing the character encoding of the linked resource. **/ var charset : String; /** Is a `DOMString` representing the anchor name. **/ var name : String; /** Is a `DOMString` representing that the `rev` HTML attribute, specifying the relationship of the link object to the target object. **/ var rev : String; /** Is a `DOMString` representing the shape of the active area. **/ var shape : String; var href : String; var origin(default,null) : String; var protocol : String; var username : String; var password : String; var host : String; var hostname : String; var port : String; var pathname : String; var search : String; var hash : String; }haxe_3.4.4.orig/std/js/html/Animation.hx0000664000175000017500000001003113166552354020041 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Animation.webidl. Do not edit! package js.html; /** The `Animation` interface of the Web Animations API represents a single animation player and provides playback controls and a timeline for an animation node or source. Documentation [Animation](https://developer.mozilla.org/en-US/docs/Web/API/Animation) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Animation$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Animation") extern class Animation extends EventTarget { /** Gets and sets the `String` used to identify the animation. **/ var id : String; /** Gets and sets the `AnimationEffectReadOnly` associated with this animation. This will usually be a `KeyframeEffect` object. **/ var effect(default,null) : AnimationEffectReadOnly; /** Gets or sets the `AnimationTimeline` associated with this animation. **/ var timeline(default,null) : AnimationTimeline; /** Gets or sets the scheduled time when an animation's playback should begin. **/ var startTime : Float; /** The current time value of the animation in milliseconds, whether running or paused. If the animation lacks a `AnimationTimeline`, is inactive or hasn't been played yet, its value is `null`. **/ var currentTime : Float; /** Gets or sets the playback rate of the animation. **/ var playbackRate : Float; /** Returns an enumerated value describing the playback state of an animation. **/ var playState(default,null) : AnimationPlayState; /** Returns the current ready Promise for this animation. **/ var ready(default,null) : Promise; /** Returns the current finished Promise for this animation. **/ var finished(default,null) : Promise; /** Gets and sets the event handler for the `finish` event. **/ var onfinish : haxe.Constraints.Function; /** Gets and sets the event handler for the `cancel` event. **/ var oncancel : haxe.Constraints.Function; /** @throws DOMError */ function new( ?effect : KeyframeEffectReadOnly, ?timeline : AnimationTimeline ) : Void; /** Clears all `KeyframeEffect` caused by this animation and aborts its playback. **/ function cancel() : Void; /** @throws DOMError */ /** Seeks either end of an animation, depending on whether the animation is playing or reversing. **/ function finish() : Void; /** @throws DOMError */ /** Starts or resumes playing of an animation, or begins the animation again if it previously finished. **/ function play() : Void; /** @throws DOMError */ /** Suspends playing of an animation. **/ function pause() : Void; /** @throws DOMError */ /** Reverses playback direction, stopping at the start of the animation. If the animation is finished or unplayed, it will play from end to beginning. **/ function reverse() : Void; }haxe_3.4.4.orig/std/js/html/AnimationEffectReadOnly.hx0000664000175000017500000000440413166552354022623 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AnimationEffectReadOnly.webidl. Do not edit! package js.html; /** The `AnimationEffectReadOnly` interface of the Web Animations API defines current and future animation effects like `KeyframeEffect`, which can be passed to `Animation` objects for playing, and `KeyframeEffectReadOnly` (which is used by CSS Animations and Transitions). Documentation [AnimationEffectReadOnly](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEffectReadOnly) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEffectReadOnly$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("AnimationEffectReadOnly") extern class AnimationEffectReadOnly { /** The `AnimationEffectTimingReadOnly` object associated with the animation containing all the animation's timing values. **/ var timing(default,null) : AnimationEffectTimingReadOnly; /** Returns the calculated timing properties for this Animation Effect. **/ function getComputedTiming() : ComputedTimingProperties; }haxe_3.4.4.orig/std/js/html/AnimationEffectTiming.hx0000664000175000017500000000353713166552354022343 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AnimationEffectTiming.webidl. Do not edit! package js.html; /** The `AnimationEffectTiming` interface of the Web Animations API is comprised of timing properties. It is returned by the `timing` attribute of a `KeyframeEffect`. Documentation [AnimationEffectTiming](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEffectTiming) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEffectTiming$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("AnimationEffectTiming") extern class AnimationEffectTiming extends AnimationEffectTimingReadOnly { }haxe_3.4.4.orig/std/js/html/AnimationEffectTimingProperties.hx0000664000175000017500000000307013166552354024410 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AnimationEffectReadOnly.webidl. Do not edit! package js.html; typedef AnimationEffectTimingProperties = { @:optional var delay : Float; @:optional var direction : PlaybackDirection; @:optional var duration : haxe.extern.EitherType; @:optional var easing : String; @:optional var endDelay : Float; @:optional var fill : FillMode; @:optional var iterationStart : Float; @:optional var iterations : Float; }haxe_3.4.4.orig/std/js/html/AnimationEffectTimingReadOnly.hx0000664000175000017500000000676213166552354024004 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AnimationEffectTimingReadOnly.webidl. Do not edit! package js.html; /** The `AnimationEffectTimingReadOnly` interface of the Web Animations API is comprised of timing properties. Documentation [AnimationEffectTimingReadOnly](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEffectTimingReadOnly) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEffectTimingReadOnly$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("AnimationEffectTimingReadOnly") extern class AnimationEffectTimingReadOnly { /** The number of milliseconds to delay the start of the animation. Defaults to `0`. **/ var delay(default,null) : Float; /** The number of milliseconds to delay after the end of an animation. This is primarily of use when sequencing animations based on the end time of another animation. Defaults to `0`. **/ var endDelay(default,null) : Float; /** Dictates whether the animation's effects should be reflected by the element(s) state prior to playing (`backwards`), retained after the animation has completed playing (`forwards`), or `both`. Defaults to `none`. **/ var fill(default,null) : FillMode; /** A number representing which repetition the animation begins at and its progress through it. **/ var iterationStart(default,null) : Float; /** The number of times the animation should repeat. Defaults to `1`, and can also take a value of infinity to make it repeat infinitely. **/ var iterations(default,null) : Float; /** The number of milliseconds each iteration of the animation takes to complete. Defaults to `0`. **/ var duration(default,null) : haxe.extern.EitherType; /** Whether the animation runs forwards (`normal`), backwards (`reverse`), switches direction after each iteration (`alternate`), or runs backwards and switches direction after each iteration (`alternate-reverse`). Defaults to `normal`. **/ var direction(default,null) : PlaybackDirection; /** The rate of the animation's change over time. Accepts the pre-defined values `linear`, `ease`, `ease-in`, `ease-out`, and `ease-in-out`, or a custom cubic-bezier value like `cubic-bezier(0.42, 0, 0.58, 1)`. Defaults to `linear`. **/ var easing(default,null) : String; }haxe_3.4.4.orig/std/js/html/AnimationEvent.hx0000664000175000017500000000516213166552354021054 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AnimationEvent.webidl. Do not edit! package js.html; /** The `AnimationEvent` interface represents events providing information related to animations. Documentation [AnimationEvent](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("AnimationEvent") extern class AnimationEvent extends Event { /** Is a `DOMString` containing the value of the `animation-name` CSS property associated with the transition. **/ var animationName(default,null) : String; /** Is a `float` giving the amount of time the animation has been running, in seconds, when this event fired, excluding any time the animation was paused. For an `"animationstart"` event, `elapsedTime` is `0.0` unless there was a negative value for `animation-delay`, in which case the event will be fired with `elapsedTime` containing  `(-1 * `delay`)`. **/ var elapsedTime(default,null) : Float; /** Is a `DOMString`, starting with `'::'`, containing the name of the pseudo-element the animation runs on. If the animation doesn't run on a pseudo-element but on the element, an empty string: `''``.` **/ var pseudoElement(default,null) : String; /** @throws DOMError */ function new( type : String, ?eventInitDict : AnimationEventInit ) : Void; }haxe_3.4.4.orig/std/js/html/AnimationEventInit.hx0000664000175000017500000000254613166552354021703 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AnimationEvent.webidl. Do not edit! package js.html; typedef AnimationEventInit = { > EventInit, @:optional var animationName : String; @:optional var elapsedTime : Float; @:optional var pseudoElement : String; }haxe_3.4.4.orig/std/js/html/AnimationPlayState.hx0000664000175000017500000000255013166552354021677 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Animation.webidl. Do not edit! package js.html; @:enum abstract AnimationPlayState(String) { var IDLE = "idle"; var PENDING = "pending"; var RUNNING = "running"; var PAUSED = "paused"; var FINISHED = "finished"; }haxe_3.4.4.orig/std/js/html/AnimationTimeline.hx0000664000175000017500000000420113166552354021532 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AnimationTimeline.webidl. Do not edit! package js.html; /** The `AnimationTimeline` interface of the Web Animations API represents the timeline of an animation. This interface exists to define timeline features (inherited by `DocumentTimeline` and future timeline types) and is not itself directly used by developers. Anywhere you see `AnimationTimeline`, you should use `DocumentTimeline` or any other timeline type instead. Documentation [AnimationTimeline](https://developer.mozilla.org/en-US/docs/Web/API/AnimationTimeline) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/AnimationTimeline$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("AnimationTimeline") extern class AnimationTimeline { /** Returns the time value in milliseconds for this timeline or `null` if this timeline is inactive. **/ var currentTime(default,null) : Float; }haxe_3.4.4.orig/std/js/html/AppletElement.hx0000664000175000017500000000277213166552354020676 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLAppletElement.webidl. Do not edit! package js.html; @:native("HTMLAppletElement") extern class AppletElement extends Element { var align : String; var alt : String; var archive : String; var code : String; var codeBase : String; var height : String; var hspace : Int; var name : String; var object : String; var vspace : Int; var width : String; }haxe_3.4.4.orig/std/js/html/ApplicationCache.hx0000664000175000017500000000403613166552354021321 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\OfflineResourceList.webidl. Do not edit! package js.html; @:native("ApplicationCache") extern class ApplicationCache extends EventTarget implements ArrayAccess { static inline var UNCACHED : Int = 0; static inline var IDLE : Int = 1; static inline var CHECKING : Int = 2; static inline var DOWNLOADING : Int = 3; static inline var UPDATEREADY : Int = 4; static inline var OBSOLETE : Int = 5; var status(default,null) : Int; var onchecking : haxe.Constraints.Function; var onerror : haxe.Constraints.Function; var onnoupdate : haxe.Constraints.Function; var ondownloading : haxe.Constraints.Function; var onprogress : haxe.Constraints.Function; var onupdateready : haxe.Constraints.Function; var oncached : haxe.Constraints.Function; var onobsolete : haxe.Constraints.Function; /** @throws DOMError */ function update() : Void; /** @throws DOMError */ function swapCache() : Void; }haxe_3.4.4.orig/std/js/html/AreaElement.hx0000664000175000017500000000676313166552354020325 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLAreaElement.webidl. Do not edit! package js.html; /** The `HTMLAreaElement` interface provides special properties and methods (beyond those of the regular object `HTMLElement` interface it also has available to it by inheritance) for manipulating the layout and presentation of area elements. Documentation [HTMLAreaElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLAreaElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLAreaElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLAreaElement") extern class AreaElement extends Element { /** Is a `DOMString` that reflects the `alt` HTML attribute, containing alternative text for the element. **/ var alt : String; /** Is a `DOMString` that reflects the `coords` HTML attribute, containing coordinates to define the hot-spot region. **/ var coords : String; /** Is a `DOMString` that reflects the `shape` HTML attribute, indicating the shape of the hot-spot, limited to known values. **/ var shape : String; /** Is a `DOMString` that reflects the `target` HTML attribute, indicating the browsing context in which to open the linked resource. **/ var target : String; /** Is a `DOMString` indicating that the linked resource is intended to be downloaded rather than displayed in the browser. The value represent the proposed name of the file. If the name is not a valid filename of the underlying OS, browser will adapt it. **/ var download : String; var ping : String; /** Is a `DOMString` that reflects the `rel` HTML attribute, indicating relationships of the current document to the linked resource. **/ var rel : String; /** Returns a `DOMTokenList` that reflects the `rel` HTML attribute, indicating relationships of the current document to the linked resource, as a list of tokens. **/ var relList(default,null) : DOMTokenList; /** Is a `Boolean` flag indicating if the area is inactive (`true`) or active (`false`). **/ var noHref : Bool; var href : String; var origin(default,null) : String; var protocol : String; var username : String; var password : String; var host : String; var hostname : String; var port : String; var pathname : String; var search : String; var hash : String; }haxe_3.4.4.orig/std/js/html/ArrayBuffer.hx0000664000175000017500000000302013166552354020332 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from typedarray.webidl. Do not edit! package js.html; // Explicitly include the compatibility class import js.html.compat.ArrayBuffer; @:native("ArrayBuffer") extern class ArrayBuffer { static function isView( value : Dynamic ) : Bool; var byteLength(default,null) : Int; /** @throws DOMError */ function new( length : Int ) : Void; function slice( begin : Int, ?end : Int ) : ArrayBuffer; }haxe_3.4.4.orig/std/js/html/ArrayBufferView.hx0000664000175000017500000000347013166552354021176 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from typedarray.webidl. Do not edit! package js.html; /** `ArrayBufferView` is a helper type representing any of the following JavaScript `TypedArray` types: Documentation [ArrayBufferView](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("ArrayBufferView") extern class ArrayBufferView { var buffer(default,null) : ArrayBuffer; var byteOffset(default,null) : Int; var byteLength(default,null) : Int; }haxe_3.4.4.orig/std/js/html/Attr.hx0000664000175000017500000000371213166552354017044 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Attr.webidl. Do not edit! package js.html; /** This type represents a DOM element's attribute as an object. In most DOM methods, you will probably directly retrieve the attribute as a string (e.g., `Element.getAttribute()`, but certain functions (e.g., `Element.getAttributeNode()`) or means of iterating give `Attr` types. Documentation [Attr](https://developer.mozilla.org/en-US/docs/Web/API/Attr) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Attr$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Attr") extern class Attr extends Node { var value : String; var name(default,null) : String; var specified(default,null) : Bool; var ownerElement(default,null) : Element; }haxe_3.4.4.orig/std/js/html/Audio.hx0000664000175000017500000000247313166552354017176 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from namedConstructors.webidl. Do not edit! package js.html; @:native("Audio") extern class Audio extends AudioElement { /** @throws DOMError */ function new( ?src : String ) : Void; }haxe_3.4.4.orig/std/js/html/AudioChannel.hx0000664000175000017500000000272313166552354020465 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AudioChannel.webidl. Do not edit! package js.html; @:enum abstract AudioChannel(String) { var NORMAL = "normal"; var CONTENT = "content"; var NOTIFICATION = "notification"; var ALARM = "alarm"; var TELEPHONY = "telephony"; var RINGER = "ringer"; var PUBLICNOTIFICATION = "publicnotification"; var SYSTEM = "system"; }haxe_3.4.4.orig/std/js/html/AudioContextState.hx0000664000175000017500000000247613166552354021547 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AudioContext.webidl. Do not edit! package js.html; @:enum abstract AudioContextState(String) { var SUSPENDED = "suspended"; var RUNNING = "running"; var CLOSED = "closed"; }haxe_3.4.4.orig/std/js/html/AudioElement.hx0000664000175000017500000000346513166552354020512 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLAudioElement.webidl. Do not edit! package js.html; /** The `HTMLAudioElement` interface provides access to the properties of `audio` elements, as well as methods to manipulate them. It derives from the `HTMLMediaElement` interface. Documentation [HTMLAudioElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLAudioElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLAudioElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLAudioElement") extern class AudioElement extends MediaElement { }haxe_3.4.4.orig/std/js/html/AudioStreamTrack.hx0000664000175000017500000000243413166552354021334 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AudioStreamTrack.webidl. Do not edit! package js.html; @:native("AudioStreamTrack") extern class AudioStreamTrack extends MediaStreamTrack { }haxe_3.4.4.orig/std/js/html/AudioTrack.hx0000664000175000017500000000262313166552354020160 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AudioTrack.webidl. Do not edit! package js.html; @:native("AudioTrack") extern class AudioTrack { var id(default,null) : String; var kind(default,null) : String; var label(default,null) : String; var language(default,null) : String; var enabled : Bool; }haxe_3.4.4.orig/std/js/html/AudioTrackList.hx0000664000175000017500000000302313166552354021007 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AudioTrackList.webidl. Do not edit! package js.html; @:native("AudioTrackList") extern class AudioTrackList extends EventTarget implements ArrayAccess { var length(default,null) : Int; var onchange : haxe.Constraints.Function; var onaddtrack : haxe.Constraints.Function; var onremovetrack : haxe.Constraints.Function; function getTrackById( id : String ) : AudioTrack; }haxe_3.4.4.orig/std/js/html/BRElement.hx0000664000175000017500000000350013166552354017742 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLBRElement.webidl. Do not edit! package js.html; /** The `HTMLBRElement` interface represents a HTML line break element (`br`). It inherits from `HTMLElement`. Documentation [HTMLBRElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLBRElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLBRElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLBRElement") extern class BRElement extends Element { /** Is a `DOMString` indicating the flow of text around floating objects. **/ var clear : String; }haxe_3.4.4.orig/std/js/html/BarProp.hx0000664000175000017500000000237713166552354017505 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\BarProp.webidl. Do not edit! package js.html; @:native("BarProp") extern class BarProp { var visible : Bool; }haxe_3.4.4.orig/std/js/html/BaseElement.hx0000664000175000017500000000421413166552354020314 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLBaseElement.webidl. Do not edit! package js.html; /** The `HTMLBaseElement` interface contains the base URI for a document. This object inherits all of the properties and methods as described in the `HTMLElement` interface. Documentation [HTMLBaseElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLBaseElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLBaseElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLBaseElement") extern class BaseElement extends Element { /** Is a `DOMString` that reflects the `href` HTML attribute, containing a base URL for relative URLs in the document. **/ var href : String; /** Is a `DOMString` that reflects the `target` HTML attribute, containing a default target browsing context or frame for elements that do not have a target reference specified. **/ var target : String; }haxe_3.4.4.orig/std/js/html/BatteryManager.hx0000664000175000017500000000603113166552354021034 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\BatteryManager.webidl. Do not edit! package js.html; /** The `BatteryManager` interface provides ways to get information about the system's battery charge level. Documentation [BatteryManager](https://developer.mozilla.org/en-US/docs/Web/API/BatteryManager) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/BatteryManager$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("BatteryManager") extern class BatteryManager extends EventTarget { /** A Boolean value indicating whether or not the battery is currently being charged. **/ var charging(default,null) : Bool; /** A number representing the remaining time in seconds until the battery is fully charged, or 0 if the battery is already fully charged. **/ var chargingTime(default,null) : Float; /** A number representing the remaining time in seconds until the battery is completely discharged and the system will suspend. **/ var dischargingTime(default,null) : Float; /** A number representing the system's battery charge level scaled to a value between 0.0 and 1.0. **/ var level(default,null) : Float; /** A handler for the `chargingchange` event; This event is sent when the battery charging state is updated. **/ var onchargingchange : haxe.Constraints.Function; /** A handler for the `chargingtimechange` event; This event is sent when the battery charging time is updated **/ var onchargingtimechange : haxe.Constraints.Function; /** A handler for the `dischargingtimechange` event; This event is sent when the battery discharging time is updated. **/ var ondischargingtimechange : haxe.Constraints.Function; /** A handler for the `levelchange` event; This event is sent when the battery level is updated. **/ var onlevelchange : haxe.Constraints.Function; }haxe_3.4.4.orig/std/js/html/BeforeUnloadEvent.hx0000664000175000017500000000342113166552354021476 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\BeforeUnloadEvent.webidl. Do not edit! package js.html; /** The `beforeunload` event is fired when the window, the document and its resources are about to be unloaded. Documentation [BeforeUnloadEvent](https://developer.mozilla.org/en-US/docs/Web/API/BeforeUnloadEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/BeforeUnloadEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("BeforeUnloadEvent") extern class BeforeUnloadEvent extends Event { var returnValue : String; }haxe_3.4.4.orig/std/js/html/BinaryType.hx0000664000175000017500000000243213166552354020216 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\WebSocket.webidl. Do not edit! package js.html; @:enum abstract BinaryType(String) { var BLOB = "blob"; var ARRAYBUFFER = "arraybuffer"; }haxe_3.4.4.orig/std/js/html/Blob.hx0000664000175000017500000000502613166552354017010 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Blob.webidl. Do not edit! package js.html; /** A `Blob` object represents a file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format. The `File` interface is based on `Blob`, inheriting blob functionality and expanding it to support files on the user's system. Documentation [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Blob$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Blob") extern class Blob { /** The size, in bytes, of the data contained in the `Blob` object. **/ var size(default,null) : Int; /** A string indicating the MIME type of the data contained in the `Blob`. If the type is unknown, this string is empty. **/ var type(default,null) : String; /** @throws DOMError */ @:overload( function() : Void {} ) function new( blobParts : Array>>>, ?options : BlobPropertyBag ) : Void; /** @throws DOMError */ /** Returns a new `Blob` object containing the data in the specified range of bytes of the source `Blob`. **/ function slice( ?start : Int, ?end : Int, ?contentType : String = "" ) : Blob; }haxe_3.4.4.orig/std/js/html/BlobPropertyBag.hx0000664000175000017500000000245713166552354021174 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Blob.webidl. Do not edit! package js.html; typedef BlobPropertyBag = { @:optional var endings : Dynamic/*MISSING EndingTypes*/; @:optional var type : String; }haxe_3.4.4.orig/std/js/html/BodyElement.hx0000664000175000017500000000607413166552354020345 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLBodyElement.webidl. Do not edit! package js.html; /** The `HTMLBodyElement` interface provides special properties (beyond those of the regular `HTMLElement` interface they also inherit) for manipulating body elements. Documentation [HTMLBodyElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLBodyElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLBodyElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLBodyElement") extern class BodyElement extends Element { /** Is a `DOMString` that represents the foreground color of text. **/ var text : String; /** Is a `DOMString` that represents the color of unvisited links. **/ var link : String; /** Is a `DOMString` that represents the color of visited links. **/ var vLink : String; /** Is a `DOMString` that represents the color of active hyperlinks. **/ var aLink : String; /** Is a `DOMString` that represents the background color for the document. **/ var bgColor : String; /** Is a `DOMString` that represents the description of the location of the background image resource. Note that this is not an URI, though some older version of some browsers do expect it. **/ var background : String; var onafterprint : haxe.Constraints.Function; var onbeforeprint : haxe.Constraints.Function; var onbeforeunload : Event -> String; var onhashchange : haxe.Constraints.Function; var onlanguagechange : haxe.Constraints.Function; var onmessage : haxe.Constraints.Function; var onoffline : haxe.Constraints.Function; var ononline : haxe.Constraints.Function; var onpagehide : haxe.Constraints.Function; var onpageshow : haxe.Constraints.Function; var onpopstate : haxe.Constraints.Function; var onstorage : haxe.Constraints.Function; var onunload : haxe.Constraints.Function; }haxe_3.4.4.orig/std/js/html/BroadcastChannel.hx0000664000175000017500000000524613166552354021331 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\BroadcastChannel.webidl. Do not edit! package js.html; /** The `BroadcastChannel` interface represents a named channel that any browsing context of a given origin can subscribe to. It allows communication between different documents (in different windows, tabs, frames or iframes) of the same origin. Messages are broadcasted via a `message` event fired at all `BroadcastChannel` objects listening to the channel. Documentation [BroadcastChannel](https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("BroadcastChannel") extern class BroadcastChannel extends EventTarget { /** Returns a `DOMString`, the name of the channel. **/ var name(default,null) : String; /** Is an `EventHandler` property that specifies the function to execute when a `message` event is fired on this object. **/ var onmessage : haxe.Constraints.Function; /** @throws DOMError */ function new( channel : String ) : Void; /** @throws DOMError */ /** Sends the message, of any type of object, to each `BroadcastChannel` object listening to the same channel. **/ function postMessage( message : Dynamic ) : Void; /** Closes the channel object, indicating it won't get any new messages, and allowing it to be, eventually, garbage collected. **/ function close() : Void; }haxe_3.4.4.orig/std/js/html/ButtonElement.hx0000664000175000017500000001240113166552354020712 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLButtonElement.webidl. Do not edit! package js.html; /** The `HTMLButtonElement` interface provides properties and methods (beyond the `button` object interface it also has available to them by inheritance) for manipulating the layout and presentation of button elements. Documentation [HTMLButtonElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLButtonElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLButtonElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLButtonElement") extern class ButtonElement extends Element { /** Is a `Boolean` indicating whether or not the control should have input focus when the page loads, unless the user overrides it, for example by typing in a different control. Only one form-associated element in a document can have this attribute specified. **/ var autofocus : Bool; /** Is a `Boolean` indicating whether or not the control is disabled, meaning that it does not accept any clicks. **/ var disabled : Bool; /** Is a `HTMLFormElement` reflecting the form that this button is associated with. If the button is a descendant of a form element, then this attribute is the ID of that form element. If the button is not a descendant of a form element, then the attribute can be the ID of any form element in the same document it is related to, or the `null` value if none matches. **/ var form(default,null) : FormElement; /** Is a `DOMString` reflecting the URI of a resource that processes information submitted by the button. If specified, this attribute overrides the `action` attribute of the `form` element that owns this element. **/ var formAction : String; var formEnctype : String; /** Is a `DOMString` reflecting the HTTP method that the browser uses to submit the form. If specified, this attribute overrides the `method` attribute of the `form` element that owns this element. **/ var formMethod : String; /** Is a `Boolean` indicating that the form is not to be validated when it is submitted. If specified, this attribute overrides the `novalidate` attribute of the `form` element that owns this element. **/ var formNoValidate : Bool; /** Is a `DOMString` reflecting a name or keyword indicating where to display the response that is received after submitting the form. If specified, this attribute overrides the `target` attribute of the `form` element that owns this element. **/ var formTarget : String; /** Is a `DOMString` representing the name of the object when submitted with a form. {{HTMLVersionInline(5)}} If specified, it must not be the empty string. **/ var name : String; /** Is a `DOMString` indicating the behavior of the button. This is an enumerated attribute with the following possible values: `"submit"`: The button submits the form. This is the default value if the attribute is not specified, {{HTMLVersionInline(5)}} or if it is dynamically changed to an empty or invalid value. `"reset"`: The button resets the form. `"button"`: The button does nothing. `"menu"`: The button displays a menu. (experimental) **/ var type : String; /** Is a `DOMString` representing the current form control value of the button. **/ var value : String; /** Is a `Boolean` indicating whether the button is a candidate for constraint validation. It is `false` if any conditions bar it from constraint validation. **/ var willValidate(default,null) : Bool; /** Is a `ValidityState` representing the validity states that this button is in. **/ var validity(default,null) : ValidityState; /** Is a `DOMString` representing the localized message that describes the validation constraints that the control does not satisfy (if any). This attribute is the empty string if the control is not a candidate for constraint validation (`willValidate` is `false`), or it satisfies its constraints. **/ var validationMessage(default,null) : String; function checkValidity() : Bool; function setCustomValidity( error : String ) : Void; }haxe_3.4.4.orig/std/js/html/CDATASection.hx0000664000175000017500000000352013166552354020270 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CDATASection.webidl. Do not edit! package js.html; /** The `CDATASection` interface represents a CDATA section that can be used within XML to include extended portions of unescaped text, such that the symbols and & do not need escaping as they normally do within XML when used as text. Documentation [CDATASection](https://developer.mozilla.org/en-US/docs/Web/API/CDATASection) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CDATASection$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CDATASection") extern class CDATASection extends Text { }haxe_3.4.4.orig/std/js/html/CSS.hx0000664000175000017500000000362713166552354016567 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CSS.webidl. Do not edit! package js.html; /** The `CSS` interface holds useful CSS-related methods. No object with this interface are implemented: it contains only static methods and therefore is a utilitarian interface. Documentation [CSS](https://developer.mozilla.org/en-US/docs/Web/API/CSS) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CSS$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CSS") extern class CSS { /** @throws DOMError */ @:overload( function( property : String, value : String ) : Bool {} ) static function supports( conditionText : String ) : Bool; static function escape( ident : String ) : String; }haxe_3.4.4.orig/std/js/html/CSSAnimation.hx0000664000175000017500000000246613166552354020427 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CSSAnimation.webidl. Do not edit! package js.html; @:native("CSSAnimation") extern class CSSAnimation extends Animation { var animationName(default,null) : String; }haxe_3.4.4.orig/std/js/html/CSSCharsetRule.hx0000664000175000017500000000243013166552354020720 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from cssrule.webidl. Do not edit! package js.html; @:native("CSSCharsetRule") extern class CSSCharsetRule extends CSSRule { var encoding : String; }haxe_3.4.4.orig/std/js/html/CSSFontFaceRule.hx0000664000175000017500000000246213166552354021021 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from cssrule.webidl. Do not edit! package js.html; @:native("CSSFontFaceRule") extern class CSSFontFaceRule extends CSSRule { var style(default,null) : CSSStyleDeclaration; }haxe_3.4.4.orig/std/js/html/CSSImportRule.hx0000664000175000017500000000256513166552354020612 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from cssrule.webidl. Do not edit! package js.html; @:native("CSSImportRule") extern class CSSImportRule extends CSSRule { var href(default,null) : String; var media(default,null) : MediaList; var styleSheet(default,null) : CSSStyleSheet; }haxe_3.4.4.orig/std/js/html/CSSMediaRule.hx0000664000175000017500000000415213166552354020351 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from cssrule.webidl. Do not edit! package js.html; /** The `CSSMediaRule` is an interface representing a single CSS `@media` rule. It implements the `CSSConditionRule` interface, and therefore the `CSSGroupingRule` and the `CSSRule` interface with a type value of `4` (`CSSRule.MEDIA_RULE`). Documentation [CSSMediaRule](https://developer.mozilla.org/en-US/docs/Web/API/CSSMediaRule) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CSSMediaRule$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CSSMediaRule") extern class CSSMediaRule extends CSSRule { /** Specifies a `MediaList` representing the intended destination medium for style information. **/ var media(default,null) : MediaList; var cssRules(default,null) : CSSRuleList; function insertRule( rule : String, index : Int ) : Int; function deleteRule( index : Int ) : Void; }haxe_3.4.4.orig/std/js/html/CSSPageRule.hx0000664000175000017500000000373313166552354020212 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from cssrule.webidl. Do not edit! package js.html; /** `CSSPageRule` is an interface representing a single CSS `@page` rule. It implements the `CSSRule` interface with a type value of `6` (`CSSRule.PAGE_RULE`). Documentation [CSSPageRule](https://developer.mozilla.org/en-US/docs/Web/API/CSSPageRule) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CSSPageRule$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CSSPageRule") extern class CSSPageRule extends CSSRule { /** Represents the text of the page selector associated with the at-rule. **/ var selectorText : String; /** Returns the declaration block associated with the at-rule. **/ var style(default,null) : CSSStyleDeclaration; }haxe_3.4.4.orig/std/js/html/CSSPrimitiveValue.hx0000664000175000017500000002375613166552354021462 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CSSPrimitiveValue.webidl. Do not edit! package js.html; /** The `CSSPrimitiveValue` interface derives from the `CSSValue` interface and represents the current computed value of a CSS property. Documentation [CSSPrimitiveValue](https://developer.mozilla.org/en-US/docs/Web/API/CSSPrimitiveValue) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CSSPrimitiveValue$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CSSPrimitiveValue") extern class CSSPrimitiveValue extends CSSValue { static inline var CSS_UNKNOWN : Int = 0; static inline var CSS_NUMBER : Int = 1; static inline var CSS_PERCENTAGE : Int = 2; static inline var CSS_EMS : Int = 3; static inline var CSS_EXS : Int = 4; static inline var CSS_PX : Int = 5; static inline var CSS_CM : Int = 6; static inline var CSS_MM : Int = 7; static inline var CSS_IN : Int = 8; static inline var CSS_PT : Int = 9; static inline var CSS_PC : Int = 10; static inline var CSS_DEG : Int = 11; static inline var CSS_RAD : Int = 12; static inline var CSS_GRAD : Int = 13; static inline var CSS_MS : Int = 14; static inline var CSS_S : Int = 15; static inline var CSS_HZ : Int = 16; static inline var CSS_KHZ : Int = 17; static inline var CSS_DIMENSION : Int = 18; static inline var CSS_STRING : Int = 19; static inline var CSS_URI : Int = 20; static inline var CSS_IDENT : Int = 21; static inline var CSS_ATTR : Int = 22; static inline var CSS_COUNTER : Int = 23; static inline var CSS_RECT : Int = 24; static inline var CSS_RGBCOLOR : Int = 25; /** An unsigned short representing the type of the value. Possible values are:
Constant Description
CSS_ATTR The value is an attr() function. The value can be obtained by using the getStringValue() method.
CSS_CM The value is a length in centimeters. The value can be obtained by using the getFloatValue() method.
CSS_COUNTER The value is a counter or counters function. The value can be obtained by using the getCounterValue() method.
CSS_DEG The value is an angle in degrees. The value can be obtained by using the getFloatValue() method.
CSS_DIMENSION The value is a number with an unknown dimension. The value can be obtained by using the getFloatValue() method.
CSS_EMS The value is a length in em units. The value can be obtained by using the getFloatValue() method.
CSS_EXS The value is a length in ex units. The value can be obtained by using the getFloatValue() method.
CSS_GRAD The value is an angle in grads. The value can be obtained by using the getFloatValue() method.
CSS_HZ The value is a frequency in Hertz. The value can be obtained by using the getFloatValue method.
CSS_IDENT The value is an identifier. The value can be obtained by using the getStringValue() method.
CSS_IN The value is a length in inches. The value can be obtained by using the getFloatValue() method.
CSS_KHZ The value is a frequency in Kilohertz. The value can be obtained by using the getFloatValue() method.
CSS_MM The value is a length in millimeters. The value can be obtained by using the getFloatValue() method.
CSS_MS The value is a time in milliseconds. The value can be obtained by using the getFloatValue() method.
CSS_NUMBER The value is a simple number. The value can be obtained by using the getFloatValue() method.
CSS_PC The value is a length in picas. The value can be obtained by using the getFloatValue() method.
CSS_PERCENTAGE The value is a percentage. The value can be obtained by using the getFloatValue() method.
CSS_PT The value is a length in points. The value can be obtained by using the getFloatValue() method.
CSS_PX The value is a length in pixels. The value can be obtained by using the getFloatValue() method.
CSS_RAD The value is an angle in radians. The value can be obtained by using the getFloatValue() method.
CSS_RECT The value is a shape function. The value can be obtained by using the getRectValue() method.
CSS_RGBCOLOR The value is an color. The value can be obtained by using the getRGBColorValue() method.
CSS_S The value is a time in seconds. The value can be obtained by using the getFloatValue() method.
CSS_STRING The value is a string. The value can be obtained by using the getStringValue() method.
CSS_UNKNOWN The value is not a recognized CSS2 value. The value can only be obtained by using the CSSValue.cssText attribute.
CSS_URI The value is a uri. The value can be obtained by using the getStringValue() method.
**/ var primitiveType(default,null) : Int; /** @throws DOMError */ /** A method to set the float value with a specified unit. If the property attached with this value can not accept the specified unit or the float value, the value will be unchanged and a `DOMException` will be raised. **/ function setFloatValue( unitType : Int, floatValue : Float ) : Void; /** @throws DOMError */ /** This method is used to get a float value in a specified unit. If this CSS value doesn't contain a float value or can't be converted into the specified unit, a `DOMException` is raised. **/ function getFloatValue( unitType : Int ) : Float; /** @throws DOMError */ /** A method to set the string value with the specified unit. If the property attached to this value can't accept the specified unit or the string value, the value will be unchanged and a `DOMException` will be raised. **/ function setStringValue( stringType : Int, stringValue : String ) : Void; /** @throws DOMError */ /** This method is used to get the string value. If the CSS value doesn't contain a string value, a `DOMException` is raised. **/ function getStringValue() : String; /** @throws DOMError */ /** This method is used to get the counter value. If this CSS value doesn't contain a counter value, a `DOMException` is raised. Modification to the corresponding style property can be achieved using the `Counter` interface. **/ function getCounterValue() : Dynamic/*MISSING Counter*/; /** @throws DOMError */ /** This method is used to get the Rect value. If this CSS value doesn't contain a rect value, a `DOMException` is raised. Modification to the corresponding style property can be achieved using the `Rect` interface. **/ function getRectValue() : Rect; /** @throws DOMError */ /** This method is used to get the RGB color. If this CSS value doesn't contain a RGB color value, a `DOMException` is raised. Modification to the corresponding style property can be achieved using the `RGBColor` interface. **/ function getRGBColorValue() : RGBColor; }haxe_3.4.4.orig/std/js/html/CSSPseudoElement.hx0000664000175000017500000000304313166552354021251 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CSSPseudoElement.webidl. Do not edit! package js.html; @:native("CSSPseudoElement") extern class CSSPseudoElement { var type(default,null) : String; var parentElement(default,null) : Element; /** @throws DOMError */ function animate( frames : Dynamic, ?options : haxe.extern.EitherType ) : Animation; function getAnimations() : Array; }haxe_3.4.4.orig/std/js/html/CSSRule.hx0000664000175000017500000000415713166552354017416 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from cssrule.webidl. Do not edit! package js.html; /** The `CSSRule` interface represents a single CSS rule. There are several types of rules, listed in the Type constants section below. Documentation [CSSRule](https://developer.mozilla.org/en-US/docs/Web/API/CSSRule) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CSSRule$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CSSRule") extern class CSSRule { static inline var UNKNOWN_RULE : Int = 0; static inline var STYLE_RULE : Int = 1; static inline var CHARSET_RULE : Int = 2; static inline var IMPORT_RULE : Int = 3; static inline var MEDIA_RULE : Int = 4; static inline var FONT_FACE_RULE : Int = 5; static inline var PAGE_RULE : Int = 6; var type(default,null) : Int; var cssText : String; var parentStyleSheet(default,null) : CSSStyleSheet; var parentRule(default,null) : CSSRule; }haxe_3.4.4.orig/std/js/html/CSSRuleList.hx0000664000175000017500000000346213166552354020250 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CSSRuleList.webidl. Do not edit! package js.html; /** A `CSSRuleList` is an (indirect-modify only) array-like object containing an ordered collection of `CSSRule` objects. Documentation [CSSRuleList](https://developer.mozilla.org/en-US/docs/Web/API/CSSRuleList) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CSSRuleList$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CSSRuleList") extern class CSSRuleList implements ArrayAccess { var length(default,null) : Int; function item( index : Int ) : CSSRule; }haxe_3.4.4.orig/std/js/html/CSSStyleDeclaration.hx0000664000175000017500000007230013166552354021750 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CSSStyleDeclaration.webidl. Do not edit! package js.html; /** `CSSStyleDeclaration` represents a collection of CSS property-value pairs. It is used in a few APIs: Documentation [CSSStyleDeclaration](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CSSStyleDeclaration") extern class CSSStyleDeclaration implements ArrayAccess { var cssText : String; var length(default,null) : Int; var parentRule(default,null) : CSSRule; /** Shorthand for the "align-content" CSS property. */ var alignContent :String; /** Shorthand for the "align-items" CSS property. */ var alignItems :String; /** Shorthand for the "align-self" CSS property. */ var alignSelf :String; /** Shorthand for the "alignment-adjust" CSS property. */ var alignmentAdjust :String; /** Shorthand for the "alignment-baseline" CSS property. */ var alignmentBaseline :String; /** Shorthand for the "all" CSS property. */ var all :String; /** Shorthand for the "anchor-point" CSS property. */ var anchorPoint :String; /** Shorthand for the "animation" CSS property. */ var animation :String; /** Shorthand for the "animation-delay" CSS property. */ var animationDelay :String; /** Shorthand for the "animation-direction" CSS property. */ var animationDirection :String; /** Shorthand for the "animation-duration" CSS property. */ var animationDuration :String; /** Shorthand for the "animation-fill-mode" CSS property. */ var animationFillMode :String; /** Shorthand for the "animation-iteration-count" CSS property. */ var animationIterationCount :String; /** Shorthand for the "animation-name" CSS property. */ var animationName :String; /** Shorthand for the "animation-play-state" CSS property. */ var animationPlayState :String; /** Shorthand for the "animation-timing-function" CSS property. */ var animationTimingFunction :String; /** Shorthand for the "azimuth" CSS property. */ var azimuth :String; /** Shorthand for the "backface-visibility" CSS property. */ var backfaceVisibility :String; /** Shorthand for the "background" CSS property. */ var background :String; /** Shorthand for the "background-attachment" CSS property. */ var backgroundAttachment :String; /** Shorthand for the "background-clip" CSS property. */ var backgroundClip :String; /** Shorthand for the "background-color" CSS property. */ var backgroundColor :String; /** Shorthand for the "background-image" CSS property. */ var backgroundImage :String; /** Shorthand for the "background-origin" CSS property. */ var backgroundOrigin :String; /** Shorthand for the "background-position" CSS property. */ var backgroundPosition :String; /** Shorthand for the "background-repeat" CSS property. */ var backgroundRepeat :String; /** Shorthand for the "background-size" CSS property. */ var backgroundSize :String; /** Shorthand for the "baseline-shift" CSS property. */ var baselineShift :String; /** Shorthand for the "binding" CSS property. */ var binding :String; /** Shorthand for the "bleed" CSS property. */ var bleed :String; /** Shorthand for the "bookmark-label" CSS property. */ var bookmarkLabel :String; /** Shorthand for the "bookmark-level" CSS property. */ var bookmarkLevel :String; /** Shorthand for the "bookmark-state" CSS property. */ var bookmarkState :String; /** Shorthand for the "border" CSS property. */ var border :String; /** Shorthand for the "border-bottom" CSS property. */ var borderBottom :String; /** Shorthand for the "border-bottom-color" CSS property. */ var borderBottomColor :String; /** Shorthand for the "border-bottom-left-radius" CSS property. */ var borderBottomLeftRadius :String; /** Shorthand for the "border-bottom-right-radius" CSS property. */ var borderBottomRightRadius :String; /** Shorthand for the "border-bottom-style" CSS property. */ var borderBottomStyle :String; /** Shorthand for the "border-bottom-width" CSS property. */ var borderBottomWidth :String; /** Shorthand for the "border-collapse" CSS property. */ var borderCollapse :String; /** Shorthand for the "border-color" CSS property. */ var borderColor :String; /** Shorthand for the "border-image" CSS property. */ var borderImage :String; /** Shorthand for the "border-image-outset" CSS property. */ var borderImageOutset :String; /** Shorthand for the "border-image-repeat" CSS property. */ var borderImageRepeat :String; /** Shorthand for the "border-image-slice" CSS property. */ var borderImageSlice :String; /** Shorthand for the "border-image-source" CSS property. */ var borderImageSource :String; /** Shorthand for the "border-image-width" CSS property. */ var borderImageWidth :String; /** Shorthand for the "border-left" CSS property. */ var borderLeft :String; /** Shorthand for the "border-left-color" CSS property. */ var borderLeftColor :String; /** Shorthand for the "border-left-style" CSS property. */ var borderLeftStyle :String; /** Shorthand for the "border-left-width" CSS property. */ var borderLeftWidth :String; /** Shorthand for the "border-radius" CSS property. */ var borderRadius :String; /** Shorthand for the "border-right" CSS property. */ var borderRight :String; /** Shorthand for the "border-right-color" CSS property. */ var borderRightColor :String; /** Shorthand for the "border-right-style" CSS property. */ var borderRightStyle :String; /** Shorthand for the "border-right-width" CSS property. */ var borderRightWidth :String; /** Shorthand for the "border-spacing" CSS property. */ var borderSpacing :String; /** Shorthand for the "border-style" CSS property. */ var borderStyle :String; /** Shorthand for the "border-top" CSS property. */ var borderTop :String; /** Shorthand for the "border-top-color" CSS property. */ var borderTopColor :String; /** Shorthand for the "border-top-left-radius" CSS property. */ var borderTopLeftRadius :String; /** Shorthand for the "border-top-right-radius" CSS property. */ var borderTopRightRadius :String; /** Shorthand for the "border-top-style" CSS property. */ var borderTopStyle :String; /** Shorthand for the "border-top-width" CSS property. */ var borderTopWidth :String; /** Shorthand for the "border-width" CSS property. */ var borderWidth :String; /** Shorthand for the "bottom" CSS property. */ var bottom :String; /** Shorthand for the "box-decoration-break" CSS property. */ var boxDecorationBreak :String; /** Shorthand for the "box-shadow" CSS property. */ var boxShadow :String; /** Shorthand for the "box-sizing" CSS property. */ var boxSizing :String; /** Shorthand for the "box-snap" CSS property. */ var boxSnap :String; /** Shorthand for the "box-suppress" CSS property. */ var boxSuppress :String; /** Shorthand for the "break-after" CSS property. */ var breakAfter :String; /** Shorthand for the "break-before" CSS property. */ var breakBefore :String; /** Shorthand for the "break-inside" CSS property. */ var breakInside :String; /** Shorthand for the "caption-side" CSS property. */ var captionSide :String; /** Shorthand for the "chains" CSS property. */ var chains :String; /** Shorthand for the "clear" CSS property. */ var clear :String; /** Shorthand for the "clip" CSS property. */ var clip :String; /** Shorthand for the "clip-path" CSS property. */ var clipPath :String; /** Shorthand for the "clip-rule" CSS property. */ var clipRule :String; /** Shorthand for the "color" CSS property. */ var color :String; /** Shorthand for the "color-interpolation-filters" CSS property. */ var colorInterpolationFilters :String; /** Shorthand for the "column-count" CSS property. */ var columnCount :String; /** Shorthand for the "column-fill" CSS property. */ var columnFill :String; /** Shorthand for the "column-gap" CSS property. */ var columnGap :String; /** Shorthand for the "column-rule" CSS property. */ var columnRule :String; /** Shorthand for the "column-rule-color" CSS property. */ var columnRuleColor :String; /** Shorthand for the "column-rule-style" CSS property. */ var columnRuleStyle :String; /** Shorthand for the "column-rule-width" CSS property. */ var columnRuleWidth :String; /** Shorthand for the "column-span" CSS property. */ var columnSpan :String; /** Shorthand for the "column-width" CSS property. */ var columnWidth :String; /** Shorthand for the "columns" CSS property. */ var columns :String; /** Shorthand for the "contain" CSS property. */ var contain :String; /** Shorthand for the "content" CSS property. */ var content :String; /** Shorthand for the "counter-increment" CSS property. */ var counterIncrement :String; /** Shorthand for the "counter-reset" CSS property. */ var counterReset :String; /** Shorthand for the "counter-set" CSS property. */ var counterSet :String; /** Shorthand for the "crop" CSS property. */ var crop :String; /** Shorthand for the "cue" CSS property. */ var cue :String; /** Shorthand for the "cue-after" CSS property. */ var cueAfter :String; /** Shorthand for the "cue-before" CSS property. */ var cueBefore :String; /** Shorthand for the "cursor" CSS property. */ var cursor :String; /** Shorthand for the "direction" CSS property. */ var direction :String; /** Shorthand for the "display" CSS property. */ var display :String; /** Shorthand for the "display-inside" CSS property. */ var displayInside :String; /** Shorthand for the "display-list" CSS property. */ var displayList :String; /** Shorthand for the "display-outside" CSS property. */ var displayOutside :String; /** Shorthand for the "dominant-baseline" CSS property. */ var dominantBaseline :String; /** Shorthand for the "elevation" CSS property. */ var elevation :String; /** Shorthand for the "empty-cells" CSS property. */ var emptyCells :String; /** Shorthand for the "filter" CSS property. */ var filter :String; /** Shorthand for the "flex" CSS property. */ var flex :String; /** Shorthand for the "flex-basis" CSS property. */ var flexBasis :String; /** Shorthand for the "flex-direction" CSS property. */ var flexDirection :String; /** Shorthand for the "flex-flow" CSS property. */ var flexFlow :String; /** Shorthand for the "flex-grow" CSS property. */ var flexGrow :String; /** Shorthand for the "flex-shrink" CSS property. */ var flexShrink :String; /** Shorthand for the "flex-wrap" CSS property. */ var flexWrap :String; /** Shorthand for the "float" CSS property. */ var float :String; /** Shorthand for the "float-offset" CSS property. */ var floatOffset :String; /** Shorthand for the "flood-color" CSS property. */ var floodColor :String; /** Shorthand for the "flood-opacity" CSS property. */ var floodOpacity :String; /** Shorthand for the "flow-from" CSS property. */ var flowFrom :String; /** Shorthand for the "flow-into" CSS property. */ var flowInto :String; /** Shorthand for the "font" CSS property. */ var font :String; /** Shorthand for the "font-family" CSS property. */ var fontFamily :String; /** Shorthand for the "font-feature-settings" CSS property. */ var fontFeatureSettings :String; /** Shorthand for the "font-kerning" CSS property. */ var fontKerning :String; /** Shorthand for the "font-language-override" CSS property. */ var fontLanguageOverride :String; /** Shorthand for the "font-size" CSS property. */ var fontSize :String; /** Shorthand for the "font-size-adjust" CSS property. */ var fontSizeAdjust :String; /** Shorthand for the "font-stretch" CSS property. */ var fontStretch :String; /** Shorthand for the "font-style" CSS property. */ var fontStyle :String; /** Shorthand for the "font-synthesis" CSS property. */ var fontSynthesis :String; /** Shorthand for the "font-variant" CSS property. */ var fontVariant :String; /** Shorthand for the "font-variant-alternates" CSS property. */ var fontVariantAlternates :String; /** Shorthand for the "font-variant-caps" CSS property. */ var fontVariantCaps :String; /** Shorthand for the "font-variant-east-asian" CSS property. */ var fontVariantEastAsian :String; /** Shorthand for the "font-variant-ligatures" CSS property. */ var fontVariantLigatures :String; /** Shorthand for the "font-variant-numeric" CSS property. */ var fontVariantNumeric :String; /** Shorthand for the "font-variant-position" CSS property. */ var fontVariantPosition :String; /** Shorthand for the "font-weight" CSS property. */ var fontWeight :String; /** Shorthand for the "grid" CSS property. */ var grid :String; /** Shorthand for the "grid-area" CSS property. */ var gridArea :String; /** Shorthand for the "grid-auto-columns" CSS property. */ var gridAutoColumns :String; /** Shorthand for the "grid-auto-flow" CSS property. */ var gridAutoFlow :String; /** Shorthand for the "grid-auto-rows" CSS property. */ var gridAutoRows :String; /** Shorthand for the "grid-column" CSS property. */ var gridColumn :String; /** Shorthand for the "grid-column-end" CSS property. */ var gridColumnEnd :String; /** Shorthand for the "grid-column-start" CSS property. */ var gridColumnStart :String; /** Shorthand for the "grid-row" CSS property. */ var gridRow :String; /** Shorthand for the "grid-row-end" CSS property. */ var gridRowEnd :String; /** Shorthand for the "grid-row-start" CSS property. */ var gridRowStart :String; /** Shorthand for the "grid-template" CSS property. */ var gridTemplate :String; /** Shorthand for the "grid-template-areas" CSS property. */ var gridTemplateAreas :String; /** Shorthand for the "grid-template-columns" CSS property. */ var gridTemplateColumns :String; /** Shorthand for the "grid-template-rows" CSS property. */ var gridTemplateRows :String; /** Shorthand for the "hanging-punctuation" CSS property. */ var hangingPunctuation :String; /** Shorthand for the "height" CSS property. */ var height :String; /** Shorthand for the "hyphens" CSS property. */ var hyphens :String; /** Shorthand for the "icon" CSS property. */ var icon :String; /** Shorthand for the "image-orientation" CSS property. */ var imageOrientation :String; /** Shorthand for the "image-resolution" CSS property. */ var imageResolution :String; /** Shorthand for the "ime-mode" CSS property. */ var imeMode :String; /** Shorthand for the "initial-letters" CSS property. */ var initialLetters :String; /** Shorthand for the "inline-box-align" CSS property. */ var inlineBoxAlign :String; /** Shorthand for the "justify-content" CSS property. */ var justifyContent :String; /** Shorthand for the "justify-items" CSS property. */ var justifyItems :String; /** Shorthand for the "justify-self" CSS property. */ var justifySelf :String; /** Shorthand for the "left" CSS property. */ var left :String; /** Shorthand for the "letter-spacing" CSS property. */ var letterSpacing :String; /** Shorthand for the "lighting-color" CSS property. */ var lightingColor :String; /** Shorthand for the "line-box-contain" CSS property. */ var lineBoxContain :String; /** Shorthand for the "line-break" CSS property. */ var lineBreak :String; /** Shorthand for the "line-grid" CSS property. */ var lineGrid :String; /** Shorthand for the "line-height" CSS property. */ var lineHeight :String; /** Shorthand for the "line-snap" CSS property. */ var lineSnap :String; /** Shorthand for the "line-stacking" CSS property. */ var lineStacking :String; /** Shorthand for the "line-stacking-ruby" CSS property. */ var lineStackingRuby :String; /** Shorthand for the "line-stacking-shift" CSS property. */ var lineStackingShift :String; /** Shorthand for the "line-stacking-strategy" CSS property. */ var lineStackingStrategy :String; /** Shorthand for the "list-style" CSS property. */ var listStyle :String; /** Shorthand for the "list-style-image" CSS property. */ var listStyleImage :String; /** Shorthand for the "list-style-position" CSS property. */ var listStylePosition :String; /** Shorthand for the "list-style-type" CSS property. */ var listStyleType :String; /** Shorthand for the "margin" CSS property. */ var margin :String; /** Shorthand for the "margin-bottom" CSS property. */ var marginBottom :String; /** Shorthand for the "margin-left" CSS property. */ var marginLeft :String; /** Shorthand for the "margin-right" CSS property. */ var marginRight :String; /** Shorthand for the "margin-top" CSS property. */ var marginTop :String; /** Shorthand for the "marker-offset" CSS property. */ var markerOffset :String; /** Shorthand for the "marker-side" CSS property. */ var markerSide :String; /** Shorthand for the "marks" CSS property. */ var marks :String; /** Shorthand for the "mask" CSS property. */ var mask :String; /** Shorthand for the "mask-box" CSS property. */ var maskBox :String; /** Shorthand for the "mask-box-outset" CSS property. */ var maskBoxOutset :String; /** Shorthand for the "mask-box-repeat" CSS property. */ var maskBoxRepeat :String; /** Shorthand for the "mask-box-slice" CSS property. */ var maskBoxSlice :String; /** Shorthand for the "mask-box-source" CSS property. */ var maskBoxSource :String; /** Shorthand for the "mask-box-width" CSS property. */ var maskBoxWidth :String; /** Shorthand for the "mask-clip" CSS property. */ var maskClip :String; /** Shorthand for the "mask-image" CSS property. */ var maskImage :String; /** Shorthand for the "mask-origin" CSS property. */ var maskOrigin :String; /** Shorthand for the "mask-position" CSS property. */ var maskPosition :String; /** Shorthand for the "mask-repeat" CSS property. */ var maskRepeat :String; /** Shorthand for the "mask-size" CSS property. */ var maskSize :String; /** Shorthand for the "mask-source-type" CSS property. */ var maskSourceType :String; /** Shorthand for the "mask-type" CSS property. */ var maskType :String; /** Shorthand for the "max-height" CSS property. */ var maxHeight :String; /** Shorthand for the "max-lines" CSS property. */ var maxLines :String; /** Shorthand for the "max-width" CSS property. */ var maxWidth :String; /** Shorthand for the "min-height" CSS property. */ var minHeight :String; /** Shorthand for the "min-width" CSS property. */ var minWidth :String; /** Shorthand for the "move-to" CSS property. */ var moveTo :String; /** Shorthand for the "nav-down" CSS property. */ var navDown :String; /** Shorthand for the "nav-index" CSS property. */ var navIndex :String; /** Shorthand for the "nav-left" CSS property. */ var navLeft :String; /** Shorthand for the "nav-right" CSS property. */ var navRight :String; /** Shorthand for the "nav-up" CSS property. */ var navUp :String; /** Shorthand for the "object-fit" CSS property. */ var objectFit :String; /** Shorthand for the "object-position" CSS property. */ var objectPosition :String; /** Shorthand for the "opacity" CSS property. */ var opacity :String; /** Shorthand for the "order" CSS property. */ var order :String; /** Shorthand for the "orphans" CSS property. */ var orphans :String; /** Shorthand for the "outline" CSS property. */ var outline :String; /** Shorthand for the "outline-color" CSS property. */ var outlineColor :String; /** Shorthand for the "outline-offset" CSS property. */ var outlineOffset :String; /** Shorthand for the "outline-style" CSS property. */ var outlineStyle :String; /** Shorthand for the "outline-width" CSS property. */ var outlineWidth :String; /** Shorthand for the "overflow" CSS property. */ var overflow :String; /** Shorthand for the "overflow-wrap" CSS property. */ var overflowWrap :String; /** Shorthand for the "overflow-x" CSS property. */ var overflowX :String; /** Shorthand for the "overflow-y" CSS property. */ var overflowY :String; /** Shorthand for the "padding" CSS property. */ var padding :String; /** Shorthand for the "padding-bottom" CSS property. */ var paddingBottom :String; /** Shorthand for the "padding-left" CSS property. */ var paddingLeft :String; /** Shorthand for the "padding-right" CSS property. */ var paddingRight :String; /** Shorthand for the "padding-top" CSS property. */ var paddingTop :String; /** Shorthand for the "page" CSS property. */ var page :String; /** Shorthand for the "page-break-after" CSS property. */ var pageBreakAfter :String; /** Shorthand for the "page-break-before" CSS property. */ var pageBreakBefore :String; /** Shorthand for the "page-break-inside" CSS property. */ var pageBreakInside :String; /** Shorthand for the "page-policy" CSS property. */ var pagePolicy :String; /** Shorthand for the "pause" CSS property. */ var pause :String; /** Shorthand for the "pause-after" CSS property. */ var pauseAfter :String; /** Shorthand for the "pause-before" CSS property. */ var pauseBefore :String; /** Shorthand for the "perspective" CSS property. */ var perspective :String; /** Shorthand for the "perspective-origin" CSS property. */ var perspectiveOrigin :String; /** Shorthand for the "pitch" CSS property. */ var pitch :String; /** Shorthand for the "pitch-range" CSS property. */ var pitchRange :String; /** Shorthand for the "play-during" CSS property. */ var playDuring :String; /** Shorthand for the "position" CSS property. */ var position :String; /** Shorthand for the "presentation-level" CSS property. */ var presentationLevel :String; /** Shorthand for the "quotes" CSS property. */ var quotes :String; /** Shorthand for the "region-fragment" CSS property. */ var regionFragment :String; /** Shorthand for the "resize" CSS property. */ var resize :String; /** Shorthand for the "rest" CSS property. */ var rest :String; /** Shorthand for the "rest-after" CSS property. */ var restAfter :String; /** Shorthand for the "rest-before" CSS property. */ var restBefore :String; /** Shorthand for the "richness" CSS property. */ var richness :String; /** Shorthand for the "right" CSS property. */ var right :String; /** Shorthand for the "rotation" CSS property. */ var rotation :String; /** Shorthand for the "rotation-point" CSS property. */ var rotationPoint :String; /** Shorthand for the "ruby-align" CSS property. */ var rubyAlign :String; /** Shorthand for the "ruby-merge" CSS property. */ var rubyMerge :String; /** Shorthand for the "ruby-position" CSS property. */ var rubyPosition :String; /** Shorthand for the "shape-image-threshold" CSS property. */ var shapeImageThreshold :String; /** Shorthand for the "shape-outside" CSS property. */ var shapeOutside :String; /** Shorthand for the "shape-margin" CSS property. */ var shapeMargin :String; /** Shorthand for the "size" CSS property. */ var size :String; /** Shorthand for the "speak" CSS property. */ var speak :String; /** Shorthand for the "speak-as" CSS property. */ var speakAs :String; /** Shorthand for the "speak-header" CSS property. */ var speakHeader :String; /** Shorthand for the "speak-numeral" CSS property. */ var speakNumeral :String; /** Shorthand for the "speak-punctuation" CSS property. */ var speakPunctuation :String; /** Shorthand for the "speech-rate" CSS property. */ var speechRate :String; /** Shorthand for the "stress" CSS property. */ var stress :String; /** Shorthand for the "string-set" CSS property. */ var stringSet :String; /** Shorthand for the "tab-size" CSS property. */ var tabSize :String; /** Shorthand for the "table-layout" CSS property. */ var tableLayout :String; /** Shorthand for the "text-align" CSS property. */ var textAlign :String; /** Shorthand for the "text-align-last" CSS property. */ var textAlignLast :String; /** Shorthand for the "text-combine-upright" CSS property. */ var textCombineUpright :String; /** Shorthand for the "text-decoration" CSS property. */ var textDecoration :String; /** Shorthand for the "text-decoration-color" CSS property. */ var textDecorationColor :String; /** Shorthand for the "text-decoration-line" CSS property. */ var textDecorationLine :String; /** Shorthand for the "text-decoration-skip" CSS property. */ var textDecorationSkip :String; /** Shorthand for the "text-decoration-style" CSS property. */ var textDecorationStyle :String; /** Shorthand for the "text-emphasis" CSS property. */ var textEmphasis :String; /** Shorthand for the "text-emphasis-color" CSS property. */ var textEmphasisColor :String; /** Shorthand for the "text-emphasis-position" CSS property. */ var textEmphasisPosition :String; /** Shorthand for the "text-emphasis-style" CSS property. */ var textEmphasisStyle :String; /** Shorthand for the "text-height" CSS property. */ var textHeight :String; /** Shorthand for the "text-indent" CSS property. */ var textIndent :String; /** Shorthand for the "text-justify" CSS property. */ var textJustify :String; /** Shorthand for the "text-orientation" CSS property. */ var textOrientation :String; /** Shorthand for the "text-overflow" CSS property. */ var textOverflow :String; /** Shorthand for the "text-shadow" CSS property. */ var textShadow :String; /** Shorthand for the "text-space-collapse" CSS property. */ var textSpaceCollapse :String; /** Shorthand for the "text-transform" CSS property. */ var textTransform :String; /** Shorthand for the "text-underline-position" CSS property. */ var textUnderlinePosition :String; /** Shorthand for the "text-wrap" CSS property. */ var textWrap :String; /** Shorthand for the "top" CSS property. */ var top :String; /** Shorthand for the "transform" CSS property. */ var transform :String; /** Shorthand for the "transform-origin" CSS property. */ var transformOrigin :String; /** Shorthand for the "transform-style" CSS property. */ var transformStyle :String; /** Shorthand for the "transition" CSS property. */ var transition :String; /** Shorthand for the "transition-delay" CSS property. */ var transitionDelay :String; /** Shorthand for the "transition-duration" CSS property. */ var transitionDuration :String; /** Shorthand for the "transition-property" CSS property. */ var transitionProperty :String; /** Shorthand for the "transition-timing-function" CSS property. */ var transitionTimingFunction :String; /** Shorthand for the "unicode-bidi" CSS property. */ var unicodeBidi :String; /** Shorthand for the "vertical-align" CSS property. */ var verticalAlign :String; /** Shorthand for the "visibility" CSS property. */ var visibility :String; /** Shorthand for the "voice-balance" CSS property. */ var voiceBalance :String; /** Shorthand for the "voice-duration" CSS property. */ var voiceDuration :String; /** Shorthand for the "voice-family" CSS property. */ var voiceFamily :String; /** Shorthand for the "voice-pitch" CSS property. */ var voicePitch :String; /** Shorthand for the "voice-range" CSS property. */ var voiceRange :String; /** Shorthand for the "voice-rate" CSS property. */ var voiceRate :String; /** Shorthand for the "voice-stress" CSS property. */ var voiceStress :String; /** Shorthand for the "voice-volume" CSS property. */ var voiceVolume :String; /** Shorthand for the "volume" CSS property. */ var volume :String; /** Shorthand for the "white-space" CSS property. */ var whiteSpace :String; /** Shorthand for the "widows" CSS property. */ var widows :String; /** Shorthand for the "width" CSS property. */ var width :String; /** Shorthand for the "will-change" CSS property. */ var willChange :String; /** Shorthand for the "word-break" CSS property. */ var wordBreak :String; /** Shorthand for the "word-spacing" CSS property. */ var wordSpacing :String; /** Shorthand for the "word-wrap" CSS property. */ var wordWrap :String; /** Shorthand for the "wrap-flow" CSS property. */ var wrapFlow :String; /** Shorthand for the "wrap-through" CSS property. */ var wrapThrough :String; /** Shorthand for the "writing-mode" CSS property. */ var writingMode :String; /** Shorthand for the "z-index" CSS property. */ var zIndex :String; function item( index : Int ) : String; /** @throws DOMError */ function getPropertyValue( property : String ) : String; /** @throws DOMError */ function getPropertyCSSValue( property : String ) : CSSValue; function getPropertyPriority( property : String ) : String; /** @throws DOMError */ function setProperty( property : String, value : String, ?priority : String = "" ) : Void; /** @throws DOMError */ function removeProperty( property : String ) : String; }haxe_3.4.4.orig/std/js/html/CSSStyleRule.hx0000664000175000017500000000346213166552354020435 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from cssrule.webidl. Do not edit! package js.html; /** `CSSStyleRule` represents a single CSS style rule. It implements the `CSSRule` interface with a type value of `1` (`CSSRule.STYLE_RULE`). Documentation [CSSStyleRule](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleRule) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleRule$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CSSStyleRule") extern class CSSStyleRule extends CSSRule { var selectorText : String; var style(default,null) : CSSStyleDeclaration; }haxe_3.4.4.orig/std/js/html/CSSStyleSheet.hx0000664000175000017500000000374313166552354020600 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CSSStyleSheet.webidl. Do not edit! package js.html; /** The `CSSStyleSheet` interface represents a single CSS style sheet. It inherits properties and methods from its parent, `StyleSheet`. Documentation [CSSStyleSheet](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CSSStyleSheet") extern class CSSStyleSheet extends StyleSheet { var ownerRule(default,null) : CSSRule; var cssRules(default,null) : CSSRuleList; /** @throws DOMError */ function insertRule( rule : String, index : Int ) : Int; /** @throws DOMError */ function deleteRule( index : Int ) : Void; }haxe_3.4.4.orig/std/js/html/CSSTransition.hx0000664000175000017500000000247613166552354020643 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CSSTransition.webidl. Do not edit! package js.html; @:native("CSSTransition") extern class CSSTransition extends Animation { var transitionProperty(default,null) : String; }haxe_3.4.4.orig/std/js/html/CSSUnknownRule.hx0000664000175000017500000000237613166552354020777 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from cssrule.webidl. Do not edit! package js.html; @:native("CSSUnknownRule") extern class CSSUnknownRule extends CSSRule { }haxe_3.4.4.orig/std/js/html/CSSValue.hx0000664000175000017500000000605313166552354017560 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CSSValue.webidl. Do not edit! package js.html; /** The `CSSValue` interface represents the current computed value of a CSS property. Documentation [CSSValue](https://developer.mozilla.org/en-US/docs/Web/API/CSSValue) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CSSValue$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CSSValue") extern class CSSValue { static inline var CSS_INHERIT : Int = 0; static inline var CSS_PRIMITIVE_VALUE : Int = 1; static inline var CSS_VALUE_LIST : Int = 2; static inline var CSS_CUSTOM : Int = 3; /** A `DOMString` representing the current value. **/ var cssText : String; /** An unsigned short representing a code defining the type of the value. Possible values are:
Constant Description
CSS_CUSTOM The value is a custom value.
CSS_INHERIT The value is inherited and the cssText contains "inherit".
CSS_PRIMITIVE_VALUE The value is a primitive value and an instance of the CSSPrimitiveValue interface can be obtained by using binding-specific casting methods on this instance of the CSSValue interface.
CSS_VALUE_LIST The value is a CSSValue list and an instance of the CSSValueList interface can be obtained by using binding-specific casting methods on this instance of the CSSValue interface.
**/ var cssValueType(default,null) : Int; }haxe_3.4.4.orig/std/js/html/CSSValueList.hx0000664000175000017500000000426713166552354020421 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CSSValueList.webidl. Do not edit! package js.html; /** The `CSSValueList` interface derives from the `CSSValue` interface and provides the abstraction of an ordered collection of CSS values. Documentation [CSSValueList](https://developer.mozilla.org/en-US/docs/Web/API/CSSValueList) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CSSValueList$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CSSValueList") extern class CSSValueList extends CSSValue implements ArrayAccess { /** An `unsigned long` representing the number of `CSSValues` in the list. **/ var length(default,null) : Int; /** This method is used to retrieve a `CSSValue` by ordinal index. The order in this collection represents the order of the values in the CSS style property. If index is greater than or equal to the number of values in the list, this returns `null`. **/ function item( index : Int ) : CSSValue; }haxe_3.4.4.orig/std/js/html/CanvasElement.hx0000664000175000017500000001023313166552354020653 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLCanvasElement.webidl. Do not edit! package js.html; /** The `HTMLCanvasElement` interface provides properties and methods for manipulating the layout and presentation of canvas elements. The `HTMLCanvasElement` interface also inherits the properties and methods of the `HTMLElement` interface. Documentation [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLCanvasElement") extern class CanvasElement extends Element { /** Is a positive `integer` reflecting the `width` HTML attribute of the `canvas` element interpreted in CSS pixels. When the attribute is not specified, or if it is set to an invalid value, like a negative, the default value of `300` is used. **/ var width : Int; /** Is a positive `integer` reflecting the `height` HTML attribute of the `canvas` element interpreted in CSS pixels. When the attribute is not specified, or if it is set to an invalid value, like a negative, the default value of `150` is used. **/ var height : Int; /** @throws DOMError */ /** Returns a drawing context on the canvas, or null if the context ID is not supported. A drawing context lets you draw on the canvas. Calling getContext with `"2d"` returns a `CanvasRenderingContext2D` object, whereas calling it with `"experimental-webgl"` (or `"webgl"`) returns a `WebGLRenderingContext` object. This context is only available on browsers that implement WebGL. **/ function getContext( contextId : String, ?contextOptions : Dynamic ) : Dynamic/*MISSING nsISupports*/; /** @throws DOMError */ /** Returns a data-URL containing a representation of the image in the format specified by the `type` parameter (defaults to `png`). The returned image is in a resolution of 96dpi. **/ function toDataURL( ?type : String = "", ?encoderOptions : Dynamic ) : String; /** @throws DOMError */ /** Creates a `Blob` object representing the image contained in the canvas; this file may be cached on the disk or stored in memory at the discretion of the user agent. **/ function toBlob( callback : Blob -> Void, ?type : String = "", ?encoderOptions : Dynamic ) : Void; /** Shorthand for getting a CanvasRenderingContext2D. */ inline function getContext2d( ?attribs : {} ) : CanvasRenderingContext2D { return cast getContext("2d", attribs); } /** Shorthand for getting a js.html.webgl.RenderingContext. */ inline function getContextWebGL( ?attribs : js.html.webgl.ContextAttributes ) : js.html.webgl.RenderingContext { return CanvasUtil.getContextWebGL(this, attribs); } } private class CanvasUtil { public static function getContextWebGL( canvas :CanvasElement, attribs :{} ) { for (name in ["webgl", "experimental-webgl"]) { var ctx = canvas.getContext(name, attribs); if (ctx != null) return ctx; } return null; } } haxe_3.4.4.orig/std/js/html/CanvasGradient.hx0000664000175000017500000000421013166552354021015 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CanvasRenderingContext2D.webidl. Do not edit! package js.html; /** The `CanvasGradient` interface represents an opaque object describing a gradient. It is returned by the methods `CanvasRenderingContext2D.createLinearGradient()` or `CanvasRenderingContext2D.createRadialGradient()`. Documentation [CanvasGradient](https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CanvasGradient") extern class CanvasGradient { /** @throws DOMError */ /** Adds a new stop, defined by an `offset` and a `color`, to the gradient. If the offset is not between `0` and `1` an `INDEX_SIZE_ERR` is raised, if the color can't be parsed as a CSS `color`, a `SYNTAX_ERR` is raised. **/ function addColorStop( offset : Float, color : String ) : Void; }haxe_3.4.4.orig/std/js/html/CanvasPattern.hx0000664000175000017500000000366613166552354020713 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CanvasRenderingContext2D.webidl. Do not edit! package js.html; /** The `CanvasPattern` interface represents an opaque object describing a pattern, based on an image, a canvas or a video, created by the `CanvasRenderingContext2D.createPattern()` method. Documentation [CanvasPattern](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CanvasPattern") extern class CanvasPattern { /** Applies an `SVGMatrix` representing a linear transform to the pattern. **/ function setTransform( matrix : js.html.svg.Matrix ) : Void; }haxe_3.4.4.orig/std/js/html/CanvasRenderingContext2D.hx0000664000175000017500000001627213166552354022743 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CanvasRenderingContext2D.webidl. Do not edit! package js.html; /** To get an object of this interface, call `getContext()` on a `canvas element`, supplying "2d" as the argument: Documentation [CanvasRenderingContext2D](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CanvasRenderingContext2D") extern class CanvasRenderingContext2D { var canvas(default,null) : CanvasElement; var globalAlpha : Float; var globalCompositeOperation : String; var strokeStyle : haxe.extern.EitherType>; var fillStyle : haxe.extern.EitherType>; var shadowOffsetX : Float; var shadowOffsetY : Float; var shadowBlur : Float; var shadowColor : String; var filter : String; var imageSmoothingEnabled : Bool; var lineWidth : Float; var lineCap : String; var lineJoin : String; var miterLimit : Float; var lineDashOffset : Float; var font : String; var textAlign : String; var textBaseline : String; function save() : Void; function restore() : Void; /** @throws DOMError */ function scale( x : Float, y : Float ) : Void; /** @throws DOMError */ function rotate( angle : Float ) : Void; /** @throws DOMError */ function translate( x : Float, y : Float ) : Void; /** @throws DOMError */ function transform( a : Float, b : Float, c : Float, d : Float, e : Float, f : Float ) : Void; /** @throws DOMError */ function setTransform( a : Float, b : Float, c : Float, d : Float, e : Float, f : Float ) : Void; /** @throws DOMError */ function resetTransform() : Void; function createLinearGradient( x0 : Float, y0 : Float, x1 : Float, y1 : Float ) : CanvasGradient; /** @throws DOMError */ function createRadialGradient( x0 : Float, y0 : Float, r0 : Float, x1 : Float, y1 : Float, r1 : Float ) : CanvasGradient; /** @throws DOMError */ function createPattern( image : haxe.extern.EitherType>>, repetition : String ) : CanvasPattern; function clearRect( x : Float, y : Float, w : Float, h : Float ) : Void; function fillRect( x : Float, y : Float, w : Float, h : Float ) : Void; function strokeRect( x : Float, y : Float, w : Float, h : Float ) : Void; function beginPath() : Void; @:overload( function( ?winding : CanvasWindingRule = "nonzero" ) : Void {} ) function fill( path : Path2D, ?winding : CanvasWindingRule = "nonzero" ) : Void; @:overload( function() : Void {} ) function stroke( path : Path2D ) : Void; /** @throws DOMError */ function drawFocusIfNeeded( element : Element ) : Void; function drawCustomFocusRing( element : Element ) : Bool; @:overload( function( ?winding : CanvasWindingRule = "nonzero" ) : Void {} ) function clip( path : Path2D, ?winding : CanvasWindingRule = "nonzero" ) : Void; @:overload( function( x : Float, y : Float, ?winding : CanvasWindingRule = "nonzero" ) : Bool {} ) function isPointInPath( path : Path2D, x : Float, y : Float, ?winding : CanvasWindingRule = "nonzero" ) : Bool; @:overload( function( x : Float, y : Float ) : Bool {} ) function isPointInStroke( path : Path2D, x : Float, y : Float ) : Bool; /** @throws DOMError */ function fillText( text : String, x : Float, y : Float, ?maxWidth : Float ) : Void; /** @throws DOMError */ function strokeText( text : String, x : Float, y : Float, ?maxWidth : Float ) : Void; /** @throws DOMError */ function measureText( text : String ) : TextMetrics; /** @throws DOMError */ @:overload( function( image : haxe.extern.EitherType>>, dx : Float, dy : Float ) : Void {} ) @:overload( function( image : haxe.extern.EitherType>>, dx : Float, dy : Float, dw : Float, dh : Float ) : Void {} ) function drawImage( image : haxe.extern.EitherType>>, sx : Float, sy : Float, sw : Float, sh : Float, dx : Float, dy : Float, dw : Float, dh : Float ) : Void; /** @throws DOMError */ function addHitRegion( ?options : HitRegionOptions ) : Void; function removeHitRegion( id : String ) : Void; function clearHitRegions() : Void; /** @throws DOMError */ @:overload( function( sw : Float, sh : Float ) : ImageData {} ) function createImageData( imagedata : ImageData ) : ImageData; /** @throws DOMError */ function getImageData( sx : Float, sy : Float, sw : Float, sh : Float ) : ImageData; /** @throws DOMError */ @:overload( function( imagedata : ImageData, dx : Float, dy : Float ) : Void {} ) function putImageData( imagedata : ImageData, dx : Float, dy : Float, dirtyX : Float, dirtyY : Float, dirtyWidth : Float, dirtyHeight : Float ) : Void; /** @throws DOMError */ function setLineDash( segments : Array ) : Void; function getLineDash() : Array; function closePath() : Void; function moveTo( x : Float, y : Float ) : Void; function lineTo( x : Float, y : Float ) : Void; function quadraticCurveTo( cpx : Float, cpy : Float, x : Float, y : Float ) : Void; function bezierCurveTo( cp1x : Float, cp1y : Float, cp2x : Float, cp2y : Float, x : Float, y : Float ) : Void; /** @throws DOMError */ function arcTo( x1 : Float, y1 : Float, x2 : Float, y2 : Float, radius : Float ) : Void; function rect( x : Float, y : Float, w : Float, h : Float ) : Void; /** @throws DOMError */ function arc( x : Float, y : Float, radius : Float, startAngle : Float, endAngle : Float, ?anticlockwise : Bool = false ) : Void; /** @throws DOMError */ function ellipse( x : Float, y : Float, radiusX : Float, radiusY : Float, rotation : Float, startAngle : Float, endAngle : Float, ?anticlockwise : Bool = false ) : Void; }haxe_3.4.4.orig/std/js/html/CanvasWindingRule.hx0000664000175000017500000000245613166552354021521 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CanvasRenderingContext2D.webidl. Do not edit! package js.html; @:enum abstract CanvasWindingRule(String) { var NONZERO = "nonzero"; var EVENODD = "evenodd"; }haxe_3.4.4.orig/std/js/html/CaretPosition.hx0000664000175000017500000000406413166552354020716 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CaretPosition.webidl. Do not edit! package js.html; /** The `CaretPosition` interface represents the caret postion, an indicator for the text insertion point. You can get a `CaretPosition` using the `document.caretPositionFromPoint` method. Documentation [CaretPosition](https://developer.mozilla.org/en-US/docs/Web/API/CaretPosition) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CaretPosition$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CaretPosition") extern class CaretPosition { /** Returns a `Node` containing the found node at the caret's position. **/ var offsetNode(default,null) : Node; /** Returns a `long` representing the character offset in the caret position node. **/ var offset(default,null) : Int; function getClientRect() : DOMRect; }haxe_3.4.4.orig/std/js/html/CharacterData.hx0000664000175000017500000000703013166552354020615 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CharacterData.webidl. Do not edit! package js.html; /** The `CharacterData` abstract interface represents a `Node` object that contains characters. This is an abstract interface, meaning there aren't any object of type `CharacterData`: it is implemented by other interfaces, like `Text`, `Comment`, or `ProcessingInstruction` which aren't abstract. Documentation [CharacterData](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CharacterData") extern class CharacterData extends Node { /** Is a `DOMString` representing the textual data contained in this object. **/ var data : String; /** Returns an `unsigned long` representing the size of the string contained in `CharacterData.data`. **/ var length(default,null) : Int; var previousElementSibling(default,null) : Element; var nextElementSibling(default,null) : Element; /** @throws DOMError */ /** Returns a `DOMString` containing the part of `CharacterData.data` of the specified length and starting at the specified offset. **/ function substringData( offset : Int, count : Int ) : String; /** @throws DOMError */ /** Appends the given `DOMString` to the `CharacterData.data` string; when this method returns, `data` contains the concatenated `DOMString`. **/ function appendData( data : String ) : Void; /** @throws DOMError */ /** Inserts the specified characters, at the specified offset, in the `CharacterData.data` string; when this method returns, `data` contains the modified `DOMString`. **/ function insertData( offset : Int, data : String ) : Void; /** @throws DOMError */ /** Removes the specified amount of characters, starting at the specified offset, from the `CharacterData.data` string; when this method returns, `data` contains the shortened `DOMString`. **/ function deleteData( offset : Int, count : Int ) : Void; /** @throws DOMError */ /** Replaces the specified amount of characters, starting at the specified offset, with the specified `DOMString`; when this method returns, `data` contains the modified `DOMString`. **/ function replaceData( offset : Int, count : Int, data : String ) : Void; function remove() : Void; }haxe_3.4.4.orig/std/js/html/ChromeFilePropertyBag.hx0000664000175000017500000000246113166552354022326 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\File.webidl. Do not edit! package js.html; typedef ChromeFilePropertyBag = { > FilePropertyBag, @:optional var name : String; @:optional var temporary : Bool; }haxe_3.4.4.orig/std/js/html/Client.hx0000664000175000017500000000473013166552354017351 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Client.webidl. Do not edit! package js.html; /** The `Client` interface of the ServiceWorker API represents the scope of a service worker client. A service worker client is either a document in a browser context or a `SharedWorker`, which is controlled by an active worker. A client object acts as a snapshot representation of its associated service worker client in the scope of a service worker. Documentation [Client](https://developer.mozilla.org/en-US/docs/Web/API/Client) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Client$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Client") extern class Client { /** The URL of the current service worker client. **/ var url(default,null) : String; /** Indicates the type of browsing context of the current client. This value can be one of `auxiliary`, `top-level`, `nested`, or `none`. **/ var frameType(default,null) : FrameType; /** Returns the universally unique identifier of the `Client` object. **/ var id(default,null) : String; /** @throws DOMError */ /** Allows a service worker to send a message to a `ServiceWorkerClient`. **/ function postMessage( message : Dynamic, ?transfer : Array ) : Void; }haxe_3.4.4.orig/std/js/html/ClientQueryOptions.hx0000664000175000017500000000247613166552354021760 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Clients.webidl. Do not edit! package js.html; typedef ClientQueryOptions = { @:optional var includeUncontrolled : Bool; @:optional var type : Dynamic/*MISSING ClientType*/; }haxe_3.4.4.orig/std/js/html/Clients.hx0000664000175000017500000000462013166552354017532 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Clients.webidl. Do not edit! package js.html; /** The `Clients` interface of the Service Workers API represents a container for a list of `Client` objects. Documentation [Clients](https://developer.mozilla.org/en-US/docs/Web/API/Clients) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Clients$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Clients") extern class Clients { /** Gets a service worker client matching a given `id` and returns it in a `Promise`. **/ function get( id : String ) : Promise; /** Gets a list of service worker clients and returns them in a `Promise`. Include the `options` parameter to return all service worker clients whose origin is the same as the associated service worker's origin. If `options` are not included, the method returns only the service worker clients controlled by the service worker.  **/ function matchAll( ?options : ClientQueryOptions ) : Promise>; /** Allows an active Service Worker to set itself as the active worker for a client page when the worker and the page are in the same scope.  **/ function claim() : Promise; }haxe_3.4.4.orig/std/js/html/ClipboardEvent.hx0000664000175000017500000000410213166552354021025 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\ClipboardEvent.webidl. Do not edit! package js.html; /** The `ClipboardEvent` interface represents events providing information related to modification of the clipboard, that is `cut`, `copy`, and `paste` events. Documentation [ClipboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("ClipboardEvent") extern class ClipboardEvent extends Event { /** Is a `DataTransfer` object containing the data affected by the user-initiated `cut`, `copy`, or `paste` operation, along with its MIME type. **/ var clipboardData(default,null) : DataTransfer; /** @throws DOMError */ function new( type : String, ?eventInitDict : ClipboardEventInit ) : Void; }haxe_3.4.4.orig/std/js/html/ClipboardEventInit.hx0000664000175000017500000000246313166552354021661 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\ClipboardEvent.webidl. Do not edit! package js.html; typedef ClipboardEventInit = { > EventInit, @:optional var data : String; @:optional var dataType : String; }haxe_3.4.4.orig/std/js/html/CloseEvent.hx0000664000175000017500000001546413166552354020210 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CloseEvent.webidl. Do not edit! package js.html; /** A `CloseEvent` is sent to clients using WebSockets when the connection is closed. This is delivered to the listener indicated by the `WebSocket` object's `onclose` attribute. Documentation [CloseEvent](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CloseEvent") extern class CloseEvent extends Event { /** Returns a `Boolean` that Indicates whether or not the connection was cleanly closed. **/ var wasClean(default,null) : Bool; /** Returns an unsigned short containing the close code send by the server. The following values are permitted status codes.
Status code Name Description
0–999   Reserved and not used.
1000 CLOSE_NORMAL Normal closure; the connection successfully completed whatever purpose for which it was created.
1001 CLOSE_GOING_AWAY The endpoint is going away, either because of a server failure or because the browser is navigating away from the page that opened the connection.
1002 CLOSE_PROTOCOL_ERROR The endpoint is terminating the connection due to a protocol error.
1003 CLOSE_UNSUPPORTED The connection is being terminated because the endpoint received data of a type it cannot accept (for example, a text-only endpoint received binary data).
1004   Reserved. A meaning might be defined in the future.
1005 CLOSE_NO_STATUS Reserved.  Indicates that no status code was provided even though one was expected.
1006 CLOSE_ABNORMAL Reserved. Used to indicate that a connection was closed abnormally (that is, with no close frame being sent) when a status code is expected.
1007 Unsupported Data The endpoint is terminating the connection because a message was received that contained inconsistent data (e.g., non-UTF-8 data within a text message).
1008 Policy Violation The endpoint is terminating the connection because it received a message that violates its policy. This is a generic status code, used when codes 1003 and 1009 are not suitable.
1009 CLOSE_TOO_LARGE The endpoint is terminating the connection because a data frame was received that is too large.
1010 Missing Extension The client is terminating the connection because it expected the server to negotiate one or more extension, but the server didn't.
1011 Internal Error The server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.
1012 Service Restart The server is terminating the connection because it is restarting. [Ref]
1013 Try Again Later The server is terminating the connection due to a temporary condition, e.g. it is overloaded and is casting off some of its clients. [Ref]
1014   Reserved for future use by the WebSocket standard.
1015 TLS Handshake Reserved. Indicates that the connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified).
1016–1999   Reserved for future use by the WebSocket standard.
2000–2999   Reserved for use by WebSocket extensions.
3000–3999   Available for use by libraries and frameworks. May not be used by applications. Available for registration at the IANA via first-come, first-serve.
4000–4999   Available for use by applications.
**/ var code(default,null) : Int; /** Returns a `DOMString` indicating the reason the server closed the connection. This is specific to the particular server and sub-protocol. **/ var reason(default,null) : String; /** @throws DOMError */ function new( type : String, ?eventInitDict : CloseEventInit ) : Void; }haxe_3.4.4.orig/std/js/html/CloseEventInit.hx0000664000175000017500000000250713166552354021026 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CloseEvent.webidl. Do not edit! package js.html; typedef CloseEventInit = { > EventInit, @:optional var code : Int; @:optional var reason : String; @:optional var wasClean : Bool; }haxe_3.4.4.orig/std/js/html/CommandEvent.hx0000664000175000017500000000262713166552354020516 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CommandEvent.webidl. Do not edit! package js.html; @:native("CommandEvent") extern class CommandEvent extends Event { var command(default,null) : String; function initCommandEvent( type : String, canBubble : Bool, cancelable : Bool, command : String ) : Void; }haxe_3.4.4.orig/std/js/html/Comment.hx0000664000175000017500000000372313166552354017536 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Comment.webidl. Do not edit! package js.html; /** The `Comment` interface represents textual notations within markup; although it is generally not visually shown, such comments are available to be read in the source view. Comments are represented in HTML and XML as content between '`!--`' and '`--`'. In XML, the character sequence '`--`' cannot be used within a comment. Documentation [Comment](https://developer.mozilla.org/en-US/docs/Web/API/Comment) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Comment$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Comment") extern class Comment extends CharacterData { /** @throws DOMError */ function new( ?data : String = "" ) : Void; }haxe_3.4.4.orig/std/js/html/CompositeOperation.hx0000664000175000017500000000246713166552354021763 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Keyframe.webidl. Do not edit! package js.html; @:enum abstract CompositeOperation(String) { var REPLACE = "replace"; var ADD = "add"; var ACCUMULATE = "accumulate"; }haxe_3.4.4.orig/std/js/html/CompositionEvent.hx0000664000175000017500000000371313166552354021440 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CompositionEvent.webidl. Do not edit! package js.html; /** The DOM `CompositionEvent` represents events that occur due to the user indirectly entering text. Documentation [CompositionEvent](https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CompositionEvent") extern class CompositionEvent extends UIEvent { var data(default,null) : String; var locale(default,null) : String; function initCompositionEvent( typeArg : String, canBubbleArg : Bool, cancelableArg : Bool, viewArg : Window, dataArg : String, localeArg : String ) : Void; }haxe_3.4.4.orig/std/js/html/ComputedTimingProperties.hx0000664000175000017500000000271613166552354023142 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AnimationEffectReadOnly.webidl. Do not edit! package js.html; typedef ComputedTimingProperties = { > AnimationEffectTimingProperties, @:optional var activeDuration : Float; @:optional var currentIteration : Float; @:optional var endTime : Float; @:optional var localTime : Float; @:optional var progress : Float; }haxe_3.4.4.orig/std/js/html/Console.hx0000664000175000017500000001227713166552354017542 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Console.webidl. Do not edit! package js.html; /** The `Console` object provides access to the browser's debugging console (e.g., the Web Console in Firefox). The specifics of how it works vary from browser to browser, but there is a de facto set of features that are typically provided. Documentation [Console](https://developer.mozilla.org/en-US/docs/Web/API/Console) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Console$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Console") extern class Console { /** For general output of logging information. You may use string substitution and additional arguments with this method. **/ function log( data : haxe.extern.Rest ) : Void; /** Informative logging information. You may use string substitution and additional arguments with this method. **/ function info( data : haxe.extern.Rest ) : Void; /** Outputs a warning message. You may use string substitution and additional arguments with this method. **/ function warn( data : haxe.extern.Rest ) : Void; /** Outputs an error message. You may use string substitution and additional arguments with this method. **/ function error( data : haxe.extern.Rest ) : Void; /** An alias for `error()` **/ function exception( data : haxe.extern.Rest ) : Void; /** An alias for `log()` **/ function debug( data : haxe.extern.Rest ) : Void; /** Displays tabular data as a table. **/ function table( data : haxe.extern.Rest ) : Void; /** Outputs a stack trace. **/ function trace() : Void; /** Displays an interactive listing of the properties of a specified JavaScript object. This listing lets you use disclosure triangles to examine the contents of child objects. **/ function dir( data : haxe.extern.Rest ) : Void; /** Displays an XML/HTML Element representation of the specified object if possible or the JavaScript Object view if it is not. **/ function dirxml( data : haxe.extern.Rest ) : Void; /** Creates a new inline group, indenting all following output by another level. To move back out a level, call `groupEnd()`. **/ function group( data : haxe.extern.Rest ) : Void; /** Creates a new inline group, indenting all following output by another level; unlike `group()`, this starts with the inline group collapsed, requiring the use of a disclosure button to expand it. To move back out a level, call `groupEnd()`. **/ function groupCollapsed( data : haxe.extern.Rest ) : Void; /** Exits the current inline group. **/ function groupEnd( data : haxe.extern.Rest ) : Void; /** Starts a timer with a name specified as an input parameter. Up to 10,000 simultaneous timers can run on a given page. **/ function time( ?time : Dynamic ) : Void; /** Stops the specified timer and logs the elapsed time in seconds since its start. **/ function timeEnd( ?time : Dynamic ) : Void; /** Adds a marker to the browser's Timeline or Waterfall tool. **/ function timeStamp( ?data : Dynamic ) : Void; /** Starts the browser's build-in profiler (for example, the Firefox performance tool). You can specify an optional name for the profile. **/ function profile( data : haxe.extern.Rest ) : Void; /** Stops the profiler. You can see the resulting profile in the browser's performance tool (for example, the Firefox performance tool). **/ function profileEnd( data : haxe.extern.Rest ) : Void; /** Log a message and stack trace to console if first argument is `false`. **/ function assert( condition : Bool, data : haxe.extern.Rest ) : Void; /** Log the number of times this line has been called with the given label. **/ function count( data : haxe.extern.Rest ) : Void; /** Clear the console. **/ function clear() : Void; function markTimeline() : Void; function timeline() : Void; function timelineEnd() : Void; }haxe_3.4.4.orig/std/js/html/ContentElement.hx0000664000175000017500000000415213166552354021055 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLContentElement.webidl. Do not edit! package js.html; /** The `HTMLContentElement` interface represents a `content` HTML Element, which is used in Shadow DOM. Documentation [HTMLContentElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLContentElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLContentElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLContentElement") extern class ContentElement extends Element { /** Is a `DOMString` that reflects the `select` HTML attribute. The value is a comma-separated list of CSS selectors that select the content to insert in place of the `content` element. **/ var select : String; /** Returns a static `NodeList` of the `distributed nodes` associated with this `content` element.  **/ function getDistributedNodes() : NodeList; }haxe_3.4.4.orig/std/js/html/ConvertCoordinateOptions.hx0000664000175000017500000000253013166552354023133 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\GeometryUtils.webidl. Do not edit! package js.html; typedef ConvertCoordinateOptions = { @:optional var fromBox : Dynamic/*MISSING CSSBoxType*/; @:optional var toBox : Dynamic/*MISSING CSSBoxType*/; }haxe_3.4.4.orig/std/js/html/Coordinates.hx0000664000175000017500000000622413166552354020405 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Coordinates.webidl. Do not edit! package js.html; /** The `Coordinates` interface represents the position and altitude of the device on Earth, as well as the accuracy with which these properties are calculated. Documentation [Coordinates](https://developer.mozilla.org/en-US/docs/Web/API/Coordinates) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Coordinates$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Coordinates") extern class Coordinates { /** Returns a `double` representing the position's latitude in decimal degrees. **/ var latitude(default,null) : Float; /** Returns a `double` representing the position's longitude in decimal degrees. **/ var longitude(default,null) : Float; /** Returns a `double` representing the position's altitude in metres, relative to sea level. This value can be `null` if the implementation cannot provide the data. **/ var altitude(default,null) : Float; /** Returns a `double` representing the accuracy of the `latitude` and `longitude` properties, expressed in meters. **/ var accuracy(default,null) : Float; /** Returns a `double` representing the accuracy of the `altitude` expressed in meters. This value can be `null`. **/ var altitudeAccuracy(default,null) : Float; /** Returns a `double` representing the direction in which the device is traveling. This value, specified in degrees, indicates how far off from heading true north the device is. `0` degrees represents true north, and the direction is determined clockwise (which means that east is `90` degrees and west is `270` degrees). If `speed` is `0`, `heading` is `NaN`. If the device is unable to provide `heading` information, this value is `null`. **/ var heading(default,null) : Float; /** Returns a `double` representing the velocity of the device in meters per second. This value can be `null`. **/ var speed(default,null) : Float; }haxe_3.4.4.orig/std/js/html/Crypto.hx0000664000175000017500000000402613166552354017411 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Crypto.webidl. Do not edit! package js.html; /** The `Crypto` interface represents basic cryptography features available in the current context. It allows access to a cryptographically strong random number generator and to cryptographic primitives. Documentation [Crypto](https://developer.mozilla.org/en-US/docs/Web/API/Crypto) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Crypto$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Crypto") extern class Crypto { /** Returns a `SubtleCrypto` object providing access to common cryptographic primitives, like hashing, signing, encryption or decryption. **/ var subtle(default,null) : SubtleCrypto; /** @throws DOMError */ function getRandomValues( array : ArrayBufferView ) : ArrayBufferView; }haxe_3.4.4.orig/std/js/html/CryptoKey.hx0000664000175000017500000000444013166552354020062 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\SubtleCrypto.webidl. Do not edit! package js.html; /** The `CryptoKey` interface represents a cryptographic key derived from a specific key algorithm. Documentation [CryptoKey](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CryptoKey") extern class CryptoKey { /** Returns an enumerated value representing the type of the key, a secret key (for symmetric algorithm), a public or a private key (for an asymmetric algorithm) **/ var type(default,null) : String; /** Returns a `Boolean` indicating if the raw information may be exported to the application or not. **/ var extractable(default,null) : Bool; /** Returns an opaque object representing a particular cipher the key has to be used with. **/ var algorithm(default,null) : Dynamic; /** Returns an array of enumerated values indicating what the key can be used for. **/ var usages(default,null) : Array; }haxe_3.4.4.orig/std/js/html/CustomEvent.hx0000664000175000017500000000414113166552354020403 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CustomEvent.webidl. Do not edit! package js.html; /** This interface inherits properties from its parent, `Event`: Documentation [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("CustomEvent") extern class CustomEvent extends Event { /** Any data passed when initializing the event. **/ var detail(default,null) : Dynamic; /** @throws DOMError */ function new( type : String, ?eventInitDict : CustomEventInit ) : Void; /** @throws DOMError */ /** Initializes a `CustomEvent` object. If the event has already being dispatched, this method does nothing. **/ function initCustomEvent( type : String, canBubble : Bool, cancelable : Bool, detail : Dynamic ) : Void; }haxe_3.4.4.orig/std/js/html/CustomEventInit.hx0000664000175000017500000000241513166552354021231 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\CustomEvent.webidl. Do not edit! package js.html; typedef CustomEventInit = { > EventInit, @:optional var detail : Dynamic; }haxe_3.4.4.orig/std/js/html/DListElement.hx0000664000175000017500000000367213166552354020470 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLDListElement.webidl. Do not edit! package js.html; /** The `HTMLDListElement` interface provides special properties (beyond those of the regular `HTMLElement` interface it also has available to it by inheritance) for manipulating definition list elements. Documentation [HTMLDListElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDListElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDListElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLDListElement") extern class DListElement extends Element { /** Is a `Boolean` indicating that spacing between list items should be reduced. **/ var compact : Bool; }haxe_3.4.4.orig/std/js/html/DOMCursor.hx0000664000175000017500000000310713166552354017745 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMCursor.webidl. Do not edit! package js.html; @:native("DOMCursor") extern class DOMCursor extends EventTarget { var done(default,null) : Bool; var readyState(default,null) : DOMRequestReadyState; var result(default,null) : Dynamic; var error(default,null) : DOMError; var onsuccess : haxe.Constraints.Function; var onerror : haxe.Constraints.Function; /** @throws DOMError */ @:native("continue") function continue_() : Void; }haxe_3.4.4.orig/std/js/html/DOMElement.hx0000664000175000017500000002611213166552354020062 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Element.webidl. Do not edit! package js.html; /** The `Element` interface represents an object of a `Document`. This interface describes methods and properties common to all kinds of elements. Specific behaviors are described in interfaces which inherit from `Element` but add additional functionality. Documentation [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Element$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Element") extern class DOMElement extends Node { var tagName(default,null) : String; var id : String; var className : String; var classList(default,null) : DOMTokenList; var attributes(default,null) : NamedNodeMap; var onwheel : haxe.Constraints.Function; var title : String; var lang : String; var dir : String; var dataset(default,null) : DOMStringMap; var innerText : String; var itemScope : Bool; var itemType(default,null) : DOMTokenList; var itemId : String; var itemRef(default,null) : DOMTokenList; var itemProp(default,null) : DOMTokenList; var properties(default,null) : HTMLPropertiesCollection; var itemValue : Dynamic; var hidden : Bool; var tabIndex : Int; var accessKey : String; var accessKeyLabel(default,null) : String; var draggable : Bool; var contentEditable : String; var isContentEditable(default,null) : Bool; var contextMenu(default,null) : MenuElement; var spellcheck : Bool; var style(default,null) : CSSStyleDeclaration; var oncopy : haxe.Constraints.Function; var oncut : haxe.Constraints.Function; var onpaste : haxe.Constraints.Function; var offsetParent(default,null) : Element; var offsetTop(default,null) : Int; var offsetLeft(default,null) : Int; var offsetWidth(default,null) : Int; var offsetHeight(default,null) : Int; var scrollTop : Int; var scrollLeft : Int; var scrollWidth(default,null) : Int; var scrollHeight(default,null) : Int; var clientTop(default,null) : Int; var clientLeft(default,null) : Int; var clientWidth(default,null) : Int; var clientHeight(default,null) : Int; var scrollTopMax(default,null) : Int; var scrollLeftMax(default,null) : Int; var innerHTML : String; var outerHTML : String; var shadowRoot(default,null) : ShadowRoot; var onabort : haxe.Constraints.Function; var onblur : haxe.Constraints.Function; var onfocus : haxe.Constraints.Function; var oncanplay : haxe.Constraints.Function; var oncanplaythrough : haxe.Constraints.Function; var onchange : haxe.Constraints.Function; var onclick : haxe.Constraints.Function; var oncontextmenu : haxe.Constraints.Function; var ondblclick : haxe.Constraints.Function; var ondrag : haxe.Constraints.Function; var ondragend : haxe.Constraints.Function; var ondragenter : haxe.Constraints.Function; var ondragleave : haxe.Constraints.Function; var ondragover : haxe.Constraints.Function; var ondragstart : haxe.Constraints.Function; var ondrop : haxe.Constraints.Function; var ondurationchange : haxe.Constraints.Function; var onemptied : haxe.Constraints.Function; var onended : haxe.Constraints.Function; var oninput : haxe.Constraints.Function; var oninvalid : haxe.Constraints.Function; var onkeydown : haxe.Constraints.Function; var onkeypress : haxe.Constraints.Function; var onkeyup : haxe.Constraints.Function; var onload : haxe.Constraints.Function; var onloadeddata : haxe.Constraints.Function; var onloadedmetadata : haxe.Constraints.Function; var onloadstart : haxe.Constraints.Function; var onmousedown : haxe.Constraints.Function; var onmouseenter : haxe.Constraints.Function; var onmouseleave : haxe.Constraints.Function; var onmousemove : haxe.Constraints.Function; var onmouseout : haxe.Constraints.Function; var onmouseover : haxe.Constraints.Function; var onmouseup : haxe.Constraints.Function; var onpause : haxe.Constraints.Function; var onplay : haxe.Constraints.Function; var onplaying : haxe.Constraints.Function; var onprogress : haxe.Constraints.Function; var onratechange : haxe.Constraints.Function; var onreset : haxe.Constraints.Function; var onresize : haxe.Constraints.Function; var onscroll : haxe.Constraints.Function; var onseeked : haxe.Constraints.Function; var onseeking : haxe.Constraints.Function; var onselect : haxe.Constraints.Function; var onshow : haxe.Constraints.Function; var onstalled : haxe.Constraints.Function; var onsubmit : haxe.Constraints.Function; var onsuspend : haxe.Constraints.Function; var ontimeupdate : haxe.Constraints.Function; var onvolumechange : haxe.Constraints.Function; var onwaiting : haxe.Constraints.Function; var onpointercancel : haxe.Constraints.Function; var onpointerdown : haxe.Constraints.Function; var onpointerup : haxe.Constraints.Function; var onpointermove : haxe.Constraints.Function; var onpointerout : haxe.Constraints.Function; var onpointerover : haxe.Constraints.Function; var onpointerenter : haxe.Constraints.Function; var onpointerleave : haxe.Constraints.Function; var ongotpointercapture : haxe.Constraints.Function; var onlostpointercapture : haxe.Constraints.Function; var onfullscreenchange : haxe.Constraints.Function; var onfullscreenerror : haxe.Constraints.Function; var onpointerlockchange : haxe.Constraints.Function; var onpointerlockerror : haxe.Constraints.Function; var previousElementSibling(default,null) : Element; var nextElementSibling(default,null) : Element; var onerror : haxe.Constraints.Function; var children(default,null) : HTMLCollection; var firstElementChild(default,null) : Element; var lastElementChild(default,null) : Element; var childElementCount(default,null) : Int; var ontouchstart : haxe.Constraints.Function; var ontouchend : haxe.Constraints.Function; var ontouchmove : haxe.Constraints.Function; var ontouchcancel : haxe.Constraints.Function; function getAttributeNames() : Array; function getAttribute( name : String ) : String; function getAttributeNS( namespace_ : String, localName : String ) : String; /** @throws DOMError */ function setAttribute( name : String, value : String ) : Void; /** @throws DOMError */ function setAttributeNS( namespace_ : String, name : String, value : String ) : Void; /** @throws DOMError */ function removeAttribute( name : String ) : Void; /** @throws DOMError */ function removeAttributeNS( namespace_ : String, localName : String ) : Void; function hasAttribute( name : String ) : Bool; function hasAttributeNS( namespace_ : String, localName : String ) : Bool; function hasAttributes() : Bool; /** @throws DOMError */ function closest( selector : String ) : Element; /** @throws DOMError */ function matches( selector : String ) : Bool; /** @throws DOMError */ function webkitMatchesSelector( selector : String ) : Bool; function getElementsByTagName( localName : String ) : HTMLCollection; /** @throws DOMError */ function getElementsByTagNameNS( namespace_ : String, localName : String ) : HTMLCollection; function getElementsByClassName( classNames : String ) : HTMLCollection; /** @throws DOMError */ /** Designates a specific element as the capture target of future `PointerEvent`. **/ function setPointerCapture( pointerId : Int ) : Void; /** @throws DOMError */ function releasePointerCapture( pointerId : Int ) : Void; function setCapture( ?retargetToElement : Bool = false ) : Void; function releaseCapture() : Void; function requestPointerLock() : Void; function getAttributeNode( name : String ) : Attr; /** @throws DOMError */ function setAttributeNode( newAttr : Attr ) : Attr; /** @throws DOMError */ function removeAttributeNode( oldAttr : Attr ) : Attr; function getAttributeNodeNS( namespaceURI : String, localName : String ) : Attr; /** @throws DOMError */ function setAttributeNodeNS( newAttr : Attr ) : Attr; function click() : Void; /** @throws DOMError */ function focus() : Void; /** @throws DOMError */ function blur() : Void; function getClientRects() : DOMRectList; function getBoundingClientRect() : DOMRect; @:overload( function( top : Bool ) : Void {} ) function scrollIntoView( ?options : ScrollIntoViewOptions ) : Void; @:overload( function( x : Float, y : Float ) : Void {} ) function scroll( ?options : ScrollToOptions ) : Void; @:overload( function( x : Float, y : Float ) : Void {} ) function scrollTo( ?options : ScrollToOptions ) : Void; @:overload( function( x : Float, y : Float ) : Void {} ) function scrollBy( ?options : ScrollToOptions ) : Void; /** @throws DOMError */ function insertAdjacentHTML( position : String, text : String ) : Void; /** @throws DOMError */ function querySelector( selectors : String ) : Element; /** @throws DOMError */ function querySelectorAll( selectors : String ) : NodeList; /** @throws DOMError */ function createShadowRoot() : ShadowRoot; /** … **/ function getDestinationInsertionPoints() : NodeList; /** @throws DOMError */ function requestFullscreen( ?options : Dynamic ) : Void; /** @throws DOMError */ /** A shortcut method to create and run an animation on an element. Returns the created Animation object instance. **/ function animate( frames : Dynamic, ?options : haxe.extern.EitherType ) : Animation; /** Returns an array of Animation objects currently active on the element. **/ function getAnimations() : Array; function remove() : Void; /** @throws DOMError */ function convertQuadFromNode( quad : DOMQuad, from : haxe.extern.EitherType>, ?options : ConvertCoordinateOptions ) : DOMQuad; /** @throws DOMError */ function convertRectFromNode( rect : DOMRectReadOnly, from : haxe.extern.EitherType>, ?options : ConvertCoordinateOptions ) : DOMQuad; /** @throws DOMError */ function convertPointFromNode( point : DOMPointInit, from : haxe.extern.EitherType>, ?options : ConvertCoordinateOptions ) : DOMPoint; }haxe_3.4.4.orig/std/js/html/DOMError.hx0000664000175000017500000000360613166552354017565 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMError.webidl. Do not edit! package js.html; /** The `DOMError` interface describes an error object that contains an error name. Documentation [DOMError](https://developer.mozilla.org/en-US/docs/Web/API/DOMError) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMError$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMError") extern class DOMError { /** Returns a `DOMString` representing one of the error type names (see below). **/ var name(default,null) : String; var message(default,null) : String; /** @throws DOMError */ function new( name : String, ?message : String = "" ) : Void; }haxe_3.4.4.orig/std/js/html/DOMException.hx0000664000175000017500000000664213166552354020435 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMException.webidl. Do not edit! package js.html; /** The `DOMException` interface represents an abnormal event (called an exception) which occurs as a result of calling a method or accessing a property of a web API. This is basically how error conditions are described in web APIs. Documentation [DOMException](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMException$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMException") extern class DOMException { static inline var INDEX_SIZE_ERR : Int = 1; static inline var DOMSTRING_SIZE_ERR : Int = 2; static inline var HIERARCHY_REQUEST_ERR : Int = 3; static inline var WRONG_DOCUMENT_ERR : Int = 4; static inline var INVALID_CHARACTER_ERR : Int = 5; static inline var NO_DATA_ALLOWED_ERR : Int = 6; static inline var NO_MODIFICATION_ALLOWED_ERR : Int = 7; static inline var NOT_FOUND_ERR : Int = 8; static inline var NOT_SUPPORTED_ERR : Int = 9; static inline var INUSE_ATTRIBUTE_ERR : Int = 10; static inline var INVALID_STATE_ERR : Int = 11; static inline var SYNTAX_ERR : Int = 12; static inline var INVALID_MODIFICATION_ERR : Int = 13; static inline var NAMESPACE_ERR : Int = 14; static inline var INVALID_ACCESS_ERR : Int = 15; static inline var VALIDATION_ERR : Int = 16; static inline var TYPE_MISMATCH_ERR : Int = 17; static inline var SECURITY_ERR : Int = 18; static inline var NETWORK_ERR : Int = 19; static inline var ABORT_ERR : Int = 20; static inline var URL_MISMATCH_ERR : Int = 21; static inline var QUOTA_EXCEEDED_ERR : Int = 22; static inline var TIMEOUT_ERR : Int = 23; static inline var INVALID_NODE_TYPE_ERR : Int = 24; static inline var DATA_CLONE_ERR : Int = 25; var code(default,null) : Int; var message(default,null) : String; var result(default,null) : Int; var name(default,null) : String; var filename(default,null) : String; var lineNumber(default,null) : Int; var columnNumber(default,null) : Int; var data(default,null) : Dynamic/*MISSING nsISupports*/; var stack(default,null) : String; /** @throws DOMError */ function new( ?message : String = "", ?name : String ) : Void; }haxe_3.4.4.orig/std/js/html/DOMImplementation.hx0000664000175000017500000000522113166552354021454 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMImplementation.webidl. Do not edit! package js.html; /** The `DOMImplementation` interface represent an object providing methods which are not dependent on any particular document. Such an object is returned by the `Document.implementation` property. Documentation [DOMImplementation](https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMImplementation") extern class DOMImplementation { /** Returns a `Boolean` indicating if a given feature is supported or not. This function is unreliable and kept for compatibility purpose alone: except for SVG-related queries, it always returns `true`. Old browsers are very inconsistent in their behavior. **/ function hasFeature( feature : String, version : String ) : Bool; /** @throws DOMError */ /** Creates and returns a `DocumentType`. **/ function createDocumentType( qualifiedName : String, publicId : String, systemId : String ) : DocumentType; /** @throws DOMError */ /** Creates and returns an `XMLDocument`. **/ function createDocument( namespace_ : String, qualifiedName : String, ?doctype : DocumentType ) : HTMLDocument; /** @throws DOMError */ /** Creates and returns an HTML `Document`. **/ function createHTMLDocument( ?title : String ) : HTMLDocument; }haxe_3.4.4.orig/std/js/html/DOMMatrix.hx0000664000175000017500000001175513166552354017744 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMMatrix.webidl. Do not edit! package js.html; /** The `DOMMatrix` interface represents 4x4 matrices, suitable for 2D and 3D operations. Documentation [DOMMatrix](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMMatrix") extern class DOMMatrix extends DOMMatrixReadOnly { /** @throws DOMError */ @:overload( function() : Void {} ) @:overload( function( transformList : String ) : Void {} ) @:overload( function( other : DOMMatrixReadOnly ) : Void {} ) @:overload( function( array32 : Float32Array ) : Void {} ) @:overload( function( array64 : Float64Array ) : Void {} ) function new( numberSequence : Array ) : Void; function multiplySelf( other : DOMMatrix ) : DOMMatrix; function preMultiplySelf( other : DOMMatrix ) : DOMMatrix; /** Returns itself, a `DOMMatrix`, with its new content being the result of the matrix being translated by the given vector. **/ function translateSelf( tx : Float, ty : Float, ?tz : Float = 0.0 ) : DOMMatrix; /** Returns itself, a `DOMMatrix`, with its new content being the result of the matrix x and y dimensions being scaled by the given factor, centered on the origin given. **/ function scaleSelf( scale : Float, ?originX : Float = 0.0, ?originY : Float = 0.0 ) : DOMMatrix; /** Returns itself, a `DOMMatrix`, with its new content being the result of the matrix x, y and z dimension being scaled by the given factor, centered on the origin given. **/ function scale3dSelf( scale : Float, ?originX : Float = 0.0, ?originY : Float = 0.0, ?originZ : Float = 0.0 ) : DOMMatrix; /** Returns itself, a `DOMMatrix`, with its new content being the result of the matrix x, y and z dimension being scaled by the given factor for each dimension, centered on the origin given. **/ function scaleNonUniformSelf( scaleX : Float, ?scaleY : Float = 1.0, ?scaleZ : Float = 1.0, ?originX : Float = 0.0, ?originY : Float = 0.0, ?originZ : Float = 0.0 ) : DOMMatrix; /** Returns itself, a `DOMMatrix`, with its new content being the result of the original matrix being rotated by the given angle, with the rotation centered on the origin given. **/ function rotateSelf( angle : Float, ?originX : Float = 0.0, ?originY : Float = 0.0 ) : DOMMatrix; /** Returns itself, a `DOMMatrix`, with its new content being the result of the original matrix being rotated by the angle between the given vector and (1,0), centered on the origin given. **/ function rotateFromVectorSelf( x : Float, y : Float ) : DOMMatrix; /** Returns itself, a `DOMMatrix`, with its new content being the result of the original matrix being rotated by the given angle and the give vector. **/ function rotateAxisAngleSelf( x : Float, y : Float, z : Float, angle : Float ) : DOMMatrix; /** Returns itself, a `DOMMatrix`, with its new content being the result of the original matrix being skewed along the x-axis by the given factor. **/ function skewXSelf( sx : Float ) : DOMMatrix; /** Returns itself, a `DOMMatrix`, with its new content being the result of the original matrix being skewed along the y-axis by the given factor. **/ function skewYSelf( sy : Float ) : DOMMatrix; /** Returns itself,  a `DOMMatrix`, with its new content being the result of the original matrix being inverted. If the matrix cannot be inverted, all its components are set to `NaN` and `is2D()` returns `false`. **/ function invertSelf() : DOMMatrix; /** @throws DOMError */ /** Returns itself, a `DOMMatrix`, with its describing the matrix representing the same transformation as the CSS `transform` functions given in parameter. **/ function setMatrixValue( transformList : String ) : DOMMatrix; }haxe_3.4.4.orig/std/js/html/DOMMatrixReadOnly.hx0000664000175000017500000001775513166552354021410 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMMatrix.webidl. Do not edit! package js.html; /** The `DOMMatrixReadOnly` interface represents 4x4 matrices, suitable for 2D and 3D operations. If this interface defines only read-only matrices, the `DOMMatrix` interface which inherits from it, add all the properties and the methods to allow to have modifiable matrices. Documentation [DOMMatrixReadOnly](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrixReadOnly) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrixReadOnly$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMMatrixReadOnly") extern class DOMMatrixReadOnly { /** Are double representing each component of a 4x4 matrix needed for 2D rotations and translations. They are aliases for some components of the 4x4 matrix: 2D 3D equivalent
a m11
b m12
c m21
d m22
e m41
f m42
They are read-only, but their counterpart, with the same name, in DOMMatrix aren't. **/ var a(default,null) : Float; var b(default,null) : Float; var c(default,null) : Float; var d(default,null) : Float; var e(default,null) : Float; var f(default,null) : Float; /** Are `double` representing each component of a 4x4 matrix. They are read-only, but their counterpart, with the same name, in `DOMMatrix` aren't. **/ var m11(default,null) : Float; var m12(default,null) : Float; var m13(default,null) : Float; var m14(default,null) : Float; var m21(default,null) : Float; var m22(default,null) : Float; var m23(default,null) : Float; var m24(default,null) : Float; var m31(default,null) : Float; var m32(default,null) : Float; var m33(default,null) : Float; var m34(default,null) : Float; var m41(default,null) : Float; var m42(default,null) : Float; var m43(default,null) : Float; var m44(default,null) : Float; /** Is a `Boolean` indicating if the matrix contains a 2D matrix and only accept 2D transformations. **/ var is2D(default,null) : Bool; var identity(default,null) : Bool; /** Returns a `DOMMatrix` containing a new matrix being the result of the matrix being translated by the given vector. The original matrix is not modified. **/ function translate( tx : Float, ty : Float, ?tz : Float = 0.0 ) : DOMMatrix; /** Returns a `DOMMatrix` containing a new matrix being the result of the matrix x and y dimensions being scaled by the given factor, centered on the origin given. The original matrix is not modified. **/ function scale( scale : Float, ?originX : Float = 0.0, ?originY : Float = 0.0 ) : DOMMatrix; /** Returns a `DOMMatrix` containing a new matrix being the result of the matrix x, y and z dimension being scaled by the given factor, centered on the origin given. The original matrix is not modified. **/ function scale3d( scale : Float, ?originX : Float = 0.0, ?originY : Float = 0.0, ?originZ : Float = 0.0 ) : DOMMatrix; /** Returns a `DOMMatrix` containing a new matrix being the result of the matrix x, y and z dimension being scaled by the given factor for each dimension, centered on the origin given. The original matrix is not modified. **/ function scaleNonUniform( scaleX : Float, ?scaleY : Float = 1.0, ?scaleZ : Float = 1.0, ?originX : Float = 0.0, ?originY : Float = 0.0, ?originZ : Float = 0.0 ) : DOMMatrix; /** Returns a `DOMMatrix` containing a new matrix being the result of the original matrix being rotated by the given angle, with the rotation centered on the origin given. The original matrix is not modified. **/ function rotate( angle : Float, ?originX : Float = 0.0, ?originY : Float = 0.0 ) : DOMMatrix; /** Returns a `DOMMatrix` containing a new matrix being the result of the original matrix being rotated by the angle between the given vector and (1,0), centered on the origin given. The original matrix is not modified. **/ function rotateFromVector( x : Float, y : Float ) : DOMMatrix; /** Returns a `DOMMatrix` containing a new matrix being the result of the original matrix being rotated by the given angle and the give vector. The original matrix is not modified. **/ function rotateAxisAngle( x : Float, y : Float, z : Float, angle : Float ) : DOMMatrix; /** Returns a `DOMMatrix` containing a new matrix being the result of the original matrix being skewed along the x-axis by the given factor. The original matrix is not modified. **/ function skewX( sx : Float ) : DOMMatrix; /** Returns a `DOMMatrix` containing a new matrix being the result of the original matrix being skewed along the y-axis by the given factor. The original matrix is not modified. **/ function skewY( sy : Float ) : DOMMatrix; /** Returns a `DOMMatrix` containing a new matrix being the result of the original matrix being multiplied by the given `DOMMatrix`. The original matrix is not modified. **/ function multiply( other : DOMMatrix ) : DOMMatrix; /** Returns a `DOMMatrix` containing a new matrix being the result of the original matrix being flipped around the x-axis, that is multiplied by the `DOMMatrix(-1, 0, 0, 1, 0, 0)`. The original matrix is not modified. **/ function flipX() : DOMMatrix; /** Returns a `DOMMatrix` containing a new matrix being the result of the original matrix being flipped around the y-axis, that is multiplied by the `DOMMatrix(1, 0, 0, -1, 0, 0)`. The original matrix is not modified. **/ function flipY() : DOMMatrix; function inverse() : DOMMatrix; /** Returns a `DOMPoint` that is the point given in parameter multiplied by the matrix. Bot the original point and the matrix aren't modified. **/ function transformPoint( ?point : DOMPointInit ) : DOMPoint; /** @throws DOMError */ /** Returns a `Float32Array` containing the 6 components (`a`, `b`, `c`, `d`, `e`, `f`) in the case of a 2D matrix or the 16 components (`m11`, `m12`, `m13`, `m14`, `m21`, `m22`, `m23`, `m24`, `m31`, `m32`, `m33`, `m34`, `m41`, `m42`, `m43`, `m44`) for a 3D matrix. **/ function toFloat32Array() : Float32Array; /** @throws DOMError */ /** Returns a `Float64Array` containing the 6 components (`a`, `b`, `c`, `d`, `e`, `f`) in the case of a 2D matrix or the 16 components (`m11`, `m12`, `m13`, `m14`, `m21`, `m22`, `m23`, `m24`, `m31`, `m32`, `m33`, `m34`, `m41`, `m42`, `m43`, `m44`) for a 3D matrix. **/ function toFloat64Array() : Float64Array; }haxe_3.4.4.orig/std/js/html/DOMParser.hx0000664000175000017500000000377313166552354017735 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMParser.webidl. Do not edit! package js.html; /** `DOMParser` can parse XML or HTML source stored in a string into a DOM Document. `DOMParser` is specified in DOM Parsing and Serialization. Documentation [DOMParser](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMParser") extern class DOMParser { /** @throws DOMError */ @:overload( function() : Void {} ) function new( prin : Dynamic/*MISSING Principal*/, ?documentURI : Dynamic/*MISSING URI*/, ?baseURI : Dynamic/*MISSING URI*/ ) : Void; /** @throws DOMError */ function parseFromString( str : String, type : SupportedType ) : HTMLDocument; }haxe_3.4.4.orig/std/js/html/DOMPoint.hx0000664000175000017500000000347313166552354017567 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMPoint.webidl. Do not edit! package js.html; /** A `DOMPoint` represents a 2D or 3D point in a coordinate system. Documentation [DOMPoint](https://developer.mozilla.org/en-US/docs/Web/API/DOMPoint) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMPoint$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMPoint") extern class DOMPoint extends DOMPointReadOnly { /** @throws DOMError */ @:overload( function( ?point : DOMPointInit ) : Void {} ) function new( x : Float, y : Float, ?z : Float = 0.0, ?w : Float = 1.0 ) : Void; }haxe_3.4.4.orig/std/js/html/DOMPointInit.hx0000664000175000017500000000250313166552354020404 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMPoint.webidl. Do not edit! package js.html; typedef DOMPointInit = { @:optional var w : Float; @:optional var x : Float; @:optional var y : Float; @:optional var z : Float; }haxe_3.4.4.orig/std/js/html/DOMPointReadOnly.hx0000664000175000017500000000407313166552354021222 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMPoint.webidl. Do not edit! package js.html; /** The `DOMPointReadOnly` interface specifies the standard properties used by `DOMPoint` to define a 2D or 3D point in a coordinate system. Documentation [DOMPointReadOnly](https://developer.mozilla.org/en-US/docs/Web/API/DOMPointReadOnly) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMPointReadOnly$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMPointReadOnly") extern class DOMPointReadOnly { /** The x coordinate of the `DOMPoint`. **/ var x(default,null) : Float; /** The y coordinate of the `DOMPoint`. **/ var y(default,null) : Float; /** The z coordinate of the `DOMPoint`. **/ var z(default,null) : Float; /** The perspective value of the `DOMPoint`. **/ var w(default,null) : Float; }haxe_3.4.4.orig/std/js/html/DOMQuad.hx0000664000175000017500000000313413166552354017362 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMQuad.webidl. Do not edit! package js.html; @:native("DOMQuad") extern class DOMQuad { var p1(default,null) : DOMPoint; var p2(default,null) : DOMPoint; var p3(default,null) : DOMPoint; var p4(default,null) : DOMPoint; var bounds(default,null) : DOMRectReadOnly; /** @throws DOMError */ @:overload( function( ?p1 : DOMPointInit, ?p2 : DOMPointInit, ?p3 : DOMPointInit, ?p4 : DOMPointInit ) : Void {} ) function new( rect : DOMRectReadOnly ) : Void; }haxe_3.4.4.orig/std/js/html/DOMRect.hx0000664000175000017500000000337213166552354017371 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMRect.webidl. Do not edit! package js.html; /** A `DOMRect` represents a rectangle. Documentation [DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMRect") extern class DOMRect extends DOMRectReadOnly { /** @throws DOMError */ @:overload( function() : Void {} ) function new( x : Float, y : Float, width : Float, height : Float ) : Void; }haxe_3.4.4.orig/std/js/html/DOMRectList.hx0000664000175000017500000000254013166552354020221 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMRectList.webidl. Do not edit! package js.html; @:native("DOMRectList") extern class DOMRectList implements ArrayAccess { var length(default,null) : Int; function item( index : Int ) : DOMRect; }haxe_3.4.4.orig/std/js/html/DOMRectReadOnly.hx0000664000175000017500000000504213166552354021023 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMRect.webidl. Do not edit! package js.html; /** The `DOMRectReadOnly` interface specifies the standard properties used by `DOMRect` to define a rectangle. Documentation [DOMRectReadOnly](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMRectReadOnly") extern class DOMRectReadOnly { /** The x coordinate of the `DOMRect`'s origin. **/ var x(default,null) : Float; /** The y coordinate of the `DOMRect`'s origin. **/ var y(default,null) : Float; /** The width of the `DOMRect`. **/ var width(default,null) : Float; /** The height of the `DOMRect`. **/ var height(default,null) : Float; /** Returns the top coordinate value of the `DOMRect` (usually the same as `y`.) **/ var top(default,null) : Float; /** Returns the right coordinate value of the `DOMRect` (usually the same as `x + width`). **/ var right(default,null) : Float; /** Returns the bottom coordinate value of the `DOMRect` (usually the same as y + height). **/ var bottom(default,null) : Float; /** Returns the left coordinate value of the `DOMRect` (usually the same as `x`). **/ var left(default,null) : Float; }haxe_3.4.4.orig/std/js/html/DOMRequest.hx0000664000175000017500000000315513166552354020123 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMRequest.webidl. Do not edit! package js.html; @:native("DOMRequest") extern class DOMRequest extends EventTarget { var readyState(default,null) : DOMRequestReadyState; var result(default,null) : Dynamic; var error(default,null) : DOMError; var onsuccess : haxe.Constraints.Function; var onerror : haxe.Constraints.Function; /** @throws DOMError */ function then( ?fulfillCallback : haxe.Constraints.Function, ?rejectCallback : haxe.Constraints.Function ) : Dynamic; }haxe_3.4.4.orig/std/js/html/DOMRequestReadyState.hx0000664000175000017500000000243513166552354022111 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMRequest.webidl. Do not edit! package js.html; @:enum abstract DOMRequestReadyState(String) { var PENDING = "pending"; var DONE = "done"; }haxe_3.4.4.orig/std/js/html/DOMStringList.hx0000664000175000017500000000374213166552354020577 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMStringList.webidl. Do not edit! package js.html; /** A type returned by some APIs which contains a list of DOMString (strings). Documentation [DOMStringList](https://developer.mozilla.org/en-US/docs/Web/API/DOMStringList) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMStringList$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMStringList") extern class DOMStringList implements ArrayAccess { /** Returns the length of the list, **/ var length(default,null) : Int; /** Returns a `DOMString`. **/ function item( index : Int ) : String; /** Returns `Boolean` indicating if the given string is in the list **/ function contains( string : String ) : Bool; }haxe_3.4.4.orig/std/js/html/DOMStringMap.hx0000664000175000017500000000332413166552354020375 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMStringMap.webidl. Do not edit! package js.html; /** Used by the `dataset` HTML attribute to represent data for custom attributes added to elements. Documentation [DOMStringMap](https://developer.mozilla.org/en-US/docs/Web/API/DOMStringMap) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMStringMap$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMStringMap") extern class DOMStringMap implements Dynamic { }haxe_3.4.4.orig/std/js/html/DOMTokenList.hx0000664000175000017500000000561513166552354020412 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMTokenList.webidl. Do not edit! package js.html; /** The `DOMTokenList` interface represents a set of space-separated tokens. Such a set is returned by `Element.classList`, `HTMLLinkElement.relList`, `HTMLAnchorElement.relList` or `HTMLAreaElement.relList`. It is indexed beginning with `0` as with JavaScript `Array` objects. `DOMTokenList` is always case-sensitive. Documentation [DOMTokenList](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DOMTokenList") extern class DOMTokenList implements ArrayAccess { /** Is an `integer` representing the number of objects stored in the object. **/ var length(default,null) : Int; var value : String; /** Returns an item in the list by its index (or undefined if the number is greater than or equal to the length of the list, prior to `7.0` returned null) **/ function item( index : Int ) : String; /** @throws DOMError */ /** Returns `true` if the underlying string contains token, otherwise `false` **/ function contains( token : String ) : Bool; /** @throws DOMError */ /** Adds token to the underlying string **/ function add( tokens : haxe.extern.Rest ) : Void; /** @throws DOMError */ /** Removes token from the underlying string **/ function remove( tokens : haxe.extern.Rest ) : Void; /** @throws DOMError */ /** Removes token from string and returns false. If token doesn't exist it's added and the function returns true **/ function toggle( token : String, ?force : Bool ) : Bool; }haxe_3.4.4.orig/std/js/html/DOMTransaction.hx0000664000175000017500000000272113166552354020756 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMTransaction.webidl. Do not edit! package js.html; @:native("DOMTransaction") extern class DOMTransaction { var label(default,null) : String; var executeAutomatic(default,null) : Void -> Void; var execute(default,null) : Void -> Void; var undo(default,null) : Void -> Void; var redo(default,null) : Void -> Void; }haxe_3.4.4.orig/std/js/html/DOMTransactionEvent.hx0000664000175000017500000000266113166552354021763 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMTransactionEvent.webidl. Do not edit! package js.html; @:native("DOMTransactionEvent") extern class DOMTransactionEvent extends Event { var transactions(default,null) : Dynamic; /** @throws DOMError */ function new( type : String, ?eventInitDict : DOMTransactionEventInit ) : Void; }haxe_3.4.4.orig/std/js/html/DOMTransactionEventInit.hx0000664000175000017500000000244313166552354022605 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMTransactionEvent.webidl. Do not edit! package js.html; typedef DOMTransactionEventInit = { > EventInit, @:optional var transactions : Dynamic; }haxe_3.4.4.orig/std/js/html/DataElement.hx0000664000175000017500000000370613166552354020320 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLDataElement.webidl. Do not edit! package js.html; /** The `HTMLDataElement` interface provides special properties (beyond the regular `HTMLElement` interface it also has available to it by inheritance) for manipulating `data` elements. Documentation [HTMLDataElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDataElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDataElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLDataElement") extern class DataElement extends Element { /** Is a `DOMString` reflecting the `value` HTML attribute, containing a machine-readable form of the element's value. **/ var value : String; }haxe_3.4.4.orig/std/js/html/DataListElement.hx0000664000175000017500000000375713166552354021162 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLDataListElement.webidl. Do not edit! package js.html; /** The `HTMLDataListElement` interface provides special properties (beyond the `HTMLElement` object interface it also has available to it by inheritance) to manipulate `datalist` elements and their content. Documentation [HTMLDataListElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDataListElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDataListElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLDataListElement") extern class DataListElement extends Element { /** Is a `HTMLCollection` representing a collection of the contained option elements. **/ var options(default,null) : HTMLCollection; }haxe_3.4.4.orig/std/js/html/DataTransfer.hx0000664000175000017500000000755113166552354020515 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DataTransfer.webidl. Do not edit! package js.html; /** The `DataTransfer` object is used to hold the data that is being dragged during a drag and drop operation. It may hold one or more data items, each of one or more data types. For more information about drag and drop, see HTML Drag and Drop API. Documentation [DataTransfer](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DataTransfer") extern class DataTransfer { /** Gets the type of drag-and-drop operation currently selected or sets the operation to a new type. The value must be `none`, `copy`, `link` or `move`. **/ var dropEffect : String; /** Provides all of the types of operations that are possible. Must be one of `none`, `copy`, `copyLink`, `copyMove`, `link`, `linkMove`, `move`, `all` or `uninitialized`. **/ var effectAllowed : String; /** An array of `DOMString` giving the formats that were set in the `dragstart` event. **/ var types(default,null) : DOMStringList; /** Contains a list of all the local files available on the data transfer. If the drag operation doesn't involve dragging files, this property is an empty list. **/ var files(default,null) : FileList; /** @throws DOMError */ function new( eventType : String, isExternal : Bool ) : Void; /** @throws DOMError */ /** Set the image to be used for dragging if a custom one is desired. **/ function setDragImage( image : Element, x : Int, y : Int ) : Void; /** @throws DOMError */ /** Retrieves the data for a given type, or an empty string if data for that type does not exist or the data transfer contains no data. **/ function getData( format : String ) : String; /** @throws DOMError */ /** Set the data for a given type. If data for the type does not exist, it is added at the end, such that the last item in the types list will be the new format. If data for the type already exists, the existing data is replaced in the same position. **/ function setData( format : String, data : String ) : Void; /** @throws DOMError */ /** Remove the data associated with a given type. The type argument is optional. If the type is empty or not specified, the data associated with all types is removed. If data for the specified type does not exist, or the data transfer contains no data, this method will have no effect. **/ function clearData( ?format : String ) : Void; /** @throws DOMError */ /** Sets the drag source to the given element. **/ function addElement( element : Element ) : Void; }haxe_3.4.4.orig/std/js/html/DataView.hx0000664000175000017500000000513313166552354017635 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from typedarray.webidl. Do not edit! package js.html; // Explicitly include the compatibility class import js.html.compat.DataView; @:native("DataView") extern class DataView extends ArrayBufferView { /** @throws DOMError */ function new( buffer : ArrayBuffer, ?byteOffset : Int, ?byteLength : Int ) : Void; @:pure function getInt8( byteOffset : Int ) : Int; @:pure function getUint8( byteOffset : Int ) : Int; @:pure function getInt16( byteOffset : Int, ?littleEndian : Bool ) : Int; @:pure function getUint16( byteOffset : Int, ?littleEndian : Bool ) : Int; @:pure function getInt32( byteOffset : Int, ?littleEndian : Bool ) : Int; @:pure function getUint32( byteOffset : Int, ?littleEndian : Bool ) : Int; @:pure function getFloat32( byteOffset : Int, ?littleEndian : Bool ) : Float; @:pure function getFloat64( byteOffset : Int, ?littleEndian : Bool ) : Float; function setInt8( byteOffset : Int, value : Int ) : Void; function setUint8( byteOffset : Int, value : Int ) : Void; function setInt16( byteOffset : Int, value : Int, ?littleEndian : Bool ) : Void; function setUint16( byteOffset : Int, value : Int, ?littleEndian : Bool ) : Void; function setInt32( byteOffset : Int, value : Int, ?littleEndian : Bool ) : Void; function setUint32( byteOffset : Int, value : Int, ?littleEndian : Bool ) : Void; function setFloat32( byteOffset : Int, value : Float, ?littleEndian : Bool ) : Void; function setFloat64( byteOffset : Int, value : Float, ?littleEndian : Bool ) : Void; }haxe_3.4.4.orig/std/js/html/DedicatedWorkerGlobalScope.hx0000664000175000017500000000472413166552354023311 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DedicatedWorkerGlobalScope.webidl. Do not edit! package js.html; /** The `DedicatedWorkerGlobalScope` object (the `Worker` global scope) is accessible through the `self` keyword. Some additional global functions, namespaces objects, and constructors, not typically associated with the worker global scope, but available on it, are listed in the JavaScript Reference. See also: Functions available to workers. Documentation [DedicatedWorkerGlobalScope](https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DedicatedWorkerGlobalScope") extern class DedicatedWorkerGlobalScope extends WorkerGlobalScope { /** Is an `EventHandler` representing the code to be called when the `message` event is raised. These events are of type `MessageEvent` and will be called when the worker receives a message from the document that started it (i.e. from the `Worker.postMessage` method.) **/ var onmessage : haxe.Constraints.Function; /** @throws DOMError */ function postMessage( message : Dynamic, ?transfer : Array ) : Void; }haxe_3.4.4.orig/std/js/html/DesktopNotification.hx0000664000175000017500000000265013166552354022112 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DesktopNotification.webidl. Do not edit! package js.html; @:native("DesktopNotification") extern class DesktopNotification extends EventTarget { var onclick : haxe.Constraints.Function; var onclose : haxe.Constraints.Function; /** @throws DOMError */ function show() : Void; }haxe_3.4.4.orig/std/js/html/DesktopNotificationCenter.hx0000664000175000017500000000261413166552354023253 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DesktopNotification.webidl. Do not edit! package js.html; @:native("DesktopNotificationCenter") extern class DesktopNotificationCenter { function createNotification( title : String, description : String, ?iconURL : String = "" ) : DesktopNotification; }haxe_3.4.4.orig/std/js/html/DeviceAcceleration.hx0000664000175000017500000000406413166552354021644 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DeviceMotionEvent.webidl. Do not edit! package js.html; /** A `DeviceAcceleration` object provides information about the amount of acceleration the device is experiencing along all three axes. Documentation [DeviceAcceleration](https://developer.mozilla.org/en-US/docs/Web/API/DeviceAcceleration) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DeviceAcceleration$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DeviceAcceleration") extern class DeviceAcceleration { /** The amount of acceleration along the X axis. Read only. **/ var x(default,null) : Float; /** The amount of acceleration along the Y axis. Read only. **/ var y(default,null) : Float; /** The amount of acceleration along the Z axis. Read only. **/ var z(default,null) : Float; }haxe_3.4.4.orig/std/js/html/DeviceAccelerationInit.hx0000664000175000017500000000247313166552354022472 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DeviceMotionEvent.webidl. Do not edit! package js.html; typedef DeviceAccelerationInit = { @:optional var x : Float; @:optional var y : Float; @:optional var z : Float; }haxe_3.4.4.orig/std/js/html/DeviceMotionEvent.hx0000664000175000017500000000561013166552354021520 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DeviceMotionEvent.webidl. Do not edit! package js.html; /** The `DeviceMotionEvent` provides web developers with information about the speed of changes for the device's position and orientation. Documentation [DeviceMotionEvent](https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DeviceMotionEvent") extern class DeviceMotionEvent extends Event { /** An object giving the acceleration of the device on the three axis X, Y and Z. Acceleration is expressed in m/s2. **/ var acceleration(default,null) : DeviceAcceleration; /** An object giving the acceleration of the device on the three axis X, Y and Z with the effect of gravity. Acceleration is expressed in m/s2. **/ var accelerationIncludingGravity(default,null) : DeviceAcceleration; /** An object giving the rate of change of the device's orientation on the three orientation axis alpha, beta and gamma. Rotation rate is express in degrees per seconds. **/ var rotationRate(default,null) : DeviceRotationRate; /** A number representing the interval of time, in milliseconds, at which data is obtained from the device. **/ var interval(default,null) : Float; /** @throws DOMError */ function new( type : String, ?eventInitDict : DeviceMotionEventInit ) : Void; function initDeviceMotionEvent( type : String, canBubble : Bool, cancelable : Bool, acceleration : DeviceAccelerationInit, accelerationIncludingGravity : DeviceAccelerationInit, rotationRate : DeviceRotationRateInit, interval : Float ) : Void; }haxe_3.4.4.orig/std/js/html/DeviceMotionEventInit.hx0000664000175000017500000000271613166552354022350 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DeviceMotionEvent.webidl. Do not edit! package js.html; typedef DeviceMotionEventInit = { > EventInit, @:optional var acceleration : DeviceAccelerationInit; @:optional var accelerationIncludingGravity : DeviceAccelerationInit; @:optional var interval : Float; @:optional var rotationRate : DeviceRotationRateInit; }haxe_3.4.4.orig/std/js/html/DeviceOrientationEvent.hx0000664000175000017500000000546713166552354022560 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DeviceOrientationEvent.webidl. Do not edit! package js.html; /** The `DeviceOrientationEvent` provides web developers with information from the physical orientation of the device running the web page. Documentation [DeviceOrientationEvent](https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DeviceOrientationEvent") extern class DeviceOrientationEvent extends Event { /** A number representing the motion of the device around the z axis, express in degrees with values ranging from 0 to 360 **/ var alpha(default,null) : Float; /** A number representing the motion of the device around the x axis, express in degrees with values ranging from -180 to 180. This represents a front to back motion of the device. **/ var beta(default,null) : Float; /** A number representing the motion of the device around the y axis, express in degrees with values ranging from -90 to 90. This represents a left to right motion of the device. **/ var gamma(default,null) : Float; /** A boolean that indicates whether or not the device is providing orientation data absolutely. **/ var absolute(default,null) : Bool; /** @throws DOMError */ function new( type : String, ?eventInitDict : DeviceOrientationEventInit ) : Void; function initDeviceOrientationEvent( type : String, canBubble : Bool, cancelable : Bool, alpha : Float, beta : Float, gamma : Float, absolute : Bool ) : Void; }haxe_3.4.4.orig/std/js/html/DeviceOrientationEventInit.hx0000664000175000017500000000257613166552354023402 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DeviceOrientationEvent.webidl. Do not edit! package js.html; typedef DeviceOrientationEventInit = { > EventInit, @:optional var absolute : Bool; @:optional var alpha : Float; @:optional var beta : Float; @:optional var gamma : Float; }haxe_3.4.4.orig/std/js/html/DeviceRotationRate.hx0000664000175000017500000000354013166552354021664 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DeviceMotionEvent.webidl. Do not edit! package js.html; /** A `DeviceRotationRate` object provides information about the rate at which the device is rotating around all three axes. Documentation [DeviceRotationRate](https://developer.mozilla.org/en-US/docs/Web/API/DeviceRotationRate) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DeviceRotationRate$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DeviceRotationRate") extern class DeviceRotationRate { var alpha(default,null) : Float; var beta(default,null) : Float; var gamma(default,null) : Float; }haxe_3.4.4.orig/std/js/html/DeviceRotationRateInit.hx0000664000175000017500000000250613166552354022511 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DeviceMotionEvent.webidl. Do not edit! package js.html; typedef DeviceRotationRateInit = { @:optional var alpha : Float; @:optional var beta : Float; @:optional var gamma : Float; }haxe_3.4.4.orig/std/js/html/DirectionSetting.hx0000664000175000017500000000242713166552354021412 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\VTTCue.webidl. Do not edit! package js.html; @:enum abstract DirectionSetting(String) { var NONE = ""; var RL = "rl"; var LR = "lr"; }haxe_3.4.4.orig/std/js/html/Directory.hx0000664000175000017500000000262113166552354020074 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Directory.webidl. Do not edit! package js.html; @:native("Directory") extern class Directory { var name(default,null) : String; var path(default,null) : String; function getFilesAndDirectories() : Promise>>; }haxe_3.4.4.orig/std/js/html/DirectoryElement.hx0000664000175000017500000000246213166552354021411 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLDirectoryElement.webidl. Do not edit! package js.html; @:native("HTMLDirectoryElement") extern class DirectoryElement extends Element { var compact : Bool; }haxe_3.4.4.orig/std/js/html/DivElement.hx0000664000175000017500000000403713166552354020167 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLDivElement.webidl. Do not edit! package js.html; /** The `HTMLDivElement` interface provides special properties (beyond the regular `HTMLElement` interface it also has available to it by inheritance) for manipulating div elements. Documentation [HTMLDivElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLDivElement") extern class DivElement extends Element { /** Is a `DOMString` representing an enumerated property indicating alignment of the element's contents with respect to the surrounding context. The possible values are `"left"`, `"right"`, `"justify"`, and `"center"`. **/ var align : String; }haxe_3.4.4.orig/std/js/html/Document.hx0000664000175000017500000003720413166552354017713 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Document.webidl. Do not edit! package js.html; /** The `Document` interface represents any web page loaded in the browser and serves as an entry point into the web page's content, which is the DOM tree. The DOM tree includes elements such as `body` and `table`, among many others. It provides functionality global to the document, like how to obtain the page's URL and create new elements in the document. Documentation [Document](https://developer.mozilla.org/en-US/docs/Web/API/Document) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Document$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Document") extern class Document extends Node { /** Returns the DOM implementation associated with the current document. **/ var implementation(default,null) : DOMImplementation; /** Returns the document location as a string. **/ var URL(default,null) : String; /** Returns the document location as a string. **/ var documentURI(default,null) : String; /** Indicates whether the document is rendered in quirks or strict mode. **/ var compatMode(default,null) : String; /** Returns the character set being used by the document. **/ var characterSet(default,null) : String; /** Alias of `Document.characterSet`. Use this property instead. **/ var charset(default,null) : String; /** Alias of `Document.characterSet`. Use this property instead. **/ var inputEncoding(default,null) : String; /** Returns the Content-Type from the MIME Header of the current document. **/ var contentType(default,null) : String; /** Returns the Document Type Definition (DTD) of the current document. **/ var doctype(default,null) : DocumentType; /** Returns the `Element` that is a direct child of the document. For HTML documents, this is normally the `html` element. **/ var documentElement(default,null) : Element; /** Returns the URI of the current document. **/ var location(default,null) : Location; /** Returns the URI of the page that linked to this page. **/ var referrer(default,null) : String; /** Returns the date on which the document was last modified. **/ var lastModified(default,null) : String; /** Returns loading status of the document. **/ var readyState(default,null) : String; /** Sets or gets title of the current document. **/ var title : String; /** Gets/sets directionality (rtl/ltr) of the document. **/ var dir : String; /** Returns a reference to the window object. **/ var defaultView(default,null) : Window; /** Returns the currently focused element. **/ var activeElement(default,null) : Element; /** Represents the event handling code for the `readystatechange` event. **/ var onreadystatechange : haxe.Constraints.Function; /** Represents the event handling code for the `wheel` event. **/ var onwheel : haxe.Constraints.Function; /** Represents the event handling code for the `copy` event. **/ var oncopy : haxe.Constraints.Function; /** Represents the event handling code for the `cut` event. **/ var oncut : haxe.Constraints.Function; /** Represents the event handling code for the `paste` event. **/ var onpaste : haxe.Constraints.Function; /** Represents the event handling code for the `beforescriptexecute` event. **/ var onbeforescriptexecute : haxe.Constraints.Function; /** Represents the event handling code for the `afterscriptexecute` event. **/ var onafterscriptexecute : haxe.Constraints.Function; var currentScript(default,null) : Element; var fullscreenEnabled(default,null) : Bool; var fullscreenElement(default,null) : Element; /** Returns the element set as the target for mouse events while the pointer is locked. `null` if lock is pending, pointer is unlocked, or if the target is in another document. **/ var pointerLockElement(default,null) : Element; /** … **/ var hidden(default,null) : Bool; /** Returns a `string` denoting the visibility state of the document. Possible values are `visible`,  `hidden`,  `prerender`, and `unloaded`. **/ var visibilityState(default,null) : VisibilityState; /** Returns a list of the style sheet objects on the current document. **/ var styleSheets(default,null) : StyleSheetList; /** Returns which style sheet set is currently in use. **/ var selectedStyleSheetSet : String; /** Returns the name of the style sheet set that was last enabled. Has the value `null` until the style sheet is changed by setting the value of `document.selectedStyleSheetSet`. **/ var lastStyleSheetSet(default,null) : String; /** Returns the preferred style sheet set as specified by the page author. **/ var preferredStyleSheetSet(default,null) : String; /** Returns a list of the style sheet sets available on the document. **/ var styleSheetSets(default,null) : DOMStringList; /** … **/ var timeline(default,null) : DocumentTimeline; var fonts(default,null) : FontFaceSet; var onabort : haxe.Constraints.Function; var onblur : haxe.Constraints.Function; var onfocus : haxe.Constraints.Function; var oncanplay : haxe.Constraints.Function; var oncanplaythrough : haxe.Constraints.Function; var onchange : haxe.Constraints.Function; var onclick : haxe.Constraints.Function; var oncontextmenu : haxe.Constraints.Function; var ondblclick : haxe.Constraints.Function; var ondrag : haxe.Constraints.Function; var ondragend : haxe.Constraints.Function; var ondragenter : haxe.Constraints.Function; var ondragleave : haxe.Constraints.Function; var ondragover : haxe.Constraints.Function; var ondragstart : haxe.Constraints.Function; var ondrop : haxe.Constraints.Function; var ondurationchange : haxe.Constraints.Function; var onemptied : haxe.Constraints.Function; var onended : haxe.Constraints.Function; var oninput : haxe.Constraints.Function; var oninvalid : haxe.Constraints.Function; var onkeydown : haxe.Constraints.Function; var onkeypress : haxe.Constraints.Function; var onkeyup : haxe.Constraints.Function; var onload : haxe.Constraints.Function; var onloadeddata : haxe.Constraints.Function; var onloadedmetadata : haxe.Constraints.Function; var onloadstart : haxe.Constraints.Function; var onmousedown : haxe.Constraints.Function; var onmouseenter : haxe.Constraints.Function; var onmouseleave : haxe.Constraints.Function; var onmousemove : haxe.Constraints.Function; var onmouseout : haxe.Constraints.Function; var onmouseover : haxe.Constraints.Function; var onmouseup : haxe.Constraints.Function; var onpause : haxe.Constraints.Function; var onplay : haxe.Constraints.Function; var onplaying : haxe.Constraints.Function; var onprogress : haxe.Constraints.Function; var onratechange : haxe.Constraints.Function; var onreset : haxe.Constraints.Function; var onresize : haxe.Constraints.Function; var onscroll : haxe.Constraints.Function; var onseeked : haxe.Constraints.Function; var onseeking : haxe.Constraints.Function; var onselect : haxe.Constraints.Function; var onshow : haxe.Constraints.Function; var onstalled : haxe.Constraints.Function; var onsubmit : haxe.Constraints.Function; var onsuspend : haxe.Constraints.Function; var ontimeupdate : haxe.Constraints.Function; var onvolumechange : haxe.Constraints.Function; var onwaiting : haxe.Constraints.Function; var onpointercancel : haxe.Constraints.Function; var onpointerdown : haxe.Constraints.Function; var onpointerup : haxe.Constraints.Function; var onpointermove : haxe.Constraints.Function; var onpointerout : haxe.Constraints.Function; var onpointerover : haxe.Constraints.Function; var onpointerenter : haxe.Constraints.Function; var onpointerleave : haxe.Constraints.Function; var ongotpointercapture : haxe.Constraints.Function; var onlostpointercapture : haxe.Constraints.Function; /** Is an `EventHandler` representing the code to be called when the `fullscreenchange` event is raised. **/ var onfullscreenchange : haxe.Constraints.Function; /** Is an `EventHandler` representing the code to be called when the `fullscreenerror` event is raised. **/ var onfullscreenerror : haxe.Constraints.Function; /** Represents the event handling code for the `pointerlockchange` event. **/ var onpointerlockchange : haxe.Constraints.Function; /** Represetnts the event handling code for the `pointerlockerror` event. **/ var onpointerlockerror : haxe.Constraints.Function; var onerror : haxe.Constraints.Function; var children(default,null) : HTMLCollection; var firstElementChild(default,null) : Element; var lastElementChild(default,null) : Element; var childElementCount(default,null) : Int; var ontouchstart : haxe.Constraints.Function; var ontouchend : haxe.Constraints.Function; var ontouchmove : haxe.Constraints.Function; var ontouchcancel : haxe.Constraints.Function; /** @throws DOMError */ function new() : Void; /** Returns a list of elements with the given tag name. **/ function getElementsByTagName( localName : String ) : HTMLCollection; /** @throws DOMError */ /** Returns a list of elements with the given tag name and namespace. **/ function getElementsByTagNameNS( namespace_ : String, localName : String ) : HTMLCollection; /** Returns a list of elements with the given class name. **/ function getElementsByClassName( classNames : String ) : HTMLCollection; function getElementById( elementId : String ) : Element; /** @throws DOMError */ @:overload( function( localName : String ) : Element {} ) /** Creates a new element with the given tag name. **/ function createElement( localName : String, typeExtension : String ) : Element; /** @throws DOMError */ @:overload( function( namespace_ : String, qualifiedName : String ) : Element {} ) /** Creates a new element with the given tag name and namespace URI. **/ function createElementNS( namespace_ : String, qualifiedName : String, typeExtension : String ) : Element; /** Creates a new document fragment. **/ function createDocumentFragment() : DocumentFragment; /** Creates a text node. **/ function createTextNode( data : String ) : Text; /** Creates a new comment node and returns it. **/ function createComment( data : String ) : Comment; /** @throws DOMError */ /** Creates a new `ProcessingInstruction` object. **/ function createProcessingInstruction( target : String, data : String ) : ProcessingInstruction; /** @throws DOMError */ /** Returns a clone of a node from an external document. **/ function importNode( node : Node, ?deep : Bool = false ) : Node; /** @throws DOMError */ /** Adopt node from an external document. **/ function adoptNode( node : Node ) : Node; /** @throws DOMError */ /** Creates an event object. **/ function createEvent( interface_ : String ) : Event; /** @throws DOMError */ /** Creates a `Range` object. **/ function createRange() : Range; /** @throws DOMError */ /** Creates a `NodeIterator` object. **/ function createNodeIterator( root : Node, ?whatToShow : Int = cast 4294967295, ?filter : NodeFilter ) : NodeIterator; /** @throws DOMError */ /** Creates a `TreeWalker` object. **/ function createTreeWalker( root : Node, ?whatToShow : Int = cast 4294967295, ?filter : NodeFilter ) : TreeWalker; /** @throws DOMError */ /** Creates a new CDATA node and returns it. **/ function createCDATASection( data : String ) : CDATASection; /** @throws DOMError */ /** Creates a new `Attr` object and returns it. **/ function createAttribute( name : String ) : Attr; /** @throws DOMError */ /** Creates a new attribute node in a given namespace and returns it. **/ function createAttributeNS( namespace_ : String, name : String ) : Attr; /** @throws DOMError */ function hasFocus() : Bool; /** Releases the current mouse capture if it's on an element in this document. **/ function releaseCapture() : Void; function exitFullscreen() : Void; /** Release the pointer lock. **/ function exitPointerLock() : Void; /** @throws DOMError */ /** Registers a web component. **/ function registerElement( name : String, ?options : ElementRegistrationOptions ) : Dynamic; /** Enables the style sheets for the specified style sheet set. **/ function enableStyleSheetsForSet( name : String ) : Void; /** Returns the topmost element at the specified coordinates.  **/ function elementFromPoint( x : Float, y : Float ) : Element; /** Returns an array of all elements at the specified coordinates. **/ function elementsFromPoint( x : Float, y : Float ) : Array; /** Gets the `CaretPosition` at or near the specified coordinates. **/ function caretPositionFromPoint( x : Float, y : Float ) : CaretPosition; /** @throws DOMError */ function querySelector( selectors : String ) : Element; /** @throws DOMError */ function querySelectorAll( selectors : String ) : NodeList; /** Returns an array of all `Animation` objects currently in effect whose target elements are descendants of the `document`. **/ function getAnimations() : Array; /** Creates a `Touch` object. **/ function createTouch( ?view : Window, ?target : EventTarget, ?identifier : Int = 0, ?pageX : Int = 0, ?pageY : Int = 0, ?screenX : Int = 0, ?screenY : Int = 0, ?clientX : Int = 0, ?clientY : Int = 0, ?radiusX : Int = 0, ?radiusY : Int = 0, ?rotationAngle : Float = 0.0, ?force : Float = 0.0 ) : Touch; @:overload( function( touch : Touch, touches : haxe.extern.Rest ) : TouchList {} ) @:overload( function() : TouchList {} ) /** Creates a `TouchList` object. **/ function createTouchList( touches : Array ) : TouchList; /** @throws DOMError */ function convertQuadFromNode( quad : DOMQuad, from : haxe.extern.EitherType>, ?options : ConvertCoordinateOptions ) : DOMQuad; /** @throws DOMError */ function convertRectFromNode( rect : DOMRectReadOnly, from : haxe.extern.EitherType>, ?options : ConvertCoordinateOptions ) : DOMQuad; /** @throws DOMError */ function convertPointFromNode( point : DOMPointInit, from : haxe.extern.EitherType>, ?options : ConvertCoordinateOptions ) : DOMPoint; /** @throws DOMError */ function createExpression( expression : String, resolver : XPathNSResolver ) : XPathExpression; function createNSResolver( nodeResolver : Node ) : Node; /** @throws DOMError */ function evaluate( expression : String, contextNode : Node, resolver : XPathNSResolver, type : Int, result : Dynamic ) : XPathResult; }haxe_3.4.4.orig/std/js/html/DocumentFragment.hx0000664000175000017500000000525013166552354021373 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DocumentFragment.webidl. Do not edit! package js.html; /** The `DocumentFragment` interface represents a minimal document object that has no parent. It is used as a light-weight version of `Document` to store well-formed or potentially non-well-formed fragments of XML. Documentation [DocumentFragment](https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DocumentFragment") extern class DocumentFragment extends Node { var children(default,null) : HTMLCollection; var firstElementChild(default,null) : Element; var lastElementChild(default,null) : Element; var childElementCount(default,null) : Int; /** @throws DOMError */ function new() : Void; /** Returns the first `Element` node within the DocumentFragment`, in document order, that matches the specified ID. **/ function getElementById( elementId : String ) : Element; /** @throws DOMError */ /** Returns the first `Element` node within the `DocumentFragment`, in document order, that matches the specified selectors. **/ function querySelector( selectors : String ) : Element; /** @throws DOMError */ /** Returns a `NodeList` of all the `Element` nodes within the `DocumentFragment` that match the specified selectors. **/ function querySelectorAll( selectors : String ) : NodeList; }haxe_3.4.4.orig/std/js/html/DocumentTimeline.hx0000664000175000017500000000347013166552354021400 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DocumentTimeline.webidl. Do not edit! package js.html; /** The `DocumentTimeline` interface of the the Web Animations API represents animation timelines, including the default document timeline (accessed via `Document.timeline`). Documentation [DocumentTimeline](https://developer.mozilla.org/en-US/docs/Web/API/DocumentTimeline) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DocumentTimeline$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DocumentTimeline") extern class DocumentTimeline extends AnimationTimeline { }haxe_3.4.4.orig/std/js/html/DocumentType.hx0000664000175000017500000000355413166552354020556 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DocumentType.webidl. Do not edit! package js.html; /** The `DocumentType` interface represents a `Node` containing a doctype. Documentation [DocumentType](https://developer.mozilla.org/en-US/docs/Web/API/DocumentType) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DocumentType$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DocumentType") extern class DocumentType extends Node { /** ... **/ var name(default,null) : String; /** ... **/ var publicId(default,null) : String; /** ... **/ var systemId(default,null) : String; function remove() : Void; }haxe_3.4.4.orig/std/js/html/DragEvent.hx0000664000175000017500000000461613166552354020015 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DragEvent.webidl. Do not edit! package js.html; /** The `DragEvent` interface is a `DOM event` that represents a drag and drop interaction. The user initiates a drag by placing a pointer device (such as a mouse) on the touch surface and then dragging the pointer to a new location (such as another DOM element). Applications are free to interpret a drag and drop interaction in an application-specific way. Documentation [DragEvent](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("DragEvent") extern class DragEvent extends MouseEvent { var dataTransfer(default,null) : DataTransfer; /** @throws DOMError */ function new( type : String, ?eventInitDict : DragEventInit ) : Void; function initDragEvent( type : String, canBubble : Bool, cancelable : Bool, aView : Window, aDetail : Int, aScreenX : Int, aScreenY : Int, aClientX : Int, aClientY : Int, aCtrlKey : Bool, aAltKey : Bool, aShiftKey : Bool, aMetaKey : Bool, aButton : Int, aRelatedTarget : EventTarget, aDataTransfer : DataTransfer ) : Void; }haxe_3.4.4.orig/std/js/html/DragEventInit.hx0000664000175000017500000000243113166552354020632 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DragEvent.webidl. Do not edit! package js.html; typedef DragEventInit = { > MouseEventInit, @:optional var dataTransfer : DataTransfer; }haxe_3.4.4.orig/std/js/html/DummyInterface.hx0000664000175000017500000000257013166552354021047 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DummyBinding.webidl. Do not edit! package js.html; @:native("DummyInterface") extern class DummyInterface { function lifecycleCallbacks( ?arg : LifecycleCallbacks ) : Void; function promiseJobCallback( arg : Void -> Void ) : Void; }haxe_3.4.4.orig/std/js/html/DummyInterfaceWorkers.hx0000664000175000017500000000241113166552354022416 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DummyBinding.webidl. Do not edit! package js.html; @:native("DummyInterfaceWorkers") extern class DummyInterfaceWorkers { }haxe_3.4.4.orig/std/js/html/Element.hx0000664000175000017500000000340013166552354017515 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLElement.webidl. Do not edit! package js.html; /** The `HTMLElement` interface represents any HTML element. Some elements directly implement this interface, others implement it via an interface that inherits it. Documentation [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLElement") extern class Element extends DOMElement { }haxe_3.4.4.orig/std/js/html/ElementRegistrationOptions.hx0000664000175000017500000000250713166552354023473 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\WebComponents.webidl. Do not edit! package js.html; typedef ElementRegistrationOptions = { @:native("extends") @:optional var extends_ : String; @:optional var prototype : Dynamic; }haxe_3.4.4.orig/std/js/html/EmbedElement.hx0000664000175000017500000000534513166552354020464 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLEmbedElement.webidl. Do not edit! package js.html; /** The `HTMLEmbedElement` interface, which provides special properties (beyond the regular `HTMLElement` interface it also has available to it by inheritance) for manipulating `embed` elements. Documentation [HTMLEmbedElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLEmbedElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLEmbedElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLEmbedElement") extern class EmbedElement extends Element { /** Is a `DOMString` that reflects the `src` HTML attribute, containing the address of the resource. **/ var src : String; /** Is a `DOMString` that reflects the `type` HTML attribute, containing the type of the resource. **/ var type : String; /** Is a `DOMString` that reflects the `width` HTML attribute, containing the displayed width of the resource. **/ var width : String; /** Is a `DOMString` representing an enumerated property indicating alignment of the element's contents with respect to the surrounding context. The possible values are `"left"`, `"right"`, `"center"`, and `"justify"`. **/ var height : String; /** Is a `DOMString` reflecting the `height` HTML attribute, containing the displayed height of the resource. **/ var align : String; /** Is a `DOMString` representing the name of the embedded object. **/ var name : String; function getSVGDocument() : HTMLDocument; }haxe_3.4.4.orig/std/js/html/ErrorEvent.hx0000664000175000017500000000466613166552354020236 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\ErrorEvent.webidl. Do not edit! package js.html; /** The `ErrorEvent` interface represents events providing information related to errors in scripts or in files. Documentation [ErrorEvent](https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("ErrorEvent") extern class ErrorEvent extends Event { /** Is a `DOMString` containing a human-readable error message describing the problem. **/ var message(default,null) : String; /** Is a `DOMString` containing the name of the script file in which the error occurred. **/ var filename(default,null) : String; /** Is an `integer` containing the line number of the script file on which the error occurred. **/ var lineno(default,null) : Int; /** Is an `integer` containing the column number of the script file on which the error occurred. **/ var colno(default,null) : Int; /** Is a JavaScript `Object` that is concerned by the event. **/ var error(default,null) : Dynamic; /** @throws DOMError */ function new( type : String, ?eventInitDict : ErrorEventInit ) : Void; }haxe_3.4.4.orig/std/js/html/ErrorEventInit.hx0000664000175000017500000000261213166552354021047 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\ErrorEvent.webidl. Do not edit! package js.html; typedef ErrorEventInit = { > EventInit, @:optional var colno : Int; @:optional var error : Dynamic; @:optional var filename : String; @:optional var lineno : Int; @:optional var message : String; }haxe_3.4.4.orig/std/js/html/Event.hx0000664000175000017500000001163313166552354017214 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Event.webidl. Do not edit! package js.html; /** The `Event` interface represents any event which takes place in the DOM; some are user-generated (such as mouse or keyboard events), while others are generated by APIs (such as events that indicate an animation has finished running, a video has been paused, and so forth). There are many types of event, some of which use are other interfaces based on the main `Event` interface. `Event` itself contains the properties and methods which are common to all events. Documentation [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Event$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Event") extern class Event { static inline var NONE : Int = 0; static inline var CAPTURING_PHASE : Int = 1; static inline var AT_TARGET : Int = 2; static inline var BUBBLING_PHASE : Int = 3; static inline var ALT_MASK : Int = 1; static inline var CONTROL_MASK : Int = 2; static inline var SHIFT_MASK : Int = 4; static inline var META_MASK : Int = 8; /** The name of the event (case-insensitive). **/ var type(default,null) : String; /** A reference to the target to which the event was originally dispatched. **/ var target(default,null) : EventTarget; /** A reference to the currently registered target for the event. This is the object to which the event is currently slated to be sent to; it's possible this has been changed along the way through retargeting. **/ var currentTarget(default,null) : EventTarget; /** Indicates which phase of the event flow is being processed. **/ var eventPhase(default,null) : Int; /** A Boolean indicating whether the event bubbles up through the DOM or not. **/ var bubbles(default,null) : Bool; /** A Boolean indicating whether the event is cancelable. **/ var cancelable(default,null) : Bool; /** Indicates whether or not `event.preventDefault()` has been called on the event. **/ var defaultPrevented(default,null) : Bool; /** Indicates whether or not the event was initiated by the browser (after a user click for instance) or by a script (using an event creation method, like event.initEvent) **/ var isTrusted(default,null) : Bool; /** The time at which the event was created, in milliseconds. By specification, this value is time since epoch, but in reality browsers' definitions vary; in addition, work is underway to change this to be a `DOMHighResTimeStamp` instead. **/ var timeStamp(default,null) : Float; /** The original target of the event, before any retargetings (Mozilla-specific). **/ var originalTarget(default,null) : EventTarget; /** The explicit original target of the event (Mozilla-specific). **/ var explicitOriginalTarget(default,null) : EventTarget; /** @throws DOMError */ function new( type : String, ?eventInitDict : EventInit ) : Void; /** Stops the propagation of events further along in the DOM. **/ function stopPropagation() : Void; /** For this particular event, no other listener will be called. Neither those attached on the same element, nor those attached on elements which will be traversed later (in capture phase, for instance) **/ function stopImmediatePropagation() : Void; /** Cancels the event (if it is cancelable). **/ function preventDefault() : Void; /** Initializes the value of an Event created. If the event has already being dispatched, this method does nothing. **/ function initEvent( type : String, bubbles : Bool, cancelable : Bool ) : Void; /** Non-standard. Returns the value of `Event.defaultPrevented`. Use `Event.defaultPrevented` instead. **/ function getPreventDefault() : Bool; }haxe_3.4.4.orig/std/js/html/EventInit.hx0000664000175000017500000000242413166552354020036 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Event.webidl. Do not edit! package js.html; typedef EventInit = { @:optional var bubbles : Bool; @:optional var cancelable : Bool; }haxe_3.4.4.orig/std/js/html/EventListener.hx0000664000175000017500000000336113166552354020721 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from events.webidl. Do not edit! package js.html; /** This method is called whenever an event occurs of the type for which the `EventListener` interface was registered. Documentation [EventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventListener) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/EventListener$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("EventListener") extern class EventListener { function handleEvent( event : Event ) : Void; }haxe_3.4.4.orig/std/js/html/EventModifierInit.hx0000664000175000017500000000331713166552354021517 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\UIEvent.webidl. Do not edit! package js.html; typedef EventModifierInit = { > UIEventInit, @:optional var altKey : Bool; @:optional var ctrlKey : Bool; @:optional var metaKey : Bool; @:optional var modifierAltGraph : Bool; @:optional var modifierCapsLock : Bool; @:optional var modifierFn : Bool; @:optional var modifierFnLock : Bool; @:optional var modifierNumLock : Bool; @:optional var modifierOS : Bool; @:optional var modifierScrollLock : Bool; @:optional var modifierSymbol : Bool; @:optional var modifierSymbolLock : Bool; @:optional var shiftKey : Bool; }haxe_3.4.4.orig/std/js/html/EventSource.hx0000664000175000017500000000576013166552354020401 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\EventSource.webidl. Do not edit! package js.html; /** The `EventSource` interface is used to receive server-sent events. It connects to a server over HTTP and receives events in `text/event-stream` format without closing the connection. Documentation [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/EventSource$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("EventSource") extern class EventSource extends EventTarget { static inline var CONNECTING : Int = 0; static inline var OPEN : Int = 1; static inline var CLOSED : Int = 2; /** A `DOMString` representing the URL of the source. **/ var url(default,null) : String; var withCredentials(default,null) : Bool; /** An `unsigned short` representing the state of the connection. Possible values are `CONNECTING` (`0`), `OPEN` (`1`), or `CLOSED` (`2`). **/ var readyState(default,null) : Int; /** Is an `EventHandler` being called when an `open` event is received, that is when the connection was just opened. **/ var onopen : haxe.Constraints.Function; /** Is an `EventHandler` being called when a `message` event is received, that is when a message is coming from the source. **/ var onmessage : haxe.Constraints.Function; /** Is an `EventHandler` being called when an error occurs and the `error` event is dispatched on this object. **/ var onerror : haxe.Constraints.Function; /** @throws DOMError */ function new( url : String, ?eventSourceInitDict : EventSourceInit ) : Void; /** Closes the connection, if any, and sets the `readyState` attribute to `CLOSED`. If the connection is already closed, the method does nothing. **/ function close() : Void; }haxe_3.4.4.orig/std/js/html/EventSourceInit.hx0000664000175000017500000000240513166552354021216 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\EventSource.webidl. Do not edit! package js.html; typedef EventSourceInit = { @:optional var withCredentials : Bool; }haxe_3.4.4.orig/std/js/html/EventTarget.hx0000664000175000017500000000472513166552354020367 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\EventTarget.webidl. Do not edit! package js.html; /** `EventTarget` is an interface implemented by objects that can receive events and may have listeners for them. Documentation [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("EventTarget") extern class EventTarget { /** @throws DOMError */ @:overload( function( type : String, listener : EventListener, ?capture : Bool = false, ?wantsUntrusted : Bool ) : Void {} ) /** Register an event handler of a specific event type on the `EventTarget`. **/ function addEventListener( type : String, listener : haxe.Constraints.Function, ?capture : Bool = false ) : Void; /** @throws DOMError */ @:overload( function( type : String, listener : EventListener, ?capture : Bool = false ) : Void {} ) /** Removes an event listener from the `EventTarget`. **/ function removeEventListener( type : String, listener : haxe.Constraints.Function, ?capture : Bool = false ) : Void; /** @throws DOMError */ /** Dispatch an event to this `EventTarget`. **/ function dispatchEvent( event : Event ) : Bool; }haxe_3.4.4.orig/std/js/html/Exception.hx0000664000175000017500000000305213166552354020065 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\DOMException.webidl. Do not edit! package js.html; @:native("Exception") extern class Exception { var message(default,null) : String; var result(default,null) : Int; var name(default,null) : String; var filename(default,null) : String; var lineNumber(default,null) : Int; var columnNumber(default,null) : Int; var data(default,null) : Dynamic/*MISSING nsISupports*/; var stack(default,null) : String; }haxe_3.4.4.orig/std/js/html/ExtendableEvent.hx0000664000175000017500000000415313166552354021207 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\ExtendableEvent.webidl. Do not edit! package js.html; /** The `ExtendableEvent` interface extends the lifetime of the `install` and `activate` events dispatched on the global scope as part of the service worker lifecycle. This ensures that any functional events (like `FetchEvent`) are not dispatched until it upgrades database schemas and deletes the outdated cache entries. Documentation [ExtendableEvent](https://developer.mozilla.org/en-US/docs/Web/API/ExtendableEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/ExtendableEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("ExtendableEvent") extern class ExtendableEvent extends Event { /** @throws DOMError */ function new( type : String, ?eventInitDict : ExtendableEventInit ) : Void; /** @throws DOMError */ function waitUntil( p : Promise ) : Void; }haxe_3.4.4.orig/std/js/html/ExtendableEventInit.hx0000664000175000017500000000236313166552354022034 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\ExtendableEvent.webidl. Do not edit! package js.html; typedef ExtendableEventInit = { > EventInit, }haxe_3.4.4.orig/std/js/html/ExtendableMessageEvent.hx0000664000175000017500000000537313166552354022521 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\ExtendableMessageEvent.webidl. Do not edit! package js.html; /** The `ExtendableMessageEvent` interface of the `ServiceWorker API` represents the event object of a `message` event fired on a service worker (when a channel message is received on the `ServiceWorkerGlobalScope` from another context) — extends the lifetime of such events. Documentation [ExtendableMessageEvent](https://developer.mozilla.org/en-US/docs/Web/API/ExtendableMessageEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/ExtendableMessageEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("ExtendableMessageEvent") extern class ExtendableMessageEvent extends ExtendableEvent { /** Returns the event's data. It can be any data type. **/ var data(default,null) : Dynamic; /** Returns the origin of the `ServiceWorkerClient` that sent the message **/ var origin(default,null) : String; /** Represents, in server-sent events, the last event ID of the event source. **/ var lastEventId(default,null) : String; /** Returns a reference to the service worker that sent the message. **/ var source(default,null) : haxe.extern.EitherType>; /** Returns the array containing the `MessagePort` objects representing the ports of the associated message channel. **/ var ports(default,null) : MessagePortList; /** @throws DOMError */ function new( type : String, ?eventInitDict : ExtendableMessageEventInit ) : Void; }haxe_3.4.4.orig/std/js/html/ExtendableMessageEventInit.hx0000664000175000017500000000301113166552354023330 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\ExtendableMessageEvent.webidl. Do not edit! package js.html; typedef ExtendableMessageEventInit = { > ExtendableEventInit, @:optional var data : Dynamic; @:optional var lastEventId : String; @:optional var origin : String; @:optional var ports : Array; @:optional var source : haxe.extern.EitherType>; }haxe_3.4.4.orig/std/js/html/External.hx0000664000175000017500000000275413166552354017721 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\External.webidl. Do not edit! package js.html; @:native("External") extern class External { function AddSearchProvider( aDescriptionURL : String ) : Void; function IsSearchProviderInstalled( aSearchURL : String ) : Int; function addSearchEngine( engineURL : String, iconURL : String, suggestedTitle : String, suggestedCategory : String ) : Void; }haxe_3.4.4.orig/std/js/html/FetchEvent.hx0000664000175000017500000000541213166552354020164 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FetchEvent.webidl. Do not edit! package js.html; /** The parameter passed into the `ServiceWorkerGlobalScope.onfetch` handler, `FetchEvent` represents a fetch action that is dispatched on the `ServiceWorkerGlobalScope` of a `ServiceWorker`. It contains information about the request and resulting response, and provides the `FetchEvent.respondWith()` method, which allows us to provide an arbitrary response back to the controlled page. Documentation [FetchEvent](https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("FetchEvent") extern class FetchEvent extends ExtendableEvent { /** Returns the `Request` that triggered the event handler. **/ var request(default,null) : Request; /** Returns the id of the client that the current service worker is controlling. **/ var clientId(default,null) : String; /** Returns a `Boolean` that is `true` if the event was dispatched with the user's intention for the page to reload, and `false` otherwise. Typically, pressing the refresh button in a browser is a reload, while clicking a link and pressing the back button is not. **/ var isReload(default,null) : Bool; /** @throws DOMError */ function new( type : String, eventInitDict : FetchEventInit ) : Void; /** @throws DOMError */ /** Resolves by returning a `Response` or a network error  to Fetch`. **/ function respondWith( r : Promise ) : Void; }haxe_3.4.4.orig/std/js/html/FetchEventInit.hx0000664000175000017500000000250513166552354021010 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FetchEvent.webidl. Do not edit! package js.html; typedef FetchEventInit = { > EventInit, @:optional var clientId : String; @:optional var isReload : Bool; var request : Request; }haxe_3.4.4.orig/std/js/html/FieldSetElement.hx0000664000175000017500000000436613166552354021151 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLFieldSetElement.webidl. Do not edit! package js.html; /** The `HTMLFieldSetElement` interface has special properties and methods (beyond the regular `HTMLElement` interface it also has available to it by inheritance) for manipulating the layout and presentation of field-set elements. Documentation [HTMLFieldSetElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFieldSetElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFieldSetElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLFieldSetElement") extern class FieldSetElement extends Element { var disabled : Bool; var form(default,null) : FormElement; var name : String; var type(default,null) : String; var elements(default,null) : HTMLCollection; var willValidate(default,null) : Bool; var validity(default,null) : ValidityState; var validationMessage(default,null) : String; function checkValidity() : Bool; function setCustomValidity( error : String ) : Void; }haxe_3.4.4.orig/std/js/html/File.hx0000664000175000017500000000507513166552354017015 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\File.webidl. Do not edit! package js.html; /** The `File` interface provides information about files and allows JavaScript in a web page to access their content. Documentation [File](https://developer.mozilla.org/en-US/docs/Web/API/File) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/File$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("File") extern class File extends Blob { /** Returns the name of the file referenced by the `File` object. **/ var name(default,null) : String; /** Returns the last modified time of the file, in millisecond since the UNIX epoch (January 1st, 1970 at Midnight). **/ var lastModified(default,null) : Int; /** Returns the last modified `Date` of the file referenced by the `File` object. **/ var lastModifiedDate(default,null) : Date; /** @throws DOMError */ @:overload( function( fileBits : Array>>>, fileName : String, ?options : FilePropertyBag ) : Void {} ) @:overload( function( fileBits : Blob, ?options : ChromeFilePropertyBag ) : Void {} ) @:overload( function( fileBits : Dynamic/*MISSING nsIFile*/, ?options : ChromeFilePropertyBag ) : Void {} ) function new( fileBits : String, ?options : ChromeFilePropertyBag ) : Void; }haxe_3.4.4.orig/std/js/html/FileList.hx0000664000175000017500000000374613166552354017654 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FileList.webidl. Do not edit! package js.html; /** An object of this type is returned by the `files` property of the HTML `input` element; this lets you access the list of files selected with the `input type="file"` element. It's also used for a list of files dropped into web content when using the drag and drop API; see the `DataTransfer` object for details on this usage. Documentation [FileList](https://developer.mozilla.org/en-US/docs/Web/API/FileList) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/FileList$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("FileList") extern class FileList implements ArrayAccess { var length(default,null) : Int; function item( index : Int ) : File; }haxe_3.4.4.orig/std/js/html/FileMode.hx0000664000175000017500000000243313166552354017615 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FileMode.webidl. Do not edit! package js.html; @:enum abstract FileMode(String) { var READONLY = "readonly"; var READWRITE = "readwrite"; }haxe_3.4.4.orig/std/js/html/FilePropertyBag.hx0000664000175000017500000000243113166552354021165 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\File.webidl. Do not edit! package js.html; typedef FilePropertyBag = { @:optional var lastModified : Int; @:optional var type : String; }haxe_3.4.4.orig/std/js/html/FileReader.hx0000664000175000017500000001170413166552354020134 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FileReader.webidl. Do not edit! package js.html; /** The `FileReader` object lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer, using `File` or `Blob` objects to specify the file or data to read. Documentation [FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/FileReader$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("FileReader") extern class FileReader extends EventTarget { static inline var EMPTY : Int = 0; static inline var LOADING : Int = 1; static inline var DONE : Int = 2; /** A number indicating the state of the FileReader. This is one of the following:
EMPTY 0 No data has been loaded yet.
LOADING 1 Data is currently being loaded.
DONE 2 The entire read request has been completed.
**/ var readyState(default,null) : Int; /** The file's contents. This property is only valid after the read operation is complete, and the format of the data depends on which of the methods was used to initiate the read operation. **/ var result(default,null) : Dynamic; /** A `DOMError` representing the error that occurred while reading the file. **/ var error(default,null) : DOMError; /** A handler for the `loadstart` event. This event is triggered each time the reading is starting. **/ var onloadstart : haxe.Constraints.Function; /** A handler for the `progress` event. This event is triggered while reading a `Blob` content. **/ var onprogress : haxe.Constraints.Function; /** A handler for the `load` event. This event is triggered each time the reading operation is successfully completed. **/ var onload : haxe.Constraints.Function; /** A handler for the `abort` event. This event is triggered each time the reading operation is aborted. **/ var onabort : haxe.Constraints.Function; /** A handler for the `error` event. This event is triggered each time the reading operation encounter an error. **/ var onerror : haxe.Constraints.Function; /** A handler for the `loadend` event. This event is triggered each time the reading operation is completed (either in success or failure). **/ var onloadend : haxe.Constraints.Function; /** @throws DOMError */ function new() : Void; /** @throws DOMError */ /** Starts reading the contents of the specified `Blob`, once finished, the `result` attribute contains an `ArrayBuffer` representing the file's data. **/ function readAsArrayBuffer( blob : Blob ) : Void; /** @throws DOMError */ /** Starts reading the contents of the specified `Blob`, once finished, the `result` attribute contains the contents of the file as a text string. **/ function readAsText( blob : Blob, ?label : String = "" ) : Void; /** @throws DOMError */ /** Starts reading the contents of the specified `Blob`, once finished, the `result` attribute contains a `data:` URL representing the file's data. **/ function readAsDataURL( blob : Blob ) : Void; /** @throws DOMError */ /** Aborts the read operation. Upon return, the `readyState` will be `DONE`. **/ function abort() : Void; /** @throws DOMError */ /** Starts reading the contents of the specified `Blob`, once finished, the `result` attribute contains the raw binary data from the file as a string. **/ function readAsBinaryString( filedata : Blob ) : Void; }haxe_3.4.4.orig/std/js/html/FileReaderSync.hx0000664000175000017500000000407213166552354020771 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FileReaderSync.webidl. Do not edit! package js.html; /** The `FileReaderSync` interface allows to read `File` or `Blob` objects in a synchronous way. Documentation [FileReaderSync](https://developer.mozilla.org/en-US/docs/Web/API/FileReaderSync) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/FileReaderSync$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("FileReaderSync") extern class FileReaderSync { /** @throws DOMError */ function new() : Void; /** @throws DOMError */ function readAsArrayBuffer( blob : Blob ) : ArrayBuffer; /** @throws DOMError */ function readAsBinaryString( blob : Blob ) : String; /** @throws DOMError */ function readAsText( blob : Blob, ?encoding : String ) : String; /** @throws DOMError */ function readAsDataURL( blob : Blob ) : String; }haxe_3.4.4.orig/std/js/html/FillMode.hx0000664000175000017500000000254613166552354017631 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\AnimationEffectReadOnly.webidl. Do not edit! package js.html; @:enum abstract FillMode(String) { var NONE = "none"; var FORWARDS = "forwards"; var BACKWARDS = "backwards"; var BOTH = "both"; var AUTO = "auto"; }haxe_3.4.4.orig/std/js/html/Float32Array.hx0000664000175000017500000000363613166552354020350 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from typedarray.webidl. Do not edit! package js.html; // Explicitly include the compatibility class import js.html.compat.Float32Array; @:native("Float32Array") extern class Float32Array extends ArrayBufferView implements ArrayAccess { static inline var BYTES_PER_ELEMENT : Int = 4; var length(default,null) : Int; /** @throws DOMError */ @:overload( function( length : Int ) : Void {} ) @:overload( function( array : Float32Array ) : Void {} ) @:overload( function( array : Array ) : Void {} ) function new( buffer : ArrayBuffer, ?byteOffset : Int, ?length : Int ) : Void; @:overload( function( array : Float32Array, ?offset : Int ) : Void {} ) function set( array : Array, ?offset : Int ) : Void; function subarray( start : Int, ?end : Int ) : Float32Array; }haxe_3.4.4.orig/std/js/html/Float64Array.hx0000664000175000017500000000363613166552354020355 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from typedarray.webidl. Do not edit! package js.html; // Explicitly include the compatibility class import js.html.compat.Float64Array; @:native("Float64Array") extern class Float64Array extends ArrayBufferView implements ArrayAccess { static inline var BYTES_PER_ELEMENT : Int = 8; var length(default,null) : Int; /** @throws DOMError */ @:overload( function( length : Int ) : Void {} ) @:overload( function( array : Float64Array ) : Void {} ) @:overload( function( array : Array ) : Void {} ) function new( buffer : ArrayBuffer, ?byteOffset : Int, ?length : Int ) : Void; @:overload( function( array : Float64Array, ?offset : Int ) : Void {} ) function set( array : Array, ?offset : Int ) : Void; function subarray( start : Int, ?end : Int ) : Float64Array; }haxe_3.4.4.orig/std/js/html/FocusEvent.hx0000664000175000017500000000404113166552354020207 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FocusEvent.webidl. Do not edit! package js.html; /** The `FocusEvent` interface represents focus-related events like `focus`, `blur`, `focusin`, or `focusout`. Documentation [FocusEvent](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("FocusEvent") extern class FocusEvent extends UIEvent { /** Is an `EventTarget` representing a secondary target for this event. As in some cases (like when tabbing in or out a page), this property may be set to `null` for security reasons. **/ var relatedTarget(default,null) : EventTarget; /** @throws DOMError */ function new( typeArg : String, ?focusEventInitDict : FocusEventInit ) : Void; }haxe_3.4.4.orig/std/js/html/FocusEventInit.hx0000664000175000017500000000243013166552354021033 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FocusEvent.webidl. Do not edit! package js.html; typedef FocusEventInit = { > UIEventInit, @:optional var relatedTarget : EventTarget; }haxe_3.4.4.orig/std/js/html/FontElement.hx0000664000175000017500000000251313166552354020350 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLFontElement.webidl. Do not edit! package js.html; @:native("HTMLFontElement") extern class FontElement extends Element { var color : String; var face : String; var size : String; }haxe_3.4.4.orig/std/js/html/FontFace.hx0000664000175000017500000000721313166552354017617 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FontFace.webidl. Do not edit! package js.html; /** The `FontFace` interface represents a single usable font face. It allows control of the source of the font face, being a URL to an external resource, or a buffer; it also allows control of when the font face is loaded and its current status. Documentation [FontFace](https://developer.mozilla.org/en-US/docs/Web/API/FontFace) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/FontFace$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("FontFace") extern class FontFace { /** Is a `DOMString` that contains the family of the font. It is equivalent to the `@font-face/family` descriptor. **/ var family : String; /** Is a `DOMString` that contains the style of the font. It is equivalent to the `@font-face/style` descriptor. **/ var style : String; /** Is a `DOMString` that contains the weight of the font. It is equivalent to the `@font-face/weight` descriptor. **/ var weight : String; /** Is a `DOMString` that contains how the font stretches. It is equivalent to the `@font-face/stretch` descriptor. **/ var stretch : String; /** Is a `DOMString` that contains the range of code encompassed the font. It is equivalent to the `@font-face/unicode-range` descriptor. **/ var unicodeRange : String; /** Is a `DOMString` that contains the variant of the font. It is equivalent to the `@font-face/range` descriptor. **/ var variant : String; /** Is a `DOMString` that contains the features of the font. It is equivalent to the `@font-face/feature-settings` descriptor. **/ var featureSettings : String; /** Returns an enumerated value indicating the status of the font. It can be one of the following: `"unloaded"`, `"loading"`, `"loaded"`, or `"error"`. **/ var status(default,null) : FontFaceLoadStatus; /** Returns a `Promise` to a `FontFace` that fulfills when the font is completely loaded and rejects when an error happens. **/ var loaded(default,null) : Promise; /** @throws DOMError */ function new( family : String, source : haxe.extern.EitherType>, ?descriptors : FontFaceDescriptors ) : Void; /** @throws DOMError */ /** Loads the font, returning a `Promise` to a `FontFace` that fulfills when the font is completely loaded and rejects when an error happens. **/ function load() : Promise; }haxe_3.4.4.orig/std/js/html/FontFaceDescriptors.hx0000664000175000017500000000272613166552354022045 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FontFace.webidl. Do not edit! package js.html; typedef FontFaceDescriptors = { @:optional var display : String; @:optional var featureSettings : String; @:optional var stretch : String; @:optional var style : String; @:optional var unicodeRange : String; @:optional var variant : String; @:optional var weight : String; }haxe_3.4.4.orig/std/js/html/FontFaceLoadStatus.hx0000664000175000017500000000251713166552354021625 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FontFace.webidl. Do not edit! package js.html; @:enum abstract FontFaceLoadStatus(String) { var UNLOADED = "unloaded"; var LOADING = "loading"; var LOADED = "loaded"; var ERROR = "error"; }haxe_3.4.4.orig/std/js/html/FontFaceSet.hx0000664000175000017500000000616313166552354020276 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FontFaceSet.webidl. Do not edit! package js.html; /** The `FontFaceSet` interface of the CSS Font Loading API is an interface for loading font faces and checking their download statuses. Documentation [FontFaceSet](https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("FontFaceSet") extern class FontFaceSet extends EventTarget { var size(default,null) : Int; /** An `EventListener` property called whenever an event of type `loading` is fired, indicating that a font face set has started to load. **/ var onloading : haxe.Constraints.Function; /** An `EventListener` property called whenever an event of type `loadingdone` is fired, indicating that a font face set has finished loading. **/ var onloadingdone : haxe.Constraints.Function; /** An `EventListener` property called whenever an event of type `loadingerror` is fired, indicating that an error occurred during the loading of a font face set. **/ var onloadingerror : haxe.Constraints.Function; var ready(default,null) : Promise; /** Indicates the font face's loading status. It will be one of `'loading'` or `'loaded'`. **/ var status(default,null) : FontFaceSetLoadStatus; /** @throws DOMError */ function add( font : FontFace ) : Void; function has( font : FontFace ) : Bool; @:native("delete") function delete_( font : FontFace ) : Bool; function clear() : Void; function entries() : FontFaceSetIterator; function values() : FontFaceSetIterator; /** @throws DOMError */ function forEach( cb : FontFace -> FontFace -> FontFaceSet -> Void, ?thisArg : Dynamic ) : Void; function load( font : String, ?text : String = " " ) : Promise>; /** @throws DOMError */ function check( font : String, ?text : String = " " ) : Bool; }haxe_3.4.4.orig/std/js/html/FontFaceSetIterator.hx0000664000175000017500000000251313166552354022003 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FontFaceSet.webidl. Do not edit! package js.html; @:native("FontFaceSetIterator") extern class FontFaceSetIterator { /** @throws DOMError */ function next() : FontFaceSetIteratorResult; }haxe_3.4.4.orig/std/js/html/FontFaceSetIteratorResult.hx0000664000175000017500000000241713166552354023205 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FontFaceSet.webidl. Do not edit! package js.html; typedef FontFaceSetIteratorResult = { var done : Bool; var value : Dynamic; }haxe_3.4.4.orig/std/js/html/FontFaceSetLoadStatus.hx0000664000175000017500000000244313166552354022277 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FontFaceSet.webidl. Do not edit! package js.html; @:enum abstract FontFaceSetLoadStatus(String) { var LOADING = "loading"; var LOADED = "loaded"; }haxe_3.4.4.orig/std/js/html/FormData.hx0000664000175000017500000000727413166552354017636 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FormData.webidl. Do not edit! package js.html; /** The `FormData` interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the `XMLHttpRequest.send()` method. It uses the same format a form would use if the encoding type were set to `"multipart/form-data"`. Documentation [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/FormData$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("FormData") extern class FormData { /** @throws DOMError */ function new( ?form : FormElement ) : Void; /** @throws DOMError */ @:overload( function( name : String, value : Blob, ?filename : String ) : Void {} ) /** Appends a new value onto an existing key inside a `FormData` object, or adds the key if it does not already exist. **/ function append( name : String, value : String ) : Void; @:native("delete") function delete_( name : String ) : Void; /** Returns the first value associated with a given key from within a `FormData` object. **/ function get( name : String ) : haxe.extern.EitherType; /** Returns an array of all the values associated with a given key from within a `FormData`. **/ function getAll( name : String ) : Array>; /** Returns a boolean stating whether a `FormData` object contains a certain key/value pair. **/ function has( name : String ) : Bool; /** @throws DOMError */ @:overload( function( name : String, value : Blob, ?filename : String ) : Void {} ) /** Sets a new value for an existing key inside a `FormData `object, or adds the key/value if it does not already exist. **/ function set( name : String, value : String ) : Void; /** @throws DOMError */ /** Returns an `Iteration_protocols` allowing to go through all key/value pairs contained in this object. **/ function entries() : FormDataIterator; /** @throws DOMError */ /** Returns an `Iteration_protocols` allowing to go through all keys of the key/value pairs contained in this object. **/ function keys() : FormDataIterator; /** @throws DOMError */ /** Returns an `Iteration_protocols` allowing to go through all values of the key/value pairs contained in this object. **/ function values() : FormDataIterator; /** @throws DOMError */ function forEach( callback : Dynamic, ?thisArg : Dynamic ) : Void; }haxe_3.4.4.orig/std/js/html/FormDataIterator.hx0000664000175000017500000000246013166552354021340 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\FormData.webidl. Do not edit! package js.html; @:native("FormDataIterator") extern class FormDataIterator { /** @throws DOMError */ function next() : Dynamic; }haxe_3.4.4.orig/std/js/html/FormElement.hx0000664000175000017500000000504313166552354020346 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLFormElement.webidl. Do not edit! package js.html; /** The `HTMLFormElement` interface provides methods to create and modify `form` elements. document.forms - returns an array of HTMLFormElement objects referencing all forms on the page. document.forms[index] - returns an HTMLFormElement object referencing the form at the specified index. document.forms['id'] - returns an HTMLFormElement object referencing the form with the specified id. document.forms['name'] - returns an HTMLFormElement object referencing the form with the specified name. Documentation [HTMLFormElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLFormElement") extern class FormElement extends Element implements ArrayAccess { var acceptCharset : String; var action : String; var autocomplete : String; var enctype : String; var encoding : String; var method : String; var name : String; var noValidate : Bool; var target : String; var elements(default,null) : HTMLCollection; var length(default,null) : Int; /** @throws DOMError */ function submit() : Void; function reset() : Void; function checkValidity() : Bool; }haxe_3.4.4.orig/std/js/html/FrameElement.hx0000664000175000017500000000305713166552354020500 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLFrameElement.webidl. Do not edit! package js.html; @:native("HTMLFrameElement") extern class FrameElement extends Element { var name : String; var scrolling : String; var src : String; var frameBorder : String; var longDesc : String; var noResize : Bool; var contentDocument(default,null) : HTMLDocument; var contentWindow(default,null) : Window; var marginHeight : String; var marginWidth : String; }haxe_3.4.4.orig/std/js/html/FrameSetElement.hx0000664000175000017500000000511513166552354021151 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLFrameSetElement.webidl. Do not edit! package js.html; /** The `HTMLFrameSetElement` interface provides special properties (beyond those of the regular `HTMLElement` interface they also inherit) for manipulating `frameset` elements. Documentation [HTMLFrameSetElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFrameSetElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFrameSetElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLFrameSetElement") extern class FrameSetElement extends Element { /** Is a `DOMString` that represents the foreground color of text. **/ var cols : String; /** Is a `DOMString` that represents the color of visited links. **/ var rows : String; var onafterprint : haxe.Constraints.Function; var onbeforeprint : haxe.Constraints.Function; var onbeforeunload : Event -> String; var onhashchange : haxe.Constraints.Function; var onlanguagechange : haxe.Constraints.Function; var onmessage : haxe.Constraints.Function; var onoffline : haxe.Constraints.Function; var ononline : haxe.Constraints.Function; var onpagehide : haxe.Constraints.Function; var onpageshow : haxe.Constraints.Function; var onpopstate : haxe.Constraints.Function; var onstorage : haxe.Constraints.Function; var onunload : haxe.Constraints.Function; }haxe_3.4.4.orig/std/js/html/FrameType.hx0000664000175000017500000000251013166552354020021 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Client.webidl. Do not edit! package js.html; @:enum abstract FrameType(String) { var AUXILIARY = "auxiliary"; var TOP_LEVEL = "top-level"; var NESTED = "nested"; var NONE = "none"; }haxe_3.4.4.orig/std/js/html/Gamepad.hx0000664000175000017500000000537713166552354017501 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Gamepad.webidl. Do not edit! package js.html; /** The `Gamepad` interface of the Gamepad API defines an individual gamepad or other controller, allowing access to information such as button presses, axis positions, and id. Documentation [Gamepad](https://developer.mozilla.org/en-US/docs/Web/API/Gamepad) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Gamepad$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Gamepad") extern class Gamepad { /** A `DOMString` containing identifying information about the controller. **/ var id(default,null) : String; /** An integer that is auto-incremented to be unique for each device currently connected to the system. **/ var index(default,null) : Int; /** A string indicating whether the browser has remapped the controls on the device to a known layout. **/ var mapping(default,null) : GamepadMappingType; /** A boolean indicating whether the gamepad is still connected to the system. **/ var connected(default,null) : Bool; /** An array of `gamepadButton` objects representing the buttons present on the device. **/ var buttons(default,null) : Array; /** An array representing the controls with axes present on the device (e.g. analog thumb sticks). **/ var axes(default,null) : Array; /** A `DOMHighResTimeStamp` representing the last time the data for this gamepad was updated. Note that this property is not currently supported anywhere. **/ var timestamp(default,null) : Float; }haxe_3.4.4.orig/std/js/html/GamepadButton.hx0000664000175000017500000000436013166552354020664 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Gamepad.webidl. Do not edit! package js.html; /** The `GamepadButton` interface defines an individual button of a gamepad or other controller, allowing access to the current state of different types of buttons available on the control device. Documentation [GamepadButton](https://developer.mozilla.org/en-US/docs/Web/API/GamepadButton) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/GamepadButton$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("GamepadButton") extern class GamepadButton { /** A boolean value indicating whether the button is currently pressed (`true`) or unpressed (`false`). **/ var pressed(default,null) : Bool; /** A double value used to represent the current state of analog buttons, such as the triggers on many modern gamepads. The values are normalized to the range 0.0 —1.0, with 0.0 representing a button that is not pressed, and 1.0 representing a button that is fully pressed. **/ var value(default,null) : Float; }haxe_3.4.4.orig/std/js/html/GamepadMappingType.hx0000664000175000017500000000242613166552354021647 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Gamepad.webidl. Do not edit! package js.html; @:enum abstract GamepadMappingType(String) { var NONE = ""; var STANDARD = "standard"; }haxe_3.4.4.orig/std/js/html/Geolocation.hx0000664000175000017500000000503213166552354020372 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\Geolocation.webidl. Do not edit! package js.html; /** The `Geolocation` interface represents an object able to programmatically obtain the position of the device. It gives Web content access to the location of the device. This allows a Web site or app to offer customized results based on the user's location. Documentation [Geolocation](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("Geolocation") extern class Geolocation { /** @throws DOMError */ /** Determines the device's current location and gives back a `Position` object with the data. **/ function getCurrentPosition( successCallback : Position -> Void, ?errorCallback : PositionError -> Void, ?options : PositionOptions ) : Void; /** @throws DOMError */ /** Returns a `long` value representing the newly established callback function to be invoked whenever the device location changes. **/ function watchPosition( successCallback : Position -> Void, ?errorCallback : PositionError -> Void, ?options : PositionOptions ) : Int; /** Removes the particular handler previously installed using `watchPosition()`. **/ function clearWatch( watchId : Int ) : Void; }haxe_3.4.4.orig/std/js/html/GetUserMediaRequest.hx0000664000175000017500000000272613166552354022025 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\GetUserMediaRequest.webidl. Do not edit! package js.html; @:native("GetUserMediaRequest") extern class GetUserMediaRequest { var windowID(default,null) : Int; var innerWindowID(default,null) : Int; var callID(default,null) : String; var isSecure(default,null) : Bool; function getConstraints() : MediaStreamConstraints; }haxe_3.4.4.orig/std/js/html/HRElement.hx0000664000175000017500000000360713166552354017760 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLHRElement.webidl. Do not edit! package js.html; /** The `HTMLHRElement` interface provides special properties (beyond those of the `HTMLElement` interface it also has available to it by inheritance) for manipulating `hr` elements. Documentation [HTMLHRElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLHRElement) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLHRElement$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLHRElement") extern class HRElement extends Element { var align : String; var color : String; var noShade : Bool; var size : String; var width : String; }haxe_3.4.4.orig/std/js/html/HTMLAllCollection.hx0000664000175000017500000000303213166552354021336 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLAllCollection.webidl. Do not edit! package js.html; @:native("HTMLAllCollection") extern class HTMLAllCollection implements ArrayAccess { var length(default,null) : Int; @:overload( function( index : Int ) : Node {} ) function item( name : String ) : haxe.extern.EitherType; function namedItem( name : String ) : haxe.extern.EitherType; }haxe_3.4.4.orig/std/js/html/HTMLCollection.hx0000664000175000017500000000466013166552354020715 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLCollection.webidl. Do not edit! package js.html; /** The `HTMLCollection` interface represents a generic collection (array-like object similar to arguments) of elements (in document order) and offers methods and properties for selecting from the list. Documentation [HTMLCollection](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLCollection") extern class HTMLCollection implements ArrayAccess { /** Returns the number of items in the collection. **/ var length(default,null) : Int; /** Returns the specific node at the given zero-based `index` into the list. Returns `null` if the `index` is out of range. **/ function item( index : Int ) : Element; /** Returns the specific node whose ID or, as a fallback, name matches the string specified by `name`. Matching by name is only done as a last resort, only in HTML, and only if the referenced element supports the `name` attribute. Returns `null` if no node exists by the given name. **/ function namedItem( name : String ) : Element; }haxe_3.4.4.orig/std/js/html/HTMLDocument.hx0000664000175000017500000003213613166552354020377 0ustar andyandy00000000000000/* * Copyright (C)2005-2017 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. */ // This file is generated from mozilla\HTMLDocument.webidl. Do not edit! package js.html; /** `HTMLDocument` is an abstract interface of the DOM which provides access to special properties and methods not present by default on a regular (XML) document. Documentation [HTMLDocument](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDocument) by [Mozilla Contributors](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDocument$history), licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/). @see **/ @:native("HTMLDocument") extern class HTMLDocument extends Document { var domain : String; var cookie : String; var body : BodyElement; var head(default,null) : HeadElement; var images(default,null) : HTMLCollection; var embeds(default,null) : HTMLCollection; var plugins(default,null) : HTMLCollection; var links(default,null) : HTMLCollection; var forms(default,null) : HTMLCollection; var scripts(default,null) : HTMLCollection; var designMode : String; var fgColor : String; var linkColor : String; var vlinkColor : String; var alinkColor : String; var bgColor : String; var anchors(default,null) : HTMLCollection; var applets(default,null) : HTMLCollection; var all(default,null) : HTMLAllCollection; function getElementsByName( elementName : String ) : NodeList; function getItems( ?typeNames : String = "" ) : NodeList; /** @throws DOMError */ @:overload( function( ?type : String = "text/html", ?replace : String = "" ) : HTMLDocument {} ) function open( url : String, name : String, features : String, ?replace : Bool = false ) : Window; /** @throws DOMError */ function close() : Void; /** @throws DOMError */ function write( text : haxe.extern.Rest ) : Void; /** @throws DOMError */ function writeln( text : haxe.extern.Rest ) : Void; /** @throws DOMError */ function execCommand( commandId : String, ?showUI : Bool = false, ?value : String = "" ) : Bool; /** @throws DOMError */ function queryCommandEnabled( commandId : String ) : Bool; /** @throws DOMError */ function queryCommandIndeterm( commandId : String ) : Bool; /** @throws DOMError */ function queryCommandState( commandId : String ) : Bool; function queryCommandSupported( commandId : String ) : Bool; /** @throws DOMError */ function queryCommandValue( commandId : String ) : String; function clear() : Void; /** @throws DOMError */ function getSelection() : Selection; function captureEvents() : Void; function releaseEvents() : Void; /** Shorthand for creating an HTML `` element. */ inline function createTableCellElement() : TableCellElement { return cast createElement("td"); } /** Shorthand for creating an HTML `
` element. */ inline function createHRElement() : HRElement { return cast createElement("hr"); } /** Shorthand for creating an HTML `` element. */ inline function createInputElement() : InputElement { return cast createElement("input"); } /** Shorthand for creating an HTML `` element. */ inline function createEmbedElement() : EmbedElement { return cast createElement("embed"); } /** Shorthand for creating an HTML `` element. */ inline function createMeterElement() : MeterElement { return cast createElement("meter"); } /** Shorthand for creating an HTML `` element. */ inline function createPictureElement() : PictureElement { return cast createElement("picture"); } /** Shorthand for creating an HTML `
` element. */
	inline function createPreElement() : PreElement { return cast createElement("pre"); }
	/** Shorthand for creating an HTML `` element. */
	inline function createTableSectionElement() : TableSectionElement { return cast createElement("thead"); }
	/** Shorthand for creating an HTML `` element. */
	inline function createHeadElement() : HeadElement { return cast createElement("head"); }
	/** Shorthand for creating an HTML `` element. */
	inline function createBaseElement() : BaseElement { return cast createElement("base"); }
	/** Shorthand for creating an HTML `` element. */
	inline function createOptGroupElement() : OptGroupElement { return cast createElement("optgroup"); }
	/** Shorthand for creating an HTML `` element. */
	inline function createQuoteElement() : QuoteElement { return cast createElement("quote"); }
	/** Shorthand for creating an HTML `