├── .github └── workflows │ ├── generate_documentation.yml │ ├── nightly-build.yml │ └── test-runtime.yml ├── .gitignore ├── DevEnv.hxml ├── LICENSE ├── README.md ├── Submit.hx ├── documentation ├── .gitignore ├── book.toml ├── pages │ ├── SUMMARY.md │ ├── basic_usage │ │ ├── constant_preloads.md │ │ ├── exporting_properties.md │ │ ├── first_node.md │ │ ├── on_ready.md │ │ ├── signals.md │ │ └── syntax_class.md │ └── intro │ │ ├── adding_first_class.md │ │ ├── godot_api.md │ │ └── setup.md └── theme │ └── highlight.js ├── extraParams.hxml ├── haxelib.json ├── img ├── Logo.aseprite └── Logo.png ├── src └── gdcompiler │ ├── GDCompiler.hx │ ├── GDCompilerInit.hx │ ├── config │ ├── Define.hx │ └── Meta.hx │ └── subcompilers │ ├── EnumCompiler.hx │ └── TypeCompiler.hx ├── std ├── GDScript.hx └── gdscript │ ├── ArrayEx.hx │ ├── Dictionary.hx │ ├── ObjectEx.hx │ ├── StringEx.hx │ ├── StringName.hx │ ├── Syntax.hx │ ├── Untyped.hx │ ├── UntypedArray.hx │ ├── UntypedDictionary.hx │ └── _std │ ├── Array.hx │ ├── EReg.hx │ ├── Math.hx │ ├── Reflect.hx │ ├── Std.hx │ ├── String.hx │ ├── Sys.hx │ └── haxe │ ├── Exception.hx │ ├── Log.hx │ └── ds │ ├── IntMap.hx │ ├── ObjectMap.hx │ └── StringMap.hx └── test ├── .gitignore ├── BuildProject.bat ├── TODO.md ├── Test.hxml ├── TestProject.bat ├── Test_WithHaxelib.hxml ├── godot_project ├── .gitattributes ├── .gitignore ├── export_presets.cfg ├── gdscript │ ├── Test.gd │ ├── Test.gd.uid │ └── out │ │ ├── EReg.gd │ │ ├── EReg.gd.uid │ │ ├── Log.gd │ │ ├── Log.gd.uid │ │ ├── MyAbstract.gd │ │ ├── MyAbstract.gd.uid │ │ ├── Reflect.gd │ │ ├── Reflect.gd.uid │ │ ├── StringBuf.gd │ │ ├── StringBuf.gd.uid │ │ ├── StringTools.gd │ │ ├── StringTools.gd.uid │ │ ├── TestAll.gd │ │ ├── TestAll.gd.uid │ │ ├── TestArray.gd │ │ ├── TestArray.gd.uid │ │ ├── TestClass.gd │ │ ├── TestClass.gd.uid │ │ ├── TestEReg.gd │ │ ├── TestEReg.gd.uid │ │ ├── TestEnum.gd │ │ ├── TestEnum.gd.uid │ │ ├── TestMap.gd │ │ ├── TestMap.gd.uid │ │ ├── TestMath.gd │ │ ├── TestMath.gd.uid │ │ ├── TestMeta.gd │ │ ├── TestMeta.gd.uid │ │ ├── TestNode.gd │ │ ├── TestNode.gd.uid │ │ ├── TestReflect.gd │ │ ├── TestReflect.gd.uid │ │ ├── TestSignals.gd │ │ ├── TestSignals.gd.uid │ │ ├── TestStaticVar.gd │ │ ├── TestStaticVar.gd.uid │ │ ├── TestStd.gd │ │ ├── TestStd.gd.uid │ │ ├── TestString.gd │ │ ├── TestString.gd.uid │ │ ├── TestSyntax.gd │ │ ├── TestSyntax.gd.uid │ │ ├── TestSys.gd │ │ ├── TestSys.gd.uid │ │ ├── _GeneratedFiles.txt │ │ ├── haxe_ArrayIterator.gd │ │ ├── haxe_ArrayIterator.gd.uid │ │ ├── haxe_ArrayKeyValueIterator.gd │ │ ├── haxe_ArrayKeyValueIterator.gd.uid │ │ ├── haxe_Constraints_IMap.gd.uid │ │ ├── haxe_Encoding.gd │ │ ├── haxe_Encoding.gd.uid │ │ ├── haxe_IntMap.gd │ │ ├── haxe_IntMap.gd.uid │ │ ├── haxe_List.gd │ │ ├── haxe_List.gd.uid │ │ ├── haxe_MapKeyValueIterator.gd │ │ ├── haxe_MapKeyValueIterator.gd.uid │ │ ├── haxe_NotImplementedException.gd │ │ ├── haxe_NotImplementedException.gd.uid │ │ ├── haxe_ObjectMap.gd │ │ ├── haxe_ObjectMap.gd.uid │ │ ├── haxe_PosException.gd │ │ ├── haxe_PosException.gd.uid │ │ ├── haxe_StringMap.gd │ │ ├── haxe_StringMap.gd.uid │ │ ├── haxe_ds_List_ListNode.gd │ │ ├── haxe_ds_List_ListNode.gd.uid │ │ ├── haxe_macro_Expr_Access.gd │ │ ├── haxe_macro_Expr_Access.gd.uid │ │ ├── haxe_macro_Expr_EFieldKind.gd │ │ ├── haxe_macro_Expr_EFieldKind.gd.uid │ │ ├── haxe_macro_Expr_Error.gd │ │ ├── haxe_macro_Expr_Error.gd.uid │ │ ├── haxe_macro_Expr_QuoteStatus.gd │ │ ├── haxe_macro_Expr_QuoteStatus.gd.uid │ │ ├── haxe_macro_Expr_StringLiteralKind.gd │ │ ├── haxe_macro_Expr_StringLiteralKind.gd.uid │ │ ├── haxe_macro_Expr_Unop.gd │ │ ├── haxe_macro_Expr_Unop.gd.uid │ │ ├── haxe_macro_Type_MethodKind.gd │ │ ├── haxe_macro_Type_MethodKind.gd.uid │ │ ├── test_MyAbstract_AbstractBase.gd │ │ ├── test_MyAbstract_AbstractBase.gd.uid │ │ ├── test_MyAbstract_AbstractZ.gd │ │ ├── test_MyAbstract_AbstractZ.gd.uid │ │ ├── test_MyAbstract_ClassWithHashCode.gd │ │ ├── test_MyAbstract_ClassWithHashCode.gd.uid │ │ ├── test_MyAbstract_ClassWithoutHashCode.gd │ │ ├── test_MyAbstract_ClassWithoutHashCode.gd.uid │ │ ├── test_MyAbstract_ExposingAbstract.gd │ │ ├── test_MyAbstract_ExposingAbstract.gd.uid │ │ ├── test_MyAbstract_Kilometer.gd │ │ ├── test_MyAbstract_Kilometer.gd.uid │ │ ├── test_MyAbstract_Meter.gd │ │ ├── test_MyAbstract_Meter.gd.uid │ │ ├── test_MyAbstract_MyAbstractClosure.gd │ │ ├── test_MyAbstract_MyAbstractClosure.gd.uid │ │ ├── test_MyAbstract_MyAbstractCounter.gd │ │ ├── test_MyAbstract_MyAbstractCounter.gd.uid │ │ ├── test_MyAbstract_MyAbstractSetter.gd │ │ ├── test_MyAbstract_MyAbstractSetter.gd.uid │ │ ├── test_MyAbstract_MyAbstractThatCallsAMember.gd │ │ ├── test_MyAbstract_MyAbstractThatCallsAMember.gd.uid │ │ ├── test_MyAbstract_MyClassWithAbstractArgCtor.gd │ │ ├── test_MyAbstract_MyClassWithAbstractArgCtor.gd.uid │ │ ├── test_MyAbstract_MyDebugString.gd │ │ ├── test_MyAbstract_MyDebugString.gd.uid │ │ ├── test_MyAbstract_MyHash.gd │ │ ├── test_MyAbstract_MyHash.gd.uid │ │ ├── test_MyAbstract_MyInt.gd │ │ ├── test_MyAbstract_MyInt.gd.uid │ │ ├── test_MyAbstract_MyInt2.gd │ │ ├── test_MyAbstract_MyInt2.gd.uid │ │ ├── test_MyAbstract_MyPoint3.gd │ │ ├── test_MyAbstract_MyPoint3.gd.uid │ │ ├── test_MyAbstract_MyReflect.gd │ │ ├── test_MyAbstract_MyReflect.gd.uid │ │ ├── test_MyAbstract_MySpecialString.gd │ │ ├── test_MyAbstract_MySpecialString.gd.uid │ │ ├── test_MyAbstract_MyVector.gd │ │ ├── test_MyAbstract_MyVector.gd.uid │ │ ├── test_MyAbstract_TemplateWrap.gd │ │ ├── test_MyAbstract_TemplateWrap.gd.uid │ │ ├── test_TestEnum_MyGDEnum.gd │ │ ├── test_TestEnum_MyGDEnum.gd.uid │ │ ├── test_TestReflect_MyClass.gd │ │ ├── test_TestReflect_MyClass.gd.uid │ │ ├── test_TestStaticVar_OtherClass.gd │ │ ├── test_TestStaticVar_OtherClass.gd.uid │ │ ├── test_TestStd_A.gd │ │ ├── test_TestStd_A.gd.uid │ │ ├── test_TestStd_B.gd │ │ ├── test_TestStd_B.gd.uid │ │ ├── test_TestStd_C.gd │ │ └── test_TestStd_C.gd.uid ├── icon.svg ├── icon.svg.import ├── project.godot └── test_scene.tscn └── src ├── Assert.hx └── test ├── HelperMacros.hx ├── MyAbstract.hx ├── TestAll.hx ├── TestArray.hx ├── TestClass.hx ├── TestEReg.hx ├── TestEnum.hx ├── TestMap.hx ├── TestMath.hx ├── TestMeta.hx ├── TestNode.hx ├── TestReflect.hx ├── TestSignals.hx ├── TestStaticVar.hx ├── TestStd.hx ├── TestString.hx ├── TestSyntax.hx └── TestSys.hx /.github/workflows/generate_documentation.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Generate Documentation 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | paths: 9 | - documentation/** 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 15 | permissions: 16 | contents: read 17 | pages: write 18 | id-token: write 19 | 20 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 21 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 22 | concurrency: 23 | group: "pages" 24 | cancel-in-progress: false 25 | 26 | jobs: 27 | # Single deploy job since we're just deploying 28 | deploy: 29 | environment: 30 | name: github-pages 31 | url: ${{ steps.deployment.outputs.page_url }} 32 | runs-on: ubuntu-latest 33 | steps: 34 | - name: Checkout 35 | uses: actions/checkout@v4 36 | - name: Setup Pages 37 | uses: actions/configure-pages@v5 38 | - name: Install Rust 39 | uses: actions-rust-lang/setup-rust-toolchain@v1 40 | - name: Install MDBook 41 | run: cargo install mdbook 42 | - name: Build Documentation 43 | run: mdbook build 44 | working-directory: documentation 45 | - name: Upload artifact 46 | uses: actions/upload-pages-artifact@v3 47 | with: 48 | # Upload entire repository 49 | path: 'documentation/book' 50 | - name: Deploy to GitHub Pages 51 | id: deployment 52 | uses: actions/deploy-pages@v4 53 | -------------------------------------------------------------------------------- /.github/workflows/nightly-build.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | 6 | jobs: 7 | build_nightly: 8 | runs-on: ubuntu-latest 9 | name: Build Nightly 10 | steps: 11 | - name: Install Haxe 12 | uses: krdlab/setup-haxe@v1 13 | with: 14 | haxe-version: 4.3.0 15 | 16 | - name: Checkout 17 | uses: actions/checkout@v3 18 | 19 | - name: Install Reflaxe 20 | run: haxelib git reflaxe https://github.com/SomeRanDev/reflaxe.git 21 | 22 | - name: Construct Haxelib Folder 23 | run: haxelib run reflaxe build 24 | 25 | - name: Push to Nightly Branch 26 | uses: s0/git-publish-subdir-action@develop 27 | env: 28 | REPO: self 29 | BRANCH: nightly # The branch name where you want to push the assets 30 | FOLDER: _Build # The directory where your assets are generated 31 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub will automatically add this - you don't need to bother getting a token 32 | MESSAGE: "Build: ({sha}) {msg}" # The commit message 33 | 34 | - name: Submit to Haxelib 35 | run: | 36 | haxe -version 37 | haxelib submit _Build ${{ secrets.HAXELIB_PASSWORD }} --always 38 | env: 39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 40 | -------------------------------------------------------------------------------- /.github/workflows/test-runtime.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | pull_request: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | build_ubuntu: 11 | runs-on: ubuntu-latest 12 | name: Test Runtime & Null Safety 13 | steps: 14 | - uses: krdlab/setup-haxe@v1 15 | with: 16 | haxe-version: latest 17 | 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | 21 | - name: Install & Check Haxe 22 | run: haxe -version 23 | 24 | - name: Install Reflaxe 25 | run: haxelib git reflaxe https://github.com/RobertBorghese/reflaxe.git 26 | 27 | - name: Test Dev. Environment 28 | run: haxe DevEnv.hxml 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Test 2 | test/gdscript/out 3 | test/project.godot 4 | 5 | # Reflaxe Build 6 | _Build/ 7 | 8 | # Bindings 9 | godot/ 10 | 11 | # Haxelib Files 12 | extension_api.json 13 | gdscript.zip 14 | Submit.bat 15 | 16 | # Projects and Personal Utilities 17 | Build.bat 18 | ReflaxeGDScript.code-workspace 19 | -------------------------------------------------------------------------------- /DevEnv.hxml: -------------------------------------------------------------------------------- 1 | # DevEnv.hxml 2 | # Makes auto-completion work in VS code while developing this project. 3 | # Also checks null-safety when executed (`haxe DevEnv.hxml`). 4 | -D reflaxe_runtime 5 | -D gdscript_runtime 6 | --macro nullSafety("gdcompiler") 7 | -lib reflaxe 8 | -cp src 9 | gdcompiler 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 RoBBoR 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Reflaxe Thread [![Button Click]][Link] 4 | 5 | _Compile Haxe to GDScript 2.0 like any other Haxe target. Made using [Reflaxe](https://github.com/RobertBorghese/reflaxe)._ 6 | 7 | 8 | [Button Click]: https://img.shields.io/badge/Documentation-Click_here!-yellow 9 | [Link]: https://somerandev.github.io/reflaxe.GDScript 'Documentation' 10 |   11 | 12 | **Haxe Code** 13 | 14 | ```haxe 15 | function main() { 16 | trace("Hello world!"); 17 | 18 | final num = if(Math.random() < 0.5) { 19 | 123; 20 | } else { 21 | 321; 22 | } 23 | } 24 | ``` 25 | 26 | **Reflaxe/GDScript Output** 27 | 28 | ```gdscript 29 | class_name Main 30 | 31 | func main(): 32 | HxStaticVars._Log.trace.call("Hello world!", { "fileName": "src/Main.hx", "lineNumber": 2, "className": "Main", "methodName": "main" }) 33 | 34 | var num 35 | if (randf() < 0.5): 36 | num = 123 37 | else: 38 | num = 321 39 | ``` 40 | 41 |   42 | 43 | # Table of Contents 44 | 45 | | Topic | Description | 46 | | ------------------------------------------------------------------------------- | -------------------------------------------------- | 47 | | [Installation](#installation) | How to install and use this project. | 48 | | [GDScript Output as a Plugin](#loading-your-gdscript-output-as-a-plugin) | How to load your code using the plugin workflow. | 49 | | [Godot Bindings](#godot-bindings) | How to setup the Godot bindings. | 50 | | [Read the Documentation!](https://somerandev.github.io/reflaxe.GDScript) | The documentation for this project | 51 | 52 |   53 | 54 | # Installation 55 | 56 | | # | What to do | What to write | 57 | | --- | ---------------------------------------------------- | ---------------------------------------- | 58 | | 1 | Install via haxelib (DON'T FORGET `1.0.0-beta!`) |
haxelib install gdscript 1.0.0-beta
| 59 | | 2 | Add the lib to your `.hxml` file or compile command. |
-lib gdscript
| 60 | | 3 | Set the output folder for the compiled GDScript. |
-D gdscript-output=out
| 61 | | 4 | Optionally, generate your code as a Godot plugin. |
-D generate_godot_plugin
| 62 | 63 |   64 | 65 | # Loading Your GDScript Output as a Plugin 66 | 67 | If you choose to output a Godot plugin, the setup process is very easy. Generate the GDScript code into a folder in your "addons" folder for your Godot project. For example: 68 | ``` 69 | -D gdscript-output=MY_GODOT_PROJECT/addons/haxe_output 70 | ``` 71 | 72 | To enable the plugin, go to `Project (top-left) > Project Settings > Plugins (tab)` and click the checkbox next to your plugin's name. 73 | 74 |   75 | 76 | # Godot Bindings 77 | 78 | Reflaxe/GDScript does not come with bindings to Godot types by default since the version of Godot is different for every person. However, generating the bindings is SUPER DUPER easy. 79 | 80 | First, install the [Haxe Godot Bindings Generator](https://github.com/SomeRanDev/Haxe-GodotBindingsGenerator) library: 81 | ``` 82 | haxelib git godot-api-generator https://github.com/SomeRanDev/Haxe-GodotBindingsGenerator 83 | ``` 84 | 85 | Next, run this command to generate: 86 | ``` 87 | haxelib run godot-api-generator 88 | ``` 89 | 90 | This will generate all the Godot bindings as `.hx` Haxe source code files in a local folder named "godot". 91 | 92 | ### Godot Executable Configuration 93 | When you run the command, you will be asked for the path to your Godot engine executable, so be sure to find it first! If you do not want to enter it manually, you can assign it to the `GODOT_PATH` environment variable before running the command. 94 | 95 |   96 | 97 | ## How Does It Work? 98 | 99 | - As GDScript outputs one file per class, each class, regardless of module, receives its own file. 100 | - A custom version of the Haxe standard library is made for GDScript (check out `std/gdscript/_std`) 101 | - Bindings to the Godot classes/functions are generated using [Godot Bindings Generator for Haxe](https://github.com/SomeRanDev/Haxe-GodotBindingsGenerator) 102 | 103 | ### Inject GDScript 104 | - GDScript can be injected directly using: 105 | ```haxe 106 | // Haxe 107 | untyped __gdscript__("print(123)"); 108 | 109 | //GDScript 110 | print(123); 111 | ``` 112 | 113 | ### GDScript Annotations 114 | - GDScript meta can be defined using `@:meta`, though there should be defined metadata for each existing attribute in GDScript. 115 | ```haxe 116 | // Haxe 117 | @:meta(onready) var someVal = get_node("myNode") 118 | 119 | // GDScript 120 | @onready 121 | var someVal = get_node("myNode") 122 | ``` 123 | 124 | ### Enum Support 125 | - Haxe enums are converted into simple dictionaries in GDScript. 126 | ```haxe 127 | // Haxe 128 | var myEnum = SomeEnumCase(123, "Hello!"); 129 | 130 | // GDScript 131 | var myEnum = { "_index": 2, "num": 123, "text": "Hello!" } 132 | ``` 133 | -------------------------------------------------------------------------------- /Submit.hx: -------------------------------------------------------------------------------- 1 | //==================================================================== 2 | // * Haxe to GDScript Submit Script 3 | // 4 | // Haxelib is dumb and only allows for one class path, so this 5 | // script merges all the class paths (`src`, `std`, `std/gdscript/_std`) 6 | // into a single folder to help with haxelib submission. 7 | //==================================================================== 8 | 9 | package; 10 | 11 | import sys.io.File; 12 | import haxe.io.Path; 13 | 14 | class Submit { 15 | public static function main() { 16 | if(sys.FileSystem.exists("_submit")) throw "'Folder /_submit/ should not exist before running this script.'"; 17 | makeDirIfNonExist("_submit"); 18 | 19 | copyDirContent("src", "_submit"); 20 | copyDirContent("std", "_submit", "std/gdscript/_std"); 21 | copyDirContent("std/gdscript/_std", "_submit", "", ".cross.hx"); 22 | } 23 | 24 | static function makeDirIfNonExist(p: String) { 25 | if(!sys.FileSystem.exists(p)) { 26 | sys.FileSystem.createDirectory(p); 27 | } 28 | } 29 | 30 | static function copyDirContent(from: String, to: String, ignore: String = "", replaceExt: Null = null) { 31 | if(sys.FileSystem.exists(from)) { 32 | for(file in sys.FileSystem.readDirectory(from)) { 33 | final path = Path.join([from, file]); 34 | var dest = Path.join([to, file]); 35 | if(!sys.FileSystem.isDirectory(path)) { 36 | if(replaceExt != null) { 37 | dest = Path.withoutExtension(dest) + replaceExt; 38 | } 39 | File.copy(path, dest); 40 | } else { 41 | if(ignore.length > 0 && ignore == path) { 42 | return; 43 | } 44 | final d = Path.addTrailingSlash(path); 45 | final d2 = Path.addTrailingSlash(dest); 46 | makeDirIfNonExist(d2); 47 | copyDirContent(d, d2, ignore, replaceExt); 48 | } 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /documentation/.gitignore: -------------------------------------------------------------------------------- 1 | book 2 | -------------------------------------------------------------------------------- /documentation/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["Maybee Rezbit"] 3 | language = "en" 4 | multilingual = false 5 | src = "pages" 6 | title = "Reflaxe/GDScript" 7 | -------------------------------------------------------------------------------- /documentation/pages/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | # Intro 4 | - [Setup](./intro/setup.md) 5 | - [Adding First Class](./intro/adding_first_class.md) 6 | - [Adding Godot API](./intro/godot_api.md) 7 | 8 | # Basic Usage 9 | - [First Node](./basic_usage/first_node.md) 10 | - [Exporting Properties](./basic_usage/exporting_properties.md) 11 | - [On Ready](./basic_usage/on_ready.md) 12 | - [Signals](./basic_usage/signals.md) 13 | - [Constant Preloads](./basic_usage/constant_preloads.md) 14 | - [`gdscript.Syntax` Class](./basic_usage/syntax_class.md) 15 | -------------------------------------------------------------------------------- /documentation/pages/basic_usage/constant_preloads.md: -------------------------------------------------------------------------------- 1 | # Constant Preloads 2 | 3 | `@:const` creates a `const` variable in GDScript. 4 | ```haxe 5 | class MyNode extends godot.Node { 6 | @:const 7 | static final MAX_JUMPS = 4; 8 | } 9 | ``` 10 | 11 | This would be converted to: 12 | ```gdscript 13 | extends Node; 14 | class_name MyNode; 15 | 16 | const MAX_JUMPS: int = 4; 17 | ``` 18 | 19 | ## Preloading Resources 20 | 21 | A common pattern in GDScript is to `preload` resources into a `const` variable. The `@:const` metadata provides a helper feature to achieve this: 22 | ```haxe 23 | class MyNode extends godot.Node { 24 | // Use `gdscript.Syntax.NoAssign` since Haxe requires us to assign something to `final`. 25 | @:const(preload = "res://scenes/bullet.tscn") 26 | static final BULLET_SCENE: PackedScene = gdscript.Syntax.NoAssign; 27 | } 28 | ``` 29 | 30 | This would be converted to: 31 | ```gdscript 32 | extends Node; 33 | class_name MyNode; 34 | 35 | const BULLET_SCENE: PackedScene = preload("res://scenes/bullet.tscn"); 36 | ``` 37 | -------------------------------------------------------------------------------- /documentation/pages/basic_usage/exporting_properties.md: -------------------------------------------------------------------------------- 1 | # Exporting Properties 2 | 3 | `@:export` can be used like the `@export` metadata from GDScript: 4 | ```haxe 5 | class MyNode extends godot.Node { 6 | @:export 7 | var customNumber: Int = 20; 8 | } 9 | ``` 10 | 11 | This would be converted to: 12 | ```gdscript 13 | extends Node; 14 | class_name MyNode; 15 | 16 | @export 17 | var customNumber: int = 20; 18 | ``` 19 | -------------------------------------------------------------------------------- /documentation/pages/basic_usage/first_node.md: -------------------------------------------------------------------------------- 1 | # First Node 2 | 3 | Here's the basic outline for an extended `Node` in Haxe with Reflaxe/GDScript: 4 | ```haxe 5 | import godot.*; 6 | 7 | class MyNode extends Node { 8 | public override function _ready() { 9 | // on ready... 10 | } 11 | 12 | public override function _process(delta: Float) { 13 | // on update... 14 | } 15 | } 16 | ``` 17 | 18 | You can override any functions marked "virtual" in Godot's documentation like this: 19 | 20 | ```haxe 21 | import godot.*; 22 | 23 | class MyNode extends Node { 24 | public override function _input(event: InputEvent) { 25 | // on ready... 26 | } 27 | 28 | public override function _physics_process(delta: Float) { 29 | // on physics update... 30 | } 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /documentation/pages/basic_usage/on_ready.md: -------------------------------------------------------------------------------- 1 | # On Ready 2 | 3 | `@:onready` can be used like the `@on_ready` metadata from GDScript: 4 | ```haxe 5 | class MyNode extends godot.Node { 6 | @:onready 7 | var customNumber: Int = 20; 8 | } 9 | ``` 10 | 11 | This would be converted to: 12 | ```gdscript 13 | extends Node; 14 | class_name MyNode; 15 | 16 | @onready 17 | var customNumber: int = 20; 18 | ``` 19 | 20 | ## Loading Nodes 21 | 22 | `@:onready` has a helper feature that can be used to load nodes from a path. Simply pass a `String` assignment to `node`: 23 | ```haxe 24 | class MyNode extends godot.Node { 25 | @:onready(node = "Label") 26 | var label: Label; 27 | } 28 | ``` 29 | 30 | This would be converted to: 31 | ```gdscript 32 | extends Node; 33 | class_name MyNode; 34 | 35 | @onready 36 | var label: Label = $Label; 37 | ``` 38 | -------------------------------------------------------------------------------- /documentation/pages/basic_usage/signals.md: -------------------------------------------------------------------------------- 1 | # Signals 2 | 3 | A signal can be added using the `@:signal` metadata: 4 | ```haxe 5 | import godot.*; 6 | 7 | class MyNode extends CharacterBody2D { 8 | // Any code in this function will be ignored 9 | @:signal 10 | function onHitGround(speed: Float) {} 11 | } 12 | ``` 13 | 14 | The `emit_signal` function from the generated API only supports a `String` parameter, but you can use `emit_signal` from the Reflaxe/GDScript API class: `gdscript.ObjectEx`. 15 | ```haxe 16 | import godot.*; 17 | import gdscript.ObjectEx; 18 | 19 | class MyNode extends CharacterBody2D { 20 | @:signal 21 | function onHitGround(speed: Float) {} 22 | 23 | public override function _physics_process(delta: Float) { 24 | var hitGround = false; 25 | 26 | // Do some processing... 27 | 28 | if(hitGround) { 29 | ObjectEx.emit_signal("onHitGround", velocity.length()); 30 | } 31 | } 32 | } 33 | ``` 34 | -------------------------------------------------------------------------------- /documentation/pages/basic_usage/syntax_class.md: -------------------------------------------------------------------------------- 1 | # `gdscript.Syntax` class 2 | 3 | The `Syntax` class has a couple utilities. 4 | 5 | ## `is` Operator 6 | 7 | This allows for direct generation of `is` expressions. 8 | 9 | For example: 10 | ```haxe 11 | if(gdscript.Syntax.is(sprite, Sprite2D)) { 12 | cast(sprite, Sprite2D).centered = true; 13 | } 14 | ``` 15 | 16 | Converts to: 17 | ```gdscript 18 | if sprite is Sprite2D: 19 | (sprite as Sprite2D).centered = true; 20 | ``` 21 | 22 | ## Node Path Using `$` 23 | 24 | To generate an expression for obtaining a node via `$`, `gdscript.Syntax.dollar` can be used. The parameter can either be an identifier or String. 25 | 26 | For example: 27 | ```haxe 28 | var a: godot.Label = gdscript.Syntax.dollar(MyLabel); 29 | var b: godot.Label = gdscript.Syntax.dollar("Path/To/OtherLabel"); // must use String for slashes 30 | ``` 31 | 32 | Converts to: 33 | ```gdscript 34 | var a: Label = $MyLabel; 35 | var b: Label = $Path/To/OtherLabel; 36 | ``` 37 | 38 | ## Accessing Unique Name Nodes 39 | 40 | The `%` syntax can be used with `gdscript.Syntax.percent`. 41 | 42 | For example: 43 | ```haxe 44 | var a: godot.Sprite2D = gdscript.Syntax.percent(MySprite); 45 | ``` 46 | 47 | Converts to: 48 | ```gdscript 49 | var a: Sprite2D = %MySprite; 50 | ``` 51 | 52 | ## Generating Variables Without Assignments 53 | 54 | Sometimes you may want to use `final` in Haxe since you don't want to reassign it, but the initial assignment doesn't happen within the Haxe code. For example, a variable that uses `@:export` or `@:const(preload = "...")`. 55 | 56 | Simply assign `gdscript.Syntax.NoAssign` to bypass the error in the Haxe compiler, but assign nothing in the generated GDScript. 57 | 58 | For example: 59 | ```haxe 60 | @:export final other_sprite: godot.Sprite2D = gdscript.Syntax.NoAssign; 61 | ``` 62 | 63 | Converts to: 64 | ```gdscript 65 | @export var other_sprite: Sprite2D; 66 | ``` 67 | -------------------------------------------------------------------------------- /documentation/pages/intro/adding_first_class.md: -------------------------------------------------------------------------------- 1 | # Adding First Class 2 | 3 | Let's go ahead and make a class in Haxe to compile into GDScript! 4 | 5 | ```haxe 6 | // MyClass.hx 7 | package; 8 | 9 | class MyClass { 10 | public function new(myNumber: Int) { 11 | trace('Received number: $myNumber'); 12 | } 13 | } 14 | ``` 15 | ```hxml 16 | # Compile.hxml 17 | -p src 18 | -lib gdscript 19 | -D gdscript-output=out 20 | ``` 21 | 22 | WAIT! There's no main function? Godot doesn't use a main, it just takes GDScript files created by the user. But because of Haxe's DCE, our `MyClass` class won't be compiled. 23 | 24 | ## Choosing What to Compile 25 | 26 | Since GDScript does not rely on a `main` function, you need to tell Haxe what files it needs to compile for your project. This can be done by listing modules in your `.hxml` file. 27 | 28 | ```haxe 29 | // MyClass.hx 30 | package; 31 | 32 | class MyClass { 33 | public function new(myNumber: Int) { 34 | trace('Received number: $myNumber'); 35 | } 36 | } 37 | ``` 38 | ```hxml 39 | # Compile.hxml 40 | -p src 41 | -lib gdscript 42 | -D gdscript-output=out 43 | 44 | MyClass 45 | ``` 46 | 47 | ### Just Compile Everything! 48 | 49 | This could get annoying when adding new files, so instead you can also place all of your "to-be-compiled" classes in a package and write that. 50 | ```haxe 51 | // game/MyClass.hx 52 | package game; 53 | 54 | class MyClass { 55 | public function new(myNumber: Int) { 56 | trace('Received number: $myNumber'); 57 | } 58 | } 59 | ``` 60 | ```hxml 61 | # Compile.hxml 62 | -p src 63 | -lib gdscript 64 | -D gdscript-output=out 65 | 66 | game # Every class in `game` will now be compiled 67 | ``` 68 | 69 | ### Output 70 | 71 | Aaaand now you should receive some output like this: 72 | ```gdscript 73 | class_name MyClass; 74 | 75 | func _init(myNumber: int): 76 | print("game/MyClass.hx:6: Received number: " + myNumber); 77 | ``` 78 | -------------------------------------------------------------------------------- /documentation/pages/intro/godot_api.md: -------------------------------------------------------------------------------- 1 | # Godot API 2 | 3 | Okay!! Now let's make a custom Node! ... oh wait, there's no `Node2D` or `Node3D` class to extend from? 4 | 5 | As the Godot API can change depending on the version, no specific API is packaged with Reflaxe/GDScript. Instead, you need to generate your own Haxe bindings for Godot. 6 | 7 | ## Generating the Bindings 8 | 9 | First, install the [Haxe Godot Bindings Generator](https://github.com/SomeRanDev/Haxe-GodotBindingsGenerator) library: 10 | ``` 11 | haxelib git godot-api-generator https://github.com/SomeRanDev/Haxe-GodotBindingsGenerator 12 | ``` 13 | 14 | Next, enter your Haxe source code folder: 15 | ``` 16 | cd src 17 | ``` 18 | 19 | Finally, run this command to generate: 20 | ``` 21 | haxelib run godot-api-generator 22 | ``` 23 | 24 | This will generate all the Godot bindings as `.hx` Haxe source code files in a local folder named "godot". The files are generated with the expectation they will be in a `godot` package, so this should be perfect. 25 | 26 | ### Godot Executable Configuration 27 | When you run the command, you will be asked for the path to your Godot engine executable, so be sure to find it first! If you do not want to enter it manually, you can assign it to the `GODOT_PATH` environment variable before running the command. 28 | 29 | ## Extending from a Node 30 | You can now extend from `Node` like this: 31 | ```haxe 32 | class MyNode extends godot.Node { 33 | public override function _ready() { 34 | trace("MyNode is ready!"); 35 | } 36 | } 37 | ``` 38 | 39 | ## Easy Access 40 | If you'd like easy access to all of the Godot API, just `import godot.*`. 41 | ```haxe 42 | import godot.*; 43 | 44 | class MyNode extends Node { 45 | public override function _ready() { 46 | trace("MyNode is ready!"); 47 | } 48 | } 49 | ``` 50 | -------------------------------------------------------------------------------- /documentation/pages/intro/setup.md: -------------------------------------------------------------------------------- 1 | # Setup 2 | 3 | To get started, install the `gdscript` Haxelib package and add it to a Haxe project. 4 | 5 | | # | What to do | What to write | 6 | | --- | ----------------------------------------------------- | ---------------------------------------- | 7 | | 1 | Install via haxelib |
haxelib install gdscript 1.0.0-beta
| 8 | | 2 | Add the lib to your `.hxml` file or compile command. |
-lib gdscript
| 9 | | 3 | Set the output folder for the compiled GDScript. |
-D gdscript-output=out
| 10 | | 4 | Optionally, generate your code as a Godot plugin. |
-D generate_godot_plugin
| 11 | -------------------------------------------------------------------------------- /extraParams.hxml: -------------------------------------------------------------------------------- 1 | -D gdscript 2 | -D retain-untyped-meta 3 | --macro gdcompiler.GDCompilerInit.Start() -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gdscript", 3 | "version": "1.0.0-beta", 4 | "description": "Compile Haxe to GDScript 2.0 as easily as you'd output to any other target.", 5 | "url": "https://github.com/RobertBorghese/Haxe-to-GDScript", 6 | "license": "MIT", 7 | "tags": [ 8 | "godot", 9 | "gdscript", 10 | "macro", 11 | "compiler", 12 | "target", 13 | "game", 14 | "engine", 15 | "externs", 16 | "metadata", 17 | "extension" 18 | ], 19 | "dependencies": { 20 | "reflaxe": "4.0.0-beta" 21 | }, 22 | "classPath": "src/", 23 | "releasenote": "Nightly version of Reflaxe/GDScript.", 24 | "contributors": ["SomeRanDev"], 25 | "reflaxe": { 26 | "name": "GDScript", 27 | "abbv": "gdscript", 28 | "stdPaths": ["std", "std/gdscript/_std"] 29 | } 30 | } -------------------------------------------------------------------------------- /img/Logo.aseprite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SomeRanDev/reflaxe.GDScript/26b3f18bff0e32de7a19c3e9b422b59a39c45b1b/img/Logo.aseprite -------------------------------------------------------------------------------- /img/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SomeRanDev/reflaxe.GDScript/26b3f18bff0e32de7a19c3e9b422b59a39c45b1b/img/Logo.png -------------------------------------------------------------------------------- /src/gdcompiler/GDCompilerInit.hx: -------------------------------------------------------------------------------- 1 | package gdcompiler; 2 | 3 | #if (macro || gdscript_runtime) 4 | 5 | import haxe.macro.Compiler; 6 | import haxe.macro.Expr; 7 | import haxe.macro.Type; 8 | import haxe.display.Display.MetadataTarget; 9 | 10 | import reflaxe.ReflectCompiler; 11 | import reflaxe.input.ExpressionModifier; 12 | import reflaxe.preprocessors.ExpressionPreprocessor; 13 | 14 | using reflaxe.helpers.ExprHelper; 15 | 16 | class GDCompilerInit { 17 | public static function Start() { 18 | if(isRunScript()) { 19 | return; 20 | } 21 | 22 | // Add our compiler to Reflaxe 23 | ReflectCompiler.AddCompiler(new GDCompiler(), { 24 | expressionPreprocessors: [ 25 | SanitizeEverythingIsExpression({ 26 | convertIncrementAndDecrementOperators: true 27 | }), 28 | RemoveTemporaryVariables(OnlyAvoidTemporaryFieldAccess), 29 | PreventRepeatVariables({}), 30 | WrapLambdaCaptureVariablesInArray({ 31 | wrapMetadata: [":copyType"] 32 | }), 33 | RemoveSingleExpressionBlocks, 34 | RemoveConstantBoolIfs, 35 | RemoveUnnecessaryBlocks, 36 | RemoveReassignedVariableDeclarations, 37 | RemoveLocalVariableAliases, 38 | MarkUnusedVariables, 39 | ], 40 | fileOutputExtension: ".gd", 41 | outputDirDefineName: "gdscript-output", 42 | fileOutputType: FilePerClass, 43 | ignoreTypes: [], 44 | reservedVarNames: reservedNames(), 45 | targetCodeInjectionName: "__gdscript__", 46 | allowMetaMetadata: true, 47 | autoNativeMetaFormat: "@{}", 48 | metadataTemplates: [ 49 | ReflectCompiler.MetaTemplate(":tool", "", true, [], [Class], (e, p) -> "@tool"), 50 | 51 | // ReflectCompiler.MetaTemplate(":onready", "", true, [], [ClassField], (e, p) -> "@onready"), 52 | ReflectCompiler.MetaTemplate(":export", "", true, [], [ClassField], (e, p) -> "@export"), 53 | 54 | ReflectCompiler.MetaTemplate(":exportEnum", "", true, null, [ClassField], (e, p) -> "@export_enum(" + p.join(", ") + ")"), 55 | ReflectCompiler.MetaTemplate(":exportFile", "", true, [Optional], [ClassField], (e, p) -> { 56 | "@export_file" + (p.length > 0 ? ("(" + p.join(", ") + ")") : ""); 57 | }), 58 | ReflectCompiler.MetaTemplate(":exportDir", "", true, [], [ClassField], (e, p) -> "@export_dir"), 59 | ReflectCompiler.MetaTemplate(":exportGlobalFile", "", true, [Optional], [ClassField], (e, p) -> { 60 | "@export_global_file" + (p.length > 0 ? ("(" + p.join(", ") + ")") : ""); 61 | }), 62 | ReflectCompiler.MetaTemplate(":exportToolButton", "", true, [String, String], [ClassField], (e, p) -> { 63 | "@export_tool_button" + (p.length > 0 ? ("(" + p.join(", ") + ")") : ""); 64 | }), 65 | 66 | 67 | ReflectCompiler.MetaTemplate(":exportGlobalDir", "", true, [], [ClassField], (e, p) -> "@export_global_dir"), 68 | ReflectCompiler.MetaTemplate(":exportMultiline", "", true, [], [ClassField], (e, p) -> "@export_multiline"), 69 | ReflectCompiler.MetaTemplate(":exportRange", "", true, [Number, Number, Optional, Optional, Optional], [ClassField], (e, p) -> "@export_range(" + p.join(", ") + ")"), 70 | 71 | ReflectCompiler.MetaTemplate(":exportExpEasing", "", true, [], [ClassField], (e, p) -> "@export_exp_easing"), 72 | ReflectCompiler.MetaTemplate(":exportColorNoAlpha", "", true, [], [ClassField], (e, p) -> "@export_color_no_alpha"), 73 | 74 | ReflectCompiler.MetaTemplate(":exportNodePath", "", true, null, [ClassField], (e, p) -> "@export_node_path(" + p.join(", ") + ")"), 75 | ReflectCompiler.MetaTemplate(":exportFlags", "", true, null, [ClassField], (e, p) -> "@export_flags(" + p.join(", ") + ")"), 76 | 77 | ReflectCompiler.MetaTemplate(":exportFlags2dPhysics", "", true, [], [ClassField], (e, p) -> "@export_flags_2d_physics"), 78 | ReflectCompiler.MetaTemplate(":exportFlags2dRender", "", true, [], [ClassField], (e, p) -> "@export_flags_2d_render"), 79 | ReflectCompiler.MetaTemplate(":exportFlags2dNavigation", "", true, [], [ClassField], (e, p) -> "@export_flags_2d_navigation"), 80 | ReflectCompiler.MetaTemplate(":exportFlags3dPhysics", "", true, [], [ClassField], (e, p) -> "@export_flags_3d_physics"), 81 | ReflectCompiler.MetaTemplate(":exportFlags3dRender", "", true, [], [ClassField], (e, p) -> "@export_flags_3d_render"), 82 | ReflectCompiler.MetaTemplate(":exportFlags3dNavigation", "", true, [], [ClassField], (e, p) -> "@export_flags_3d_navigation") 83 | ] 84 | }); 85 | } 86 | 87 | /** 88 | We don't want this running during our "Run.hx" script, so this checks if that is occuring. 89 | **/ 90 | static function isRunScript() { 91 | return ["reflaxe.gdscript", "gdscript"].contains((Sys.getEnv("HAXELIB_RUN_NAME") ?? "").toLowerCase()); 92 | } 93 | 94 | /** 95 | List of reserved words found here: 96 | https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html 97 | **/ 98 | static var _reservedNames = [ 99 | // keywords 100 | "if", "elif", "else", "for", "while", "match", "break", "continue", "pass", 101 | "return", "class", "class_name", "extends", "is", "in", "as", "self", "signal", 102 | "func", "static", "const", "enum", "var", "breakpoint", "preload", 103 | "await", "yield", "assert", "void", "PI", "TAU", "INF", "NAN", 104 | 105 | // types 106 | "void", "bool", "int", "float", 107 | 108 | // utility_functions 109 | "sin", "cos", "tan", "sinh", "cosh", "tanh", "asin", "acos", "atan", "atan2", 110 | "asinh", "acosh", "atanh", "sqrt", "fmod", "fposmod", "posmod", "floor", "floorf", 111 | "floori", "ceil", "ceilf", "ceili", "round", "roundf", "roundi", "abs", "absf", 112 | "absi", "sign", "signf", "signi", "snapped", "snappedf", "snappedi", "pow", "log", 113 | "exp", "is_nan", "is_inf", "is_equal_approx", "is_zero_approx", "is_finite", "ease", 114 | "step_decimals", "lerp", "lerpf", "cubic_interpolate", "cubic_interpolate_angle", 115 | "cubic_interpolate_in_time", "cubic_interpolate_angle_in_time", "bezier_interpolate", 116 | "bezier_derivative", "angle_difference", "lerp_angle", "inverse_lerp", "remap", "smoothstep", 117 | "move_toward", "rotate_toward", "deg_to_rad", "rad_to_deg", "linear_to_db", "db_to_linear", 118 | "wrap", "wrapi", "wrapf", "max", "maxi", "maxf", "min", "mini", "minf", "clamp", "clampi", 119 | "clampf", "nearest_po2", "pingpong", "randomize", "randi", "randf", "randi_range", "randf_range", 120 | "randfn", "seed", "rand_from_seed", "weakref", "typeof", "type_convert", "str", "error_string", 121 | "type_string", "print", "print_rich", "printerr", "printt", "prints", "printraw", "print_verbose", 122 | "push_error", "push_warning", "var_to_str", "str_to_var", "var_to_bytes", "bytes_to_var", 123 | "var_to_bytes_with_objects", "bytes_to_var_with_objects", "hash", "instance_from_id", "is_instance_id_valid", 124 | "is_instance_valid", "rid_allocate_id", "rid_from_int64", "is_same", 125 | 126 | // Object fields 127 | // These are on ALL objects, so better to just be safe than sorry... 128 | "_get", "_get_property_list", "_init", "_iter_get", "_iter_init", "_iter_next", "_notification", 129 | "_property_can_revert", "_property_get_revert", "_set", "_to_string", "_validate_property", 130 | "get_class", "is_class", "set", "get", "set_indexed", "get_indexed", "get_property_list", 131 | "get_method_list", "property_can_revert", "property_get_revert", "notification", "to_string", 132 | "get_instance_id", "set_script", "get_script", "set_meta", "remove_meta", "get_meta", "has_meta", 133 | "get_meta_list", "add_user_signal", "has_user_signal", "remove_user_signal", "emit_signal", "call", 134 | "call_deferred", "set_deferred", "callv", "has_method", "get_method_argument_count", "has_signal", 135 | "get_signal_list", "get_signal_connection_list", "get_incoming_connections", "connect", "disconnect", 136 | "is_connected", "has_connections", "set_block_signals", "is_blocking_signals", "notify_property_list_changed", 137 | "set_message_translation", "can_translate_messages", "tr", "tr_n", "get_translation_domain", "set_translation_domain", 138 | "is_queued_for_deletion", "cancel_free", 139 | 140 | // Reserved for @:wrapper argument 141 | "_self" 142 | ]; 143 | static function reservedNames() { 144 | return _reservedNames; 145 | } 146 | } 147 | 148 | #end 149 | -------------------------------------------------------------------------------- /src/gdcompiler/config/Define.hx: -------------------------------------------------------------------------------- 1 | package gdcompiler.config; 2 | 3 | enum abstract Define(String) from String to String { 4 | /** 5 | -D generate_godot_plugin 6 | 7 | If defined, a Godot plugin will be generated with the output. 8 | **/ 9 | var GenerateGodotPlugin = "generate_godot_plugin"; 10 | 11 | /** 12 | -D godot_plugin_name=NAME 13 | 14 | Defines the "name" entry in `plugin.cfg` if a plugin is generated. 15 | **/ 16 | var GodotPluginName = "godot_plugin_name"; 17 | 18 | /** 19 | -D godot_plugin_description=DESCRIPTION 20 | 21 | Defines the "description" entry in `plugin.cfg` if a plugin is generated. 22 | **/ 23 | var GodotPluginDescription = "godot_plugin_description"; 24 | 25 | /** 26 | -D godot_plugin_author=AUTHOR 27 | 28 | Defines the "author" entry in `plugin.cfg` if a plugin is generated. 29 | **/ 30 | var GodotPluginAuthor = "godot_plugin_author"; 31 | 32 | /** 33 | -D godot_plugin_version=VERSION 34 | 35 | Defines the "version" entry in `plugin.cfg` if a plugin is generated. 36 | **/ 37 | var GodotPluginVersion = "godot_plugin_version"; 38 | 39 | /** 40 | -D godot_plugin_script_name=FILE_NAME.gd 41 | 42 | Sets the name of the "script" file generated for the plugin. 43 | **/ 44 | var GodotPluginScriptName = "godot_plugin_script_name"; 45 | 46 | /** 47 | -D gdscript_output_dirs 48 | 49 | If defined, the GDScript is generated in folders based on the package. 50 | **/ 51 | var GDScriptOutputDirs = "gdscript_output_dirs"; 52 | 53 | /** 54 | -D gdscript_snake_case 55 | 56 | If defined, features will use snake-case instead of camel-case. 57 | **/ 58 | var GDScriptUseSnakeCase = "gdscript_snake_case"; 59 | 60 | /** 61 | -D gdscript_always_packages_in_output_filenames 62 | 63 | If defined, the file names will include the package path even if 64 | `-D gdscript_output_dirs` is defined. 65 | **/ 66 | var GDScriptAlwaysUsePackagesInOutputFilenames = "gdscript_always_packages_in_output_filenames"; 67 | } 68 | -------------------------------------------------------------------------------- /src/gdcompiler/config/Meta.hx: -------------------------------------------------------------------------------- 1 | package gdcompiler.config; 2 | 3 | enum abstract Meta(String) from String to String { 4 | /** 5 | @:await 6 | 7 | `await`s an expression. 8 | 9 | --- 10 | 11 | The conversion is extremely simple; it converts `@:await` into await. 12 | ```haxe 13 | // This 14 | final waited_for_value = @:await auth.login(password); 15 | ``` 16 | ```gdscript 17 | # Becomes this 18 | var waited_for_value = await auth.login(password); 19 | ``` 20 | **/ 21 | var Await = ":await"; 22 | 23 | /** 24 | @:onready 25 | 26 | Marks a variable as `@onready`. 27 | 28 | --- 29 | 30 | To assign this a specific GDScript expression, use `val = "something"`: 31 | ```haxe 32 | // This 33 | @:onready(val = "my.custom.expression()") var my_field: String; 34 | ``` 35 | ```gdscript 36 | # Becomes this 37 | @onready var my_field: String = my.custom.expression(); 38 | ``` 39 | 40 | To assign to a child node path, use `node = "path"`: 41 | ```haxe 42 | // This 43 | @:onready(node = "Container/Label") var my_label: godot.Label; 44 | ``` 45 | ```gdscript 46 | # Becomes this 47 | @onready var my_label: Label = $Container/Label; 48 | ``` 49 | **/ 50 | var OnReady = ":onready"; 51 | 52 | /** 53 | @:const 54 | 55 | Creates a `const` variable. 56 | **/ 57 | var Const = ":const"; 58 | 59 | /** 60 | @:signal 61 | 62 | Treats the class function as a signal declaration. 63 | **/ 64 | var Signal = ":signal"; 65 | 66 | /** 67 | @:icon(path: String) 68 | 69 | Use on a class with `godot.Node` or `godot.Resource` in its class hierarchy. 70 | This defines a custom path for the type's icon. 71 | **/ 72 | var Icon = ":icon"; 73 | 74 | /** 75 | @:get(functionIdentifier: Expr) 76 | 77 | Adds a `get` implementation to the variable. 78 | 79 | The argument must be the identifier to a function with no arguments and 80 | returns the same type as the variable. 81 | **/ 82 | var Get = ":get"; 83 | 84 | /** 85 | @:set(functionIdentifier: Expr) 86 | 87 | Adds a `set` implementation to the variable. 88 | 89 | The argument must be the identifier to a function with no return and 90 | one argument the same type as the variable. 91 | **/ 92 | var Set = ":set"; 93 | 94 | /** 95 | @:outputFile(path: String) 96 | 97 | Explicitly sets the output file path for a class. 98 | **/ 99 | var OutputFile = ":outputFile"; 100 | 101 | /** 102 | @:dontAddToPlugin 103 | 104 | If added to a class, the class will not be loaded by the generated plugin. 105 | **/ 106 | var DontAddToPlugin = ":dontAddToPlugin"; 107 | 108 | /** 109 | @:dont_compile 110 | 111 | If used on a type declaration, that type is never compiled to GDScript. 112 | 113 | ```haxe 114 | final a: gdscript.Untyped = 123; 115 | ``` 116 | 117 | ```gdscript 118 | # Normally this would be: 119 | # var a: int = 123; 120 | 121 | var a = 123; 122 | ``` 123 | **/ 124 | var DontCompile = ":dont_compile"; 125 | 126 | /** 127 | @:uncompilable 128 | 129 | If Reflaxe/GDScript attempts to compile a field with this metadata, 130 | it will throw an error. 131 | 132 | Used to ensure fields intended to be replaced at compile-time aren't compiled. 133 | **/ 134 | var Uncompilable = ":uncompilable"; 135 | 136 | /** 137 | @:wrapper(selfName: String = "_self") 138 | 139 | If added to a class, that class will be treated as a wrapper class. This means 140 | instead of using `self`, all instance functions will be provided a `self` replacement 141 | argument to use as `self`. 142 | 143 | Class variables will still be implemented entirely in GDScript. 144 | **/ 145 | var Wrapper = ":wrapper"; 146 | 147 | /** 148 | @:wrapPublicOnly 149 | 150 | If added to a class with `@:wrapper`, this will make it so only public function are 151 | "wrapped". Private functions will be generated and called entirely within 152 | GDScript. 153 | **/ 154 | var WrapPublicOnly = ":wrapPublicOnly"; 155 | 156 | /** 157 | @:bypass_wrapper 158 | 159 | If used on a field, the effects of `@:wrapper` will be ignored when accessing it. 160 | **/ 161 | var BypassWrapper = ":bypass_wrapper"; 162 | 163 | /** 164 | @:nativeName(name: String) 165 | 166 | Use instead of `@:native`. 167 | **/ 168 | var NativeName = ":nativeName"; 169 | 170 | /** 171 | @:keepName 172 | 173 | Keeps the name of the field no matter what. 174 | **/ 175 | var KeepName = ":keepName"; 176 | } 177 | -------------------------------------------------------------------------------- /src/gdcompiler/subcompilers/EnumCompiler.hx: -------------------------------------------------------------------------------- 1 | package gdcompiler.subcompilers; 2 | 3 | import haxe.macro.Type; 4 | 5 | import reflaxe.data.EnumOptionData; 6 | 7 | using reflaxe.helpers.ArrayHelper; 8 | using reflaxe.helpers.BaseTypeHelper; 9 | using reflaxe.helpers.ClassFieldHelper; 10 | using reflaxe.helpers.ClassTypeHelper; 11 | using reflaxe.helpers.ExprHelper; 12 | using reflaxe.helpers.ModuleTypeHelper; 13 | using reflaxe.helpers.NameMetaHelper; 14 | using reflaxe.helpers.NullableMetaAccessHelper; 15 | using reflaxe.helpers.NullHelper; 16 | using reflaxe.helpers.OperatorHelper; 17 | using reflaxe.helpers.StringBufHelper; 18 | using reflaxe.helpers.SyntaxHelper; 19 | using reflaxe.helpers.TypedExprHelper; 20 | using reflaxe.helpers.TypeHelper; 21 | 22 | // --- 23 | 24 | enum EnumCompileKind { 25 | GDScriptEnum; 26 | AsInt; 27 | AsDictionary; 28 | } 29 | 30 | // --- 31 | 32 | @:access(gdcompiler.GDCompiler) 33 | class EnumCompiler { 34 | var main: GDCompiler; 35 | 36 | public function new(main: GDCompiler) { 37 | this.main = main; 38 | } 39 | 40 | public function compile(enumType: EnumType, options:Array, path) { 41 | if(getCompileKind(enumType) != GDScriptEnum) { 42 | return; 43 | } 44 | 45 | final name = main.typeCompiler.compileEnumName(enumType); 46 | 47 | final content = new StringBuf(); 48 | content.addMulti("class_name ", name, " extends Object\n\n"); 49 | content.addMulti("enum ", name, " {\n"); 50 | for(option in options) { 51 | content.addMulti("\t", option.name, ",\n"); 52 | } 53 | content.add("}\n"); 54 | 55 | main.setExtraFile(path, content.toString()); 56 | } 57 | 58 | public function getCompileKind(enumType: EnumType): EnumCompileKind { 59 | var storesData = false; 60 | 61 | for(_ => value in enumType.constructs) { 62 | final args = switch(value.type) { 63 | case TFun(args, ret): args; 64 | case _: []; 65 | } 66 | 67 | if(args.length > 0) { 68 | storesData = true; 69 | break; 70 | } 71 | } 72 | 73 | return storesData ? AsDictionary : GDScriptEnum; 74 | } 75 | 76 | public function compileExpressionFromIndex(enumType: EnumType, enumField: EnumField, exprArgsPassed: Null>) { 77 | if(enumType.isReflaxeExtern()) { 78 | return enumType.getNameOrNative() + "." + enumField.name; 79 | } 80 | 81 | final providedArgs = exprArgsPassed != null && exprArgsPassed.length > 0; 82 | final kind = if(providedArgs) { 83 | AsDictionary; 84 | } else { 85 | getCompileKind(enumType); 86 | } 87 | 88 | return switch(kind) { 89 | case GDScriptEnum: { 90 | final name = main.typeCompiler.compileEnumName(enumType); 91 | name + "." + name + "." + enumField.name; 92 | } 93 | case AsInt: { 94 | Std.string(enumField.index); 95 | } 96 | case AsDictionary if(exprArgsPassed != null && providedArgs): { // Redundant null-check for null-safety 97 | final result = new StringBuf(); 98 | final enumFieldArgs = switch(enumField.type) { 99 | case TFun(args, _): args; 100 | case _: []; 101 | } 102 | 103 | result.addMulti("{ \"_index\": ", Std.string(enumField.index), ", "); 104 | for(i in 0...exprArgsPassed.length) { 105 | if(enumFieldArgs[i] == null) { 106 | continue; 107 | } 108 | result.addMulti("\"", enumFieldArgs[i].name, "\": ", main.compileExpressionOrError(exprArgsPassed[i])); 109 | if(i < exprArgsPassed.length - 1) { 110 | result.add(", "); 111 | } 112 | } 113 | result.add(" }"); 114 | result.toString(); 115 | } 116 | case AsDictionary: { 117 | "{ \"_index\": " + enumField.index + " }"; 118 | } 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /src/gdcompiler/subcompilers/TypeCompiler.hx: -------------------------------------------------------------------------------- 1 | package gdcompiler.subcompilers; 2 | 3 | import gdcompiler.config.Meta; 4 | import gdcompiler.subcompilers.EnumCompiler; 5 | import gdcompiler.GDCompiler; 6 | 7 | import reflaxe.helpers.Context; 8 | import haxe.macro.Expr; 9 | import haxe.macro.Type; 10 | import haxe.macro.TypeTools; 11 | 12 | using reflaxe.helpers.ArrayHelper; 13 | using reflaxe.helpers.BaseTypeHelper; 14 | using reflaxe.helpers.ModuleTypeHelper; 15 | using reflaxe.helpers.NameMetaHelper; 16 | using reflaxe.helpers.NullableMetaAccessHelper; 17 | using reflaxe.helpers.TypeHelper; 18 | 19 | @:access(gdcompiler.GDCompiler) 20 | class TypeCompiler { 21 | var main: GDCompiler; 22 | 23 | public function new(main: GDCompiler) { 24 | this.main = main; 25 | } 26 | 27 | function isGodotClass(classType: ClassType): Bool { 28 | return switch(classType.meta.extractExpressionsFromFirstMeta(":bindings_api_type")) { 29 | case [macro "class"]: true; 30 | case _ if(classType.superClass != null): isGodotClass(classType.superClass.t.get()); 31 | case _: false; 32 | } 33 | } 34 | 35 | public function compileClassName(classType: ClassType): String { 36 | // Classes in `haxe` package have simple names that might conflict, so let's use pack_Name. 37 | if(classType.pack.length >= 1 && classType.pack[0] == "haxe") { 38 | return classType.pack.join("_") + "_" + classType.getNameOrNativeName(); 39 | } 40 | return classType.getNameOrNativeName(); 41 | } 42 | 43 | public function compileEnumName(enumType: EnumType): String { 44 | return enumType.getNameOrNativeName(); 45 | } 46 | 47 | function compileModuleType(m: ModuleType, isExport: Bool): String { 48 | return switch(m) { 49 | case TClassDecl(clsRef): { 50 | compileClassName(clsRef.get()); 51 | } 52 | case TEnumDecl(enmRef): { 53 | compileEnum(enmRef, isExport); 54 | } 55 | case _: m.getNameOrNative(); 56 | } 57 | } 58 | 59 | function compileEnum(enmRef: Ref, isExport: Bool) { 60 | final e = enmRef.get(); 61 | return if(e.isReflaxeExtern()) { 62 | e.pack.joinAppend(".") + e.getNameOrNativeName(); 63 | } else { 64 | final kind = main.enumCompiler.getCompileKind(e); 65 | switch(kind) { 66 | case GDScriptEnum: { 67 | final name = compileEnumName(e); 68 | name + "." + name; 69 | } 70 | case AsInt: { 71 | "int"; 72 | } 73 | case AsDictionary: { 74 | if(!isExport) { 75 | "Variant"; 76 | } else { 77 | "Dictionary"; 78 | } 79 | } 80 | } 81 | } 82 | } 83 | 84 | public function compileType(t: Type, errorPos: Position, isExport: Bool = false): Null { 85 | // Check for @:dont_compile 86 | if(t.getMeta().maybeHas(Meta.DontCompile)) { 87 | return null; 88 | } 89 | 90 | // Process and return content from @:nativeTypeCode 91 | if(t.getMeta().maybeHas(":nativeTypeCode")) { 92 | final params = t.getParams(); 93 | final paramCallbacks = if(params != null && params.length > 0) { 94 | params.map(paramType -> (() -> compileType(paramType, errorPos, isExport) ?? "Variant")); 95 | } else { 96 | []; 97 | } 98 | final code = main.compileNativeTypeCodeMeta(t, paramCallbacks); 99 | if(code != null) { 100 | return code; 101 | } 102 | } 103 | 104 | if(t.isNull()) { 105 | // Primitives, Arrays, Dictionaries, and copy-types (Vector2, etc.) cannot be assigned `null`. 106 | // The only way to handle these is to remain "untyped" at the moment. 107 | // 108 | // Object types are generated with `@:bindings_api_type("class")`, so those are safe to 109 | // type and assign `null`. 110 | final unwrappedType = Context.followWithAbstracts(t.unwrapNullTypeOrSelf(), true); 111 | switch(unwrappedType) { 112 | case TInst(clsRef, _): { 113 | if(isGodotClass(clsRef.get())) { 114 | return compileType(unwrappedType, errorPos, isExport); 115 | } 116 | } 117 | case _: 118 | } 119 | 120 | return null; 121 | } 122 | // Ignore Null and just compile as T 123 | // if(t.isNull()) { 124 | // switch(Context.follow(t.unwrapNullTypeOrSelf())) { 125 | // case TEnum(_, _) | TAnonymous(_) if(!isExport): return "Variant"; 126 | // case _: 127 | // } 128 | // return compileType(t.unwrapNullTypeOrSelf(), errorPos, isExport); 129 | // } 130 | 131 | switch(t) { 132 | case TAbstract(_, _) if(t.isMultitype()): { 133 | return compileType(Context.followWithAbstracts(t, true), errorPos, isExport); 134 | } 135 | case TAbstract(absRef, params): { 136 | final abs = absRef.get(); 137 | 138 | final primitiveResult = if(params.length == 0) { 139 | switch(abs.name) { 140 | case "Void": "void"; 141 | case "Int": "int"; 142 | case "Float":"float"; 143 | case "Single": "float"; 144 | case "Bool": "bool"; 145 | case "Any" | "Dynamic": null; 146 | case _: null; 147 | } 148 | } else { 149 | null; 150 | } 151 | 152 | if(primitiveResult != null) { 153 | return primitiveResult; 154 | } 155 | 156 | // Compile internal type for Abstract 157 | final absType = abs.type; 158 | 159 | // Apply type parameters to figure out internal type. 160 | final internalType = #if macro { 161 | TypeTools.applyTypeParameters(absType, abs.params, params); 162 | } #else absType #end; 163 | 164 | // If Null, must be Variant since built-in types cannot be assigned `null`. 165 | if(internalType.isNull()) { 166 | return null; 167 | } 168 | 169 | // Prevent recursion... 170 | if(!internalType.equals(t)) { 171 | return compileType(internalType, errorPos, isExport); 172 | } 173 | } 174 | 175 | case TDynamic(_): return null; 176 | case TAnonymous(_): return "Variant"; 177 | case TFun(_, _): return null; 178 | case _ if(t.isTypeParameter()): return null; 179 | 180 | case TInst(_.get() => cls, _) if(cls.isInterface): { 181 | // Interfaces don't exist, just use a Variant 182 | return "Variant"; 183 | } 184 | case TInst(clsRef, _): { 185 | return compileModuleType(TClassDecl(clsRef), isExport); 186 | } 187 | case TEnum(enmRef, _): return compileEnum(enmRef, isExport); 188 | case TType(defRef, _): return compileType(defRef.get().type, errorPos, isExport); 189 | 190 | case TMono(typeRef): { 191 | final t = typeRef.get(); 192 | return if(t != null) compileType(t, errorPos, isExport); 193 | else null; // It's okay to return `null` here. 194 | } 195 | 196 | case _: 197 | } 198 | 199 | // Old behavior 200 | // TODO: Phase this out... 201 | final ct = haxe.macro.TypeTools.toComplexType(t); 202 | final typeName = switch(ct) { 203 | case TPath(typePath): { 204 | // copy TypePath and ignore "params" since GDScript is typeless 205 | haxe.macro.ComplexTypeTools.toString(TPath({ 206 | name: typePath.name, 207 | pack: typePath.pack, 208 | sub: typePath.sub, 209 | params: null 210 | })); 211 | } 212 | case _: null; 213 | } 214 | if(typeName == null) { 215 | return Context.error("Incomplete Feature: Cannot convert this type to GDScript at the moment. " + Std.string(t), errorPos); 216 | } 217 | return typeName; 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /std/GDScript.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | /** 4 | Builtin GDScript constants, functions, and annotations. 5 | https://docs.godotengine.org/en/stable/classes/class_%40gdscript.html 6 | 7 | These are not covered in `extension_api.json`. 8 | 9 | However, some functions will require Godot externs to be available and 10 | under the "godot" package. 11 | 12 | TODO: Complete this!! 13 | **/ 14 | extern class GDScript { 15 | @:native("load") 16 | public static function load(path: String): #if has_godot_externs godot.Resource #else Dynamic #end; 17 | 18 | @:native("preload") 19 | public static function preload(path: String): #if has_godot_externs godot.Resource #else Dynamic #end; 20 | 21 | @:native("type_exists") 22 | public static function typeExists(type: #if has_godot_externs godot.StringName #else String #end): Bool; 23 | 24 | @:native("assert") 25 | public static overload function assert(check: Bool): Void; 26 | 27 | @:native("assert") 28 | public static overload function assert(check: Bool, msg: String): Void; 29 | } 30 | -------------------------------------------------------------------------------- /std/gdscript/ArrayEx.hx: -------------------------------------------------------------------------------- 1 | package gdscript; 2 | 3 | /** 4 | Allows Haxe's `Array`s to use functions from Godot's `Array` type. 5 | 6 | Last updated for Godot 4.4. 7 | **/ 8 | class ArrayEx { 9 | public static extern inline function size(self: Array): Int return untyped __gdscript__("{0}.size()", self); 10 | public static extern inline function is_empty(self: Array): Bool return untyped __gdscript__("{0}.is_empty()", self); 11 | public static extern inline function clear(self: Array): Void untyped __gdscript__("{0}.clear()", self); 12 | public static extern inline function hash(self: Array): Int return untyped __gdscript__("{0}.hash()", self); 13 | public static extern inline function assign(self: Array, array: Array): Void untyped __gdscript__("{0}.assign({1})", self, array); 14 | public static extern inline function get(self: Array, index: Int): T return untyped __gdscript__("{0}.get({1})", self, index); 15 | public static extern inline function set(self: Array, index: Int, value: T) untyped __gdscript__("{0}.set({1}, {2})", self, index, value); 16 | public static extern inline function push_back(self: Array, value: T): Void untyped __gdscript__("{0}.push_back({1})", self, value); 17 | public static extern inline function push_front(self: Array, value: T): Void untyped __gdscript__("{0}.push_front({1})", self, value); 18 | public static extern inline function append(self: Array, value: T): Void untyped __gdscript__("{0}.append({1})", self, value); 19 | public static extern inline function append_array(self: Array, array: Array): Void untyped __gdscript__("{0}.append_array({1})", self, array); 20 | public static extern inline function resize(self: Array, size: Int): Int return untyped __gdscript__("{0}.resize({1})", self, size); 21 | public static extern inline function insert(self: Array, position:Int, value: T): Int return untyped __gdscript__("{0}.insert({1}, {2})", self, position, value); 22 | public static extern inline function remove_at(self: Array, position: Int): Void untyped __gdscript__("{0}.remove_at({1})", self, position); 23 | public static extern inline function fill(self: Array, value: T): Void untyped __gdscript__("{0}.fill({1})", self, value); 24 | public static extern inline function erase(self: Array, value: T): Void untyped __gdscript__("{0}.erase({1})", self, value); 25 | public static extern inline function front(self: Array): T return untyped __gdscript__("{0}.front()", self); 26 | public static extern inline function back(self: Array): T return untyped __gdscript__("{0}.back()", self); 27 | public static extern inline function pick_random(self: Array): T return untyped __gdscript__("{0}.pick_random()", self); 28 | public static extern inline function find(self: Array, what: T, from: Int = 0): Int return untyped __gdscript__("{0}.find({1}, {2})", self, what, from); 29 | public static extern inline function find_custom(self: Array, method: (T) -> Bool, from: Int = 0): Int return untyped __gdscript__("{0}.find_custom({1}, {2})", self, method, from); 30 | public static extern inline function rfind(self: Array, what: Dynamic, from: Int = -1): Int return untyped __gdscript__("{0}.rfind({1}, {2})", self, what, from); 31 | public static extern inline function rfind_custom(self: Array, method: (T) -> Bool, from: Int = -1): Int return untyped __gdscript__("{0}.rfind_custom({1}, {2})", self, method, from); 32 | public static extern inline function count(self: Array, value: T): Int return untyped __gdscript__("{0}.count({1})", self, value); 33 | public static extern inline function has(self: Array, value: T): Bool return untyped __gdscript__("{0}.has({1})", self, value); 34 | public static extern inline function pop_back(self: Array): T return untyped __gdscript__("{0}.pop_back()", self); 35 | public static extern inline function pop_front(self: Array): T return untyped __gdscript__("{0}.pop_front()", self); 36 | public static extern inline function pop_at(self: Array, position: Int): T return untyped __gdscript__("{0}.pop_at({1})", self, position); 37 | public static extern inline function sort(self: Array): Void untyped __gdscript__("{0}.sort()", self); 38 | public static extern inline function sort_custom(self: Array, func: (T, T) -> Bool) untyped __gdscript__("{0}.sort_custom({1})", self, func); 39 | public static extern inline function shuffle(self: Array): Void untyped __gdscript__("{0}.shuffle()", self); 40 | public static extern inline function bsearch(self: Array, value: Dynamic, before: Bool = true): Int return untyped __gdscript__("{0}.bsearch({1}, {2})", self, value, before); 41 | public static extern inline function bsearch_custom(self: Array, func: (T) -> Bool, before: Bool = true): Int return untyped __gdscript__("{0}.bsearch_custom({1}, {2})", self, func, before); 42 | public static extern inline function reverse(self: Array): Void untyped __gdscript__("{0}.reverse()", self); 43 | public static extern inline function duplicate(self: Array, deep: Bool = false): Array return untyped __gdscript__("{0}.duplicate({1})", self, deep); 44 | public static extern inline function slice(self: Array, begin: Int, end: Int = 2147483647, step: Int = 1, deep: Bool = false): Array return untyped __gdscript__("{0}.duplicate({1}, {2}, {3}, {4})", self, begin, end, step, deep); 45 | public static extern inline function filter(self: Array, method: (T) -> Bool): Array return untyped __gdscript__("{0}.filter({1})", self, method); 46 | public static extern inline function map(self: Array, method: (T) -> U): Array return untyped __gdscript__("{0}.map({1})", self, method); 47 | public static extern inline function reduce(self: Array, method: (T) -> T, ?accum:T): T return untyped __gdscript__("{0}.reduce({1}, {2})", self, method, accum); 48 | public static extern inline function any(self: Array, method: (T) -> Bool): Bool return untyped __gdscript__("{0}.any({1})", self, method); 49 | public static extern inline function all(self: Array, method: (T) -> Bool): Bool return untyped __gdscript__("{0}.all({1})", self, method); 50 | public static extern inline function max(self: Array): T return untyped __gdscript__("{0}.max()", self); 51 | public static extern inline function min(self: Array): T return untyped __gdscript__("{0}.min()", self); 52 | public static extern inline function is_typed(self: Array): Bool return untyped __gdscript__("{0}.is_typed()", self); 53 | public static extern inline function is_same_typed(self: Array, array: Array): Bool return untyped __gdscript__("{0}.is_same_typed({1})", self, array); 54 | public static extern inline function get_typed_builtin(self: Array): Int return untyped __gdscript__("{0}.get_typed_builtin()", self); 55 | public static extern inline function get_typed_class_name(self: Array): StringName return untyped __gdscript__("{0}.get_typed_class_name()", self); 56 | public static extern inline function get_typed_script(self: Array): Dynamic return untyped __gdscript__("{0}.get_typed_script()", self); 57 | public static extern inline function make_read_only(self: Array): Void untyped __gdscript__("{0}.make_read_only()", self); 58 | public static extern inline function is_read_only(self: Array): Bool return untyped __gdscript__("{0}.is_read_only()", self); 59 | } 60 | -------------------------------------------------------------------------------- /std/gdscript/Dictionary.hx: -------------------------------------------------------------------------------- 1 | package gdscript; 2 | 3 | /** 4 | Godot's typed Dictionary type. 5 | 6 | For using `Dictionary` without type arguments, use `gdscript.UntypedDictionary`. 7 | 8 | Last updated for Godot 4.4. 9 | **/ 10 | @:forward 11 | @:forward.new 12 | @:forwardStatics 13 | @:copyType 14 | @:nativeTypeCode("Dictionary[{type0}, {type1}]") 15 | @:bindings_api_type("builtin_classes") 16 | extern abstract Dictionary(Dictionary_Fields) { 17 | @:arrayAccess public inline function arrayAccessGet(key: String): Dynamic { return untyped __gdscript__("({0}[{1}])", this, key); } 18 | @:arrayAccess public inline function arrayAccessSet(key: String, value: Dynamic): Dynamic { 19 | untyped __gdscript__("({0}[{1}] = {2})", this, key, value); 20 | return value; 21 | } 22 | 23 | @:op(!A) public static inline function not (self: Dictionary): Bool return untyped __gdscript__("(!{0})", self); 24 | @:op(A == B) public static inline function eq (self: Dictionary, other: Dynamic): Bool return untyped __gdscript__("(({0}) == ({1}))", self, other); 25 | @:op(A != B) public static inline function notEq (self: Dictionary, other: Dynamic): Bool return untyped __gdscript__("(({0}) != ({1}))", self, other); 26 | @:op(A == B) public static inline function eq2 (self: Dictionary, other: Dictionary): Bool return untyped __gdscript__("(({0}) == ({1}))", self, other); 27 | @:op(A != B) public static inline function notEq2(self: Dictionary, other: Dictionary): Bool return untyped __gdscript__("(({0}) != ({1}))", self, other); 28 | @:op(A in B) public static inline function inOp (self: Dictionary, other: Dictionary): Bool return untyped __gdscript__("(({0}) in ({1}))", self, other); 29 | @:op(A in B) public static inline function inOp2 (self: Dictionary, other: Array): Bool return untyped __gdscript__("(({0}) in ({1}))", self, other); 30 | } 31 | 32 | @:noCompletion 33 | @:native("Dictionary") 34 | @:copyType 35 | @:avoid_temporaries 36 | @:nativeTypeCode("Dictionary[{type0}, {type1}]") 37 | @:bindings_api_type("builtin_classes") 38 | extern class Dictionary_Fields { 39 | @:overload(function(from: Dictionary): Void { }) 40 | @:overload(function(base: Dictionary, key_type: Int, key_class_name: StringName, key_script: Dynamic, value_type: Int, value_class_name: StringName, value_script: Dynamic): Void { }) 41 | @:nativeFunctionCode("{}") public function new(); 42 | public function size(): Int; 43 | public function is_empty(): Bool; 44 | public function clear(): Void; 45 | public function assign(dictionary: Dictionary): Void; 46 | public function sort(): Void; 47 | public function merge(dictionary: Dictionary, overwrite: Bool = false): Void; 48 | public function merged(dictionary: Dictionary, overwrite: Bool = false): Dictionary; 49 | public function has(key: Dynamic): Bool; 50 | public function has_all(keys: Array): Bool; 51 | public function find_key(value: Dynamic): Dynamic; 52 | public function erase(key: Dynamic): Bool; 53 | public function hash(): Int; 54 | public function keys(): Array; 55 | public function values(): Array; 56 | public function duplicate(deep: Bool = false): Dictionary; 57 | @:nativeName("get") public function get(key: Dynamic, ?default_value: Dynamic): Dynamic; 58 | public function get_or_add(key: Dynamic, ?default_value: Dynamic): Dynamic; 59 | @:nativeName("set") public function set(key: Dynamic, value: Dynamic): Bool; 60 | public function is_typed(): Bool; 61 | public function is_typed_key(): Bool; 62 | public function is_typed_value(): Bool; 63 | public function is_same_typed(dictionary: Dictionary): Bool; 64 | public function is_same_typed_key(dictionary: Dictionary): Bool; 65 | public function is_same_typed_value(dictionary: Dictionary): Bool; 66 | public function get_typed_key_builtin(): Int; 67 | public function get_typed_value_builtin(): Int; 68 | public function get_typed_key_class_name(): StringName; 69 | public function get_typed_value_class_name(): StringName; 70 | public function get_typed_key_script(): Dynamic; 71 | public function get_typed_value_script(): Dynamic; 72 | public function make_read_only(): Void; 73 | public function is_read_only(): Bool; 74 | public function recursive_equal(dictionary: Dictionary, recursion_count: Int): Bool; 75 | } -------------------------------------------------------------------------------- /std/gdscript/ObjectEx.hx: -------------------------------------------------------------------------------- 1 | package gdscript; 2 | 3 | import haxe.macro.Context; 4 | import haxe.macro.Expr; 5 | 6 | class ObjectEx { 7 | @:native("emit_signal") 8 | public static macro function emit_signal(args: Array): Expr { 9 | final injectArgs = []; 10 | for(i in 0...args.length) { 11 | injectArgs.push('{$i}'); 12 | } 13 | final injectString = 'emit_signal(${injectArgs.join(", ")})'; 14 | return { 15 | expr: ECall(macro untyped __gdscript__, [macro $v{injectString}].concat(args)), 16 | pos: Context.currentPos() 17 | }; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /std/gdscript/StringEx.hx: -------------------------------------------------------------------------------- 1 | package gdscript; 2 | 3 | /** 4 | Allows Haxe's `String`s to use functions from Godot's `String` type. 5 | 6 | Last updated for Godot 4.4. 7 | **/ 8 | class StringEx { 9 | public static extern inline function replace(self: String, what: String, forwhat: String): String return untyped __gdscript__("{0}.replace({1}, {2})", self, what, forwhat); 10 | 11 | // Requires the Godot API bindings to be generated... 12 | #if godot_api 13 | public static extern inline function join(self: String, parts: godot.PackedStringArray): String return untyped __gdscript__("{0}.join({1})", self, parts); 14 | #end 15 | } 16 | -------------------------------------------------------------------------------- /std/gdscript/StringName.hx: -------------------------------------------------------------------------------- 1 | package gdscript; 2 | 3 | /** 4 | TODO: Implement StringName properly 5 | **/ 6 | typedef StringName = String; 7 | -------------------------------------------------------------------------------- /std/gdscript/Syntax.hx: -------------------------------------------------------------------------------- 1 | package gdscript; 2 | 3 | import haxe.macro.Context; 4 | import haxe.macro.Expr; 5 | 6 | class Syntax { 7 | /** 8 | Assign this to a variable declaration to have the 9 | variable be generated without a value. 10 | 11 | This is helpful in rare circumstances. 12 | 13 | For example: 14 | ```haxe 15 | @:const(preload = "res://texture.png") 16 | static final TEXTURE: godot.CompressedTexture2D = gdscript.Syntax.NoAssign; 17 | ``` 18 | 19 | Converts to: 20 | ```gdscript 21 | const TEXTURE: CompressedTexture2D = preload("res://texture.png"); 22 | ``` 23 | **/ 24 | @:uncompilable 25 | public static var NoAssign: Dynamic; 26 | 27 | /** 28 | Generates an `is` expression in GDScript. 29 | 30 | For example: 31 | ```haxe 32 | if(gdscript.Syntax.is(sprite, Sprite2D)) { 33 | cast(sprite, Sprite2D).centered = true; 34 | } 35 | ``` 36 | 37 | Converts to: 38 | ```gdscript 39 | if sprite is Sprite2D: 40 | (sprite as Sprite2D).centered = true; 41 | ``` 42 | **/ 43 | @:nativeFunctionCode("({arg0} is {arg1})") 44 | public static extern function is(any: T, class_type: Class): Bool; 45 | 46 | /** 47 | Generates a % node reference. 48 | 49 | For example: 50 | ```haxe 51 | var a: godot.Sprite2D = gdscript.Syntax.percent(MySprite); 52 | ``` 53 | 54 | Converts to: 55 | ```gdscript 56 | var a: Sprite2D = %MySprite; 57 | ``` 58 | **/ 59 | public static macro function percent(identifier: Expr): Expr { 60 | final identifier = switch(identifier.expr) { 61 | case EConst(CString(s, _) | CIdent(s)): s; 62 | case _: { 63 | Context.error("Expected String or identifier expression", identifier.pos); 64 | return macro {}; 65 | } 66 | } 67 | 68 | final identifier = "%" + identifier; 69 | return macro untyped __gdscript__($v{identifier}); 70 | } 71 | 72 | /** 73 | Generates a $ node reference. 74 | 75 | For example: 76 | ```haxe 77 | var a: godot.Label = gdscript.Syntax.dollar(MyLabel); 78 | var b: godot.Label = gdscript.Syntax.dollar("Path/To/OtherLabel"); // must use String for slashes 79 | ``` 80 | 81 | Converts to: 82 | ```gdscript 83 | var a: Label = $MyLabel; 84 | var b: Label = $Path/To/OtherLabel; 85 | ``` 86 | **/ 87 | public static macro function dollar(identifier: Expr): Expr { 88 | final identifier = switch(identifier.expr) { 89 | case EConst(CString(s, _) | CIdent(s)): s; 90 | case _: { 91 | Context.error("Expected String or identifier expression", identifier.pos); 92 | return macro {}; 93 | } 94 | } 95 | 96 | final identifier = "$" + identifier; 97 | return macro untyped __gdscript__($v{identifier}); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /std/gdscript/Untyped.hx: -------------------------------------------------------------------------------- 1 | package gdscript; 2 | 3 | @:dont_compile 4 | typedef Untyped = Dynamic; 5 | -------------------------------------------------------------------------------- /std/gdscript/UntypedArray.hx: -------------------------------------------------------------------------------- 1 | package gdscript; 2 | 3 | @:nativeTypeCode("Array") 4 | typedef UntypedArray = Array; 5 | -------------------------------------------------------------------------------- /std/gdscript/UntypedDictionary.hx: -------------------------------------------------------------------------------- 1 | package gdscript; 2 | 3 | @:nativeTypeCode("Dictionary") 4 | typedef UntypedDictionary = Dictionary; 5 | -------------------------------------------------------------------------------- /std/gdscript/_std/Array.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import haxe.iterators.ArrayKeyValueIterator; 4 | 5 | @:coreApi 6 | @:nativeTypeCode("Array[{type0}]") 7 | @:bindings_api_type("builtin_classes") 8 | extern class Array { 9 | // ---------------------------- 10 | // Haxe String Functions 11 | // ---------------------------- 12 | 13 | @:nativeName("size()") 14 | public var length(default, null): Int; 15 | 16 | // ---------- 17 | // constructor 18 | @:nativeFunctionCode("[]") 19 | public function new(); 20 | 21 | @:nativeFunctionCode("({this} + {arg0})") 22 | public function concat(a: Array): Array; 23 | 24 | @:runtime public inline function join(sep: String): String { 25 | var result: String = ""; 26 | final len = length; 27 | for(i in 0...len) { 28 | result += Std.string(get(i)) + (i == len - 1 ? "" : sep); 29 | } 30 | return result; 31 | } 32 | 33 | @:nativeFunctionCode("{this}[{arg0}]") 34 | private function get(index: Int): T; 35 | 36 | @:nativeName("pop_back") 37 | public function pop(): Null; 38 | 39 | @:nativeName("push_back") 40 | public function push(x: T): Int; 41 | 42 | @:nativeName("reverse") 43 | public function reverse(): Void; 44 | 45 | @:nativeName("pop_front") 46 | public function shift(): Null; 47 | 48 | @:nativeName("slice") 49 | public function slice(pos: Int, end: Int = 2147483647):Array; 50 | 51 | @:runtime public inline function sort(f: (T, T) -> Int): Void { 52 | sortCustom(function(a, b) return f(a, b) < 0); 53 | } 54 | 55 | @:nativeName("sort_custom") 56 | private function sortCustom(f: (T, T) -> Bool): Void; 57 | 58 | @:runtime public inline function splice(pos: Int, len: Int): Array { 59 | final result = []; 60 | if(pos < 0) pos = 0; 61 | var i = pos + len - 1; 62 | if(i >= length) i = length - 1; 63 | while(i >= pos) { 64 | result.push(get(pos)); 65 | removeAt(pos); 66 | i--; 67 | } 68 | return result; 69 | } 70 | 71 | @:nativeName("remove_at") 72 | private function removeAt(pos: Int): Void; 73 | 74 | @:nativeFunctionCode("str({this})") 75 | public function toString(): String; 76 | 77 | @:nativeName("push_front") 78 | public function unshift(x: T): Void; 79 | 80 | @:nativeName("insert") 81 | private function gdInsert(pos: Int, x: T): Void; 82 | 83 | @:runtime public inline function insert(pos: Int, x: T): Void { 84 | return (pos < 0) ? gdInsert(length + 1 + pos, x) : gdInsert(pos, x); 85 | } 86 | 87 | @:runtime public inline function remove(x: T): Bool { 88 | final index = indexOf(x); 89 | return if(index >= 0) { 90 | removeAt(index); 91 | true; 92 | } else { 93 | false; 94 | } 95 | } 96 | 97 | @:nativeName("has") 98 | @:pure public function contains(x : T): Bool; 99 | 100 | @:nativeName("find") 101 | public function indexOf(x: T, fromIndex: Int = 0): Int; 102 | 103 | @:nativeName("rfind") 104 | public function lastIndexOf(x: T, fromIndex: Int = -1): Int; 105 | 106 | @:runtime public inline function copy(): Array { 107 | return [for (v in this) v]; 108 | } 109 | 110 | @:runtime inline function iterator(): haxe.iterators.ArrayIterator { 111 | return new haxe.iterators.ArrayIterator(this); 112 | } 113 | 114 | @:pure @:runtime public inline function keyValueIterator() : ArrayKeyValueIterator { 115 | return new ArrayKeyValueIterator(this); 116 | } 117 | 118 | @:runtime inline function map(f: (T) -> S):Array { 119 | final temp = f; 120 | final result = []; 121 | for(v in this) result.push(temp(v)); 122 | return result; 123 | } 124 | 125 | @:runtime inline function filter(f: (T) -> Bool):Array { 126 | final temp = f; 127 | final result = []; 128 | for(v in this) if(temp(v)) result.push(v); 129 | return result; 130 | } 131 | 132 | @:nativeName("resize") 133 | public function resize(len: Int): Void; 134 | } 135 | -------------------------------------------------------------------------------- /std/gdscript/_std/EReg.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | class EReg { 4 | private var regObj: Dynamic; 5 | private var regexStr: String; 6 | private var m: Dynamic = null; 7 | 8 | public function new(r: String, opt: String) { 9 | regObj = untyped __gdscript__("RegEx.new()"); 10 | regexStr = r; 11 | } 12 | 13 | private function reset() { 14 | untyped regObj.clear(); 15 | untyped regObj.compile(regexStr); 16 | } 17 | 18 | public function match(s: String): Bool { 19 | reset(); 20 | m = untyped regObj.search(s); 21 | return untyped !!m; 22 | } 23 | 24 | public function matched(n: Int): String { 25 | if(m != null) { 26 | return m.get_string(n); 27 | } 28 | return ""; 29 | } 30 | 31 | public function matchedLeft(): String { 32 | throw "EReg.matchedLeft not implemented for GDScript."; 33 | return ""; 34 | } 35 | 36 | public function matchedRight(): String { 37 | throw "EReg.matchedRight not implemented for GDScript."; 38 | return ""; 39 | } 40 | 41 | public function matchedPos(): { pos: Int, len: Int } { 42 | if(m == null) { 43 | return { pos: -1, len: -1 }; 44 | } 45 | return untyped { 46 | pos: m.get_start(), 47 | len: m.get_end() - m.get_start() 48 | }; 49 | } 50 | 51 | public function matchSub(s: String, pos: Int, len: Int = -1): Bool { 52 | reset(); 53 | m = untyped regObj.search(s, pos, (len == -1 ? -1 : (s.length - pos + len))); 54 | return untyped !!m; 55 | } 56 | 57 | public function split(s: String): Array { 58 | if(s == null || s.length <= 0) { 59 | return [s]; 60 | } 61 | 62 | final result = []; 63 | var index = 0; 64 | while(true) { 65 | if(matchSub(s, index)) { 66 | final pos = matchedPos(); 67 | result.push(s.substring(index, pos.pos)); 68 | 69 | // prevent infinite loop 70 | if((pos.pos + pos.len) <= index) { 71 | break; 72 | } 73 | 74 | index = pos.pos + pos.len; 75 | 76 | if(index >= s.length) { 77 | break; 78 | } 79 | 80 | } else { 81 | result.push(s.substring(index)); 82 | break; 83 | } 84 | } 85 | 86 | return result; 87 | } 88 | 89 | public function replace(s: String, by: String): String { 90 | return untyped regObj.sub(s, by); 91 | } 92 | 93 | public function map(s: String, f: (EReg)->String): String { 94 | throw "EReg.map not implemented for GDScript."; 95 | return ""; 96 | } 97 | 98 | public static function escape(s: String): String { 99 | throw "EReg.escape not implemented for GDScript."; 100 | return ""; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /std/gdscript/_std/Math.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | extern class Math { 4 | public static var PI(get, never): Float; 5 | @:runtime public static inline function get_PI(): Float return untyped __gdscript__("PI"); 6 | 7 | @:native("-INF") 8 | public static var NEGATIVE_INFINITY(default, null): Float; 9 | 10 | @:native("INF") 11 | public static var POSITIVE_INFINITY(default, null): Float; 12 | 13 | public static var NaN(get, never): Float; 14 | @:runtime public static inline function get_NaN(): Float return untyped __gdscript__("NAN"); 15 | 16 | @:native("abs") public static function abs(v: Float): Float; 17 | @:native("min") public static function min(a: Float, b: Float): Float; 18 | @:native("max") public static function max(a: Float, b: Float): Float; 19 | 20 | @:native("sin") public static function sin(v: Float): Float; 21 | @:native("cos") public static function cos(v: Float): Float; 22 | @:native("tan") public static function tan(v: Float): Float; 23 | @:native("asin") public static function asin(v: Float): Float; 24 | @:native("acos") public static function acos(v: Float): Float; 25 | @:native("atan") public static function atan(v: Float): Float; 26 | 27 | @:native("atan2") public static function atan2(y: Float, x: Float): Float; 28 | 29 | @:native("exp") public static function exp(v: Float): Float; 30 | @:native("log") public static function log(v: Float): Float; 31 | 32 | @:native("pow") public static function pow(v: Float, exp: Float): Float; 33 | 34 | @:native("sqrt") public static function sqrt(v: Float): Float; 35 | 36 | @:runtime public static inline function round(v: Float): Int return Std.int(fround(v)); 37 | @:runtime public static inline function floor(v: Float): Int return Std.int(ffloor(v)); 38 | @:runtime public static inline function ceil(v: Float): Int return Std.int(fceil(v)); 39 | 40 | @:native("round") public static function fround(v: Float): Float; 41 | @:native("floor") public static function ffloor(v: Float): Float; 42 | @:native("ceil") public static function fceil(v: Float): Float; 43 | 44 | @:native("randf") public static function random(): Float; 45 | 46 | @:native("is_nan") public static function isNaN(f: Float): Bool; 47 | 48 | @:native("is_finite") public static function isFinite(f: Float): Bool; 49 | } 50 | -------------------------------------------------------------------------------- /std/gdscript/_std/Reflect.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | class Reflect { 4 | @:runtime public inline static function hasField(o: Dynamic, fieldName: String): Bool { 5 | return untyped __gdscript__("{0} in {1}", fieldName, o); 6 | } 7 | 8 | @:runtime public inline static function field(o: Dynamic, fieldName: String): Dynamic { 9 | return untyped __gdscript__("{0}.get({1})", o, fieldName); 10 | } 11 | 12 | public static function setField(o: Dynamic, fieldName: String, value: Dynamic): Void { 13 | return if(isEnumValue(o)) { 14 | untyped __gdscript__("{0}[{1}] = {2}", o, fieldName, value); 15 | } else { 16 | untyped __gdscript__("{0}.set({1}, {2})", o, fieldName, value); 17 | } 18 | } 19 | 20 | public static function getProperty(o: Dynamic, fieldName: String): Dynamic { 21 | return if(hasField(o, "get_" + fieldName)) { 22 | field(o, "get_" + fieldName)(); 23 | } else { 24 | field(o, fieldName); 25 | } 26 | } 27 | 28 | public static function setProperty(o: Dynamic, fieldName: String, value: Dynamic): Void { 29 | return if(hasField(o, "set_" + fieldName)) { 30 | field(o, "set_" + fieldName)(value); 31 | } else { 32 | setField(o, fieldName, value); 33 | } 34 | } 35 | 36 | @:runtime public inline static function callMethod(o: Dynamic, func: haxe.Constraints.Function, args: Array): Dynamic { 37 | return untyped __gdscript__("{0}.callv({1})", func, args); 38 | } 39 | 40 | public static function fields(o: Dynamic): Array { 41 | return untyped { 42 | final list: Array<{ name: String }> = untyped __gdscript__("{0}.get_property_list()", o); 43 | var result = []; 44 | for(l in list) { 45 | result.push(l.name); 46 | } 47 | result; 48 | } 49 | } 50 | 51 | @:runtime public inline static function isFunction(f: Dynamic): Bool { 52 | return untyped __gdscript__("({0} as Variant) is Callable", f); 53 | } 54 | 55 | public static function compare(a: T, b: T): Int { 56 | return if(untyped __gdscript__("{0} < {1}", a, b)) { 57 | -1; 58 | } else if(untyped __gdscript__("{0} > {1}", a, b)) { 59 | 1; 60 | } else { 61 | 0; 62 | } 63 | } 64 | 65 | @:runtime public inline static function compareMethods(f1: Dynamic, f2: Dynamic): Bool { 66 | return f1 == f2; 67 | } 68 | 69 | @:runtime public inline static function isObject(v: Dynamic): Bool { 70 | return untyped __gdscript__("({0} as Variant) is Object", v); 71 | } 72 | 73 | @:runtime public inline static function isEnumValue(v: Dynamic): Bool { 74 | return untyped __gdscript__("({0} as Variant) is Dictionary", v); 75 | } 76 | 77 | public static function deleteField(o: Dynamic, fieldName: String): Bool { 78 | final result = hasField(o, fieldName); 79 | if(result) Reflect.setField(o, fieldName, null); 80 | return result; 81 | } 82 | 83 | public static function copy(o: Null): Null { 84 | if(o == null) return null; 85 | if(isEnumValue(o)) { 86 | return untyped __gdscript__("{0}.duplicate()", o); 87 | } 88 | throw "Only anonymous structures (Dictionaries) may be used with `Reflect.copy`."; 89 | } 90 | 91 | @:overload(function(f:Array->Void):Dynamic {}) 92 | public static function makeVarArgs(f: Array->Dynamic): Dynamic { 93 | return function(...args: Dynamic) { 94 | return f(args); 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /std/gdscript/_std/Std.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | extern class Std { 4 | @:deprecated('Std.is is deprecated. Use Std.isOfType instead.') 5 | @:runtime public inline static function is(v: Dynamic, t: Dynamic): Bool return isOfType(v, t); 6 | 7 | @:nativeFunctionCode("(({arg0} as Variant) is {arg1})") 8 | public static function isOfType(v: Dynamic, t: Dynamic): Bool; 9 | 10 | @:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.') 11 | @:runtime public inline static function instance(value: T, c: Class): S return downcast(value, c); 12 | 13 | @:nativeFunctionCode("({arg0} as {arg1})") 14 | public static function downcast(value: T, c: Class): S; 15 | 16 | @:native("str") 17 | public static function string(s: Dynamic): String; 18 | 19 | @:native("int") 20 | public static function int(x: Float): Int; 21 | 22 | @:nativeFunctionCode("{arg0}.to_int()") 23 | public static function parseInt(x: String): Null; 24 | 25 | @:nativeFunctionCode("{arg0}.to_float()") 26 | public static function parseFloat(x: String): Float; 27 | 28 | @:nativeFunctionCode("floor(randf() * {arg0})") 29 | public static function random(x: Int): Int; 30 | } 31 | -------------------------------------------------------------------------------- /std/gdscript/_std/String.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | @:coreApi 4 | extern class String { 5 | // ---------------------------- 6 | // Haxe String Functions 7 | // ---------------------------- 8 | 9 | // ---------- 10 | // constructor 11 | @:nativeFunctionCode("{arg0}") 12 | public function new(string: String); 13 | 14 | // ---------- 15 | // @:nativeName 16 | @:nativeName("length()") 17 | public var length(default, null): Int; 18 | 19 | @:nativeName("to_upper") 20 | public function toUpperCase(): String; 21 | 22 | @:nativeName("to_lower") 23 | public function toLowerCase(): String; 24 | 25 | @:nativeName("find") 26 | public function indexOf(str: String, startIndex: Int = 0): Int; 27 | 28 | @:nativeName("substr") 29 | public function substr(pos: Int, len: Int = -1): String; 30 | 31 | // ---------- 32 | // @:native 33 | @:native("char") 34 | public static function fromCharCode(code: Int): String; 35 | 36 | // ---------- 37 | // @:nativeFunctionCode 38 | @:nativeFunctionCode("{this}[{arg0}]") 39 | public function charAt(index: Int): String; 40 | 41 | @:nativeFunctionCode("{this}") 42 | public function toString(): String; 43 | 44 | // ---------- 45 | // @:runtime inline 46 | @:runtime public inline function charCodeAt(index: Int): Null { 47 | return if(index >= 0 && index < length) { 48 | unicodeAt(index); 49 | } else { 50 | null; 51 | } 52 | } 53 | 54 | @:runtime public inline function lastIndexOf(str: String, startIndex: Int = -1): Int { 55 | return if(startIndex < 0) { 56 | rfind(str); 57 | } else { 58 | substring(0, startIndex + this.length).rfind(str); 59 | } 60 | } 61 | 62 | @:runtime public inline function split(delimiter: String): Array { 63 | return untyped __gdscript__("Array(Array({0}.split({1})), Variant.Type.TYPE_STRING, \"\", null)", this, delimiter); 64 | } 65 | 66 | @:runtime public inline function substring(startIndex: Int, endIndex: Int = -1): String { 67 | return if(endIndex < 0) { 68 | substr(startIndex); 69 | } else { 70 | substr(startIndex, endIndex - startIndex); 71 | } 72 | } 73 | 74 | // ---------------------------- 75 | // GDScript String Functions 76 | // 77 | // (gotta keep these private cause @:coreApi requires all 78 | // fields that don't match the api to be explicitly private). 79 | // ---------------------------- 80 | @:nativeName("unicode_at") private function unicodeAt(at: Int): Int; 81 | @:nativeName("rfind") private function rfind(what: String): Int; 82 | @:nativeName("findn") private function findNoCase(what: String, from: Int = 0): Int; 83 | @:nativeName("length") private function getLength(): Int; 84 | } 85 | -------------------------------------------------------------------------------- /std/gdscript/_std/Sys.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | @:require(sys) 4 | extern class Sys { 5 | @:runtime public inline static function print(v: Dynamic): Void { 6 | untyped __gdscript__("print(str({0}))", v); 7 | } 8 | 9 | @:runtime public inline static function println(v: Dynamic): Void { 10 | untyped __gdscript__("print(str({0}) + \"\n\")", v); 11 | } 12 | 13 | @:runtime public inline static function args(): Array { 14 | return []; 15 | } 16 | 17 | @:runtime public inline static function getEnv(s: String): String { 18 | return untyped __gdscript__("OS.get_environment({0})", s); 19 | } 20 | 21 | @:runtime public inline static function putEnv(s: String, v: Null): Void { 22 | return untyped __gdscript__("OS.set_environment({0}, {1})", s, v == null ? "" : v); 23 | } 24 | 25 | @:runtime public inline static function environment(): Map { 26 | throw "Sys.environment not implemented for GDScript."; 27 | } 28 | 29 | @:runtime public inline static function sleep(seconds: Float): Void { 30 | untyped __gdscript__("OS.delay_msec({0} * 1000)", seconds); 31 | } 32 | 33 | @:runtime public inline static function setTimeLocale(loc: String): Bool { 34 | return false; 35 | } 36 | 37 | @:runtime public inline static function getCwd(): String { 38 | return programPath(); 39 | } 40 | 41 | @:runtime public inline static function setCwd(s: String): Void { 42 | throw "Sys.setCwd not implemented for GDScript."; 43 | } 44 | 45 | @:runtime public inline static function systemName(): String { 46 | return switch untyped __gdscript__("OS.get_name()") { 47 | case "macOS": "Mac"; 48 | case "FreeBSD" | "NetBSD" | "OpenBSD": "BSD"; 49 | case s: s; 50 | } 51 | } 52 | 53 | @:runtime public inline static function command(cmd: String, ?args: Array): Int { 54 | if(args == null) args = []; 55 | return untyped __gdscript__("OS.execute({0}, PackedStringArray({1}))", cmd, args); 56 | } 57 | 58 | @:runtime public inline static function exit(code: Int): Void { 59 | throw "Sys.exit not implemented for GDScript."; 60 | } 61 | 62 | @:runtime public inline static function time(): Float { 63 | throw "Sys.time not implemented for GDScript."; 64 | } 65 | 66 | @:runtime public inline static function cpuTime(): Float { 67 | return untyped __gdscript__("(Time.get_ticks_msec() * 1000)"); 68 | } 69 | 70 | @:deprecated("Use programPath instead") 71 | @:runtime public inline static function executablePath(): String { 72 | return programPath(); 73 | } 74 | 75 | @:runtime public inline static function programPath(): String { 76 | return untyped __gdscript__("OS.get_executable_path()"); 77 | } 78 | 79 | @:runtime public inline static function getChar(echo: Bool): Int { 80 | throw "Sys.getChar not implemented for GDScript."; 81 | } 82 | 83 | @:runtime public inline static function stdin(): haxe.io.Input { 84 | throw "Sys.stdin not implemented for GDScript."; 85 | } 86 | 87 | @:runtime public inline static function stdout(): haxe.io.Output { 88 | throw "Sys.stdout not implemented for GDScript."; 89 | } 90 | 91 | @:runtime public inline static function stderr(): haxe.io.Output { 92 | throw "Sys.stderr not implemented for GDScript."; 93 | } 94 | } -------------------------------------------------------------------------------- /std/gdscript/_std/haxe/Exception.hx: -------------------------------------------------------------------------------- 1 | package haxe; 2 | 3 | class Exception { 4 | /** 5 | Exception message. 6 | **/ 7 | public var message(get,never): String; 8 | var _message: String; 9 | private function get_message(): String return _message; 10 | 11 | /** 12 | The call stack at the moment of the exception creation. 13 | **/ 14 | public var stack(get,never): CallStack; 15 | private function get_stack(): CallStack { 16 | return []; 17 | } 18 | 19 | /** 20 | Contains an exception, which was passed to `previous` constructor argument. 21 | **/ 22 | public var previous(get, never): Null; 23 | var _previous: Null; 24 | private function get_previous(): Null return _previous; 25 | 26 | /** 27 | Native exception, which caused this exception. 28 | **/ 29 | public var native(get,never): Any; 30 | var _native: Any; 31 | final private function get_native(): Any return _native; 32 | 33 | /** 34 | Used internally for wildcard catches like `catch(e:Exception)`. 35 | **/ 36 | static private function caught(value: Any): Exception { 37 | return new haxe.Exception(Std.string(value)); 38 | } 39 | 40 | /** 41 | Used internally for wrapping non-throwable values for `throw` expressions. 42 | **/ 43 | static private function thrown(value: Any): Any { 44 | return value; 45 | } 46 | 47 | /** 48 | Create a new Exception instance. 49 | 50 | The `previous` argument could be used for exception chaining. 51 | 52 | The `native` argument is for internal usage only. 53 | There is no need to provide `native` argument manually and no need to keep it 54 | upon extending `haxe.Exception` unless you know what you're doing. 55 | **/ 56 | public function new(message: String, ?previous: Exception, ?native: Any):Void { 57 | _message = message; 58 | _previous = previous; 59 | _native = native; 60 | } 61 | 62 | /** 63 | Extract an originally thrown value. 64 | 65 | Used internally for catching non-native exceptions. 66 | Do _not_ override unless you know what you are doing. 67 | **/ 68 | private function unwrap():Any { 69 | return _native; 70 | } 71 | 72 | /** 73 | Returns exception message. 74 | **/ 75 | public function toString():String { 76 | return _message; 77 | } 78 | 79 | /** 80 | Detailed exception description. 81 | 82 | Includes message, stack and the chain of previous exceptions (if set). 83 | **/ 84 | public function details():String { 85 | return _message; 86 | } 87 | 88 | /** 89 | If this field is defined in a target implementation, then a call to this 90 | field will be generated automatically in every constructor of derived classes 91 | to make exception stacks point to derived constructor invocations instead of 92 | `super` calls. 93 | **/ 94 | // @:noCompletion @:ifFeature("haxe.Exception.stack") private function __shiftStack():Void; 95 | } 96 | -------------------------------------------------------------------------------- /std/gdscript/_std/haxe/Log.hx: -------------------------------------------------------------------------------- 1 | package haxe; 2 | 3 | @:tool 4 | class Log { 5 | public static function formatOutput(v: Dynamic, infos: PosInfos): String { 6 | var str = Std.string(v); 7 | if (infos == null) 8 | return str; 9 | var pstr = infos.fileName + ":" + infos.lineNumber; 10 | if (infos.customParams != null) 11 | for (v in infos.customParams) 12 | str += ", " + Std.string(v); 13 | return pstr + ": " + str; 14 | } 15 | 16 | public static dynamic function trace(v: Dynamic, ?infos: PosInfos):Void { 17 | var str = formatOutput(v, infos); 18 | untyped __gdscript__("print({0})", str); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /std/gdscript/_std/haxe/ds/IntMap.hx: -------------------------------------------------------------------------------- 1 | package haxe.ds; 2 | 3 | class IntMap implements haxe.Constraints.IMap { 4 | var m: gdscript.Dictionary; 5 | 6 | public function new(): Void { 7 | m = new gdscript.Dictionary(); 8 | } 9 | 10 | public function set(key: Int, value: T): Void { 11 | m.set(key, value); 12 | } 13 | 14 | public function get(key: Int): Null { 15 | return if(m.has(key)) { 16 | m.get(key); 17 | } else { 18 | null; 19 | } 20 | } 21 | 22 | public function exists(key: Int): Bool { 23 | return m.has(key); 24 | } 25 | 26 | public function remove(key: Int): Bool { 27 | return m.erase(key); 28 | } 29 | 30 | public function keys(): Iterator { 31 | return m.keys().iterator(); 32 | } 33 | 34 | public function iterator(): Iterator { 35 | return m.values().iterator(); 36 | } 37 | 38 | @:runtime public inline function keyValueIterator(): KeyValueIterator { 39 | return new haxe.iterators.MapKeyValueIterator(this); 40 | } 41 | 42 | public function copy(): IntMap { 43 | final result = new IntMap(); 44 | result.m = m.duplicate(false); 45 | return result; 46 | } 47 | 48 | public function toString(): String { 49 | var result = "["; 50 | var first = true; 51 | for(key => value in this) { 52 | result += (first ? "" : ", ") + (Std.string(key) + " => " + Std.string(value)); 53 | if(first) first = false; 54 | } 55 | return result + "]"; 56 | } 57 | 58 | public function clear(): Void { 59 | m.clear(); 60 | } 61 | } -------------------------------------------------------------------------------- /std/gdscript/_std/haxe/ds/ObjectMap.hx: -------------------------------------------------------------------------------- 1 | package haxe.ds; 2 | 3 | class ObjectMap implements haxe.Constraints.IMap { 4 | var m: gdscript.Dictionary; 5 | 6 | public function new(): Void { 7 | m = new gdscript.Dictionary(); 8 | } 9 | 10 | public function set(key: K, value: T): Void { 11 | m.set(key, value); 12 | } 13 | 14 | public function get(key: K): Null { 15 | return if(m.has(key)) { 16 | m.get(key); 17 | } else { 18 | null; 19 | } 20 | } 21 | 22 | public function exists(key: K): Bool { 23 | return m.has(key); 24 | } 25 | 26 | public function remove(key: K): Bool { 27 | return m.erase(key); 28 | } 29 | 30 | public function keys(): Iterator { 31 | return m.keys().iterator(); 32 | } 33 | 34 | public function iterator(): Iterator { 35 | return m.values().iterator(); 36 | } 37 | 38 | @:runtime public inline function keyValueIterator(): KeyValueIterator { 39 | return new haxe.iterators.MapKeyValueIterator(this); 40 | } 41 | 42 | public function copy(): ObjectMap { 43 | final result = new ObjectMap(); 44 | result.m = m.duplicate(false); 45 | return result; 46 | } 47 | 48 | public function toString(): String { 49 | var result = "["; 50 | var first = true; 51 | for(key => value in this) { 52 | result += (first ? "" : ", ") + (Std.string(key) + " => " + Std.string(value)); 53 | if(first) first = false; 54 | } 55 | return result + "]"; 56 | } 57 | 58 | public function clear(): Void { 59 | m.clear(); 60 | } 61 | } -------------------------------------------------------------------------------- /std/gdscript/_std/haxe/ds/StringMap.hx: -------------------------------------------------------------------------------- 1 | package haxe.ds; 2 | 3 | class StringMap implements haxe.Constraints.IMap { 4 | var m: gdscript.Dictionary; 5 | 6 | public function new(): Void { 7 | m = new gdscript.Dictionary(); 8 | } 9 | 10 | public function set(key: String, value: T): Void { 11 | m.set(key, value); 12 | } 13 | 14 | public function get(key: String): Null { 15 | return if(m.has(key)) { 16 | m.get(key); 17 | } else { 18 | null; 19 | } 20 | } 21 | 22 | public function exists(key: String): Bool { 23 | return m.has(key); 24 | } 25 | 26 | public function remove(key: String): Bool { 27 | return m.erase(key); 28 | } 29 | 30 | public function keys(): Iterator { 31 | return m.keys().iterator(); 32 | } 33 | 34 | public function iterator(): Iterator { 35 | return m.values().iterator(); 36 | } 37 | 38 | @:runtime public inline function keyValueIterator(): KeyValueIterator { 39 | return new haxe.iterators.MapKeyValueIterator(this); 40 | } 41 | 42 | public function copy(): StringMap { 43 | final result = new StringMap(); 44 | result.m = m.duplicate(false); 45 | return result; 46 | } 47 | 48 | public function toString(): String { 49 | var result = "["; 50 | var first = true; 51 | for(key => value in this) { 52 | result += (first ? "" : ", ") + (Std.string(key) + " => " + Std.string(value)); 53 | if(first) first = false; 54 | } 55 | return result + "]"; 56 | } 57 | 58 | public function clear(): Void { 59 | m.clear(); 60 | } 61 | } -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ -------------------------------------------------------------------------------- /test/BuildProject.bat: -------------------------------------------------------------------------------- 1 | mkdir bin 2 | cd godot_project 3 | godot --headless --export-release "Windows" "../bin/reflaxe_gdscript_test.exe" 4 | cd .. -------------------------------------------------------------------------------- /test/TODO.md: -------------------------------------------------------------------------------- 1 | # Tests I need to add: 2 | 3 | * `cast`, specifically casting something to `Int` or other primitives 4 | * Type compiling -------------------------------------------------------------------------------- /test/Test.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | 3 | -D gdscript-output=godot_project/gdscript/out 4 | 5 | --no-opt 6 | 7 | test 8 | -------------------------------------------------------------------------------- /test/TestProject.bat: -------------------------------------------------------------------------------- 1 | "bin/reflaxe_gdscript_test.exe" --headless -------------------------------------------------------------------------------- /test/Test_WithHaxelib.hxml: -------------------------------------------------------------------------------- 1 | -lib gdscript 2 | 3 | Test.hxml 4 | -------------------------------------------------------------------------------- /test/godot_project/.gitattributes: -------------------------------------------------------------------------------- 1 | # Normalize EOL for all files that Git considers text files. 2 | * text=auto eol=lf 3 | -------------------------------------------------------------------------------- /test/godot_project/.gitignore: -------------------------------------------------------------------------------- 1 | # Godot 4+ specific ignores 2 | .godot/ 3 | -------------------------------------------------------------------------------- /test/godot_project/export_presets.cfg: -------------------------------------------------------------------------------- 1 | [preset.0] 2 | 3 | name="Windows" 4 | platform="Windows Desktop" 5 | runnable=true 6 | dedicated_server=false 7 | custom_features="" 8 | export_filter="all_resources" 9 | include_filter="" 10 | exclude_filter="" 11 | export_path="" 12 | encryption_include_filters="" 13 | encryption_exclude_filters="" 14 | encrypt_pck=false 15 | encrypt_directory=false 16 | 17 | [preset.0.options] 18 | 19 | custom_template/debug="" 20 | custom_template/release="" 21 | debug/export_console_wrapper=1 22 | binary_format/embed_pck=false 23 | texture_format/bptc=true 24 | texture_format/s3tc=true 25 | texture_format/etc=false 26 | texture_format/etc2=false 27 | binary_format/architecture="x86_64" 28 | codesign/enable=false 29 | codesign/timestamp=true 30 | codesign/timestamp_server_url="" 31 | codesign/digest_algorithm=1 32 | codesign/description="" 33 | codesign/custom_options=PackedStringArray() 34 | application/modify_resources=true 35 | application/icon="" 36 | application/console_wrapper_icon="" 37 | application/icon_interpolation=4 38 | application/file_version="" 39 | application/product_version="" 40 | application/company_name="" 41 | application/product_name="" 42 | application/file_description="" 43 | application/copyright="" 44 | application/trademarks="" 45 | application/export_angle=0 46 | ssh_remote_deploy/enabled=false 47 | ssh_remote_deploy/host="user@host_ip" 48 | ssh_remote_deploy/port="22" 49 | ssh_remote_deploy/extra_args_ssh="" 50 | ssh_remote_deploy/extra_args_scp="" 51 | ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}' 52 | $action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}' 53 | $trigger = New-ScheduledTaskTrigger -Once -At 00:00 54 | $settings = New-ScheduledTaskSettingsSet 55 | $task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings 56 | Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true 57 | Start-ScheduledTask -TaskName godot_remote_debug 58 | while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 } 59 | Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue" 60 | ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue 61 | Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue 62 | Remove-Item -Recurse -Force '{temp_dir}'" 63 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/Test.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | class_name Test 3 | 4 | func _init(): 5 | TestAll.test(); 6 | 7 | func _ready(): 8 | call_deferred("quit"); 9 | 10 | func quit(): pass 11 | # quits too soon for some reason?? Fix later 12 | # get_tree().quit(0); 13 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/Test.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ct7urpn1juqu1 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/EReg.gd: -------------------------------------------------------------------------------- 1 | class_name EReg 2 | 3 | var regObj 4 | var regexStr: String 5 | var m = null 6 | 7 | func _init(r: String, opt: String) -> void: 8 | self.regObj = RegEx.new() 9 | self.regexStr = r 10 | 11 | func reset() -> void: 12 | self.regObj.clear.call() 13 | self.regObj.compile.call(self.regexStr) 14 | 15 | func _match(s: String) -> bool: 16 | self.reset() 17 | self.m = self.regObj.search.call(s) 18 | 19 | return !(!self.m) 20 | 21 | func matched(n: int) -> String: 22 | if (self.m != null): 23 | return self.m.get_string.call(n) 24 | 25 | return "" 26 | 27 | func matchedLeft() -> String: 28 | assert(false, "EReg.matchedLeft not implemented for GDScript.") 29 | 30 | return "" 31 | 32 | func matchedRight() -> String: 33 | assert(false, "EReg.matchedRight not implemented for GDScript.") 34 | 35 | return "" 36 | 37 | func matchedPos() -> Variant: 38 | if (self.m == null): 39 | return { 40 | "pos": -1, 41 | "len": -1 42 | } 43 | 44 | return { 45 | "pos": self.m.get_start.call(), 46 | "len": self.m.get_end.call() - self.m.get_start.call() 47 | } 48 | 49 | func matchSub(s: String, pos: int, len: int = -1) -> bool: 50 | self.reset() 51 | 52 | var tempNumber 53 | 54 | if (len == -1): 55 | tempNumber = -1 56 | else: 57 | tempNumber = s.length() - pos + len 58 | 59 | self.m = self.regObj.search.call(s, pos, tempNumber) 60 | 61 | return !(!self.m) 62 | 63 | func split(s: String) -> Array[String]: 64 | if (s == null || s.length() <= 0): 65 | return ([s] as Array[String]) 66 | 67 | var result: Array[String] = ([] as Array[String]) 68 | var index: int = 0 69 | 70 | while (true): 71 | if (self.matchSub(s, index, -1)): 72 | var pos: Variant = self.matchedPos() 73 | var tempString 74 | if true: 75 | var endIndex: int = pos.get("pos") 76 | if (endIndex < 0): 77 | tempString = s.substr(index) 78 | else: 79 | tempString = s.substr(index, endIndex - index) 80 | result.push_back(tempString) 81 | if (pos.get("pos") + pos.get("len") <= index): 82 | break 83 | index = pos.get("pos") + pos.get("len") 84 | if (index >= s.length()): 85 | break 86 | else: 87 | var tempString1 88 | if true: 89 | var endIndex: int = -1 90 | if (endIndex < 0): 91 | tempString1 = s.substr(index) 92 | else: 93 | tempString1 = s.substr(index, endIndex - index) 94 | result.push_back(tempString1) 95 | break 96 | 97 | return result 98 | 99 | func replace(s: String, by: String) -> String: 100 | return self.regObj.sub.call(s, by) 101 | 102 | func map(s: String, f) -> String: 103 | assert(false, "EReg.map not implemented for GDScript.") 104 | 105 | return "" 106 | 107 | static func escape(s: String) -> String: 108 | assert(false, "EReg.escape not implemented for GDScript.") 109 | 110 | return "" 111 | 112 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/EReg.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cxgoj68661nxy 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/Log.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | class_name Log 3 | 4 | static var trace = func(v, infos = null) -> void: 5 | var _str: String = Log.formatOutput(v, infos) 6 | print(_str) 7 | 8 | func _init() -> void: 9 | pass 10 | 11 | static func formatOutput(v, infos: Variant) -> String: 12 | var _str: String = str(v) 13 | 14 | if (infos == null): 15 | return _str 16 | 17 | var pstr: String = infos.get("fileName") + ":" + str(infos.get("lineNumber")) 18 | 19 | if (infos.get("customParams") != null): 20 | var _g: int = 0 21 | var _g1 = infos.get("customParams") 22 | while (_g < _g1.size()): 23 | var v2 = _g1[_g] 24 | _g += 1 25 | _str += ", " + str(v2) 26 | 27 | return pstr + ": " + _str 28 | 29 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/Log.gd.uid: -------------------------------------------------------------------------------- 1 | uid://h6s28ry0yx76 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/MyAbstract.gd: -------------------------------------------------------------------------------- 1 | class_name MyAbstract_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func _new(x: int) -> int: 7 | var this1: int = x 8 | 9 | return this1 10 | 11 | static func incr(this1: int) -> int: 12 | this1 += 1 13 | 14 | var tempResult: int = this1 15 | 16 | return tempResult 17 | 18 | static func toInt(this1: int) -> int: 19 | return this1 20 | 21 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/MyAbstract.gd.uid: -------------------------------------------------------------------------------- 1 | uid://nxh6q0njd8um 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/Reflect.gd: -------------------------------------------------------------------------------- 1 | class_name Reflect 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func hasField(o, fieldName: String) -> bool: 7 | return fieldName in o 8 | 9 | static func field(o, fieldName: String): 10 | return o.get(fieldName) 11 | 12 | static func setField(o, fieldName: String, value) -> void: 13 | if ((o as Variant) is Dictionary): 14 | o[fieldName] = value 15 | else: 16 | o.set(fieldName, value) 17 | 18 | static func getProperty(o, fieldName: String): 19 | var tempResult 20 | 21 | if ("get_" + fieldName in o): 22 | tempResult = o.get("get_" + fieldName).call() 23 | else: 24 | tempResult = o.get(fieldName) 25 | 26 | return tempResult 27 | 28 | static func setProperty(o, fieldName: String, value) -> void: 29 | if ("set_" + fieldName in o): 30 | o.get("set_" + fieldName).call(value) 31 | else: 32 | Reflect.setField(o, fieldName, value) 33 | 34 | static func callMethod(o, _func, args: Array[Variant]): 35 | return _func.callv(args) 36 | 37 | static func fields(o) -> Array[String]: 38 | var list: Array[Variant] = o.get_property_list() 39 | var result: Array[String] = ([] as Array[String]) 40 | var _g: int = 0 41 | 42 | while (_g < list.size()): 43 | var l: Variant = list[_g] 44 | _g += 1 45 | result.push_back(l.get("name")) 46 | 47 | return result 48 | 49 | static func isFunction(f) -> bool: 50 | return (f as Variant) is Callable 51 | 52 | static func compare(a, b) -> int: 53 | var tempResult 54 | 55 | if (a < b): 56 | tempResult = -1 57 | else: 58 | if (a > b): 59 | tempResult = 1 60 | else: 61 | tempResult = 0 62 | 63 | return tempResult 64 | 65 | static func compareMethods(f1, f2) -> bool: 66 | return f1 == f2 67 | 68 | static func isObject(v) -> bool: 69 | return (v as Variant) is Object 70 | 71 | static func isEnumValue(v) -> bool: 72 | return (v as Variant) is Dictionary 73 | 74 | static func deleteField(o, fieldName: String) -> bool: 75 | var result: bool = fieldName in o 76 | 77 | if (result): 78 | Reflect.setField(o, fieldName, null) 79 | 80 | return result 81 | 82 | static func copy(o): 83 | if (o == null): 84 | return null 85 | if ((o as Variant) is Dictionary): 86 | return o.duplicate() 87 | 88 | assert(false, "Only anonymous structures (Dictionaries) may be used with `Reflect.copy`.") 89 | 90 | static func makeVarArgs(f): 91 | return func(args: Array[Variant]): 92 | var tempArray 93 | if true: 94 | var _g: Array[Variant] = ([] as Array[Variant]) 95 | var _g1: int = 0 96 | var _g2: Array[Variant] = args 97 | while (_g1 < _g2.size()): 98 | var v = _g2[_g1] 99 | _g1 += 1 100 | _g.push_back(v) 101 | tempArray = _g 102 | return f.call(tempArray) 103 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/Reflect.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dp4b3vrkog3gu 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/StringBuf.gd: -------------------------------------------------------------------------------- 1 | class_name StringBuf 2 | 3 | var b: String 4 | 5 | func _init() -> void: 6 | self.b = "" 7 | 8 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/StringBuf.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bsxt5ki4dmvao 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/StringTools.gd: -------------------------------------------------------------------------------- 1 | class_name StringTools 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func startsWith(s: String, start: String) -> bool: 7 | var tempNumber 8 | 9 | if (0 < 0): 10 | tempNumber = s.rfind(start) 11 | else: 12 | var tempString 13 | var endIndex: int = 0 + s.length() 14 | if (endIndex < 0): 15 | tempString = s.substr(0) 16 | else: 17 | tempString = s.substr(0, endIndex - 0) 18 | tempNumber = (tempString).rfind(start) 19 | 20 | return s.length() >= start.length() && (tempNumber) == 0 21 | 22 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/StringTools.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bkkj8rk650qu2 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestAll.gd: -------------------------------------------------------------------------------- 1 | class_name TestAll 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func test() -> void: 7 | TestSyntax.test() 8 | TestMath.test() 9 | TestStd.test() 10 | TestString.test() 11 | TestStaticVar.test() 12 | TestArray.test() 13 | TestEnum.test() 14 | TestMeta.test() 15 | TestSys.test() 16 | TestEReg.test() 17 | TestReflect.test() 18 | TestClass.test() 19 | TestSignals.test() 20 | TestMap.test() 21 | Log.trace.call("Tests successful!!", { 22 | "fileName": "src/test/TestAll.hx", 23 | "lineNumber": 20, 24 | "className": "test.TestAll", 25 | "methodName": "test" 26 | }) 27 | 28 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestAll.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cgraxggwvgmna 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestArray.gd: -------------------------------------------------------------------------------- 1 | class_name TestArray 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func test() -> void: 7 | var arr: Array[int] = [] 8 | 9 | if true: 10 | var cond: bool = arr.size() == 0 11 | assert(cond, "Test assert failed.") 12 | 13 | arr.push_back(0 + 1) 14 | arr.push_back(1 + 1) 15 | arr.push_back(2 + 1) 16 | 17 | if true: 18 | var cond: bool = arr.size() == 3 19 | assert(cond, "Test assert failed.") 20 | if true: 21 | var cond: bool = (arr + ([4, 5, 6] as Array[int])).size() == 6 22 | assert(cond, "Test assert failed.") 23 | if true: 24 | var cond: bool = arr.has(3) 25 | assert(cond, "Test assert failed.") 26 | if true: 27 | var cond: bool = !arr.has(5) 28 | assert(cond, "Test assert failed.") 29 | 30 | assert(arr == arr, "Test assert failed.") 31 | 32 | if true: 33 | var tempRight 34 | if true: 35 | var _g: Array[int] = ([] as Array[int]) 36 | if true: 37 | var _g1: int = 0 38 | while (_g1 < arr.size()): 39 | var v: int = arr[_g1] 40 | _g1 += 1 41 | _g.push_back(v) 42 | tempRight = _g 43 | var cond: bool = arr == tempRight 44 | assert(cond, "Test assert failed.") 45 | if true: 46 | var tempArray 47 | if true: 48 | var temp = func(i: int) -> bool: 49 | return i != 1 50 | var result: Array[int] = ([] as Array[int]) 51 | if true: 52 | var _g: int = 0 53 | while (_g < arr.size()): 54 | var v: int = arr[_g] 55 | _g += 1 56 | if (temp.call(v)): 57 | result.push_back(v) 58 | tempArray = result 59 | var cond: bool = (tempArray).size() == 2 60 | assert(cond, "Test assert failed.") 61 | if true: 62 | var cond: bool = arr.find(2) == 1 63 | assert(cond, "Test assert failed.") 64 | 65 | if (0 < 0): 66 | arr.insert(arr.size() + 1 + 0, 0) 67 | else: 68 | arr.insert(0, 0) 69 | 70 | null 71 | 72 | if true: 73 | var cond: bool = arr.size() == 4 74 | assert(cond, "Test assert failed.") 75 | 76 | assert(arr[0] == 0, "Test assert failed.") 77 | assert(arr[2] == 2, "Test assert failed.") 78 | 79 | if (-1 < 0): 80 | arr.insert(arr.size() + 1 + (-1), 4) 81 | else: 82 | arr.insert(-1, 4) 83 | 84 | null 85 | 86 | if true: 87 | var cond: bool = arr.size() == 5 88 | assert(cond, "Test assert failed.") 89 | 90 | assert(arr[4] == 4, "Test assert failed.") 91 | assert(arr[2] == 2, "Test assert failed.") 92 | 93 | var total: int = 0 94 | var it_current: int = 0 95 | 96 | while (it_current < arr.size()): 97 | var tempIndex 98 | it_current += 1 99 | tempIndex = it_current - 1 100 | total += arr[tempIndex] 101 | 102 | assert(total == 10, "Test assert failed.") 103 | 104 | if true: 105 | var tempLeft 106 | if true: 107 | var result: String = "" 108 | var len: int = arr.size() 109 | if true: 110 | var _g: int = 0 111 | var _g1: int = len 112 | while (_g < _g1): 113 | var tempNumber 114 | if true: 115 | _g += 1 116 | tempNumber = _g - 1 117 | var i: int = tempNumber 118 | var tempString 119 | if (i == len - 1): 120 | tempString = "" 121 | else: 122 | tempString = ", " 123 | result += str(arr[i]) + (tempString) 124 | tempLeft = result 125 | var cond: bool = tempLeft == "0, 1, 2, 3, 4" 126 | assert(cond, "Test assert failed.") 127 | 128 | var tempArray1 129 | 130 | if true: 131 | var temp = func(i: int) -> int: 132 | return i * 2 133 | var result: Array[int] = ([] as Array[int]) 134 | if true: 135 | var _g: int = 0 136 | while (_g < arr.size()): 137 | var v: int = arr[_g] 138 | _g += 1 139 | result.push_back(temp.call(v)) 140 | tempArray1 = result 141 | 142 | var keyTotal: int = 0 143 | var doubleTotal: int = 0 144 | var kvit_current: int = 0 145 | 146 | while (kvit_current < tempArray1.size()): 147 | var o_value 148 | var o_key 149 | o_value = tempArray1[kvit_current] 150 | var tempRight1 151 | kvit_current += 1 152 | tempRight1 = kvit_current - 1 153 | o_key = tempRight1 154 | keyTotal += o_key 155 | doubleTotal += o_value 156 | 157 | assert(keyTotal == 10, "Test assert failed.") 158 | assert(doubleTotal == 20, "Test assert failed.") 159 | 160 | var stack: Array[int] = ([84, 29, 655] as Array[int]) 161 | 162 | if true: 163 | var cond: bool = stack.pop_back() == 655 164 | assert(cond, "Test assert failed.") 165 | if true: 166 | var cond: bool = stack.size() == 2 167 | assert(cond, "Test assert failed.") 168 | 169 | stack.push_back(333) 170 | assert(stack[2] == 333, "Test assert failed.") 171 | 172 | var tempBool 173 | var index: int = stack.find(84) 174 | 175 | if (index >= 0): 176 | stack.remove_at(index) 177 | tempBool = true 178 | else: 179 | tempBool = false 180 | if (tempBool): 181 | if true: 182 | var cond: bool = stack.size() == 2 183 | assert(cond, "Test assert failed.") 184 | assert(stack[0] == 29, "Test assert failed.") 185 | else: 186 | assert(false, "Test assert failed.") 187 | 188 | var ordered: Array[int] = ([3, 6, 9, 12] as Array[int]) 189 | 190 | ordered.reverse() 191 | assert(ordered == ([12, 9, 6, 3] as Array[int]), "Test assert failed.") 192 | 193 | if true: 194 | var cond: bool = ordered.pop_front() == 12 195 | assert(cond, "Test assert failed.") 196 | 197 | var newArr: Array[int] = ([22, 44, 66, 88] as Array[int]) 198 | 199 | if true: 200 | var cond: bool = newArr.slice(1) == ([44, 66, 88] as Array[int]) 201 | assert(cond, "Test assert failed.") 202 | if true: 203 | var cond: bool = newArr.slice(2, 3) == ([66] as Array[int]) 204 | assert(cond, "Test assert failed.") 205 | 206 | var sortable: Array[int] = ([2, 7, 1, 4, 0, 4] as Array[int]) 207 | var f = func(a: int, b: int) -> int: 208 | return a - b 209 | 210 | sortable.sort_custom(func(a: int, b: int) -> bool: 211 | return f.call(a, b) < 0) 212 | assert(sortable == ([0, 1, 2, 4, 4, 7] as Array[int]), "Test assert failed.") 213 | 214 | if true: 215 | var tempLeft1 216 | if true: 217 | var pos: int = 2 218 | var result: Array[int] = ([] as Array[int]) 219 | if (pos < 0): 220 | pos = 0 221 | var i: int = pos + 1 - 1 222 | if (i >= sortable.size()): 223 | i = sortable.size() - 1 224 | while (i >= pos): 225 | result.push_back(sortable[pos]) 226 | sortable.remove_at(pos) 227 | i -= 1 228 | tempLeft1 = result 229 | var cond: bool = tempLeft1 == ([2] as Array[int]) 230 | assert(cond, "Test assert failed.") 231 | if true: 232 | var tempLeft2 233 | if true: 234 | var pos: int = 1 235 | var result: Array[int] = ([] as Array[int]) 236 | if (pos < 0): 237 | pos = 0 238 | var i: int = pos + 3 - 1 239 | if (i >= sortable.size()): 240 | i = sortable.size() - 1 241 | while (i >= pos): 242 | result.push_back(sortable[pos]) 243 | sortable.remove_at(pos) 244 | i -= 1 245 | tempLeft2 = result 246 | var cond: bool = tempLeft2 == ([1, 4, 4] as Array[int]) 247 | assert(cond, "Test assert failed.") 248 | if true: 249 | var cond: bool = str(sortable) == "[0, 7]" 250 | assert(cond, "Test assert failed.") 251 | 252 | var unfinished: Array[int] = ([3, 4, 5] as Array[int]) 253 | 254 | unfinished.push_front(2) 255 | unfinished.push_front(1) 256 | assert(unfinished == ([1, 2, 3, 4, 5] as Array[int]), "Test assert failed.") 257 | 258 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestArray.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c4b00n5x5mdi8 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestClass.gd: -------------------------------------------------------------------------------- 1 | class_name TestClass 2 | 3 | var a: int = 2 4 | var b: float = 3.0 5 | var c: bool = false 6 | 7 | func _init() -> void: 8 | if (!self.c): 9 | Log.trace.call(self.a, { 10 | "fileName": "src/test/TestClass.hx", 11 | "lineNumber": 10, 12 | "className": "test.TestClass", 13 | "methodName": "new", 14 | "customParams": ([self.b] as Array[Variant]) 15 | }) 16 | 17 | static func test() -> void: 18 | Log.trace.call(TestClass.new(), { 19 | "fileName": "src/test/TestClass.hx", 20 | "lineNumber": 15, 21 | "className": "test.TestClass", 22 | "methodName": "test" 23 | }) 24 | 25 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestClass.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cm22russthpfu 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestEReg.gd: -------------------------------------------------------------------------------- 1 | class_name TestEReg 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func test() -> void: 7 | var reg: EReg = EReg.new("abc", "") 8 | 9 | if true: 10 | var cond: bool = reg._match("abcdef") 11 | assert(cond, "Test assert failed.") 12 | if true: 13 | var cond: bool = reg.matched(0) == "abc" 14 | assert(cond, "Test assert failed.") 15 | 16 | var pos: Variant = reg.matchedPos() 17 | 18 | if true: 19 | var cond: bool = pos.get("pos") == 0 20 | assert(cond, "Test assert failed.") 21 | if true: 22 | var cond: bool = pos.get("len") == 3 23 | assert(cond, "Test assert failed.") 24 | if true: 25 | var cond: bool = EReg.new("abc", "").matchSub("abcabc", 1, -1) 26 | assert(cond, "Test assert failed.") 27 | if true: 28 | var cond: bool = EReg.new("\\s*,\\s*", "").split("one,two ,three, four") == (["one", "two", "three", "four"] as Array[String]) 29 | assert(cond, "Test assert failed.") 30 | if true: 31 | var cond: bool = reg.replace("123abc", "456") == "123456" 32 | assert(cond, "Test assert failed.") 33 | 34 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestEReg.gd.uid: -------------------------------------------------------------------------------- 1 | uid://k44tgapylcgc 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestEnum.gd: -------------------------------------------------------------------------------- 1 | class_name TestEnum 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func isLeftWinner(left: MyGDEnum.MyGDEnum, right: MyGDEnum.MyGDEnum) -> bool: 7 | var tempResult 8 | 9 | match (((left as Variant) as int)): 10 | 0: 11 | tempResult = right == MyGDEnum.MyGDEnum.Scissors 12 | 1: 13 | tempResult = right == MyGDEnum.MyGDEnum.Rock 14 | 2: 15 | tempResult = right == MyGDEnum.MyGDEnum.Paper 16 | 17 | return tempResult 18 | 19 | static func test() -> void: 20 | if true: 21 | var cond: bool = TestEnum.isLeftWinner(MyGDEnum.MyGDEnum.Paper, MyGDEnum.MyGDEnum.Rock) 22 | assert(cond, "Test assert failed.") 23 | if true: 24 | var cond: bool = !TestEnum.isLeftWinner(MyGDEnum.MyGDEnum.Rock, MyGDEnum.MyGDEnum.Paper) 25 | assert(cond, "Test assert failed.") 26 | if true: 27 | var cond: bool = !TestEnum.isLeftWinner(MyGDEnum.MyGDEnum.Scissors, MyGDEnum.MyGDEnum.Scissors) 28 | assert(cond, "Test assert failed.") 29 | 30 | var a: Variant = { "_index": 0 } 31 | var b: Variant = { "_index": 1, "i": 123 } 32 | var c: Variant = { "_index": 2, "s": "Test" } 33 | 34 | match (b._index): 35 | 0: 36 | assert(false, "Test assert failed.") 37 | 1: 38 | var _g: int = b.i 39 | if true: 40 | var i: int = _g 41 | assert(i == 123, "Test assert failed.") 42 | 2: 43 | var _g: String = b.s 44 | if true: 45 | var s: String = _g 46 | assert(false, "Test assert failed.") 47 | match (c._index): 48 | 0: 49 | assert(false, "Test assert failed.") 50 | 1: 51 | var _g: int = c.i 52 | if true: 53 | var i: int = _g 54 | assert(false, "Test assert failed.") 55 | 2: 56 | var _g: String = c.s 57 | if true: 58 | var s: String = _g 59 | assert(s == "Test", "Test assert failed.") 60 | 61 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestEnum.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dskwdrnml8jeb 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestMap.gd.uid: -------------------------------------------------------------------------------- 1 | uid://vmtlthgbwfti 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestMath.gd: -------------------------------------------------------------------------------- 1 | class_name TestMath 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func test() -> void: 7 | if true: 8 | var tempLeft 9 | if true: 10 | var v: float = 2 * pow(PI, 2) 11 | tempLeft = int(ceil(v)) 12 | var cond: bool = tempLeft == 20 13 | assert(cond, "Test assert failed.") 14 | if true: 15 | var cond: bool = abs(-3) == 3 16 | assert(cond, "Test assert failed.") 17 | 18 | assert(3 == 3, "Test assert failed.") 19 | assert(1 == 1, "Test assert failed.") 20 | 21 | if true: 22 | var tempLeft1 23 | if true: 24 | var v: float = exp(1.0) 25 | tempLeft1 = int(ceil(v)) 26 | var cond: bool = tempLeft1 == 3 27 | assert(cond, "Test assert failed.") 28 | if true: 29 | var tempLeft2 30 | if true: 31 | var v: float = exp(1.0) 32 | tempLeft2 = int(floor(v)) 33 | var cond: bool = tempLeft2 == 2 34 | assert(cond, "Test assert failed.") 35 | 36 | assert(99 == 99, "Test assert failed.") 37 | assert(1.0 == 1.0, "Test assert failed.") 38 | 39 | if true: 40 | var cond: bool = is_finite(12) 41 | assert(cond, "Test assert failed.") 42 | if true: 43 | var cond: bool = is_nan(NAN) 44 | assert(cond, "Test assert failed.") 45 | if true: 46 | var cond: bool = !is_finite(INF) 47 | assert(cond, "Test assert failed.") 48 | if true: 49 | var cond: bool = !is_finite(-INF) 50 | assert(cond, "Test assert failed.") 51 | if true: 52 | var input: float = sin(PI) 53 | assert(abs(0.0 - input) < 0.0001, "Test assert failed.") 54 | if true: 55 | var input: float = cos(0) 56 | assert(abs(1 - input) < 0.0001, "Test assert failed.") 57 | if true: 58 | var input: float = tan(4) 59 | assert(abs(1.157821 - input) < 0.0001, "Test assert failed.") 60 | if true: 61 | var input: float = asin(1) 62 | assert(abs(1.570796 - input) < 0.0001, "Test assert failed.") 63 | if true: 64 | var input: float = acos(100) 65 | assert(abs(0 - input) < 0.0001, "Test assert failed.") 66 | if true: 67 | var input: float = atan(12) 68 | assert(abs(1.4876 - input) < 0.0001, "Test assert failed.") 69 | if true: 70 | var input: float = atan2(-3, 3) 71 | assert(abs(-0.78539 - input) < 0.0001, "Test assert failed.") 72 | if true: 73 | var input: float = log(10) 74 | assert(abs(2.30258 - input) < 0.0001, "Test assert failed.") 75 | if true: 76 | var cond: bool = sqrt(25) == 5 77 | assert(cond, "Test assert failed.") 78 | if true: 79 | var cond: bool = sqrt(100) == 10 80 | assert(cond, "Test assert failed.") 81 | 82 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestMath.gd.uid: -------------------------------------------------------------------------------- 1 | uid://co21n2htjyc3h 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestMeta.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | class_name TestMeta 3 | 4 | var prop: int = 123 5 | @export_enum("Hello", "World") 6 | var enumField: int = 0 7 | 8 | func _init() -> void: 9 | self.prop = 123 10 | 11 | static func test() -> void: 12 | var tm: TestMeta = TestMeta.new() 13 | var cond: bool = tm.prop == 123 14 | 15 | assert(cond, "Test assert failed.") 16 | 17 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestMeta.gd.uid: -------------------------------------------------------------------------------- 1 | uid://sn7nle4mycvp 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestNode.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | class_name TestNode 3 | 4 | @export 5 | var dictionary: Dictionary[String, String] = {} 6 | 7 | func _init() -> void: 8 | self.dictionary = {} 9 | 10 | func _ready() -> void: 11 | Log.trace.call(self.dictionary, { 12 | "fileName": "src/test/TestNode.hx", 13 | "lineNumber": 11, 14 | "className": "test.TestNode", 15 | "methodName": "_ready" 16 | }) 17 | 18 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestNode.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cx1b4may35vuv 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestReflect.gd: -------------------------------------------------------------------------------- 1 | class_name TestReflect 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func test() -> void: 7 | var obj: Variant = { 8 | "num": 123, 9 | "str": "String" 10 | } 11 | var cls: MyClass = MyClass.new() 12 | 13 | if true: 14 | var cond: bool = "num" in obj 15 | assert(cond, "Test assert failed.") 16 | if true: 17 | var cond: bool = !"dog" in obj 18 | assert(cond, "Test assert failed.") 19 | if true: 20 | var cond: bool = obj.get("str") == "String" 21 | assert(cond, "Test assert failed.") 22 | 23 | Reflect.setField(obj, "num", 444) 24 | 25 | if true: 26 | var cond: bool = obj.get("num") == 444 27 | assert(cond, "Test assert failed.") 28 | if true: 29 | var cond: bool = Reflect.getProperty(cls, "myProp") == 1 30 | assert(cond, "Test assert failed.") 31 | 32 | Reflect.setProperty(cls, "myProp", 10) 33 | 34 | if true: 35 | var cond: bool = Reflect.getProperty(cls, "myProp") == 10 36 | assert(cond, "Test assert failed.") 37 | 38 | var _func = func(a: int) -> int: 39 | return a + 123 40 | 41 | if true: 42 | var cond: bool = _func.callv(([100] as Array[Variant])) == 223 43 | assert(cond, "Test assert failed.") 44 | if true: 45 | var cond: bool = Reflect.fields(cls).size() == 4 46 | assert(cond, "Test assert failed.") 47 | if true: 48 | var cond: bool = !(obj as Variant) is Callable 49 | assert(cond, "Test assert failed.") 50 | if true: 51 | var cond: bool = (_func as Variant) is Callable 52 | assert(cond, "Test assert failed.") 53 | if true: 54 | var cond: bool = Reflect.compare(12, 14) == -1 55 | assert(cond, "Test assert failed.") 56 | 57 | assert(_func == _func, "Test assert failed.") 58 | 59 | if true: 60 | var cond: bool = !(obj as Variant) is Object 61 | assert(cond, "Test assert failed.") 62 | if true: 63 | var cond: bool = (obj as Variant) is Dictionary 64 | assert(cond, "Test assert failed.") 65 | 66 | var obj2 = Reflect.copy(obj) 67 | 68 | if true: 69 | var cond: bool = obj2.get("str") == obj.get("str") 70 | assert(cond, "Test assert failed.") 71 | 72 | Reflect.deleteField(obj, "num") 73 | 74 | if true: 75 | var cond: bool = obj.get("num") == null 76 | assert(cond, "Test assert failed.") 77 | 78 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestReflect.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dfeby3uh201r0 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestSignals.gd: -------------------------------------------------------------------------------- 1 | class_name TestSignals 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | signal my_signal(i: int) 7 | 8 | func do_test() -> void: 9 | connect("my_signal", self.test2) 10 | emit_signal("my_signal", 123) 11 | 12 | func test2(i: int) -> void: 13 | assert(i == 123, "Test assert failed.") 14 | 15 | static func test() -> void: 16 | var t: TestSignals = TestSignals.new() 17 | 18 | t.do_test() 19 | 20 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestSignals.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dxkm1k85042aj 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestStaticVar.gd: -------------------------------------------------------------------------------- 1 | class_name TestStaticVar 2 | 3 | static var count: int = 0 4 | 5 | func _init() -> void: 6 | count += 1 7 | 8 | static func test() -> void: 9 | count = 10 10 | 11 | if true: 12 | var cond: bool = count == 10 13 | assert(cond, "Test assert failed.") 14 | 15 | var list: Array[TestStaticVar] = ([] as Array[TestStaticVar]) 16 | 17 | list.push_back(TestStaticVar.new()) 18 | list.push_back(TestStaticVar.new()) 19 | list.push_back(TestStaticVar.new()) 20 | list.push_back(TestStaticVar.new()) 21 | list.push_back(TestStaticVar.new()) 22 | list.push_back(TestStaticVar.new()) 23 | list.push_back(TestStaticVar.new()) 24 | list.push_back(TestStaticVar.new()) 25 | list.push_back(TestStaticVar.new()) 26 | list.push_back(TestStaticVar.new()) 27 | 28 | if true: 29 | var cond: bool = count == 20 30 | assert(cond, "Test assert failed.") 31 | if true: 32 | var cond: bool = OtherClass._str.length() == 0 33 | assert(cond, "Test assert failed.") 34 | 35 | OtherClass.add.call() 36 | OtherClass.add.call() 37 | OtherClass.add.call() 38 | 39 | if true: 40 | var cond: bool = OtherClass._str.length() == 3 41 | assert(cond, "Test assert failed.") 42 | 43 | OtherClass.clear() 44 | 45 | if true: 46 | var cond: bool = OtherClass._str.length() == 0 47 | assert(cond, "Test assert failed.") 48 | 49 | var old = OtherClass.add 50 | 51 | OtherClass.add = func() -> void: 52 | old.call() 53 | old.call() 54 | OtherClass.add.call() 55 | 56 | if true: 57 | var cond: bool = OtherClass._str == "||" 58 | assert(cond, "Test assert failed.") 59 | 60 | if (OtherClass.add != null): 61 | assert(true, "Test assert failed.") 62 | else: 63 | assert(false, "Test assert failed.") 64 | 65 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestStaticVar.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bbut2cloib4qd 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestStd.gd: -------------------------------------------------------------------------------- 1 | class_name TestStd 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func test() -> void: 7 | var a: A = A.new() 8 | var b: B = B.new() 9 | 10 | if true: 11 | var cond: bool = ((a as Variant) is A) 12 | assert(cond, "Test assert failed.") 13 | if true: 14 | var cond: bool = ((b as Variant) is B) 15 | assert(cond, "Test assert failed.") 16 | if true: 17 | var cond: bool = !((a as Variant) is B) 18 | assert(cond, "Test assert failed.") 19 | if true: 20 | var cond: bool = !((b as Variant) is A) 21 | assert(cond, "Test assert failed.") 22 | 23 | var c: C = (b as C) 24 | 25 | assert(c == null, "Test assert failed.") 26 | 27 | if true: 28 | var cond: bool = str(123) == "123" 29 | assert(cond, "Test assert failed.") 30 | if true: 31 | var cond: bool = str(false) == "false" 32 | assert(cond, "Test assert failed.") 33 | if true: 34 | var cond: bool = StringTools.startsWith(str(a), "= 0 && r < 10, "Test assert failed.") 53 | 54 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestStd.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c041ea2qnbgwu 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestString.gd: -------------------------------------------------------------------------------- 1 | class_name TestString 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func test() -> void: 7 | var _str: String = "Test" 8 | 9 | assert(_str == "Test", "Test assert failed.") 10 | 11 | if true: 12 | var cond: bool = _str.length() == 4 13 | assert(cond, "Test assert failed.") 14 | if true: 15 | var cond: bool = _str == "Test" 16 | assert(cond, "Test assert failed.") 17 | if true: 18 | var cond: bool = char(70) == "F" 19 | assert(cond, "Test assert failed.") 20 | if true: 21 | var tempMaybeNumber 22 | if (1 >= 0 && 1 < _str.length()): 23 | tempMaybeNumber = _str.unicode_at(1) 24 | else: 25 | tempMaybeNumber = null 26 | var cond: bool = (tempMaybeNumber) == 101 27 | assert(cond, "Test assert failed.") 28 | if true: 29 | var cond: bool = _str.find("es") == 1 30 | assert(cond, "Test assert failed.") 31 | if true: 32 | var cond: bool = _str.find("Hey") == -1 33 | assert(cond, "Test assert failed.") 34 | if true: 35 | var cond: bool = _str.find("Te", 2) == -1 36 | assert(cond, "Test assert failed.") 37 | if true: 38 | var tempLeft 39 | if true: 40 | var startIndex: int = -1 41 | if (startIndex < 0): 42 | tempLeft = _str.rfind("Te") 43 | else: 44 | var tempString 45 | if true: 46 | var endIndex: int = startIndex + _str.length() 47 | if (endIndex < 0): 48 | tempString = _str.substr(0) 49 | else: 50 | tempString = _str.substr(0, endIndex - 0) 51 | tempLeft = (tempString).rfind("Te") 52 | var cond: bool = tempLeft == 0 53 | assert(cond, "Test assert failed.") 54 | if true: 55 | var cond: bool = Array(Array(_str.split("s")), Variant.Type.TYPE_STRING, "", null)[0] == "Te" 56 | assert(cond, "Test assert failed.") 57 | if true: 58 | var cond: bool = Array(Array(_str.split("e")), Variant.Type.TYPE_STRING, "", null).size() == 2 59 | assert(cond, "Test assert failed.") 60 | 61 | var str2: String = "Hello, World!" 62 | 63 | if true: 64 | var cond: bool = str2.substr(7, 5) == "World" 65 | assert(cond, "Test assert failed.") 66 | if true: 67 | var tempString1 68 | if (12 < 0): 69 | tempString1 = str2.substr(7) 70 | else: 71 | tempString1 = str2.substr(7, 12 - 7) 72 | var cond: bool = (tempString1) == "World" 73 | assert(cond, "Test assert failed.") 74 | if true: 75 | var cond: bool = str2.to_lower() == "hello, world!" 76 | assert(cond, "Test assert failed.") 77 | if true: 78 | var cond: bool = str2.to_upper() == "HELLO, WORLD!" 79 | assert(cond, "Test assert failed.") 80 | 81 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestString.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c0j4oqhu2obqm 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestSyntax.gd: -------------------------------------------------------------------------------- 1 | class_name TestSyntax 2 | 3 | var testField: int = 123 4 | 5 | func _init() -> void: 6 | assert(self.testField == 123, "Test assert failed.") 7 | 8 | static func test() -> void: 9 | assert(true, "Test assert failed.") 10 | assert(!false, "Test assert failed.") 11 | assert(1 + 1 == 2, "Test assert failed.") 12 | assert(1 - 1 == 0, "Test assert failed.") 13 | assert(2 * 2 == 4, "Test assert failed.") 14 | assert(10 / 2 == 5, "Test assert failed.") 15 | 16 | var myNull = null 17 | 18 | assert(myNull == null, "Test assert failed.") 19 | 20 | var obj: TestSyntax = TestSyntax.new() 21 | 22 | assert(obj == obj, "Test assert failed.") 23 | 24 | if true: 25 | var cond: bool = obj.testField == 123 26 | assert(cond, "Test assert failed.") 27 | 28 | var _str: String = "World" 29 | 30 | _str = "Hello, " + _str 31 | _str += "!" 32 | assert(_str == "Hello, World!", "Test assert failed.") 33 | 34 | if (_str != "Goodbye World!"): 35 | var num: int = 3 36 | assert(num > 1, "Test assert failed.") 37 | assert(num >= 3 && num >= 2, "Test assert failed.") 38 | assert(num == 3, "Test assert failed.") 39 | assert(num <= 3 && num <= 6, "Test assert failed.") 40 | assert(num < 4, "Test assert failed.") 41 | else: 42 | assert(false, "Test assert failed.") 43 | 44 | var num: int = 3 45 | 46 | assert((num & 1) == 1, "Test assert failed.") 47 | assert((num & 4) == 0, "Test assert failed.") 48 | assert((num | 8) == 11, "Test assert failed.") 49 | assert((num | 3) == 3, "Test assert failed.") 50 | assert(1 + 1 == 1 + 1, "Test assert failed.") 51 | 52 | var dict = { 53 | "hey": "Hey", 54 | "thing": obj, 55 | "number": 3 56 | } 57 | 58 | if true: 59 | var cond: bool = dict.hey == "Hey" 60 | assert(cond, "Test assert failed.") 61 | if true: 62 | var cond: bool = dict.number == 3 63 | assert(cond, "Test assert failed.") 64 | 65 | dict.pokemon = "Pikachu" 66 | 67 | if true: 68 | var cond: bool = dict.pokemon == "Pikachu" 69 | assert(cond, "Test assert failed.") 70 | 71 | var arr_0: int = 1 72 | var arr_1: int = 2 73 | var arr_2: int = 3 74 | 75 | assert(arr_1 == 2, "Test assert failed.") 76 | 77 | if true: 78 | var cond: bool = 3 == 3 79 | assert(cond, "Test assert failed.") 80 | 81 | var arr2: Array[int] = [] 82 | var _bool: bool = true 83 | 84 | assert(_bool, "Test assert failed.") 85 | 86 | var mutNum = [1000] 87 | 88 | mutNum[0] += 1 89 | mutNum[0] += 1 90 | 91 | if true: 92 | var tempLeft 93 | if true: 94 | mutNum[0] += 1 95 | tempLeft = mutNum[0] - 1 96 | var cond: bool = tempLeft == 1002 97 | assert(cond, "Test assert failed.") 98 | if true: 99 | var tempLeft1 100 | if true: 101 | mutNum[0] -= 1 102 | tempLeft1 = mutNum[0] 103 | var cond: bool = tempLeft1 == 1002 104 | assert(cond, "Test assert failed.") 105 | if true: 106 | var tempLeft2 107 | if true: 108 | mutNum[0] -= 1 109 | tempLeft2 = mutNum[0] 110 | var cond: bool = tempLeft2 == 1001 111 | assert(cond, "Test assert failed.") 112 | 113 | assert(mutNum[0] == 1001, "Test assert failed.") 114 | 115 | var myFunc = func() -> void: 116 | mutNum[0] += 1 117 | 118 | myFunc.call() 119 | myFunc.call() 120 | assert(mutNum[0] == 1003, "Test assert failed.") 121 | 122 | var a: int = 2 123 | var tempNumber: int = a * a 124 | var blockVal: int = tempNumber 125 | 126 | assert(blockVal == 4, "Test assert failed.") 127 | 128 | if (blockVal == 4): 129 | assert(true, "Test assert failed.") 130 | else: 131 | assert(false, "Test assert failed.") 132 | 133 | var i: int = 0 134 | 135 | while true: 136 | var tempLeft3 137 | i += 1 138 | tempLeft3 = i - 1 139 | if !(tempLeft3 < 1000): 140 | break 141 | if (i == 800): 142 | assert(i / 80 == 10, "Test assert failed.") 143 | 144 | var j: int = 0 145 | 146 | while true: 147 | var tempRight 148 | assert(true, "Test assert failed.") 149 | tempRight = 6 150 | if !(j < tempRight): 151 | break 152 | assert(true, "Test assert failed.") 153 | j += 1 154 | 155 | var anotherNum: int = 3 156 | var anotherNum2: int = anotherNum 157 | 158 | assert(anotherNum == anotherNum2, "Test assert failed.") 159 | anotherNum += 10 160 | anotherNum2 = anotherNum 161 | assert(anotherNum == anotherNum2, "Test assert failed.") 162 | 163 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestSyntax.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dtl4svssor1gk 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestSys.gd: -------------------------------------------------------------------------------- 1 | class_name TestSys 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func test() -> void: 7 | if true: 8 | var cond: bool = 0 == 0 9 | assert(cond, "Test assert failed.") 10 | 11 | var first: float = (Time.get_ticks_msec() * 1000) 12 | 13 | OS.delay_msec(0.1 * 1000) 14 | 15 | if true: 16 | var cond: bool = (Time.get_ticks_msec() * 1000) - first > 10000 17 | assert(cond, "Test assert failed.") 18 | 19 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/TestSys.gd.uid: -------------------------------------------------------------------------------- 1 | uid://egng1mr0h5io 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/_GeneratedFiles.txt: -------------------------------------------------------------------------------- 1 | version // 1 2 | 0//1 3 | test_TestStd_C.gd 4 | test_TestStd_B.gd 5 | test_TestStd_A.gd 6 | test_TestStaticVar_OtherClass.gd 7 | test_TestReflect_MyClass.gd 8 | test_TestEnum_MyGDEnum.gd 9 | test_MyAbstract_TemplateWrap.gd 10 | test_MyAbstract_MyVector.gd 11 | test_MyAbstract_MySpecialString.gd 12 | test_MyAbstract_MyReflect.gd 13 | test_MyAbstract_MyPoint3.gd 14 | test_MyAbstract_MyInt2.gd 15 | test_MyAbstract_MyInt.gd 16 | test_MyAbstract_MyHash.gd 17 | test_MyAbstract_MyDebugString.gd 18 | test_MyAbstract_MyClassWithAbstractArgCtor.gd 19 | test_MyAbstract_MyAbstractThatCallsAMember.gd 20 | test_MyAbstract_MyAbstractSetter.gd 21 | test_MyAbstract_MyAbstractCounter.gd 22 | test_MyAbstract_MyAbstractClosure.gd 23 | test_MyAbstract_Meter.gd 24 | test_MyAbstract_Kilometer.gd 25 | test_MyAbstract_ExposingAbstract.gd 26 | test_MyAbstract_ClassWithoutHashCode.gd 27 | test_MyAbstract_ClassWithHashCode.gd 28 | test_MyAbstract_AbstractZ.gd 29 | test_MyAbstract_AbstractBase.gd 30 | haxe_macro_Type_MethodKind.gd 31 | haxe_macro_Expr_Unop.gd 32 | haxe_macro_Expr_StringLiteralKind.gd 33 | haxe_macro_Expr_QuoteStatus.gd 34 | haxe_macro_Expr_Error.gd 35 | haxe_macro_Expr_EFieldKind.gd 36 | haxe_macro_Expr_Access.gd 37 | haxe_ds_List_ListNode.gd 38 | haxe_StringMap.gd 39 | haxe_PosException.gd 40 | haxe_ObjectMap.gd 41 | haxe_NotImplementedException.gd 42 | haxe_MapKeyValueIterator.gd 43 | haxe_List.gd 44 | haxe_IntMap.gd 45 | haxe_Encoding.gd 46 | haxe_ArrayKeyValueIterator.gd 47 | haxe_ArrayIterator.gd 48 | TestSys.gd 49 | TestSyntax.gd 50 | TestString.gd 51 | TestStd.gd 52 | TestStaticVar.gd 53 | TestSignals.gd 54 | TestReflect.gd 55 | TestNode.gd 56 | TestMeta.gd 57 | TestMath.gd 58 | TestMap.gd 59 | TestEnum.gd 60 | TestEReg.gd 61 | TestClass.gd 62 | TestArray.gd 63 | TestAll.gd 64 | Template.gd 65 | StringTools.gd 66 | StringBuf.gd 67 | Reflect.gd 68 | MyAbstract.gd 69 | Log.gd 70 | EReg.gd -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_ArrayIterator.gd: -------------------------------------------------------------------------------- 1 | class_name ArrayIterator 2 | 3 | var array: Array[Variant] 4 | var current: int = 0 5 | 6 | func _init(array2: Array[Variant]) -> void: 7 | self.array = array2 8 | 9 | func hasNext() -> bool: 10 | return self.current < self.array.size() 11 | 12 | func next(): 13 | self.current += 1 14 | 15 | var tempIndex: int = self.current - 1 16 | 17 | return self.array[tempIndex] 18 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_ArrayIterator.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c08ihw6uimcoy 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_ArrayKeyValueIterator.gd: -------------------------------------------------------------------------------- 1 | class_name ArrayKeyValueIterator 2 | 3 | var current: int = 0 4 | var array: Array[Variant] 5 | 6 | func _init(array2: Array[Variant]) -> void: 7 | self.array = array2 8 | 9 | func hasNext() -> bool: 10 | return self.current < self.array.size() 11 | 12 | func next() -> Variant: 13 | self.current += 1 14 | 15 | var tempNumber: int = self.current - 1 16 | 17 | return { 18 | "value": self.array[self.current], 19 | "key": tempNumber 20 | } 21 | 22 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_ArrayKeyValueIterator.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dec0hjtfqboji 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_Constraints_IMap.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dgowglvd03ih4 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_Encoding.gd: -------------------------------------------------------------------------------- 1 | class_name Encoding extends Object 2 | 3 | enum Encoding { 4 | UTF8, 5 | RawNative, 6 | } 7 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_Encoding.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cpd6e3kusw287 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_IntMap.gd: -------------------------------------------------------------------------------- 1 | class_name IntMap 2 | 3 | var m: Dictionary[int, Variant] 4 | 5 | func _init() -> void: 6 | self.m = {} 7 | 8 | func __set(key: int, value) -> void: 9 | self.m.set(key, value) 10 | 11 | func __get(key: int): 12 | var tempResult 13 | 14 | if (self.m.has(key)): 15 | tempResult = self.m.get(key) 16 | else: 17 | tempResult = null 18 | 19 | return tempResult 20 | 21 | func exists(key: int) -> bool: 22 | return self.m.has(key) 23 | 24 | func remove(key: int) -> bool: 25 | return self.m.erase(key) 26 | 27 | func keys() -> Variant: 28 | var _this: Array[int] = self.m.keys() 29 | var tempResult: ArrayIterator = ArrayIterator.new(_this) 30 | 31 | return tempResult 32 | 33 | func iterator() -> Variant: 34 | var _this: Array[Variant] = self.m.values() 35 | var tempResult: ArrayIterator = ArrayIterator.new(_this) 36 | 37 | return tempResult 38 | 39 | func keyValueIterator() -> Variant: 40 | return MapKeyValueIterator.new(self) 41 | 42 | func copy() -> IntMap: 43 | var result: IntMap = IntMap.new() 44 | 45 | result.m = self.m.duplicate(false) 46 | 47 | return result 48 | 49 | func toString() -> String: 50 | var result: String = "[" 51 | var first: bool = true 52 | var _g_map: Variant = self 53 | var _g_keys: Variant = self.keys() 54 | 55 | while (_g_keys.get("hasNext").call()): 56 | var _g_value 57 | var _g_key 58 | var key: int = _g_keys.get("next").call() 59 | _g_value = _g_map.__get(key) 60 | _g_key = key 61 | var key2: int = _g_key 62 | var value = _g_value 63 | var tempString 64 | if (first): 65 | tempString = "" 66 | else: 67 | tempString = ", " 68 | result += (tempString) + (str(key2) + " => " + str(value)) 69 | if (first): 70 | first = false 71 | 72 | return result + "]" 73 | 74 | func clear() -> void: 75 | self.m.clear() 76 | 77 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_IntMap.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bgqaybcf1lfyv 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_List.gd: -------------------------------------------------------------------------------- 1 | class_name List 2 | 3 | var h: ListNode 4 | var q: ListNode 5 | var length: int 6 | 7 | func _init() -> void: 8 | self.length = 0 9 | 10 | func add(item) -> void: 11 | var next: ListNode = null 12 | var tempListNode: ListNode = ListNode.new(item, next) 13 | var x: ListNode = tempListNode 14 | 15 | if (self.h == null): 16 | self.h = x 17 | else: 18 | self.q.next = x 19 | 20 | self.q = x 21 | self.length += 1 22 | 23 | func push(item) -> void: 24 | var next: ListNode = self.h 25 | var tempListNode: ListNode = ListNode.new(item, next) 26 | var x: ListNode = tempListNode 27 | 28 | self.h = x 29 | 30 | if (self.q == null): 31 | self.q = x 32 | 33 | self.length += 1 34 | 35 | func first(): 36 | var tempResult 37 | 38 | if (self.h == null): 39 | tempResult = null 40 | else: 41 | tempResult = self.h.item 42 | 43 | return tempResult 44 | 45 | func pop(): 46 | if (self.h == null): 47 | return null 48 | 49 | var x = self.h.item 50 | 51 | self.h = self.h.next 52 | 53 | if (self.h == null): 54 | self.q = null 55 | 56 | self.length -= 1 57 | 58 | return x 59 | 60 | func isEmpty() -> bool: 61 | return self.h == null 62 | 63 | func toString() -> String: 64 | var s_b: String = "" 65 | var first: bool = true 66 | var l: ListNode = self.h 67 | 68 | s_b += str("{") 69 | 70 | while (l != null): 71 | if (first): 72 | first = false 73 | else: 74 | s_b += str(", ") 75 | var x: String = str(l.item) 76 | s_b += str(x) 77 | l = l.next 78 | 79 | s_b += str("}") 80 | 81 | return s_b 82 | 83 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_List.gd.uid: -------------------------------------------------------------------------------- 1 | uid://il254xt370us 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_MapKeyValueIterator.gd: -------------------------------------------------------------------------------- 1 | class_name MapKeyValueIterator 2 | 3 | var map: Variant 4 | var keys: Variant 5 | 6 | func _init(map2: Variant) -> void: 7 | self.map = map2 8 | self.keys = map2.keys() 9 | 10 | func hasNext() -> bool: 11 | return self.keys.get("hasNext").call() 12 | 13 | func next() -> Variant: 14 | var key = self.keys.get("next").call() 15 | 16 | return { 17 | "value": self.map.__get(key), 18 | "key": key 19 | } 20 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_MapKeyValueIterator.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bgj4p3rntne0c 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_NotImplementedException.gd: -------------------------------------------------------------------------------- 1 | extends PosException 2 | class_name NotImplementedException 3 | 4 | func _init(message: String = "Not implemented", previous = null, pos = null) -> void: 5 | super(message, previous, pos) 6 | 7 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_NotImplementedException.gd.uid: -------------------------------------------------------------------------------- 1 | uid://2hjb4v8jt5lo 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_ObjectMap.gd: -------------------------------------------------------------------------------- 1 | class_name ObjectMap 2 | 3 | var m: Dictionary[Variant, Variant] 4 | 5 | func _init() -> void: 6 | self.m = {} 7 | 8 | func __set(key, value) -> void: 9 | self.m.set(key, value) 10 | 11 | func __get(key): 12 | var tempResult 13 | 14 | if (self.m.has(key)): 15 | tempResult = self.m.get(key) 16 | else: 17 | tempResult = null 18 | 19 | return tempResult 20 | 21 | func exists(key) -> bool: 22 | return self.m.has(key) 23 | 24 | func remove(key) -> bool: 25 | return self.m.erase(key) 26 | 27 | func keys() -> Variant: 28 | var _this: Array[Variant] = self.m.keys() 29 | var tempResult: ArrayIterator = ArrayIterator.new(_this) 30 | 31 | return tempResult 32 | 33 | func iterator() -> Variant: 34 | var _this: Array[Variant] = self.m.values() 35 | var tempResult: ArrayIterator = ArrayIterator.new(_this) 36 | 37 | return tempResult 38 | 39 | func keyValueIterator() -> Variant: 40 | return MapKeyValueIterator.new(self) 41 | 42 | func copy() -> ObjectMap: 43 | var result: ObjectMap = ObjectMap.new() 44 | 45 | result.m = self.m.duplicate(false) 46 | 47 | return result 48 | 49 | func toString() -> String: 50 | var result: String = "[" 51 | var first: bool = true 52 | var _g_map: Variant = self 53 | var _g_keys: Variant = self.keys() 54 | 55 | while (_g_keys.get("hasNext").call()): 56 | var _g_value 57 | var _g_key 58 | var key = _g_keys.get("next").call() 59 | _g_value = _g_map.__get(key) 60 | _g_key = key 61 | var key2 = _g_key 62 | var value = _g_value 63 | var tempString 64 | if (first): 65 | tempString = "" 66 | else: 67 | tempString = ", " 68 | result += (tempString) + (str(key2) + " => " + str(value)) 69 | if (first): 70 | first = false 71 | 72 | return result + "]" 73 | 74 | func clear() -> void: 75 | self.m.clear() 76 | 77 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_ObjectMap.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cffihly4esjio 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_PosException.gd: -------------------------------------------------------------------------------- 1 | extends Exception 2 | class_name PosException 3 | 4 | var posInfos: Variant 5 | 6 | func _init(message: String, previous = null, pos = null) -> void: 7 | super(message, previous) 8 | 9 | if (pos == null): 10 | self.posInfos = { 11 | "fileName": "(unknown)", 12 | "lineNumber": 0, 13 | "className": "(unknown)", 14 | "methodName": "(unknown)" 15 | } 16 | else: 17 | self.posInfos = pos 18 | 19 | func toString() -> String: 20 | return "" + super.toString() + " in " + self.posInfos.get("className") + "." + self.posInfos.get("methodName") + " at " + self.posInfos.get("fileName") + ":" + str(self.posInfos.get("lineNumber")) 21 | 22 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_PosException.gd.uid: -------------------------------------------------------------------------------- 1 | uid://d222ngdbovato 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_StringMap.gd: -------------------------------------------------------------------------------- 1 | class_name StringMap 2 | 3 | var m: Dictionary[String, Variant] 4 | 5 | func _init() -> void: 6 | self.m = {} 7 | 8 | func __set(key: String, value) -> void: 9 | self.m.set(key, value) 10 | 11 | func __get(key: String): 12 | var tempResult 13 | 14 | if (self.m.has(key)): 15 | tempResult = self.m.get(key) 16 | else: 17 | tempResult = null 18 | 19 | return tempResult 20 | 21 | func exists(key: String) -> bool: 22 | return self.m.has(key) 23 | 24 | func remove(key: String) -> bool: 25 | return self.m.erase(key) 26 | 27 | func keys() -> Variant: 28 | var _this: Array[String] = self.m.keys() 29 | var tempResult: ArrayIterator = ArrayIterator.new(_this) 30 | 31 | return tempResult 32 | 33 | func iterator() -> Variant: 34 | var _this: Array[Variant] = self.m.values() 35 | var tempResult: ArrayIterator = ArrayIterator.new(_this) 36 | 37 | return tempResult 38 | 39 | func keyValueIterator() -> Variant: 40 | return MapKeyValueIterator.new(self) 41 | 42 | func copy() -> StringMap: 43 | var result: StringMap = StringMap.new() 44 | 45 | result.m = self.m.duplicate(false) 46 | 47 | return result 48 | 49 | func toString() -> String: 50 | var result: String = "[" 51 | var first: bool = true 52 | var _g_map: Variant = self 53 | var _g_keys: Variant = self.keys() 54 | 55 | while (_g_keys.get("hasNext").call()): 56 | var _g_value 57 | var _g_key 58 | var key: String = _g_keys.get("next").call() 59 | _g_value = _g_map.__get(key) 60 | _g_key = key 61 | var key2: String = _g_key 62 | var value = _g_value 63 | var tempString 64 | if (first): 65 | tempString = "" 66 | else: 67 | tempString = ", " 68 | result += (tempString) + (str(key2) + " => " + str(value)) 69 | if (first): 70 | first = false 71 | 72 | return result + "]" 73 | 74 | func clear() -> void: 75 | self.m.clear() 76 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_StringMap.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cnnxrfqctwa3y 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_ds_List_ListNode.gd: -------------------------------------------------------------------------------- 1 | class_name ListNode 2 | 3 | var item 4 | var next: ListNode 5 | 6 | func _init(item2, next2: ListNode) -> void: 7 | self.item = item2 8 | self.next = next2 9 | 10 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_ds_List_ListNode.gd.uid: -------------------------------------------------------------------------------- 1 | uid://gfbaqq2fksx6 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_Access.gd: -------------------------------------------------------------------------------- 1 | class_name Access extends Object 2 | 3 | enum Access { 4 | APublic, 5 | APrivate, 6 | AStatic, 7 | AOverride, 8 | ADynamic, 9 | AInline, 10 | AMacro, 11 | AFinal, 12 | AExtern, 13 | AAbstract, 14 | AOverload, 15 | } 16 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_Access.gd.uid: -------------------------------------------------------------------------------- 1 | uid://d4kcumjqhc5ky 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_EFieldKind.gd: -------------------------------------------------------------------------------- 1 | class_name EFieldKind extends Object 2 | 3 | enum EFieldKind { 4 | Normal, 5 | Safe, 6 | } 7 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_EFieldKind.gd.uid: -------------------------------------------------------------------------------- 1 | uid://t07eaki8a107 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_Error.gd: -------------------------------------------------------------------------------- 1 | extends Exception 2 | class_name Error 3 | 4 | var pos: Variant 5 | 6 | func _init(message: String, pos2: Variant, previous = null) -> void: 7 | super(message, previous) 8 | self.pos = pos2 9 | 10 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_Error.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bekn2xafrcfpf 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_QuoteStatus.gd: -------------------------------------------------------------------------------- 1 | class_name QuoteStatus extends Object 2 | 3 | enum QuoteStatus { 4 | Unquoted, 5 | Quoted, 6 | } 7 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_QuoteStatus.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cod7x3i77ungk 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_StringLiteralKind.gd: -------------------------------------------------------------------------------- 1 | class_name StringLiteralKind extends Object 2 | 3 | enum StringLiteralKind { 4 | DoubleQuotes, 5 | SingleQuotes, 6 | } 7 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_StringLiteralKind.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ytavs6hkpnrq 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_Unop.gd: -------------------------------------------------------------------------------- 1 | class_name Unop extends Object 2 | 3 | enum Unop { 4 | OpIncrement, 5 | OpDecrement, 6 | OpNot, 7 | OpNeg, 8 | OpNegBits, 9 | OpSpread, 10 | } 11 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Expr_Unop.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cc0ax1my8anxd 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Type_MethodKind.gd: -------------------------------------------------------------------------------- 1 | class_name MethodKind extends Object 2 | 3 | enum MethodKind { 4 | MethNormal, 5 | MethInline, 6 | MethDynamic, 7 | MethMacro, 8 | } 9 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/haxe_macro_Type_MethodKind.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dl27jdb5svsl5 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_AbstractBase.gd: -------------------------------------------------------------------------------- 1 | class_name AbstractBase 2 | 3 | var value 4 | 5 | func _init(value2) -> void: 6 | self.value = value2 7 | 8 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_AbstractBase.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cd780vg2w8e6l 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_AbstractZ.gd: -------------------------------------------------------------------------------- 1 | class_name AbstractZ_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func toFoo(a: AbstractBase) -> int: 7 | return a.value 8 | 9 | static func toString(a: AbstractBase) -> String: 10 | return a.value 11 | 12 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_AbstractZ.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cc25esq5ap1bo 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_ClassWithHashCode.gd: -------------------------------------------------------------------------------- 1 | class_name ClassWithHashCode 2 | 3 | var i: int 4 | 5 | func _init(i2: int) -> void: 6 | self.i = i2 7 | 8 | func hashCode() -> int: 9 | return self.i 10 | 11 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_ClassWithHashCode.gd.uid: -------------------------------------------------------------------------------- 1 | uid://jjjc4j42kn4e 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_ClassWithoutHashCode.gd: -------------------------------------------------------------------------------- 1 | class_name ClassWithoutHashCode 2 | 3 | var i: int 4 | 5 | func _init(i2: int) -> void: 6 | self.i = i2 7 | 8 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_ClassWithoutHashCode.gd.uid: -------------------------------------------------------------------------------- 1 | uid://df5xcdkhhx6wr 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_ExposingAbstract.gd: -------------------------------------------------------------------------------- 1 | class_name ExposingAbstract_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func _new() -> Array[Variant]: 7 | var this1: Array[Variant] = ([] as Array[Variant]) 8 | 9 | return this1 10 | 11 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_ExposingAbstract.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bagfabuu5f2bf 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_Kilometer.gd: -------------------------------------------------------------------------------- 1 | class_name Kilometer_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func _new(f: float) -> float: 7 | var this1: float = f 8 | 9 | return this1 10 | 11 | static func toString(this1: float) -> String: 12 | return str(this1) + "km" 13 | 14 | static func fromMeter(m: float) -> float: 15 | var this1: float = m / 1000. 16 | var tempResult: float = this1 17 | 18 | return tempResult 19 | 20 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_Kilometer.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bawvm0tw7exqi 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_Meter.gd: -------------------------------------------------------------------------------- 1 | class_name Meter_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func _new(f: float) -> float: 7 | var this1: float = f 8 | 9 | return this1 10 | 11 | static func __get(this1: float) -> float: 12 | return this1 13 | 14 | static func toString(this1: float) -> String: 15 | return str(this1) + "m" 16 | 17 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_Meter.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cvd0qfg2umhfr 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyAbstractClosure.gd: -------------------------------------------------------------------------------- 1 | class_name MyAbstractClosure_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func _new(value: String) -> String: 7 | var this1: String = value 8 | 9 | return this1 10 | 11 | static func test(this1: String): 12 | var fn = func() -> String: 13 | return this1 14 | 15 | return fn 16 | 17 | static func setVal(this1: String, v: String) -> void: 18 | this1 = v 19 | 20 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyAbstractClosure.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cfv5kef1k7sfe 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyAbstractCounter.gd: -------------------------------------------------------------------------------- 1 | class_name MyAbstractCounter_Impl_ 2 | 3 | static var counter: int = 0 4 | 5 | func _init() -> void: 6 | pass 7 | 8 | static func _new(v: int) -> int: 9 | var this1: int = v 10 | 11 | counter += 1 12 | 13 | return this1 14 | 15 | static func fromInt(v: int) -> int: 16 | var this1: int = v 17 | 18 | counter += 1 19 | 20 | var tempResult: int = this1 21 | 22 | return tempResult 23 | 24 | static func getValue(this1: int) -> int: 25 | return this1 + 1 26 | 27 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyAbstractCounter.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c70qoj8bkub3c 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyAbstractSetter.gd: -------------------------------------------------------------------------------- 1 | class_name MyAbstractSetter_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func _new(): 7 | var this1 = { 8 | } 9 | 10 | return this1 11 | 12 | static func get_value(this1) -> String: 13 | return this1.value 14 | 15 | static func set_value(this1, s: String) -> String: 16 | this1.value = s 17 | 18 | return s 19 | 20 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyAbstractSetter.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dey1dqgrsx4ca 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyAbstractThatCallsAMember.gd: -------------------------------------------------------------------------------- 1 | class_name MyAbstractThatCallsAMember_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func _new(i: int) -> int: 7 | var this1: int = i 8 | 9 | this1 += 1 10 | 11 | return this1 12 | 13 | static func bar(this1: int) -> void: 14 | this1 += 1 15 | 16 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyAbstractThatCallsAMember.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cbpsu4m352km6 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyClassWithAbstractArgCtor.gd: -------------------------------------------------------------------------------- 1 | class_name MyClassWithAbstractArgCtor 2 | 3 | var km: float 4 | 5 | func _init(km2: float) -> void: 6 | self.km = km2 7 | 8 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyClassWithAbstractArgCtor.gd.uid: -------------------------------------------------------------------------------- 1 | uid://b8g2xdwkq08v1 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyDebugString.gd: -------------------------------------------------------------------------------- 1 | class_name MyDebugString_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func _new(s: String) -> String: 7 | var this1: String = s 8 | 9 | return this1 10 | 11 | static func substr(this1: String, i: int, len = null) -> String: 12 | return this1.substr(i) 13 | 14 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyDebugString.gd.uid: -------------------------------------------------------------------------------- 1 | uid://qildpq4i84ir 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyHash.gd: -------------------------------------------------------------------------------- 1 | class_name MyHash_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func _new() -> StringMap: 7 | var this1: StringMap = StringMap.new() 8 | 9 | return this1 10 | 11 | static func __set(this1: StringMap, k: String, v) -> void: 12 | this1.__set(k, v) 13 | 14 | static func __get(this1: StringMap, k: String): 15 | return this1.__get(k) 16 | 17 | static func toString(this1: StringMap) -> String: 18 | return this1.toString() 19 | 20 | static func fromStringArray(arr: Array[String]) -> StringMap: 21 | var this1: StringMap = StringMap.new() 22 | var tempMyHash: StringMap = this1 23 | var i: int = 0 24 | 25 | while (i < arr.size()): 26 | var tempIndex 27 | i += 1 28 | tempIndex = i - 1 29 | var k: String = arr[tempIndex] 30 | var tempIndex1 31 | i += 1 32 | tempIndex1 = i - 1 33 | var v: String = arr[tempIndex1] 34 | tempMyHash.__set(k, v) 35 | 36 | return tempMyHash 37 | 38 | static func fromArray(arr: Array[Variant]) -> StringMap: 39 | var this1: StringMap = StringMap.new() 40 | var tempMyHash: StringMap = this1 41 | var i: int = 0 42 | 43 | while (i < arr.size()): 44 | var tempIndex 45 | i += 1 46 | tempIndex = i - 1 47 | var k = arr[tempIndex] 48 | var tempIndex1 49 | i += 1 50 | tempIndex1 = i - 1 51 | var v = arr[tempIndex1] 52 | var k2: String = str("_s" + str(k)) 53 | tempMyHash.__set(k2, v) 54 | 55 | return tempMyHash 56 | 57 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyHash.gd.uid: -------------------------------------------------------------------------------- 1 | uid://d4nruefiwn6fo 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyInt.gd: -------------------------------------------------------------------------------- 1 | class_name MyInt_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func repeat(lhs: int, rhs: String) -> String: 7 | var s_b: String = "" 8 | var _g: int = 0 9 | var _g1: int = lhs 10 | 11 | while (_g < _g1): 12 | var tempNumber 13 | _g += 1 14 | tempNumber = _g - 1 15 | var i: int = tempNumber 16 | s_b += str(rhs) 17 | 18 | return s_b 19 | 20 | static func cut(lhs: String, rhs: int) -> String: 21 | return lhs.substr(0, rhs) 22 | 23 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyInt.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bbmhj4j8ekccp 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyInt2.gd: -------------------------------------------------------------------------------- 1 | class_name MyInt2_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func _new(v: int) -> int: 7 | var this1: int = v 8 | 9 | return this1 10 | 11 | static func __get(this1: int) -> int: 12 | return this1 13 | 14 | static func invert(this1: int) -> int: 15 | var this2: int = -this1 16 | var tempResult: int = this2 17 | 18 | return tempResult 19 | 20 | static func incr(this1: int) -> void: 21 | this1 += 1 22 | 23 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyInt2.gd.uid: -------------------------------------------------------------------------------- 1 | uid://vkbtn063pmgp 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyPoint3.gd: -------------------------------------------------------------------------------- 1 | class_name MyPoint3 2 | 3 | var x: float 4 | var y: float 5 | var z: float 6 | 7 | func _init(x2: float, y2: float, z2: float) -> void: 8 | self.x = x2 9 | self.y = y2 10 | self.z = z2 11 | 12 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyPoint3.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bwogrxehkh8md 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyReflect.gd: -------------------------------------------------------------------------------- 1 | class_name MyReflect_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func arrayAccess(this1: Variant, key: String): 7 | return this1.get(key) 8 | 9 | static func arrayWrite(this1: Variant, key: String, value): 10 | Reflect.setField(this1, key, value) 11 | 12 | return value 13 | 14 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyReflect.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cpe0arx5qmn5t 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MySpecialString.gd: -------------------------------------------------------------------------------- 1 | class_name MySpecialString_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func substr(this1: String, i: int, len = null) -> String: 7 | var tempResult 8 | 9 | if (len == null): 10 | tempResult = this1.substr(i) 11 | else: 12 | tempResult = this1.substr(i, len) 13 | 14 | return tempResult 15 | 16 | static func toNormal(t: String, value: String) -> String: 17 | var this1: String = value 18 | var tempResult: String = this1 19 | 20 | return tempResult 21 | 22 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MySpecialString.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bbb0ye0bsxr18 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyVector.gd: -------------------------------------------------------------------------------- 1 | class_name MyVector_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func get_x(this1: MyPoint3) -> float: 7 | return this1.x 8 | 9 | static func get_y(this1: MyPoint3) -> float: 10 | return this1.y 11 | 12 | static func get_z(this1: MyPoint3) -> float: 13 | return this1.z 14 | 15 | static func set_x(this1: MyPoint3, x: float) -> float: 16 | this1.x = x 17 | 18 | return this1.x 19 | 20 | static func set_y(this1: MyPoint3, y: float) -> float: 21 | this1.y = y 22 | 23 | return this1.y 24 | 25 | static func set_z(this1: MyPoint3, z: float) -> float: 26 | this1.z = z 27 | 28 | return this1.z 29 | 30 | static func add(lhs: MyPoint3, rhs: MyPoint3) -> MyPoint3: 31 | return MyPoint3.new(MyVector_Impl_.get_x(lhs) + MyVector_Impl_.get_x(rhs), MyVector_Impl_.get_y(lhs) + MyVector_Impl_.get_y(rhs), MyVector_Impl_.get_z(lhs) + MyVector_Impl_.get_z(rhs)) 32 | 33 | static func scalarAssign(lhs: MyPoint3, rhs: float) -> MyPoint3: 34 | MyVector_Impl_.set_x(lhs, MyVector_Impl_.get_x(lhs) * rhs) 35 | MyVector_Impl_.set_y(lhs, MyVector_Impl_.get_y(lhs) * rhs) 36 | MyVector_Impl_.set_z(lhs, MyVector_Impl_.get_z(lhs) * rhs) 37 | 38 | return lhs 39 | 40 | static func scalar(lhs: MyPoint3, rhs: float) -> MyPoint3: 41 | return MyPoint3.new(MyVector_Impl_.get_x(lhs) * rhs, MyVector_Impl_.get_y(lhs) * rhs, MyVector_Impl_.get_z(lhs) * rhs) 42 | 43 | static func invert(t: MyPoint3) -> MyPoint3: 44 | return MyPoint3.new(-MyVector_Impl_.get_x(t), -MyVector_Impl_.get_y(t), -MyVector_Impl_.get_z(t)) 45 | 46 | static func __get(this1: MyPoint3) -> MyPoint3: 47 | return this1 48 | 49 | static func toString(this1: MyPoint3) -> String: 50 | return "(" + str(this1.x) + "," + str(this1.y) + "," + str(this1.z) + ")" 51 | 52 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_MyVector.gd.uid: -------------------------------------------------------------------------------- 1 | uid://b87aoqwkfrurx 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_TemplateWrap.gd: -------------------------------------------------------------------------------- 1 | class_name TemplateWrap_Impl_ 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | static func _new(x: String) -> Template: 7 | var this1: Template = Template.new(x) 8 | 9 | return this1 10 | 11 | static func __get(this1: Template) -> Template: 12 | return this1 13 | 14 | static func fromString(s: String) -> Template: 15 | var this1: Template = Template.new(s) 16 | var tempResult: Template = this1 17 | 18 | return tempResult 19 | 20 | static func toString(this1: Template) -> String: 21 | return this1.execute({ 22 | "t": "really works!" 23 | }, null) 24 | 25 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_MyAbstract_TemplateWrap.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cyxua17ul41i5 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestEnum_MyGDEnum.gd: -------------------------------------------------------------------------------- 1 | class_name MyGDEnum extends Object 2 | 3 | enum MyGDEnum { 4 | Rock, 5 | Paper, 6 | Scissors, 7 | } 8 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestEnum_MyGDEnum.gd.uid: -------------------------------------------------------------------------------- 1 | uid://d20cgauir711b 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestReflect_MyClass.gd: -------------------------------------------------------------------------------- 1 | class_name MyClass 2 | 3 | var internalProp: int = 1 4 | 5 | func _init() -> void: 6 | self.internalProp = 1 7 | 8 | func get_myProp() -> int: 9 | return self.internalProp 10 | 11 | func set_myProp(v: int) -> int: 12 | self.internalProp = v 13 | 14 | return self.internalProp 15 | 16 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestReflect_MyClass.gd.uid: -------------------------------------------------------------------------------- 1 | uid://rcj1t3772ncy 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestStaticVar_OtherClass.gd: -------------------------------------------------------------------------------- 1 | class_name OtherClass 2 | 3 | static var _str: String = "" 4 | static var add = func() -> void: 5 | _str += "|" 6 | 7 | func _init() -> void: 8 | pass 9 | 10 | static func clear() -> void: 11 | _str = "" 12 | 13 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestStaticVar_OtherClass.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dh0ulmby58p0s 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestStd_A.gd: -------------------------------------------------------------------------------- 1 | class_name A 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestStd_A.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ewu3jf6pq7rc 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestStd_B.gd: -------------------------------------------------------------------------------- 1 | class_name B 2 | 3 | func _init() -> void: 4 | pass 5 | 6 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestStd_B.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ge7lcl1ttcty 2 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestStd_C.gd: -------------------------------------------------------------------------------- 1 | extends B 2 | class_name C 3 | 4 | func _init() -> void: 5 | pass 6 | 7 | -------------------------------------------------------------------------------- /test/godot_project/gdscript/out/test_TestStd_C.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dor4231via4tv 2 | -------------------------------------------------------------------------------- /test/godot_project/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/godot_project/icon.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://cnixy31gmknf" 6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.svg" 14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | svg/scale=1.0 36 | editor/scale_with_editor_scale=false 37 | editor/convert_colors_with_editor_theme=false 38 | -------------------------------------------------------------------------------- /test/godot_project/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | [application] 12 | 13 | config/name="Haxe-to-GDScript-Test" 14 | run/main_scene="res://test_scene.tscn" 15 | config/features=PackedStringArray("4.4", "GL Compatibility") 16 | config/icon="res://icon.svg" 17 | 18 | [rendering] 19 | 20 | rendering_device/driver.windows="d3d12" 21 | -------------------------------------------------------------------------------- /test/godot_project/test_scene.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://b2ov0mlfa2u6n"] 2 | 3 | [ext_resource type="Script" uid="uid://ct7urpn1juqu1" path="res://gdscript/Test.gd" id="1_s5uoa"] 4 | [ext_resource type="Script" uid="uid://cx1b4may35vuv" path="res://gdscript/out/TestNode.gd" id="2_ia1lp"] 5 | 6 | [node name="Node2D" type="Node2D"] 7 | script = ExtResource("1_s5uoa") 8 | 9 | [node name="TestNode" type="Node" parent="."] 10 | script = ExtResource("2_ia1lp") 11 | dictionary = Dictionary[String, String]({ 12 | "What is this?": "This is a added in editor! Success!!" 13 | }) 14 | metadata/_custom_type_script = "uid://cx1b4may35vuv" 15 | -------------------------------------------------------------------------------- /test/src/Assert.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | @:native("assert") 4 | extern function godot_assert(cond: Bool, errMsg: Null = null): Void; 5 | 6 | extern inline function assert(cond: Bool, errMsg: String = "Test assert failed.") { 7 | godot_assert(cond, errMsg); 8 | } 9 | 10 | extern inline function assertFloat(input: Float, actual: Float, errMsg: String = "Test assert failed.") { 11 | godot_assert(Math.abs(actual - input) < 0.0001, errMsg); 12 | } 13 | -------------------------------------------------------------------------------- /test/src/test/HelperMacros.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import haxe.macro.Expr; 4 | import haxe.macro.Context.*; 5 | import haxe.macro.TypeTools.*; 6 | import haxe.macro.MacroStringTools.*; 7 | 8 | class HelperMacros { 9 | static public macro function getCompilationDate() { 10 | return macro $v { Std.string(Date.now()) }; 11 | } 12 | 13 | static public macro function typeString(e) { 14 | var typed = typeExpr(e); 15 | var s = haxe.macro.TypeTools.toString(typed.t); 16 | return macro $v{s}; 17 | } 18 | 19 | static public macro function typedAs(actual:haxe.macro.Expr, expected:haxe.macro.Expr) { 20 | var tExpected = typeof(expected); 21 | var tActual = typeof(actual); 22 | return parse("assert('" +Std.string(tActual) + "' == '" +Std.string(tExpected) + "')", currentPos()); 23 | } 24 | 25 | static public macro function isNullable(expr:haxe.macro.Expr) { 26 | var t = typeof(expr); 27 | function isNullable(t:haxe.macro.Type) { 28 | return switch (t) { 29 | case TMono(null): false; 30 | case TMono(t): isNullable(t.get()); 31 | case TAbstract(_.get() => {pack: [], name: "Null"}, _): true; 32 | case TLazy(f): isNullable(f()); 33 | case TType(_.get() => td, tl): isNullable(applyTypeParameters(td.type, td.params, tl)); 34 | case TFun(_): false; 35 | case TAbstract(_.get() => a, _) if (a.meta.has(":coreType")): !a.meta.has(":notNull"); 36 | case TAbstract(_.get() => a, tl): !a.meta.has(":notNull") && isNullable(applyTypeParameters(a.type, a.params, tl)); 37 | case _: true; 38 | } 39 | } 40 | return macro $v{isNullable(t)}; 41 | } 42 | 43 | static public macro function typeError(e:haxe.macro.Expr) { 44 | var result = try { 45 | typeof(e); 46 | "false"; 47 | } catch (e:Dynamic) "true"; 48 | return { pos: currentPos(), expr: haxe.macro.Expr.ExprDef.EConst(haxe.macro.Expr.Constant.CIdent(result)) }; 49 | } 50 | 51 | @:access(haxe.macro.Error.childErrors) 52 | static public macro function typeErrorText(e:haxe.macro.Expr) { 53 | var result = try { 54 | typeof(e); 55 | null; 56 | } catch (e:haxe.macro.Expr.Error) { 57 | var msg = e.message; 58 | if (e.childErrors != null) for (c in e.childErrors) msg += "\n" + c.message; 59 | msg; 60 | } 61 | return { 62 | pos: currentPos(), 63 | expr: if (result == null) 64 | haxe.macro.Expr.ExprDef.EConst(haxe.macro.Expr.Constant.CIdent("null")) 65 | else 66 | haxe.macro.Expr.ExprDef.EConst(haxe.macro.Expr.Constant.CString(result)) 67 | }; 68 | } 69 | 70 | static public macro function getMeta(e) { 71 | switch(e.expr) { 72 | case EMeta(m, _): 73 | return macro { name: $v{m.name}, args: $a{m.params} }; 74 | default: 75 | return macro report("Metadata expected"); 76 | } 77 | } 78 | 79 | static public macro function getErrorMessage(e:Expr) { 80 | var result = try { 81 | typeof(e); 82 | "no error"; 83 | } catch (e:haxe.Exception) Std.string(e.message); 84 | return macro $v{result}; 85 | } 86 | 87 | static public macro function parseAndPrint(s:String) { 88 | var e = parse(s, currentPos()); 89 | var s2 = new haxe.macro.Printer().printExpr(e); 90 | return macro eq($v{s}, $v{s2}); 91 | } 92 | 93 | static public macro function pipeMarkupLiteral(e:Expr) { 94 | function loop(e:Expr) { 95 | return switch (e) { 96 | case macro @:markup $v{(s:String)}: 97 | formatString(s, e.pos); 98 | case macro $b{el}: 99 | el = el.map(loop); 100 | macro $a{el}.join(""); 101 | case _: 102 | error("Markup literal expected", e.pos); 103 | } 104 | } 105 | return loop(e); 106 | } 107 | 108 | static public macro function pipeMarkupLiteralUnprocessed(e:Expr) { 109 | return switch (e) { 110 | case macro @:markup $v{(s:String)}: 111 | macro $v{s}; 112 | case _: 113 | error("Markup literal expected", e.pos); 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /test/src/test/MyAbstract.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | abstract MyAbstract(Int) { 4 | 5 | public inline function new(x) { 6 | this = x; 7 | } 8 | 9 | public inline function incr() { 10 | return ++this; 11 | } 12 | 13 | public inline function toInt() : Int { 14 | return this; 15 | } 16 | 17 | } 18 | 19 | abstract TemplateWrap(haxe.Template) { 20 | public inline function new(x) { 21 | this = new haxe.Template(x); 22 | } 23 | 24 | public inline function get() 25 | return this; 26 | 27 | @:from static inline public function fromString(s:String) { 28 | return new TemplateWrap(s); 29 | } 30 | 31 | @:to inline function toString() { 32 | return this.execute( { t: "really works!"}); 33 | } 34 | } 35 | 36 | abstract Meter(Float) from Float to Float { 37 | public inline function new(f) 38 | this = f; 39 | 40 | public inline function get() 41 | return this; 42 | 43 | @:to public inline function toString() 44 | return this + "m"; 45 | } 46 | 47 | abstract Kilometer(Float) from Float to Float { 48 | public inline function new(f) 49 | this = f; 50 | 51 | @:to public inline function toString() 52 | return this + "km"; 53 | 54 | @:from static public inline function fromMeter(m:Meter) 55 | return new Kilometer(m.get() / 1000.); 56 | } 57 | 58 | 59 | class MyClassWithAbstractArgCtor { 60 | public var km:Kilometer; 61 | public function new(km:Kilometer) { 62 | this.km = km; 63 | } 64 | } 65 | 66 | abstract MyHash(haxe.ds.StringMap) { 67 | private inline function new() { 68 | this = new haxe.ds.StringMap(); 69 | } 70 | public inline function set(k:String, v:V) 71 | this.set(k, v); 72 | public inline function get(k:String) 73 | return this.get(k); 74 | public inline function toString() 75 | return this.toString(); 76 | 77 | @:from static public function fromStringArray(arr:Array):MyHash { 78 | var hash = new MyHash(); 79 | var i = 0; 80 | while (i < arr.length) { 81 | var k = arr[i++]; 82 | var v = arr[i++]; 83 | hash.set(k, v); 84 | } 85 | return hash; 86 | } 87 | 88 | @:from static public function fromArray(arr:Array) { 89 | var hash = new MyHash(); 90 | var i = 0; 91 | while (i < arr.length) { 92 | var k = arr[i++]; 93 | var v = arr[i++]; 94 | hash.set(Std.string('_s$k'), v); 95 | } 96 | return hash; 97 | } 98 | } 99 | 100 | class AbstractBase { 101 | public var value:T; 102 | public function new(value:T) { 103 | this.value = value; 104 | } 105 | } 106 | 107 | abstract AbstractZ(AbstractBase) from AbstractBase { 108 | @:to public static function toFoo(a:AbstractBase):Int { 109 | return a.value; 110 | } 111 | 112 | @:to public static function toString(a:AbstractBase):String { 113 | return a.value; 114 | } 115 | } 116 | 117 | class MyPoint3 { 118 | public var x:Float; 119 | public var y:Float; 120 | public var z:Float; 121 | public function new(x, y, z) { 122 | this.x = x; 123 | this.y = y; 124 | this.z = z; 125 | } 126 | } 127 | 128 | abstract MyVector(MyPoint3) from MyPoint3 to MyPoint3 { 129 | var x(get, set):Float; 130 | var y(get, set):Float; 131 | var z(get, set):Float; 132 | 133 | public function get_x() return this.x; 134 | public function get_y() return this.y; 135 | public function get_z() return this.z; 136 | public function set_x(x) return this.x = x; 137 | public function set_y(y) return this.y = y; 138 | public function set_z(z) return this.z = z; 139 | 140 | @:op(A + B) static public inline function add(lhs:MyVector, rhs:MyVector):MyVector { 141 | return new MyPoint3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z); 142 | } 143 | 144 | @:op(A *= B) static public inline function scalarAssign(lhs:MyVector, rhs:Float):MyVector { 145 | lhs.x *= rhs; 146 | lhs.y *= rhs; 147 | lhs.z *= rhs; 148 | return lhs; 149 | } 150 | 151 | @:op(A * B) static public inline function scalar(lhs:MyVector, rhs:Float):MyVector { 152 | return new MyPoint3(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs); 153 | } 154 | 155 | @:op(-A) static public inline function invert(t:MyVector):MyVector { 156 | return new MyPoint3( -t.x, -t.y, -t.z); 157 | } 158 | 159 | public inline function get():MyPoint3 160 | return this; 161 | 162 | @:to public inline function toString():String 163 | return untyped '(${this.x},${this.y},${this.z})'; 164 | } 165 | 166 | abstract MyInt(Int) from Int to Int { 167 | // MyInt + MyInt can be used as is, and returns a MyInt 168 | @:op(A + B) static public function add(lhs:MyInt, rhs:MyInt):MyInt; 169 | 170 | @:commutative @:op(A * B) static public function repeat(lhs:MyInt, rhs:String):String { 171 | var s:StringBuf = new StringBuf(); 172 | for (i in 0...lhs) 173 | s.add(rhs); 174 | return s.toString(); 175 | } 176 | 177 | @:op(A / B) static public function cut(lhs:String, rhs:MyInt) { 178 | return lhs.substr(0, rhs); 179 | } 180 | } 181 | 182 | abstract MyInt2(Int) from MyInt { 183 | public inline function new(v) { 184 | this = v; 185 | } 186 | 187 | public function get():Int { 188 | return this; 189 | } 190 | 191 | @:op(-x) public inline function invert():MyInt2 { 192 | return new MyInt2(-this); 193 | } 194 | 195 | @:op(++x) public inline function incr() { 196 | ++this; 197 | } 198 | } 199 | 200 | abstract MyString(String) from String to String { 201 | @:op(A + B) static public function add(lhs:MyString, rhs:MyString):MyString; 202 | @:op(A + B) static public function addInt(lhs:MyString, rhs:Int):MyString; 203 | @:op(A + B) static public function addBool(lhs:MyString, rhs:Bool):Bool; 204 | } 205 | 206 | class ClassWithHashCode { 207 | var i:Int; 208 | public function new(i) { this.i = i; } 209 | public function hashCode() return i; 210 | } 211 | 212 | class ClassWithoutHashCode { 213 | public var i:Int; 214 | public function new(i) { this.i = i; } 215 | } 216 | 217 | abstract MyReflect({}) from {} { 218 | @:arrayAccess public inline function arrayAccess(key:String):Dynamic { 219 | return Reflect.field(this, key); 220 | } 221 | 222 | @:arrayAccess public inline function arrayWrite(key:String, value:T):T { 223 | Reflect.setField(this, key, value); 224 | return value; 225 | } 226 | } 227 | 228 | abstract MyAbstractClosure(String){ 229 | public function new(value:String) { 230 | this = value; 231 | } 232 | 233 | public function test() { 234 | var fn = function(){ 235 | return this; 236 | } 237 | return fn; 238 | } 239 | 240 | public inline function setVal(v) { 241 | this = v; 242 | } 243 | } 244 | 245 | abstract MyAbstractSetter(Dynamic) { 246 | 247 | public var value(get,set):String; 248 | 249 | public inline function new() { 250 | this = {}; 251 | } 252 | 253 | inline function get_value() { 254 | return this.value; 255 | } 256 | 257 | inline function set_value(s:String) { 258 | this.value = s; 259 | return s; 260 | } 261 | } 262 | 263 | abstract MyAbstractCounter(Int) { 264 | public static var counter = 0; 265 | inline function new(v:Int) { 266 | this = v; 267 | counter++; 268 | } 269 | 270 | @:from inline static public function fromInt(v:Int) { 271 | return new MyAbstractCounter(v); 272 | } 273 | 274 | inline public function getValue():Int return this + 1; 275 | } 276 | 277 | abstract MyAbstractThatCallsAMember(Int) to Int { 278 | public function new(i) { 279 | this = i; 280 | bar(); 281 | } 282 | 283 | inline function bar() this++; 284 | } 285 | 286 | abstract MyDebugString(String) to String { 287 | public inline function new(s:String) { 288 | this = s; 289 | } 290 | 291 | public inline function substr(i:Int, ?len:Null) { 292 | return this.substr(i); 293 | } 294 | } 295 | 296 | @:multiType abstract MySpecialString(String) { 297 | public function new(value:String); 298 | 299 | public inline function substr(i:Int, ?len:Int) { 300 | return len == null ? this.substr(i) : this.substr(i, len); 301 | } 302 | 303 | @:to static inline public function toNormal(t:String, value:String) { 304 | return new MyDebugString(value); 305 | } 306 | } 307 | 308 | #if !macro 309 | enum abstract FakeEnumAbstract(Int) { 310 | var NotFound = 404; 311 | var MethodNotAllowed = 405; 312 | } 313 | 314 | @:forward(push, pop) 315 | abstract ExposingAbstract(Array) { 316 | public inline function new() { 317 | this = []; 318 | } 319 | } 320 | #end 321 | 322 | enum abstract GADTEnumAbstract(Int) { 323 | var A:GADTEnumAbstract<()->Void> = 1; 324 | var B:GADTEnumAbstractVoid> = 2; 325 | } 326 | -------------------------------------------------------------------------------- /test/src/test/TestAll.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | class TestAll { 4 | public static function test() { 5 | TestSyntax.test(); 6 | TestMath.test(); 7 | TestStd.test(); 8 | TestString.test(); 9 | TestStaticVar.test(); 10 | TestArray.test(); 11 | TestEnum.test(); 12 | TestMeta.test(); 13 | TestSys.test(); 14 | TestEReg.test(); 15 | TestReflect.test(); 16 | TestClass.test(); 17 | TestSignals.test(); 18 | TestMap.test(); 19 | 20 | trace("Tests successful!!"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/src/test/TestArray.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | 5 | class TestArray { 6 | public static function test() { 7 | // constructor 8 | final arr = new Array(); 9 | 10 | // length 11 | assert(arr.length == 0); 12 | 13 | for(i in 0...3) arr.push(i + 1); 14 | 15 | assert(arr.length == 3); 16 | 17 | // concat 18 | assert(arr.concat([4, 5, 6]).length == 6); 19 | 20 | // contains 21 | assert(arr.contains(3)); 22 | assert(!arr.contains(5)); 23 | 24 | // copy 25 | final arr2 = arr; 26 | assert(arr == arr2); 27 | 28 | // GDScript compares Arrays by their content 29 | assert(arr == arr2.copy()); 30 | 31 | // filter 32 | assert(arr.filter(i -> i != 1).length == 2); 33 | 34 | // indexOf 35 | assert(arr.indexOf(2) == 1); 36 | 37 | // insert 38 | arr.insert(0, 0); 39 | assert(arr.length == 4); 40 | assert(arr[0] == 0); 41 | assert(arr[2] == 2); 42 | 43 | arr.insert(-1, 4); 44 | assert(arr.length == 5); 45 | assert(arr[4] == 4); 46 | assert(arr[2] == 2); 47 | 48 | // iterator 49 | var total = 0; 50 | final it = arr.iterator(); 51 | while(it.hasNext()) { 52 | total += it.next(); 53 | } 54 | assert(total == 10); 55 | 56 | // join 57 | assert(arr.join(", ") == "0, 1, 2, 3, 4"); 58 | 59 | // map 60 | final doubleArr = arr.map(i -> i * 2); 61 | 62 | // keyValueIterator 63 | var keyTotal = 0; 64 | var doubleTotal = 0; 65 | final kvit = doubleArr.keyValueIterator(); 66 | while(kvit.hasNext()) { 67 | final o = kvit.next(); 68 | keyTotal += o.key; 69 | doubleTotal += o.value; 70 | } 71 | assert(keyTotal == 10); 72 | assert(doubleTotal == 20); 73 | 74 | // pop, push 75 | final stack = [84, 29, 655]; 76 | assert(stack.pop() == 655); 77 | assert(stack.length == 2); 78 | stack.push(333); 79 | assert(stack[2] == 333); 80 | 81 | // remove 82 | if(stack.remove(84)) { 83 | assert(stack.length == 2); 84 | assert(stack[0] == 29); 85 | } else { 86 | assert(false); 87 | } 88 | 89 | // reverse 90 | final ordered = [3, 6, 9, 12]; 91 | ordered.reverse(); 92 | assert(ordered == [12, 9, 6, 3]); 93 | 94 | // shift 95 | assert(ordered.shift() == 12); 96 | 97 | // slice 98 | final newArr = [22, 44, 66, 88]; 99 | assert(newArr.slice(1) == [44, 66, 88]); 100 | assert(newArr.slice(2, 3) == [66]); 101 | 102 | // sort 103 | final sortable = [2, 7, 1, 4, 0, 4]; 104 | sortable.sort((a, b) -> a - b); 105 | assert(sortable == [0, 1, 2, 4, 4, 7]); 106 | 107 | // splice 108 | assert(sortable.splice(2, 1) == [2]); 109 | assert(sortable.splice(1, 3) == [1, 4, 4]); 110 | 111 | // toString 112 | assert(sortable.toString() == "[0, 7]"); 113 | 114 | // unshift 115 | final unfinished = [3, 4, 5]; 116 | unfinished.unshift(2); 117 | unfinished.unshift(1); 118 | assert(unfinished == [1, 2, 3, 4, 5]); 119 | } 120 | } -------------------------------------------------------------------------------- /test/src/test/TestClass.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | class TestClass { 4 | var a: Int = 2; 5 | var b: Float = 3; 6 | var c: Bool = false; 7 | 8 | public function new() { 9 | if(!c) { 10 | trace(a, b); 11 | } 12 | } 13 | 14 | public static function test() { 15 | trace(new TestClass()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/src/test/TestEReg.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | 5 | // matchedLeft, matchedRight, map, and escape unimplemented due to laziness 6 | class TestEReg { 7 | public static function test() { 8 | final reg = ~/abc/; 9 | 10 | assert(reg.match("abcdef")); 11 | 12 | assert(reg.matched(0) == "abc"); 13 | 14 | final pos = reg.matchedPos(); 15 | assert(pos.pos == 0); 16 | assert(pos.len == 3); 17 | 18 | assert(~/abc/.matchSub("abcabc", 1)); 19 | 20 | assert(~/\s*,\s*/.split("one,two ,three, four") == ["one", "two", "three", "four"]); 21 | 22 | assert(reg.replace("123abc", "456") == "123456"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/src/test/TestEnum.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | 5 | enum MyGDEnum { 6 | Rock; 7 | Paper; 8 | Scissors; 9 | } 10 | 11 | enum MyDictEnum { 12 | Entry1; 13 | Entry2(i: Int); 14 | Entry3(s: String); 15 | } 16 | 17 | class TestEnum { 18 | static function isLeftWinner(left: MyGDEnum, right: MyGDEnum) { 19 | return switch(left) { 20 | case Rock: right == Scissors; 21 | case Paper: right == Rock; 22 | case Scissors: right == Paper; 23 | } 24 | } 25 | 26 | public static function test() { 27 | assert(isLeftWinner(Paper, Rock)); 28 | assert(!isLeftWinner(Rock, Paper)); 29 | assert(!isLeftWinner(Scissors, Scissors)); 30 | 31 | final a = Entry1; 32 | final b = Entry2(123); 33 | final c = Entry3("Test"); 34 | 35 | switch(b) { 36 | case Entry1: assert(false); 37 | case Entry2(i): assert(i == 123); 38 | case Entry3(s): assert(false); 39 | } 40 | 41 | switch(c) { 42 | case Entry1: assert(false); 43 | case Entry2(i): assert(false); 44 | case Entry3(s): assert(s == "Test"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/src/test/TestMath.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | import Assert.assertFloat; 5 | 6 | class TestMath { 7 | public static function test() { 8 | assert(Math.ceil(2 * Math.pow(Math.PI, 2)) == 20); 9 | 10 | assert(Math.abs(-3) == 3); 11 | 12 | assert(Math.ceil(2.1) == 3); 13 | assert(Math.ceil(0.9) == 1); 14 | 15 | assert(Math.ceil(Math.exp(1.0)) == 3); 16 | assert(Math.floor(Math.exp(1.0)) == 2); 17 | 18 | assert(Math.floor(99.9) == 99); 19 | 20 | assert(1f64 == 1.0); 21 | 22 | assert(Math.isFinite(12)); 23 | assert(Math.isNaN(Math.NaN)); 24 | assert(!Math.isFinite(Math.POSITIVE_INFINITY)); 25 | assert(!Math.isFinite(Math.NEGATIVE_INFINITY)); 26 | 27 | assertFloat(Math.sin(Math.PI), 0.0); 28 | assertFloat(Math.cos(0), 1); 29 | assertFloat(Math.tan(4), 1.157821); 30 | assertFloat(Math.asin(1), 1.570796); 31 | 32 | // https://github.com/godotengine/godot/commit/50c5ed4876250f785be54b8f6124e7663afa38dc 33 | // acos now safe to call 34 | assertFloat(Math.acos(100), 0); 35 | 36 | assertFloat(Math.atan(12), 1.4876); 37 | assertFloat(Math.atan2(-3, 3), -0.78539); 38 | 39 | assertFloat(Math.log(10), 2.30258); 40 | 41 | assert(Math.sqrt(25) == 5); 42 | assert(Math.sqrt(100) == 10); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/src/test/TestMeta.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | 5 | @:tool 6 | class TestMeta { 7 | @:onready 8 | var prop = 123; 9 | 10 | @:exportEnum("Hello", "World") 11 | var enumField = 0; 12 | 13 | public function new() { 14 | } 15 | 16 | public static function test() { 17 | // not really sure how to write tests for annotations 18 | // they work, just take my word on it Xd 19 | final tm = new TestMeta(); 20 | assert(tm.prop == 123); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/src/test/TestNode.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | extern class Node { 4 | function _ready(): Void; 5 | } 6 | 7 | class TestNode extends Node { 8 | @:export var dictionary = new gdscript.Dictionary(); 9 | 10 | override function _ready() { 11 | trace(dictionary); // Check that this matches what's placed in editor. 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/src/test/TestReflect.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | 5 | class MyClass { 6 | public function new() {} 7 | 8 | public var myProp(get, set): Int; 9 | 10 | var internalProp: Int = 1; 11 | 12 | function get_myProp() return internalProp; 13 | function set_myProp(v) return internalProp = v; 14 | } 15 | 16 | class TestReflect { 17 | public static function test() { 18 | final obj = { 19 | num: 123, 20 | str: "String" 21 | }; 22 | 23 | final cls = new MyClass(); 24 | 25 | assert(Reflect.hasField(obj, "num")); 26 | assert(!Reflect.hasField(obj, "dog")); 27 | 28 | assert(Reflect.field(obj, "str") == "String"); 29 | 30 | Reflect.setField(obj, "num", 444); 31 | assert(Reflect.field(obj, "num") == 444); 32 | 33 | assert(Reflect.getProperty(cls, "myProp") == 1); 34 | 35 | Reflect.setProperty(cls, "myProp", 10); 36 | assert(Reflect.getProperty(cls, "myProp") == 10); 37 | 38 | final func = function(a) { return a + 123; } 39 | assert(Reflect.callMethod(null, func, [100]) == 223); 40 | 41 | assert(Reflect.fields(cls).length == 4); 42 | 43 | assert(!Reflect.isFunction(obj)); 44 | assert(Reflect.isFunction(func)); 45 | 46 | assert(Reflect.compare(12, 14) == -1); 47 | assert(Reflect.compareMethods(func, func)); 48 | 49 | assert(!Reflect.isObject(obj)); 50 | 51 | // Checks if a Dictionary, so this must be true 52 | assert(Reflect.isEnumValue(obj)); 53 | 54 | final obj2 = Reflect.copy(obj); 55 | assert(obj2.str == obj.str); 56 | 57 | Reflect.deleteField(obj, "num"); 58 | assert((obj.num: Null) == null); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /test/src/test/TestSignals.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | 5 | class TestSignals { 6 | @:signal 7 | function my_signal(i: Int) {} 8 | 9 | public static function test() { 10 | final t = new TestSignals(); 11 | t.do_test(); 12 | } 13 | 14 | public function new() { 15 | } 16 | 17 | function do_test() { 18 | untyped __gdscript__("connect(\"my_signal\", {0})", test2); 19 | untyped __gdscript__("emit_signal(\"my_signal\", {0})", 123); 20 | } 21 | 22 | function test2(i: Int) { 23 | assert(i == 123); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/src/test/TestStaticVar.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | 5 | class OtherClass { 6 | public static var str(default, null) = ""; 7 | 8 | public static dynamic function add() { 9 | str += "|"; 10 | } 11 | 12 | public static function clear() { 13 | str = ""; 14 | } 15 | } 16 | 17 | class TestStaticVar { 18 | public static var count = 0; 19 | 20 | public function new() { 21 | count++; 22 | } 23 | 24 | public static function test() { 25 | count = 10; 26 | 27 | assert(count == 10); 28 | 29 | final list = []; 30 | for(i in 0...10) { 31 | list.push(new TestStaticVar()); 32 | } 33 | 34 | assert(count == 20); 35 | 36 | assert(OtherClass.str.length == 0); 37 | 38 | for(i in 0...3) { 39 | OtherClass.add(); 40 | } 41 | 42 | assert(OtherClass.str.length == 3); 43 | 44 | OtherClass.clear(); 45 | 46 | assert(OtherClass.str.length == 0); 47 | 48 | final old = OtherClass.add; 49 | OtherClass.add = function() { 50 | old(); 51 | old(); 52 | } 53 | 54 | OtherClass.add(); 55 | 56 | assert(OtherClass.str == "||"); 57 | 58 | if(OtherClass.add != null) { 59 | assert(true); 60 | } else { 61 | assert(false); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /test/src/test/TestStd.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | import Assert.assertFloat; 5 | 6 | class A { 7 | public function new() {} 8 | } 9 | 10 | class B { 11 | public function new() {} 12 | } 13 | 14 | class C extends B { 15 | } 16 | 17 | class TestStd { 18 | public static function test() { 19 | final a = new A(); 20 | final b = new B(); 21 | assert(Std.isOfType(a, A)); 22 | assert(Std.isOfType(b, B)); 23 | assert(!Std.isOfType(a, B)); 24 | assert(!Std.isOfType(b, A)); 25 | 26 | final c = Std.downcast(b, C); 27 | assert(c == null); 28 | 29 | assert(Std.string(123) == "123"); 30 | assert(Std.string(false) == "false"); 31 | assert(StringTools.startsWith(Std.string(a), "= 0 && r < 10); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/src/test/TestString.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | 5 | class TestString { 6 | public static function test() { 7 | var str: String = new String("Test"); 8 | assert(str == "Test"); 9 | assert(str.length == 4); 10 | assert(str.toString() == "Test"); 11 | 12 | assert(String.fromCharCode(70) == "F"); 13 | 14 | assert(str.charCodeAt(1) == 101); 15 | 16 | assert(str.indexOf("es") == 1); 17 | assert(str.indexOf("Hey") == -1); 18 | assert(str.indexOf("Te", 2) == -1); 19 | 20 | assert(str.lastIndexOf("Te") == 0); 21 | 22 | assert(str.split("s")[0] == "Te"); 23 | assert(str.split("e").length == 2); 24 | 25 | var str2 = "Hello, World!"; 26 | assert(str2.substr(7, 5) == "World"); 27 | assert(str2.substring(7, 12) == "World"); 28 | 29 | assert(str2.toLowerCase() == "hello, world!"); 30 | assert(str2.toUpperCase() == "HELLO, WORLD!"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/src/test/TestSyntax.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | 5 | class TestSyntax { 6 | var testField = 123; 7 | 8 | public function new() { 9 | assert(testField == 123); 10 | } 11 | 12 | @:dce(Off) 13 | public static function test() { 14 | assert(true); 15 | assert(!false); 16 | assert(1 + 1 == 2); 17 | assert(1 - 1 == 0); 18 | assert(2 * 2 == 4); 19 | assert(10 / 2 == 5); 20 | 21 | final myNull = null; 22 | assert(myNull == null); 23 | 24 | final obj = new TestSyntax(); 25 | assert(obj == obj); 26 | assert(obj.testField == 123); 27 | 28 | var str = "Hello"; 29 | str = "World"; 30 | str = "Hello, " + str; 31 | str += "!"; 32 | assert(str == "Hello, World!"); 33 | 34 | if(str != "Goodbye World!") { 35 | var num = 3; 36 | assert(num > 1); 37 | assert(num >= 3 && num >= 2); 38 | assert(num == 3); 39 | assert(num <= 3 && num <= 6); 40 | assert(num < 4); 41 | } else { 42 | assert(false); 43 | } 44 | 45 | var num = 3; 46 | assert((num & 1) == 1); 47 | assert((num & 4) == 0); 48 | assert((num | 8) == 11); 49 | assert((num | 3) == 3); 50 | 51 | assert((1 + 1) == 1 + 1); 52 | 53 | final dict: Dynamic = { 54 | hey: "Hey", 55 | thing: obj, 56 | number: 3 57 | }; 58 | 59 | assert(dict.hey == "Hey"); 60 | assert(dict.number == 3); 61 | 62 | dict.pokemon = "Pikachu"; 63 | assert(dict.pokemon == "Pikachu"); 64 | 65 | final arr = [1, 2, 3]; 66 | assert(arr[1] == 2); 67 | assert(arr.length == 3); 68 | 69 | final arr2: Array = untyped __gdscript__("[]"); 70 | //arr2.push(12); 71 | //arr2.push(24); 72 | //assert(arr2[1] == 24); 73 | 74 | final bool = true; 75 | assert(!!bool); 76 | 77 | var mutNum = 1000; 78 | mutNum++; 79 | mutNum++; 80 | assert(mutNum++ == 1002); 81 | assert(--mutNum == 1002); 82 | assert(--mutNum == 1001); 83 | assert(mutNum == 1001); 84 | 85 | final myFunc = function() { 86 | mutNum++; 87 | } 88 | myFunc(); 89 | myFunc(); 90 | assert(mutNum == 1003); 91 | 92 | final blockVal = { 93 | final a = 2; 94 | a * a; 95 | } 96 | assert(blockVal == 4); 97 | 98 | if(blockVal == 4) { 99 | assert(true); 100 | } else { 101 | assert(false); 102 | } 103 | 104 | var i = 0; 105 | while(i++ < 1000) { 106 | if(i == 800) { 107 | assert((i / 80) == 10); 108 | } 109 | } 110 | 111 | var j = 0; 112 | while(j < { 113 | assert(true); 114 | 6; 115 | }) { 116 | assert(true); 117 | j++; 118 | } 119 | 120 | var anotherNum = 0; 121 | var anotherNum2 = anotherNum = 3; 122 | assert(anotherNum == anotherNum2); 123 | 124 | anotherNum2 = anotherNum += 10; 125 | assert(anotherNum == anotherNum2); 126 | 127 | // @:await untyped __gdscript__("get_tree().create_timer(1.0).timeout"); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /test/src/test/TestSys.hx: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import Assert.assert; 4 | 5 | // Most of the Sys class cannot be implemented due to 6 | // GDScript limitations, but most of it is unnecessary 7 | // anyway since GDScript is explicitly used for 8 | // high-level game coding (as opposed to making command 9 | // line tools). 10 | class TestSys { 11 | public static function test() { 12 | assert(Sys.args().length == 0); 13 | 14 | final first = Sys.cpuTime(); 15 | 16 | Sys.sleep(0.1); 17 | 18 | // Hopefully this is consistent across all platforms. 19 | // If not, it can probably be removed. 20 | assert((Sys.cpuTime() - first) > 10000); 21 | } 22 | } 23 | --------------------------------------------------------------------------------