diff --git a/Icons/ASTViewAttribute.svg b/Icons/ASTViewAttribute.svg
new file mode 100644
index 0000000..8deb19b
--- /dev/null
+++ b/Icons/ASTViewAttribute.svg
@@ -0,0 +1,454 @@
+
+
diff --git a/Icons/ASTViewAttribute.svg.import b/Icons/ASTViewAttribute.svg.import
new file mode 100644
index 0000000..611751a
--- /dev/null
+++ b/Icons/ASTViewAttribute.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c1ga7dfggit3m"
+path="res://.godot/imported/ASTViewAttribute.svg-3d90376a97e463f5e8c1d51842ca649c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewAttribute.svg"
+dest_files=["res://.godot/imported/ASTViewAttribute.svg-3d90376a97e463f5e8c1d51842ca649c.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewBracketToken.svg b/Icons/ASTViewBracketToken.svg
new file mode 100644
index 0000000..4790e0c
--- /dev/null
+++ b/Icons/ASTViewBracketToken.svg
@@ -0,0 +1,340 @@
+
+
diff --git a/Icons/ASTViewBracketToken.svg.import b/Icons/ASTViewBracketToken.svg.import
new file mode 100644
index 0000000..d1776e1
--- /dev/null
+++ b/Icons/ASTViewBracketToken.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://6yg4233g51mp"
+path="res://.godot/imported/ASTViewBracketToken.svg-5e10f2c1c361be5543104858ef26cbe4.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewBracketToken.svg"
+dest_files=["res://.godot/imported/ASTViewBracketToken.svg-5e10f2c1c361be5543104858ef26cbe4.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewConstantToken.svg b/Icons/ASTViewConstantToken.svg
new file mode 100644
index 0000000..b213665
--- /dev/null
+++ b/Icons/ASTViewConstantToken.svg
@@ -0,0 +1,339 @@
+
+
diff --git a/Icons/ASTViewConstantToken.svg.import b/Icons/ASTViewConstantToken.svg.import
new file mode 100644
index 0000000..ae7a75b
--- /dev/null
+++ b/Icons/ASTViewConstantToken.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bgttfb7berwwu"
+path="res://.godot/imported/ASTViewConstantToken.svg-4ea6a09e1d41b9affda10122b9f35341.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewConstantToken.svg"
+dest_files=["res://.godot/imported/ASTViewConstantToken.svg-4ea6a09e1d41b9affda10122b9f35341.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewContext.svg b/Icons/ASTViewContext.svg
new file mode 100644
index 0000000..6c0f674
--- /dev/null
+++ b/Icons/ASTViewContext.svg
@@ -0,0 +1,457 @@
+
+
diff --git a/Icons/ASTViewContext.svg.import b/Icons/ASTViewContext.svg.import
new file mode 100644
index 0000000..bf82867
--- /dev/null
+++ b/Icons/ASTViewContext.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cp8x3tr0r6dv3"
+path="res://.godot/imported/ASTViewContext.svg-01873566028d83c30ccc4aea92a1915d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewContext.svg"
+dest_files=["res://.godot/imported/ASTViewContext.svg-01873566028d83c30ccc4aea92a1915d.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewElement.svg b/Icons/ASTViewElement.svg
new file mode 100644
index 0000000..daacab1
--- /dev/null
+++ b/Icons/ASTViewElement.svg
@@ -0,0 +1,366 @@
+
+
diff --git a/Icons/ASTViewElement.svg.import b/Icons/ASTViewElement.svg.import
new file mode 100644
index 0000000..b5b42ec
--- /dev/null
+++ b/Icons/ASTViewElement.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://horcg6ltlipv"
+path="res://.godot/imported/ASTViewElement.svg-854db37c734331d0f1952d7a8058264f.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewElement.svg"
+dest_files=["res://.godot/imported/ASTViewElement.svg-854db37c734331d0f1952d7a8058264f.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewExpression.svg b/Icons/ASTViewExpression.svg
new file mode 100644
index 0000000..b47c364
--- /dev/null
+++ b/Icons/ASTViewExpression.svg
@@ -0,0 +1,354 @@
+
+
diff --git a/Icons/ASTViewExpression.svg.import b/Icons/ASTViewExpression.svg.import
new file mode 100644
index 0000000..153d5c0
--- /dev/null
+++ b/Icons/ASTViewExpression.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dfspdjcjiiud2"
+path="res://.godot/imported/ASTViewExpression.svg-b2561a31e28b205e21b61323451031cb.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewExpression.svg"
+dest_files=["res://.godot/imported/ASTViewExpression.svg-b2561a31e28b205e21b61323451031cb.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewIgnoreToken.svg b/Icons/ASTViewIgnoreToken.svg
new file mode 100644
index 0000000..8d4b208
--- /dev/null
+++ b/Icons/ASTViewIgnoreToken.svg
@@ -0,0 +1,342 @@
+
+
diff --git a/Icons/ASTViewIgnoreToken.svg.import b/Icons/ASTViewIgnoreToken.svg.import
new file mode 100644
index 0000000..1997d0d
--- /dev/null
+++ b/Icons/ASTViewIgnoreToken.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cwn7ynt0xlpy7"
+path="res://.godot/imported/ASTViewIgnoreToken.svg-b324e16e97be55e89c97922164f734bd.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewIgnoreToken.svg"
+dest_files=["res://.godot/imported/ASTViewIgnoreToken.svg-b324e16e97be55e89c97922164f734bd.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewLogicToken.svg b/Icons/ASTViewLogicToken.svg
new file mode 100644
index 0000000..dc7c605
--- /dev/null
+++ b/Icons/ASTViewLogicToken.svg
@@ -0,0 +1,346 @@
+
+
diff --git a/Icons/ASTViewLogicToken.svg.import b/Icons/ASTViewLogicToken.svg.import
new file mode 100644
index 0000000..d069a70
--- /dev/null
+++ b/Icons/ASTViewLogicToken.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cw2raas8cijij"
+path="res://.godot/imported/ASTViewLogicToken.svg-9c4a472fc688c1b5e4a5cd3c2618c538.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewLogicToken.svg"
+dest_files=["res://.godot/imported/ASTViewLogicToken.svg-9c4a472fc688c1b5e4a5cd3c2618c538.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewMember.svg b/Icons/ASTViewMember.svg
new file mode 100644
index 0000000..a06d296
--- /dev/null
+++ b/Icons/ASTViewMember.svg
@@ -0,0 +1,353 @@
+
+
diff --git a/Icons/ASTViewMember.svg.import b/Icons/ASTViewMember.svg.import
new file mode 100644
index 0000000..613ffe0
--- /dev/null
+++ b/Icons/ASTViewMember.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://n0eycqqk7w70"
+path="res://.godot/imported/ASTViewMember.svg-f9e37ae7dc9e996efbf68cb90fb61814.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewMember.svg"
+dest_files=["res://.godot/imported/ASTViewMember.svg-f9e37ae7dc9e996efbf68cb90fb61814.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewObject.svg b/Icons/ASTViewObject.svg
new file mode 100644
index 0000000..c017b4e
--- /dev/null
+++ b/Icons/ASTViewObject.svg
@@ -0,0 +1,424 @@
+
+
diff --git a/Icons/ASTViewObject.svg.import b/Icons/ASTViewObject.svg.import
new file mode 100644
index 0000000..314fc3f
--- /dev/null
+++ b/Icons/ASTViewObject.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c3f13n683odcg"
+path="res://.godot/imported/ASTViewObject.svg-7328724af634e78eee79503f51e11949.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewObject.svg"
+dest_files=["res://.godot/imported/ASTViewObject.svg-7328724af634e78eee79503f51e11949.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewOperatorToken.svg b/Icons/ASTViewOperatorToken.svg
new file mode 100644
index 0000000..dc44919
--- /dev/null
+++ b/Icons/ASTViewOperatorToken.svg
@@ -0,0 +1,337 @@
+
+
diff --git a/Icons/ASTViewOperatorToken.svg.import b/Icons/ASTViewOperatorToken.svg.import
new file mode 100644
index 0000000..aef61b3
--- /dev/null
+++ b/Icons/ASTViewOperatorToken.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bqmehmdpv5a0e"
+path="res://.godot/imported/ASTViewOperatorToken.svg-7367f1664d57ff060ff40c39c407dc2e.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewOperatorToken.svg"
+dest_files=["res://.godot/imported/ASTViewOperatorToken.svg-7367f1664d57ff060ff40c39c407dc2e.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewStatement.svg b/Icons/ASTViewStatement.svg
new file mode 100644
index 0000000..01fde4b
--- /dev/null
+++ b/Icons/ASTViewStatement.svg
@@ -0,0 +1,343 @@
+
+
diff --git a/Icons/ASTViewStatement.svg.import b/Icons/ASTViewStatement.svg.import
new file mode 100644
index 0000000..903d05d
--- /dev/null
+++ b/Icons/ASTViewStatement.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bagmilfojhs02"
+path="res://.godot/imported/ASTViewStatement.svg-e422165cc4577de625ca5f7421a00574.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewStatement.svg"
+dest_files=["res://.godot/imported/ASTViewStatement.svg-e422165cc4577de625ca5f7421a00574.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewToken.svg b/Icons/ASTViewToken.svg
new file mode 100644
index 0000000..a06d672
--- /dev/null
+++ b/Icons/ASTViewToken.svg
@@ -0,0 +1,344 @@
+
+
diff --git a/Icons/ASTViewToken.svg.import b/Icons/ASTViewToken.svg.import
new file mode 100644
index 0000000..a161357
--- /dev/null
+++ b/Icons/ASTViewToken.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://gbib2673nwww"
+path="res://.godot/imported/ASTViewToken.svg-7b92a75ae1051663a96d916309e348e2.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewToken.svg"
+dest_files=["res://.godot/imported/ASTViewToken.svg-7b92a75ae1051663a96d916309e348e2.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/ASTViewWordToken.svg b/Icons/ASTViewWordToken.svg
new file mode 100644
index 0000000..818bc62
--- /dev/null
+++ b/Icons/ASTViewWordToken.svg
@@ -0,0 +1,347 @@
+
+
diff --git a/Icons/ASTViewWordToken.svg.import b/Icons/ASTViewWordToken.svg.import
new file mode 100644
index 0000000..703cdb6
--- /dev/null
+++ b/Icons/ASTViewWordToken.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bbuyxy0mdp7gc"
+path="res://.godot/imported/ASTViewWordToken.svg-47ef9a555e6f707ad89ffb9fe548a1ca.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://addons/rokojori_action_library/Icons/ASTViewWordToken.svg"
+dest_files=["res://.godot/imported/ASTViewWordToken.svg-47ef9a555e6f707ad89ffb9fe548a1ca.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Runtime/Actions/Action.cs b/Runtime/Actions/Action.cs
index 56d1fb8..77eb37a 100644
--- a/Runtime/Actions/Action.cs
+++ b/Runtime/Actions/Action.cs
@@ -7,6 +7,7 @@ namespace Rokojori;
[Tool]
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
+[RokojoriActionCoreExport]
public partial class Action : NetworkNode
{
public enum ActionTriggerMode
diff --git a/Runtime/Actions/ActionList.cs b/Runtime/Actions/ActionList.cs
index e21a0e2..ac65a53 100644
--- a/Runtime/Actions/ActionList.cs
+++ b/Runtime/Actions/ActionList.cs
@@ -4,7 +4,7 @@ using Godot;
namespace Rokojori
{
- /**
+ /**
Executes multiple actions (Action) at once.
@@ -21,14 +21,15 @@ namespace Rokojori
[Tool]
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/ActionList.svg") ]
+ [RokojoriActionCoreExport]
public partial class ActionList : Action
{
- /** Actions to execute*/
+ /** Actions to execute */
[Export]
public Action[] actions = new Action[ 0 ];
- /** Whether to execute Action child nodes*/
+ /** Whether to execute Action child nodes*/
[Export]
public bool triggerDirectChildren = true;
diff --git a/Runtime/Actions/RJ_Action.gd b/Runtime/Actions/RJ_Action.gd
new file mode 100644
index 0000000..ca73e3e
--- /dev/null
+++ b/Runtime/Actions/RJ_Action.gd
@@ -0,0 +1,23 @@
+
+@tool
+@icon("res://addons/rokojori_action_library/Icons/Action.svg")
+class_name RJ_Action extends RJ_NetworkNode
+
+enum ActionTriggerMode
+{
+ Only_When_Processing_In_Hierarchy,
+ Always
+}
+
+@export
+var trigger_mode: ActionTriggerMode;
+
+func trigger() -> void:
+ pass
+## ---
+
+
+func _on_trigger() -> void:
+ pass
+## ---
+
diff --git a/Runtime/Actions/RJ_Action.gd.uid b/Runtime/Actions/RJ_Action.gd.uid
new file mode 100644
index 0000000..c952971
--- /dev/null
+++ b/Runtime/Actions/RJ_Action.gd.uid
@@ -0,0 +1 @@
+uid://dcqjcsh20ndon
diff --git a/Runtime/Actions/RJ_ActionList.gd b/Runtime/Actions/RJ_ActionList.gd
new file mode 100644
index 0000000..8fabcdc
--- /dev/null
+++ b/Runtime/Actions/RJ_ActionList.gd
@@ -0,0 +1,14 @@
+
+@tool
+@icon("res://addons/rokojori_action_library/Icons/ActionList.svg")
+class_name RJ_ActionList extends RJ_Action
+
+@export
+var actions: Action[];
+@export
+var trigger_direct_children: bool;
+
+func _on_trigger() -> void:
+ pass
+## ---
+
diff --git a/Runtime/Actions/RJ_ActionList.gd.uid b/Runtime/Actions/RJ_ActionList.gd.uid
new file mode 100644
index 0000000..221e527
--- /dev/null
+++ b/Runtime/Actions/RJ_ActionList.gd.uid
@@ -0,0 +1 @@
+uid://ctnc7tsiwxp3j
diff --git a/Runtime/Godot/Extensions/NodeExtensions.cs b/Runtime/Godot/Extensions/NodeExtensions.cs
index ed163db..d6dbfcb 100644
--- a/Runtime/Godot/Extensions/NodeExtensions.cs
+++ b/Runtime/Godot/Extensions/NodeExtensions.cs
@@ -60,6 +60,46 @@ namespace Rokojori
}
+ public static List MapDirectChildren( this Node node, Func mapper ) where T:Node
+ {
+ var list = new List();
+
+ node.ForEachDirectChild(
+ n =>
+ {
+ if ( n is T t)
+ {
+ list.Add( mapper( t ) );
+ }
+ }
+ );
+
+ return list;
+ }
+
+ public static bool HasDirectChildWithName( this Node node, string name, bool includeInternal = false )
+ {
+ return IndexOfDirectChildWithName( node, name, includeInternal ) != -1;
+ }
+
+ public static int IndexOfDirectChildWithName( this Node node, string name, bool includeInternal = false )
+ {
+ var numKids = node.GetChildCount( includeInternal );
+
+ for ( int i = 0; i < numKids; i++ )
+ {
+ var child = node.GetChild( i, includeInternal );
+
+ if ( child is T t && child.Name == name )
+ {
+ return i;
+ }
+
+ }
+
+ return -1;
+ }
+
public static T GetNextSiblingOrChild( this Node node ) where T:Node
{
var index = node.GetIndex();
diff --git a/Runtime/Godot/Nodes.cs b/Runtime/Godot/Nodes.cs
index b2cdd0e..16ad5ce 100644
--- a/Runtime/Godot/Nodes.cs
+++ b/Runtime/Godot/Nodes.cs
@@ -672,6 +672,30 @@ namespace Rokojori
}
}
+ public static void RemoveChildren( this Node parent, bool includeInternal = false ) where T:Node
+ {
+ if ( parent == null )
+ {
+ return;
+ }
+
+ var numChildren = parent.GetChildCount( includeInternal );
+
+ for ( int i = numChildren - 1; i >= 0; i-- )
+ {
+ var node = parent.GetChild( i, includeInternal );
+
+ var t = node as T;
+
+ if ( t == null )
+ {
+ continue;
+ }
+
+ parent.RemoveChild( node );
+ }
+ }
+
public static void DestroyChildren( this Node parent, bool includeInternal = false, bool queue = true )
{
diff --git a/Runtime/Godot/NodesWalker.cs b/Runtime/Godot/NodesWalker.cs
index bac5ac6..dc75d3b 100644
--- a/Runtime/Godot/NodesWalker.cs
+++ b/Runtime/Godot/NodesWalker.cs
@@ -42,5 +42,46 @@ namespace Rokojori
}
+ }
+
+ public class InternalNodesWalker: TreeWalker
+ {
+ static InternalNodesWalker _singleton = new InternalNodesWalker();
+ public static InternalNodesWalker Get()
+ {
+ return _singleton;
+ }
+
+ public override Node Parent( Node n )
+ {
+ if ( n == null )
+ {
+ return null;
+ }
+
+ return n.GetParent();
+ }
+
+ public override Node ChildAt( Node n, int index )
+ {
+ if ( n == null )
+ {
+ return null;
+ }
+
+ return n.GetChild( index, true );
+ }
+
+ public override int NumChildren( Node n )
+ {
+ if ( n == null )
+ {
+ return 0;
+ }
+
+ return n.GetChildCount( true );
+ }
+
+
}
}
\ No newline at end of file
diff --git a/Runtime/Graphs/Trees/TreeWalker.cs b/Runtime/Graphs/Trees/TreeWalker.cs
index 5a61af4..721099e 100644
--- a/Runtime/Graphs/Trees/TreeWalker.cs
+++ b/Runtime/Graphs/Trees/TreeWalker.cs
@@ -207,6 +207,13 @@ namespace Rokojori
return FindChild( node, false, selector );
}
+ public T FindAnyChildOfType( N node ) where T:class
+ {
+ var v = FindAnyChild( node, n => n is T );
+
+ return v == null ? default( T ) : ( v as T );
+ }
+
public N FindChild( N node, bool directChildrenOnly, Predicate selector )
{
if ( directChildrenOnly )
@@ -405,6 +412,26 @@ namespace Rokojori
return false;
}
+
+ public N ResolveToCommonParent( N nestedChild, N parent )
+ {
+ var it = nestedChild;
+
+
+ while ( it != null )
+ {
+ var p = Parent( it );
+
+ if ( p == parent )
+ {
+ return it;
+ }
+
+ it = p;
+ }
+
+ return null;
+ }
public int NumParents( N node )
@@ -658,6 +685,13 @@ namespace Rokojori
Iterate( node, addToList, childrenOnly );
}
+ public List Filter( N node, Predicate predicate, bool childrenOnly )
+ {
+ var list = new List();
+ Filter( list, node, predicate, childrenOnly );
+ return list;
+ }
+
public void FilterAndMap( List list, N node, Predicate predicate, Func mapper, bool childrenOnly )
{
Action addToList = ( N n ) =>
@@ -671,7 +705,19 @@ namespace Rokojori
Iterate( node, addToList, childrenOnly );
}
- public void Map( List list, N node, Predicate predicate, Func mapper, bool childrenOnly )
+ public List FilterAndMap( N node, Predicate predicate, Func mapper, bool childrenOnly )
+ {
+ var list = new List();
+ FilterAndMap( list, node, predicate, mapper, childrenOnly );
+ return list;
+ }
+
+ public List FilterType( N node, bool childrenOnly = true ) where U:class
+ {
+ return FilterAndMap( node, n => n is U, n => n as U, childrenOnly );
+ }
+
+ public void Map( List list, N node, Func mapper, bool childrenOnly )
{
Action addToList = ( N n ) =>
{
diff --git a/Runtime/Networking/Nodes/NetworkNode.cs b/Runtime/Networking/Nodes/NetworkNode.cs
index b098e08..725deb0 100644
--- a/Runtime/Networking/Nodes/NetworkNode.cs
+++ b/Runtime/Networking/Nodes/NetworkNode.cs
@@ -2,56 +2,60 @@ using Godot;
using Rokojori.Tools;
using System.Collections.Generic;
-namespace Rokojori
-{
- [Tool]
- [GlobalClass]
- public partial class NetworkNode : Node, INetworkNode
+namespace Rokojori;
+
+[Tool]
+[GlobalClass]
+[RokojoriActionCoreExport]
+public partial class NetworkNode : Node, INetworkNode
+{
+ #if !GD_SCRIPT_TRANSPILING
+
+ [ExportGroup("Network Settings")]
+ [Export]
+ public NetworkTransportType networkType = NetworkTransportType.Never_Networked;
+ public NetworkTransportType GetNetworkType(){ return networkType; }
+
+ [Export]
+ public int networkOwner;
+ public int GetNetworkOwner(){ return networkOwner; }
+
+
+ protected List _networkNodeMembers = null;
+ protected NetworkNodeSlot _networkNodeSlot = new NetworkNodeSlot();
+
+ public virtual List GetNetworkNodeMembers()
{
- [ExportGroup("Network Settings")]
- [Export]
- public NetworkTransportType networkType = NetworkTransportType.Never_Networked;
- public NetworkTransportType GetNetworkType(){ return networkType; }
-
- [Export]
- public int networkOwner;
- public int GetNetworkOwner(){ return networkOwner; }
-
-
- protected List _networkNodeMembers = null;
- protected NetworkNodeSlot _networkNodeSlot = new NetworkNodeSlot();
-
- public virtual List GetNetworkNodeMembers()
+ if ( _networkNodeMembers != null )
{
- if ( _networkNodeMembers != null )
- {
- return _networkNodeMembers;
- }
-
- _networkNodeMembers = CreateNetworkNodeMembers();
- _networkNodeSlot.onMessage.AddAction( _OnNetworkMessageReceived );
-
- InitializeNetworkMembers();
-
return _networkNodeMembers;
}
- protected virtual List CreateNetworkNodeMembers()
- {
- return new List(){ _networkNodeSlot };
- }
+ _networkNodeMembers = CreateNetworkNodeMembers();
+ _networkNodeSlot.onMessage.AddAction( _OnNetworkMessageReceived );
- protected virtual void InitializeNetworkMembers()
- {
- for ( int i = 0; i < _networkNodeMembers.Count; i++ )
- {
- _networkNodeMembers[ i ]._SetNode( this );
- }
- }
+ InitializeNetworkMembers();
- protected virtual void _OnNetworkMessageReceived( NetworkMessageEvent m )
- {
+ return _networkNodeMembers;
+ }
+ protected virtual List CreateNetworkNodeMembers()
+ {
+ return new List(){ _networkNodeSlot };
+ }
+
+ protected virtual void InitializeNetworkMembers()
+ {
+ for ( int i = 0; i < _networkNodeMembers.Count; i++ )
+ {
+ _networkNodeMembers[ i ]._SetNode( this );
}
}
-}
\ No newline at end of file
+
+ protected virtual void _OnNetworkMessageReceived( NetworkMessageEvent m )
+ {
+
+ }
+
+ #endif
+}
diff --git a/Runtime/Text/CodeGenerators/GDScript/CSDocToGDScriptDoc.cs b/Runtime/Text/CodeGenerators/GDScript/CSDocToGDScriptDoc.cs
new file mode 100644
index 0000000..e517b06
--- /dev/null
+++ b/Runtime/Text/CodeGenerators/GDScript/CSDocToGDScriptDoc.cs
@@ -0,0 +1,121 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+namespace Rokojori;
+
+class CSDocToGDScriptDoc
+{
+ static void AddChildrenToIgnoreSet( XMLNode n, HashSet ignoreSet )
+ {
+ var walker = XMLWalker.instance;
+
+ walker.Iterate( n,
+ ( n )=>
+ {
+ ignoreSet.Add( n );
+ }
+ );
+ }
+
+ public static string ConvertDoc( string docComment )
+ {
+ if ( docComment == null || docComment == "" )
+ {
+ return " (...) ";
+ }
+
+ var xml = XMLDocument.From( docComment );
+ var walker = XMLWalker.instance;
+
+ var d = new StringBuilder();
+
+ var docRoot = xml.documentElement;
+
+ var formats = new List(){ "i", "b", "s", "u" };
+ var ignoreSet = new HashSet();
+
+
+ walker.Iterate( docRoot,
+ n =>
+ {
+ if ( ignoreSet.Contains( n ) )
+ {
+ return;
+ }
+
+ if ( n is XMLElementNode br && br.nodeName == "br" )
+ {
+ d.Append( "[br]" );
+ AddChildrenToIgnoreSet( n, ignoreSet );
+ }
+ else if ( n is XMLElementNode url && url.nodeName == "url" )
+ {
+ d.Append( "[url=" + url.GetAttribute( "data-path" ) + "]");
+ d.Append( url.textContent );
+ d.Append( "[/url]");
+
+ AddChildrenToIgnoreSet( n, ignoreSet );
+ }
+ else if ( n is XMLElementNode s && formats.IndexOf( s.nodeName ) != -1 )
+ {
+ d.Append( "[" + s.nodeName + "]");
+ d.Append( s.textContent );
+ d.Append( "[/" + s.nodeName + "]");
+
+ AddChildrenToIgnoreSet( n, ignoreSet );
+ }
+ else if ( n is XMLElementNode c && c.nodeName.StartsWith( "doc-code" ))
+ {
+ if ( c.nodeName == "doc-code-block" )
+ {
+ d.Append( "[codeblock]");
+ d.Append( c.textContent );
+ d.Append( "[/codeblock]");
+ }
+ else
+ {
+ d.Append( "[code]");
+ d.Append( c.textContent );
+ d.Append( "[/code]");
+ }
+
+ AddChildrenToIgnoreSet( n, ignoreSet );
+ }
+ else if ( n is XMLElementNode m && m.nodeName.StartsWith( "doc-link-" ))
+ {
+ d.Append( "[");
+
+ var name = m.nodeName.Replace( "doc-link-", "" );
+
+ if ( name != "class" )
+ {
+ d.Append( name );
+ d.Append( " " );
+ }
+
+ d.Append( m.textContent );
+ d.Append( "]");
+
+ AddChildrenToIgnoreSet( n, ignoreSet );
+ }
+ else if ( n is XMLTextNode )
+ {
+ d.Append( n.textContent );
+ }
+ },
+ false
+ );
+
+
+ var dString = RegexUtility.Indent( d.ToString(), " ");
+
+ var docLines = RegexUtility.SplitLines( dString );
+
+ var gdComment = "##" + docLines.Join( "\n##" ) + "\n";
+
+ return gdComment;
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/CodeGenerators/GDScript/CSDocToGDScriptDoc.cs.uid b/Runtime/Text/CodeGenerators/GDScript/CSDocToGDScriptDoc.cs.uid
new file mode 100644
index 0000000..833f03c
--- /dev/null
+++ b/Runtime/Text/CodeGenerators/GDScript/CSDocToGDScriptDoc.cs.uid
@@ -0,0 +1 @@
+uid://bwskdk8sbbaqo
diff --git a/Runtime/Text/CodeGenerators/GDScript/GDScriptFromCSAST.cs b/Runtime/Text/CodeGenerators/GDScript/GDScriptFromCSAST.cs
index 8fdf53f..de27579 100644
--- a/Runtime/Text/CodeGenerators/GDScript/GDScriptFromCSAST.cs
+++ b/Runtime/Text/CodeGenerators/GDScript/GDScriptFromCSAST.cs
@@ -46,27 +46,116 @@ public class GDScriptFromCSAST
return sb.ToString();
}
+ static HashSet godotBuiltIn = new HashSet(){
+ "Node", "Node3D", "Node2D", "Control",
+ "Resource",
+ "Vector2", "Vector3", "Vector4"
+ };
+
+
+ public static bool IsGodotBuiltIn( string type )
+ {
+ return godotBuiltIn.Contains( type );
+ }
+
+
+ public static bool IsCSBuiltIn( string type )
+ {
+
+ return godotBuiltIn.Contains( type );
+ }
+
+ public static string GetNamespaceForType( string typeName, List namespaces )
+ {
+ var assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
+
+ foreach ( var ns in namespaces )
+ {
+ string fullName = ns + "." + typeName;
+
+ foreach ( var asm in assemblies )
+ {
+ if ( asm.GetType( fullName, false ) != null)
+ {
+ return ns;
+ }
+ }
+ }
+
+ return null;
+ }
public string GetClassName( string className, string ns )
{
- if ( ns.StartsWith( "Rokojori" ) )
+ if ( ns != null && ! ns.StartsWith( "Rokojori" ) )
{
- return rokojoriPrefix + className;
+ return className;
}
- return className;
+ if ( ns == null && IsGodotBuiltIn( className ) )
+ {
+ return className;
+ }
+
+ return rokojoriPrefix + className;
}
+ List namespaces = new List{
+ "Godot","Godot.Collections",
+ "Rokojori"
+ };
+
+
+ string ConvertRawType( string type )
+ {
+ var ns = GetNamespaceForType( type, namespaces );
+
+ if ( ns == null )
+ {
+ return type;
+ }
+
+ if ( ns.StartsWith( "Rokojori" ) )
+ {
+ return rokojoriPrefix + type;
+ }
+
+ return type;
+ }
+
+ string ConvertType( CSTypeDefinition parent )
+ {
+ if ( parent.IsGenericList() )
+ {
+ var convertedType = ConvertRawType( parent.GetGenericType() );
+ return "Array[" + convertedType + "]";
+ }
+
+ if ( parent.IsArrayType() )
+ {
+ var convertedType = ConvertRawType( parent.GetBaseType() );
+ return "Array[" + convertedType + "]";
+ }
+
+ return ConvertRawType( parent.GetBaseType() );
+ }
+
+
public void Convert( CSFileRoot root )
{
var walker = root.walker;
var csClass = walker.Find( root, n => n is CSClassDeclaration, true ) as CSClassDeclaration;
- gdClass.name = GetClassName( csClass.GetClassName(), "Rokojori" );
+ gdClass.name = GetClassName( csClass.GetClassName(), csClass.GetNamespace() );
if ( csClass.objectTail != null && csClass.objectTail.inheritanceDeclaration != null )
{
- gdClass.extendingClassName = GetClassName( csClass.objectTail.GetExtendingObject(), "Rokojori" );
+ gdClass.extendingClassName = GetClassName( csClass.objectTail.GetExtendingObject(), null );
+ }
+
+ if ( csClass.docComment != null )
+ {
+ gdClass.doc = CSDocToGDScriptDoc.ConvertDoc( csClass.GetDocumentation() );
}
var atts = CSModifierAttributesParser.GetAttributes( csClass.attributeBrackets );
@@ -122,7 +211,7 @@ public class GDScriptFromCSAST
{
var gdField = new GDScriptGeneratorField();
gdField.name = CStoGDVariable( f.GetMemberName() );
- gdField.memberType = f.GetMemberType();
+ gdField.memberType = ConvertType( f.memberType );
gdMember = gdField;
}
@@ -130,7 +219,7 @@ public class GDScriptFromCSAST
{
var gdMethod = new GDScriptGeneratorMethod();
gdMethod.name = me.isContructor ? "_init" : CStoGDVariable( me.GetMemberName() );
- gdMethod.memberType = me.GetMemberType();
+ gdMethod.memberType = me.isContructor ? me.GetMemberType() : ConvertType( me.memberType );
gdMethod.isConstructor = me.isContructor;
if ( me.parametersContent != null )
@@ -142,7 +231,7 @@ public class GDScriptFromCSAST
var gdParameter = new GDScriptGeneratorParameter();
gdParameter.name = p.GetParameterName();
- gdParameter.parameterType = p.GetParameterType();
+ gdParameter.parameterType = ConvertType( p.parameterType );
gdMethod.parameters.Add( gdParameter );
@@ -162,6 +251,11 @@ public class GDScriptFromCSAST
return;
}
+ if ( m.docComment != null )
+ {
+ gdMember.doc = CSDocToGDScriptDoc.ConvertDoc( m.GetDocumentation() );
+ }
+
if ( CSModifierAttributesParser.IsExported( m.attributeBrackets ) )
{
gdMember.annotations.Add( "export" );
diff --git a/Runtime/Text/CodeGenerators/GDScript/GDScriptGenerator.cs b/Runtime/Text/CodeGenerators/GDScript/GDScriptGenerator.cs
index 585981c..d5c6b48 100644
--- a/Runtime/Text/CodeGenerators/GDScript/GDScriptGenerator.cs
+++ b/Runtime/Text/CodeGenerators/GDScript/GDScriptGenerator.cs
@@ -10,7 +10,6 @@ public class GDScriptGenerator
public static readonly string GD_SCRIPT_TRANSPILING = "GD_SCRIPT_TRANSPILING";
public List gdClasses = new List();
-
public void Generate( string outputPath )
{
gdClasses.ForEach(
diff --git a/Runtime/Text/CodeGenerators/GDScript/GDScriptGeneratorClass.cs b/Runtime/Text/CodeGenerators/GDScript/GDScriptGeneratorClass.cs
index d733200..61810b8 100644
--- a/Runtime/Text/CodeGenerators/GDScript/GDScriptGeneratorClass.cs
+++ b/Runtime/Text/CodeGenerators/GDScript/GDScriptGeneratorClass.cs
@@ -9,6 +9,7 @@ public class GDScriptGeneratorClass
{
public List annotations = [];
public string name;
+ public string doc;
public string extendingClassName;
public List members = [];
@@ -28,12 +29,23 @@ public class GDScriptGeneratorClass
);
AddClassHeader();
- sb.Append( "\n" );
+
+
+ if ( doc != null )
+ {
+ sb.Append( doc );
+ sb.Append( "\n" );
+ }
members.ForEach( m =>
{
+ if ( m.doc != null )
+ {
+ sb.Append( m.doc );
+ }
+
m.Generate( sb );
- sb.Append( "\n" );
+ sb.Append( "\n\n" );
});
return sb.ToString();
diff --git a/Runtime/Text/CodeGenerators/GDScript/GDScriptGeneratorMember.cs b/Runtime/Text/CodeGenerators/GDScript/GDScriptGeneratorMember.cs
index 7684242..c7bbcef 100644
--- a/Runtime/Text/CodeGenerators/GDScript/GDScriptGeneratorMember.cs
+++ b/Runtime/Text/CodeGenerators/GDScript/GDScriptGeneratorMember.cs
@@ -8,6 +8,7 @@ namespace Rokojori;
public abstract class GDScriptGeneratorMember
{
public string name;
+ public string doc;
public string memberType;
public List annotations = [];
diff --git a/Runtime/Text/Lexing/LexerLibrary/XMLLexer.cs b/Runtime/Text/Lexing/LexerLibrary/XMLLexer.cs
index 0233feb..8569344 100644
--- a/Runtime/Text/Lexing/LexerLibrary/XMLLexer.cs
+++ b/Runtime/Text/Lexing/LexerLibrary/XMLLexer.cs
@@ -36,7 +36,7 @@ namespace Rokojori
public static readonly LexerMatcher XMLText =
- new LexerMatcher( "XMLText", @"([^<].)" );
+ new LexerMatcher( "XMLText", @"([^<]+)" );
public static readonly LexerMatcher XMLAttributeName =
new LexerMatcher( "XMLAttributeName",
@@ -126,6 +126,7 @@ namespace Rokojori
XMLLexer.XMLAttributeAssignment,
XMLLexer.InsideStartTag_WhiteSpaceMatcher,
XMLLexer.InsideStartTag_BreakMatcher
+
);
}
diff --git a/Runtime/Text/Lexing/LexerMatcherLibrary.cs b/Runtime/Text/Lexing/LexerMatcherLibrary.cs
index fa998f9..238e4a0 100644
--- a/Runtime/Text/Lexing/LexerMatcherLibrary.cs
+++ b/Runtime/Text/Lexing/LexerMatcherLibrary.cs
@@ -60,7 +60,7 @@ namespace Rokojori
new LexerMatcher( "Bool", "true|false" );
public static readonly LexerMatcher LogicMatcher =
- new LexerMatcher( "Logic", "if|else|switch|do|while|for|break|continue|return" );
+ new LexerMatcher( "Logic", "if|else|switch|do|while|foreach|for|break|continue|return|try|catch|lock|throw|await" );
public static readonly LexerMatcher OperatorMatcher =
new LexerMatcher( "Operator", "(?:\\=\\=)|(?:\\+\\+)|(?:\\-\\-)|(?:\\+\\=)|(?:\\*\\=)|(?:\\-\\=)|(?:\\/\\=)|(?:\\=\\>)|\\+|\\-|\\*|\\/|\\^|\\|\\||\\||\\~|\\&\\&|\\&|\\%|\\<|\\>|\\=|\\!|\\.|\\:|\\,|\\;" );
diff --git a/Runtime/Text/Parsing/AST/ASTNode.cs b/Runtime/Text/Parsing/AST/ASTNode.cs
index f1e43ee..0f77ca9 100644
--- a/Runtime/Text/Parsing/AST/ASTNode.cs
+++ b/Runtime/Text/Parsing/AST/ASTNode.cs
@@ -39,6 +39,63 @@ public abstract class ASTNode
}
+ public virtual ASTViewNode CreateViewNode()
+ {
+ var viewNode = new ASTViewElement();
+
+ if ( this is OperatorExpression )
+ {
+ viewNode = new ASTViewExpression();
+ }
+ else if (
+ this is ClassDeclaration ||
+ this is EnumDeclaration ||
+ this is InterfaceDeclaration
+ )
+ {
+ viewNode = new ASTViewObject();
+ }
+ else if ( this is MemberDeclaration )
+ {
+ viewNode = new ASTViewMember();
+ }
+ else if ( this is Statement )
+ {
+ viewNode = new ASTViewStatement();
+ }
+
+
+ viewNode.astNodeReference = this;
+
+
+ var type = GetType();
+ viewNode.astNodeType = type.Name;
+ viewNode.Name = type.Name;
+
+ if ( viewNode is ASTViewMember )
+ {
+ var md = this as MemberDeclaration;
+ viewNode.Name += " [ " + md.GetMemberName() + " ]";
+ }
+
+ if ( this is ClassDeclaration cd )
+ {
+ viewNode.Name += " [ " + cd.GetClassName() + " ]";
+ }
+
+ if ( this is InterfaceDeclaration id )
+ {
+ viewNode.Name += " [ " + id.GetInterfaceName() + " ]";
+ }
+
+ if ( this is EnumDeclaration ed )
+ {
+ viewNode.Name += " [ " + ed.GetEnumName() + " ]";
+ }
+
+ return viewNode;
+ }
+
public string CreateDebugTreeInfo()
{
var walker = ASTWalker.instance;
@@ -128,6 +185,11 @@ public abstract class ASTNode
var start = indexStart + 1;
var length = indexEnd - start;
+ if ( length <= 0 )
+ {
+ return null;
+ }
+
return MergeChildrenWith( start, length );
}
@@ -188,9 +250,40 @@ public abstract class ASTNode
return tk.match;
}
- var tokens = children.FilterType();
+ var sb = new StringBuilder();
- return tokens.Map( t => t.match ).Join( "" );
+ for ( int i = 0; i < children.Count; i++ )
+ {
+ sb.Append( children[ i ].CombinedMatch() );
+ }
+
+ // var tokens = children.FilterType();
+
+ // return tokens.Map( t => t.match ).Join( "" );
+
+ return sb.ToString();
+ }
+
+ public void ExpandToNext( ASTNode nextSibling )
+ {
+ if ( parent == null || nextSibling == null || parent != nextSibling.parent )
+ {
+ RJLog.Error( "Invalid sibling", nextSibling?.GetType().Name ?? "null" );
+ return;
+ }
+
+ var start = childIndex + 1; // A, B, C, D
+ var length = ( nextSibling.childIndex - start ) + 1 ;
+
+ var beforeCount = children.Count;
+
+ var range = parent.children.Sub( start, length );
+ parent.children.RemoveRange( start, length );
+
+ range.ForEach( r => r.parent = this );
+ children.AddRange( range );
+
+ RJLog.Log( "Expanded from", beforeCount, "to", children.Count, "( " + length + " )" );
}
public void ExpandToPrevious( ASTNode previousSibling )
@@ -489,6 +582,29 @@ public abstract class ASTNode
return IsAnyTokenOf( LexerMatcherLibrary.Ignore );
}
+ public bool IsEmptyOrIgnore()
+ {
+ if ( IsIgnoreToken() )
+ {
+ return true;
+ }
+
+ if ( children.Count == 0 )
+ {
+ return true;
+ }
+
+ for ( int i = 0; i < children.Count; i++ )
+ {
+ if ( ! children[ i ].IsIgnoreToken() )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
public int IndexOffset( int index, int offset )
{
if ( offset < 0 )
@@ -852,6 +968,11 @@ public abstract class ASTNode
return false;
}
+ public int FindSemicolonIndex( int offset )
+ {
+ return FindTriggerTokenIndex( offset, TokenPredicateData.Semicolon, TokenPredicateData.BlockPredicates );
+ }
+
public int FindTriggerTokenIndex( int offset, List triggerPredicates, List blockPredicates )
{
var blockTypesCounter = new List();
@@ -915,4 +1036,28 @@ public abstract class ASTNode
return -1;
}
+ public string GetOuterRangeMatch( int start, int end )
+ {
+ var sb = new StringBuilder();
+
+ for ( int i = start; i <= end; i++ )
+ {
+ sb.Append( children[ i ].CombinedMatch() );
+ }
+
+ return sb.ToString();
+ }
+
+ public string GetInnerRangeMatch( int start, int end )
+ {
+ var sb = new StringBuilder();
+
+ for ( int i = start + 1; i < end ; i++ )
+ {
+ sb.Append( children[ i ].CombinedMatch() );
+ }
+
+ return sb.ToString();
+ }
+
}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/ASTWalker.cs b/Runtime/Text/Parsing/AST/ASTWalker.cs
index a8b42e7..62b3849 100644
--- a/Runtime/Text/Parsing/AST/ASTWalker.cs
+++ b/Runtime/Text/Parsing/AST/ASTWalker.cs
@@ -6,6 +6,7 @@ using System.Text;
using System.Globalization;
using Godot;
using System;
+using System.Reflection;
namespace Rokojori;
@@ -33,4 +34,107 @@ public class ASTWalker:TreeWalker
{
return node?.children.Count ?? 0;
}
-}
\ No newline at end of file
+}
+
+public class ASTReferenceWalker:TreeWalker
+{
+ public override ASTNode Parent( ASTNode node )
+ {
+ return node?.parent;
+ }
+
+ public override int NumChildren( ASTNode node )
+ {
+ if ( node == null )
+ {
+ return 0;
+ }
+
+ if ( node is ASTFileRoot || node is ASTNodeList )
+ {
+ return node.children.Count;
+ }
+
+ if ( node is SeparatedSequenceExpression se )
+ {
+ return se.GetExpressions().Count;
+ }
+
+ GrabInfo( node );
+ return _typeFieldInfos[ node.GetType() ].Count;
+ }
+
+ public override ASTNode ChildAt( ASTNode node, int index )
+ {
+ if ( node == null || index < 0 || index >= node.children.Count )
+ {
+ return null;
+ }
+
+ if ( node is ASTFileRoot || node is ASTNodeList )
+ {
+ return node.children[ index ];
+ }
+
+ if ( node is SeparatedSequenceExpression se )
+ {
+ return se.GetExpressions()[ index ];
+ }
+
+ GrabInfo( node );
+ var fieldInfos = _typeFieldInfos[ node.GetType() ];
+ return fieldInfos[ index ].GetValue( node ) as ASTNode;
+ }
+
+ public string GetParentReferenceName( ASTNode node )
+ {
+ var parent = Parent( node );
+
+ if ( parent == null )
+ {
+ return "";
+ }
+
+
+ var index = ChildIndexOf( node );
+
+ return GetChildReferenceName( parent, index );
+ }
+
+ public string GetChildReferenceName( ASTNode node, int index )
+ {
+ if ( node is ASTFileRoot || node is ASTNodeList || node is SeparatedSequenceExpression )
+ {
+ return index + "";
+ }
+
+ GrabInfo( node );
+
+ var fieldInfos = _typeFieldInfos[ node.GetType() ];
+
+ return fieldInfos[ index ].Name;
+ }
+
+ Dictionary> _typeFieldInfos = new Dictionary>();
+
+ void GrabInfo( ASTNode node )
+ {
+ if ( node == null )
+ {
+ return;
+ }
+
+ var type = node.GetType();
+
+ if ( _typeFieldInfos.ContainsKey( type ) )
+ {
+ return;
+ }
+
+ _typeFieldInfos[ type ] = ReflectionHelper.GetFieldInfosOfType( node );
+
+
+ }
+
+
+}
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewAttribute.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewAttribute.cs
new file mode 100644
index 0000000..e3eaf2a
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewAttribute.cs
@@ -0,0 +1,16 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewAttribute.svg")]
+public partial class ASTViewAttribute:ASTViewElement
+{
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewAttribute.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewAttribute.cs.uid
new file mode 100644
index 0000000..17330c6
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewAttribute.cs.uid
@@ -0,0 +1 @@
+uid://byagp5r8ju6rb
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewBracketToken.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewBracketToken.cs
new file mode 100644
index 0000000..e89ad64
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewBracketToken.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewBracketToken.svg")]
+public partial class ASTViewBracketToken: ASTViewToken
+{
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewBracketToken.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewBracketToken.cs.uid
new file mode 100644
index 0000000..edfe5a3
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewBracketToken.cs.uid
@@ -0,0 +1 @@
+uid://xtiqx3nv83cr
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewConstantToken.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewConstantToken.cs
new file mode 100644
index 0000000..b60c2ce
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewConstantToken.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewConstantToken.svg")]
+public partial class ASTViewConstantToken: ASTViewToken
+{
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewConstantToken.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewConstantToken.cs.uid
new file mode 100644
index 0000000..ac99d06
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewConstantToken.cs.uid
@@ -0,0 +1 @@
+uid://geu1beuih0rh
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewContext.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewContext.cs
new file mode 100644
index 0000000..9c4e0e0
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewContext.cs
@@ -0,0 +1,249 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewContext.svg")]
+public partial class ASTViewContext:Node
+{
+ bool _hideTokens = false;
+
+ [Export]
+ public bool hideTokens
+ {
+ get => _hideTokens;
+ set { _hideTokens = value; UpdateValue(); }
+ }
+
+ void UpdateValue()
+ {
+ this.ForEach(
+ ( n )=>
+ {
+ n.UpdateFromViewContext( this );
+ }
+ );
+ }
+
+
+ public enum ViewType
+ {
+ Tree_Structure,
+ References_Only
+ }
+
+ [Export]
+ public ViewType viewType = ViewType.Tree_Structure;
+
+
+ Dictionary _nodeToView = new Dictionary();
+ List _elements = [];
+
+ public void ClearFilters()
+ {
+ _hideTokens = false;
+ }
+
+ public void Create( ASTNode root )
+ {
+ if ( ViewType.Tree_Structure == viewType )
+ {
+ CreateTreeStructure( root );
+ }
+ else
+ {
+ CreateReferenceStructure( root );
+ }
+ }
+
+ void CreateReferenceElement( string referenceName, ASTNode node, HashSet processed, ASTViewNode parentViewNode, ASTReferenceWalker walker )
+ {
+ if ( node == null || node.IsIgnoreToken() || processed.Contains( node ) )
+ {
+ return;
+ }
+
+ processed.Add( node );
+
+
+
+ Node attachingNode = parentViewNode == null ? this : parentViewNode;
+
+ var viewNode = node.CreateViewNode();
+ viewNode.Name = "-[ " + referenceName + " ] '" + viewNode.Name + "'";
+
+ if ( attachingNode.HasDirectChildWithName( viewNode.Name ) )
+ {
+ viewNode.Name += "(" + node.childIndex +")";
+ }
+
+
+ attachingNode.AddChild( viewNode );
+
+
+ viewNode.Owner = this.Owner;
+
+ var numKids = walker.NumChildren( node );
+
+ for ( int i = 0; i < numKids; i++ )
+ {
+ var name = walker.GetChildReferenceName( node, i );
+ CreateReferenceElement( name, walker.ChildAt( node, i ), processed, viewNode, walker );
+ }
+ }
+
+ void CreateReferenceStructure( ASTNode root )
+ {
+ this.ClearFilters();
+
+ this.DestroyChildren();
+ _nodeToView.Clear();
+ _elements.Clear();
+
+
+ var walker = new ASTReferenceWalker();
+
+ var processed = new HashSet();
+
+ CreateReferenceElement( "root", root, processed, null, walker );
+
+ // var it = root;
+ // var id = 0;
+
+ // while ( it != null )
+ // {
+ // if ( it.IsIgnoreToken() )
+ // {
+ // var before = it;
+
+ // it = walker.NextNode( it );
+ // this.LogInfo( "Ignoring:", before, " next:", it );
+ // continue;
+ // }
+
+ // var viewNode = it.CreateViewNode();
+ // var references = new List();
+
+
+
+ // var numKids = walker.NumChildren( it );
+ // var parentName = walker.GetParentReferenceName( it );
+
+ // this.LogInfo( viewNode.Name, parentName, numKids );
+
+ // viewNode.Name = walker.GetParentReferenceName( it ) + " " + viewNode.Name +" (" + id + ")";
+ // id ++;
+ // Node parentNode = it == root ? this : _nodeToView[ it.parent ];
+
+ // parentNode.AddChild( viewNode );
+
+ // if ( viewNode is ASTViewElement el )
+ // {
+ // _elements.Add( el );
+ // }
+
+ // _nodeToView[ it ] = viewNode;
+
+ // viewNode.Owner = Owner;
+ // it = walker.NextNode( it );
+ // }
+
+ // _elements.ForEach(
+ // ( e )=>
+ // {
+ // var references = ReflectionHelper.GetFieldInfosOfType( e.astNodeReference );
+ // references.ForEach(
+ // r =>
+ // {
+ // // if ( r.Name == "parent" )
+ // // {
+ // // return;
+ // // }
+
+ // var nodeRef = new ASTViewNodeReference();
+ // nodeRef.name = r.Name;
+
+ // var node = r.GetValue( e.astNodeReference ) as ASTNode;
+ // var viewNode = _nodeToView[ node ];
+ // nodeRef.node = e.GetPathTo( viewNode );
+
+ // e.references = e.references.Add( nodeRef );
+ // }
+ // );
+ // }
+ // );
+ }
+
+ void CreateTreeStructure( ASTNode root )
+ {
+ this.ClearFilters();
+
+ this.DestroyChildren();
+ _nodeToView.Clear();
+ _elements.Clear();
+
+
+ var walker = new ASTWalker();
+
+ var it = root;
+ var id = 0;
+
+ while ( it != null )
+ {
+ if ( it.IsIgnoreToken() )
+ {
+ it = walker.NextNode( it );
+ continue;
+ }
+
+ var viewNode = it.CreateViewNode();
+ viewNode.Name += " (" + id + ")";
+ id ++;
+ Node parentNode = it == root ? this : _nodeToView[ it.parent ];
+
+ parentNode.AddChild( viewNode );
+
+ if ( viewNode is ASTViewElement el )
+ {
+ _elements.Add( el );
+ }
+
+ _nodeToView[ it ] = viewNode;
+
+ viewNode.Owner = Owner;
+ it = walker.NextNode( it );
+ }
+
+ _elements.ForEach(
+ ( e )=>
+ {
+ var references = ReflectionHelper.GetFieldInfosOfType( e.astNodeReference );
+ references.ForEach(
+ r =>
+ {
+ // if ( r.Name == "parent" )
+ // {
+ // return;
+ // }
+
+ var nodeRef = new ASTViewNodeReference();
+ nodeRef.name = r.Name;
+
+ var node = r.GetValue( e.astNodeReference ) as ASTNode;
+ var viewNode = _nodeToView[ node ];
+ nodeRef.node = e.GetPathTo( viewNode );
+
+ e.references = e.references.Add( nodeRef );
+ }
+ );
+ }
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewContext.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewContext.cs.uid
new file mode 100644
index 0000000..f11467a
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewContext.cs.uid
@@ -0,0 +1 @@
+uid://mj8247c4u8xo
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewElement.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewElement.cs
new file mode 100644
index 0000000..92cb11c
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewElement.cs
@@ -0,0 +1,51 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewElement.svg")]
+public partial class ASTViewElement:ASTViewNode
+{
+ [Export]
+ public ASTViewNodeReference[] references = [];
+
+
+ List originalNodes;
+
+
+ public override void UpdateFromViewContext( ASTViewContext context )
+ {
+ if ( originalNodes == null )
+ {
+ originalNodes = this.GetDirectChildren();
+ // this.LogInfo( "Grabbed children:", originalNodes.Count );
+ }
+
+ var removalNodes = new List();
+
+ originalNodes.ForEach(
+ n =>
+ {
+ if ( n.astNodeReference is Token && context.hideTokens )
+ {
+ removalNodes.Add( n );
+ }
+ }
+ );
+
+ removalNodes.ForEach(
+ ( n )=>
+ {
+ RemoveChild( n );
+ }
+ );
+
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewElement.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewElement.cs.uid
new file mode 100644
index 0000000..d96ab75
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewElement.cs.uid
@@ -0,0 +1 @@
+uid://duaphjoad55ay
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewExpression.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewExpression.cs
new file mode 100644
index 0000000..2e387ee
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewExpression.cs
@@ -0,0 +1,16 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewExpression.svg")]
+public partial class ASTViewExpression:ASTViewElement
+{
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewExpression.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewExpression.cs.uid
new file mode 100644
index 0000000..c3a2532
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewExpression.cs.uid
@@ -0,0 +1 @@
+uid://blesadf7ul1pb
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewIgnoreToken.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewIgnoreToken.cs
new file mode 100644
index 0000000..d7d2893
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewIgnoreToken.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewIgnoreToken.svg")]
+public partial class ASTViewIgnoreToken: ASTViewToken
+{
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewIgnoreToken.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewIgnoreToken.cs.uid
new file mode 100644
index 0000000..59e2027
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewIgnoreToken.cs.uid
@@ -0,0 +1 @@
+uid://dpxl5ulh7ebnm
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewLogicToken.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewLogicToken.cs
new file mode 100644
index 0000000..4acb16d
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewLogicToken.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewLogicToken.svg")]
+public partial class ASTViewLogicToken: ASTViewToken
+{
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewLogicToken.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewLogicToken.cs.uid
new file mode 100644
index 0000000..46a3455
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewLogicToken.cs.uid
@@ -0,0 +1 @@
+uid://gm0ntnqork55
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewMember.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewMember.cs
new file mode 100644
index 0000000..bf80458
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewMember.cs
@@ -0,0 +1,17 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewMember.svg")]
+public partial class ASTViewMember:ASTViewElement
+{
+ [Export]
+ public string memberName;
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewMember.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewMember.cs.uid
new file mode 100644
index 0000000..c85397a
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewMember.cs.uid
@@ -0,0 +1 @@
+uid://cbdpgoxkdef7n
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewNode.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewNode.cs
new file mode 100644
index 0000000..08dcd6d
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewNode.cs
@@ -0,0 +1,25 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool]
+public abstract partial class ASTViewNode:Node
+{
+ [Export]
+ public string astNodeType;
+
+ public ASTNode astNodeReference;
+
+ public virtual void UpdateFromViewContext( ASTViewContext context )
+ {
+
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewNode.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewNode.cs.uid
new file mode 100644
index 0000000..6fe8f17
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewNode.cs.uid
@@ -0,0 +1 @@
+uid://bwwarqqq0sy8f
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewNodeReference.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewNodeReference.cs
new file mode 100644
index 0000000..89f3136
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewNodeReference.cs
@@ -0,0 +1,20 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool]
+public partial class ASTViewNodeReference:Resource
+{
+ [Export]
+ public string name;
+
+ [Export]
+ public NodePath node;
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewNodeReference.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewNodeReference.cs.uid
new file mode 100644
index 0000000..4cfa079
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewNodeReference.cs.uid
@@ -0,0 +1 @@
+uid://dmojbxb76nklf
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewObject.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewObject.cs
new file mode 100644
index 0000000..7381c62
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewObject.cs
@@ -0,0 +1,16 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewObject.svg")]
+public partial class ASTViewObject:ASTViewElement
+{
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewObject.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewObject.cs.uid
new file mode 100644
index 0000000..1d7e04d
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewObject.cs.uid
@@ -0,0 +1 @@
+uid://c6vg57y73dsaj
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewOperatorToken.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewOperatorToken.cs
new file mode 100644
index 0000000..2343bdd
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewOperatorToken.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewOperatorToken.svg")]
+public partial class ASTViewOperatorToken: ASTViewToken
+{
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewOperatorToken.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewOperatorToken.cs.uid
new file mode 100644
index 0000000..66fe3d4
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewOperatorToken.cs.uid
@@ -0,0 +1 @@
+uid://ceb3clbln6hj7
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewRoot.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewRoot.cs
new file mode 100644
index 0000000..a2a8ea8
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewRoot.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewRoot.svg")]
+public partial class ASTViewRoot:ASTViewElement
+{
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewRoot.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewRoot.cs.uid
new file mode 100644
index 0000000..75e2ab6
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewRoot.cs.uid
@@ -0,0 +1 @@
+uid://dw5wntaroqkip
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewStatement.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewStatement.cs
new file mode 100644
index 0000000..4cd6fee
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewStatement.cs
@@ -0,0 +1,16 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewStatement.svg")]
+public partial class ASTViewStatement:ASTViewElement
+{
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewStatement.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewStatement.cs.uid
new file mode 100644
index 0000000..7dde1fe
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewStatement.cs.uid
@@ -0,0 +1 @@
+uid://cyurgwe2nq4xq
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewToken.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewToken.cs
new file mode 100644
index 0000000..6cf4d0e
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewToken.cs
@@ -0,0 +1,30 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewToken.svg")]
+public partial class ASTViewToken: ASTViewNode
+{
+ [Export]
+ public string tokenType;
+
+ [Export]
+ public string match;
+
+ [Export]
+ public int characterOffset;
+
+ [Export]
+ public int line;
+
+ [Export]
+ public int lineOffset;
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewToken.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewToken.cs.uid
new file mode 100644
index 0000000..5e042e5
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewToken.cs.uid
@@ -0,0 +1 @@
+uid://dm77biqwbp4fc
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewWordToken.cs b/Runtime/Text/Parsing/AST/Debug/ASTViewWordToken.cs
new file mode 100644
index 0000000..aa48aeb
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewWordToken.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+[Tool, Icon("res://addons/rokojori_action_library/Icons/ASTViewWordToken.svg")]
+public partial class ASTViewWordToken: ASTViewToken
+{
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/AST/Debug/ASTViewWordToken.cs.uid b/Runtime/Text/Parsing/AST/Debug/ASTViewWordToken.cs.uid
new file mode 100644
index 0000000..b6e7c76
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Debug/ASTViewWordToken.cs.uid
@@ -0,0 +1 @@
+uid://cxfsprsr12ker
diff --git a/Runtime/Text/Parsing/AST/Matchers/ASTMatchResult.cs b/Runtime/Text/Parsing/AST/Matchers/ASTMatchResult.cs
index d0ea560..05b552f 100644
--- a/Runtime/Text/Parsing/AST/Matchers/ASTMatchResult.cs
+++ b/Runtime/Text/Parsing/AST/Matchers/ASTMatchResult.cs
@@ -34,6 +34,8 @@ public class ASTMatchResult
matched = true;
}
+
+
public int matchLength => ( resultEnd - resultStart ) + 1;
@@ -51,5 +53,14 @@ public class ASTMatchResult
return c;
}
+ public void CopyFrom( ASTMatchResult other )
+ {
+ parent = other.parent;
+ childOffset = other.childOffset;
+ resultStart = other.resultStart;
+ resultEnd = other.resultEnd;
+ matched = other.matched;
+ }
+
}
diff --git a/Runtime/Text/Parsing/AST/Matchers/NotIgnoreNodeMatcher.cs b/Runtime/Text/Parsing/AST/Matchers/NotIgnoreNodeMatcher.cs
new file mode 100644
index 0000000..a608527
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Matchers/NotIgnoreNodeMatcher.cs
@@ -0,0 +1,28 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+public class NotIgnoreNodeMatcher:ASTMatcher
+{
+ public override void Match( ASTMatchResult result )
+ {
+ var parent = result.parent;
+ var searchOffset = result.childOffset;
+ var node = parent.children[ searchOffset ];
+
+ if ( node.IsIgnoreToken() )
+ {
+ return;
+ }
+
+ result.SetMatched( node.childIndex );
+
+ }
+}
diff --git a/Runtime/Text/Parsing/AST/Matchers/NotIgnoreNodeMatcher.cs.uid b/Runtime/Text/Parsing/AST/Matchers/NotIgnoreNodeMatcher.cs.uid
new file mode 100644
index 0000000..b2645da
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Matchers/NotIgnoreNodeMatcher.cs.uid
@@ -0,0 +1 @@
+uid://dnchqhhc46n13
diff --git a/Runtime/Text/Parsing/AST/Matchers/TokenMatcher.cs b/Runtime/Text/Parsing/AST/Matchers/TokenMatcher.cs
new file mode 100644
index 0000000..0e98594
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Matchers/TokenMatcher.cs
@@ -0,0 +1,28 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+
+using System.Globalization;
+using Godot;
+using System;
+
+namespace Rokojori;
+
+public class TokenMatcher:ASTMatcher
+{
+ public TokenPredicateData matchData;
+
+ public override void Match( ASTMatchResult result )
+ {
+ var parent = result.parent;
+ var searchOffset = result.childOffset;
+ var node = parent.children[ searchOffset ];
+
+ if ( matchData.Matches( node ) )
+ {
+ result.SetMatched( node.childIndex );
+ }
+
+ }
+}
diff --git a/Runtime/Text/Parsing/AST/Matchers/TokenMatcher.cs.uid b/Runtime/Text/Parsing/AST/Matchers/TokenMatcher.cs.uid
new file mode 100644
index 0000000..b603c43
--- /dev/null
+++ b/Runtime/Text/Parsing/AST/Matchers/TokenMatcher.cs.uid
@@ -0,0 +1 @@
+uid://cq2mxjoy6p5im
diff --git a/Runtime/Text/Parsing/AST/Resolver/ASTParser.cs b/Runtime/Text/Parsing/AST/Resolver/ASTParser.cs
index 5f2167d..a5accfa 100644
--- a/Runtime/Text/Parsing/AST/Resolver/ASTParser.cs
+++ b/Runtime/Text/Parsing/AST/Resolver/ASTParser.cs
@@ -18,19 +18,19 @@ public class ASTParser
public void Process()
{
- var result = Resolve();
+ var result = ResolveAll();
var steps = 0;
while ( result && steps < maxSteps)
{
RJLog.Log( "Step", steps );
- result = Resolve();
+ result = ResolveAll();
steps ++;
}
}
- bool Resolve()
+ bool ResolveAll()
{
var hasResult = false;
@@ -47,39 +47,87 @@ public class ASTParser
matchResult.childOffset = tokenOffset;
matchResult.parent = root;
- for ( int resolverIndex = 0; resolverIndex < resolvers.Count; resolverIndex++ )
- {
- var matcherResolver = resolvers[ resolverIndex ];
- matcherResolver.matcher.Match( matchResult );
+ var nextTokenOffset = ResolveNext( matchResult );
- if ( ! matchResult.matched )
- {
- // RJLog.Log( ">>> Not Matched:", resolverIndex, matcherResolver.matcher, matcherResolver );
-
- continue;
- }
-
- RJLog.Log( ">>> Matched:", resolverIndex, matcherResolver.matcher, matcherResolver );
-
- if ( root.children[ tokenOffset ] is Token tk )
- {
- RJLog.Log( "...", tk.lineInfo );
- }
-
- var resolvedOffset = matcherResolver.Resolve( matchResult, matcherResolver.matcher );
- tokenOffset = resolvedOffset;
-
+ if ( nextTokenOffset != -1 )
+ {
hasResult = true;
- resolverIndex = resolvers.Count;
-
- // RJLog.Log( "Matched:", matcherIndex, matcherResolver.matcher, matcherResolver );
- //return true;
+ tokenOffset = nextTokenOffset;
}
+
+ // for ( int resolverIndex = 0; resolverIndex < resolvers.Count; resolverIndex++ )
+ // {
+ // var matcherResolver = resolvers[ resolverIndex ];
+ // matcherResolver.matcher.Match( matchResult );
+
+ // if ( ! matchResult.matched )
+ // {
+ // // RJLog.Log( ">>> Not Matched:", resolverIndex, matcherResolver.matcher, matcherResolver );
+
+ // continue;
+ // }
+
+ // RJLog.Log( ">>> Matched:", resolverIndex, matcherResolver.matcher, matcherResolver );
+
+ // if ( root.children[ tokenOffset ] is Token tk )
+ // {
+ // RJLog.Log( "...", tk.lineInfo );
+ // }
+
+ // var resolvedOffset = matcherResolver.Resolve( matchResult, matcherResolver.matcher );
+ // tokenOffset = resolvedOffset;
+
+ // hasResult = true;
+ // resolverIndex = resolvers.Count;
+
+ // // RJLog.Log( "Matched:", matcherIndex, matcherResolver.matcher, matcherResolver );
+ // //return true;
+ // }
}
return hasResult;
}
+
+ public int ResolveNext( ASTMatchResult matchResult, bool debug = false )
+ {
+ var originalResult = matchResult.Clone();
+
+ for ( int resolverIndex = 0; resolverIndex < resolvers.Count; resolverIndex++ )
+ {
+ var matcherResolver = resolvers[ resolverIndex ];
+ matcherResolver.matcher.Match( matchResult );
+
+ if ( ! matchResult.matched )
+ {
+ if ( debug )
+ {
+ var token = matchResult.parent.children[ matchResult.childOffset ] as Token;
+ RJLog.Log( ">>> Not Matched:", resolverIndex, matcherResolver.matcher, matcherResolver, "at:", token, token?.lineInfo );
+ }
+ continue;
+ }
+
+ if ( debug )
+ {
+ RJLog.Log( ">>> Matched:", resolverIndex, matcherResolver.matcher, matcherResolver );
+ }
+
+ var resolvedOffset = matcherResolver.Resolve( matchResult, matcherResolver.matcher );
+
+ if ( resolvedOffset == -1 )
+ {
+ matchResult.CopyFrom( originalResult );
+ continue;
+ }
+
+ return resolvedOffset;
+
+ }
+
+ return -1;
+ }
+
// bool ResolveOld()
// {
// var hasResult = false;
diff --git a/Runtime/Text/Parsing/AST/Token.cs b/Runtime/Text/Parsing/AST/Token.cs
index fa6893e..dd27fc0 100644
--- a/Runtime/Text/Parsing/AST/Token.cs
+++ b/Runtime/Text/Parsing/AST/Token.cs
@@ -69,6 +69,50 @@ public class Token:ASTNode
return lexerEvent.Is( matcher.type, match );
}
+ public override ASTViewNode CreateViewNode()
+ {
+ LexerMatcher[] wordLike =
+ [
+ LexerMatcherLibrary.CwordMatcher,
+ LexerMatcherLibrary.CFunctionMatcher,
+ LexerMatcherLibrary.UsingMatcher,
+
+ LexerMatcherLibrary.AccessModifierMatcher,
+ LexerMatcherLibrary.CSAccessModifierMatcher,
+ LexerMatcherLibrary.ClassMatcher,
+ LexerMatcherLibrary.RecordMatcher,
+ LexerMatcherLibrary.StructMatcher,
+ LexerMatcherLibrary.InterfaceMatcher,
+ LexerMatcherLibrary.EnumMatcher,
+ ];
+
+ LexerMatcher[] constants =
+ [
+ LexerMatcherLibrary.BoolMatcher,
+ LexerMatcherLibrary.SingleQuotedStringMatcher,
+ LexerMatcherLibrary.DoubleQuotedStringMatcher,
+ LexerMatcherLibrary.NumberMatcher,
+ LexerMatcherLibrary.NullMatcher
+ ];
+
+
+ var viewNode = IsIgnoreToken() ? new ASTViewIgnoreToken() :
+ IsAnyTokenOf( wordLike ) ? new ASTViewWordToken() :
+ IsAnyTokenOf( constants ) ? new ASTViewConstantToken() :
+ IsToken( LexerMatcherLibrary.LogicMatcher ) ? new ASTViewLogicToken() :
+ IsToken( LexerMatcherLibrary.BracketMatcher ) ? new ASTViewBracketToken() :
+ IsToken( LexerMatcherLibrary.OperatorMatcher ) ? new ASTViewOperatorToken() :
+ new ASTViewToken();
+ viewNode.astNodeReference = this;
+ viewNode.astNodeType = GetType().Name;
+ viewNode.tokenType = type;
+ viewNode.match = match;
+ viewNode.characterOffset = lexerEvent.offset;
+ viewNode.Name = "Token " + type + " '" + match + "'";
+
+
+ return viewNode;
+ }
ASTFileRoot _root;
@@ -82,7 +126,8 @@ public class Token:ASTNode
}
var textLine = _root.GetTextLinesMapper().GetLine( lexerEvent.offset );
- return "[ " + textLine.textEditorLineIndex + " ] | " + textLine.GetContent( _root.GetSource() );
+ var anchor = _root.GetTextLinesMapper().GetAnchor( lexerEvent.offset, true );
+ return "[ " + anchor.lineIndex + ":" + anchor.characterIndex + " ] | " + textLine.GetContent( _root.GetSource() );
}
}
diff --git a/Runtime/Text/Parsing/AST/TokenPredicateData.cs b/Runtime/Text/Parsing/AST/TokenPredicateData.cs
index 7fd1837..687b9ed 100644
--- a/Runtime/Text/Parsing/AST/TokenPredicateData.cs
+++ b/Runtime/Text/Parsing/AST/TokenPredicateData.cs
@@ -12,9 +12,11 @@ namespace Rokojori;
public class TokenPredicateData
{
+
public string type;
public string match;
+
public bool Matches( ASTNode node )
{
return node.IsToken( type, match );
@@ -42,4 +44,39 @@ public class TokenPredicateData
var lexedSequence = Token.CreateLexedSequenceData( lexer, value );
return lexedSequence[ 0 ];
}
+
+ public static readonly List Semicolon = [
+ TokenPredicateData.Create(
+ LexerMatcherLibrary.OperatorMatcher.type, ";"
+ ),
+ ];
+
+ public static readonly List BlockPredicates = [
+
+ TokenPredicateData.Create(
+ LexerMatcherLibrary.BracketMatcher.type, "("
+ ),
+
+ TokenPredicateData.Create(
+ LexerMatcherLibrary.BracketMatcher.type, ")"
+ ),
+
+
+ TokenPredicateData.Create(
+ LexerMatcherLibrary.BracketMatcher.type, "{"
+ ),
+
+ TokenPredicateData.Create(
+ LexerMatcherLibrary.BracketMatcher.type, "{"
+ ),
+
+
+ TokenPredicateData.Create(
+ LexerMatcherLibrary.BracketMatcher.type, "["
+ ),
+
+ TokenPredicateData.Create(
+ LexerMatcherLibrary.BracketMatcher.type, "]"
+ )
+ ];
}
diff --git a/Runtime/Text/Parsing/Expressions/ExpressionParser.cs b/Runtime/Text/Parsing/Expressions/ExpressionParser.cs
index dbcf1f5..b0dc82c 100644
--- a/Runtime/Text/Parsing/Expressions/ExpressionParser.cs
+++ b/Runtime/Text/Parsing/Expressions/ExpressionParser.cs
@@ -12,8 +12,18 @@ public class ExpressionParser:ParserPhase
ProcessExpression( parser.root );
}
- public void ProcessExpression( ASTNode expressionParent )
+ public void ProcessExpression( ASTNode expressionParent, bool checkEmpty = true )
{
+ if ( expressionParent == null )
+ {
+ return;
+ }
+
+ if ( checkEmpty && expressionParent.IsEmptyOrIgnore() )
+ {
+ return;
+ }
+
var parser = expressionParent.parser;
for ( int i = 0; i < levels.Count; i++ )
diff --git a/Runtime/Text/Parsing/Expressions/Operators/ArrayExpression.cs b/Runtime/Text/Parsing/Expressions/Operators/ArrayExpression.cs
new file mode 100644
index 0000000..846f51b
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/ArrayExpression.cs
@@ -0,0 +1,49 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Rokojori;
+
+public interface IArrayExpression:OperatorExpression
+{
+ public void InitializeArrayExpression( ASTNode caller, Token leftBracket, ASTNode indexExpression, Token rightBracket );
+ public ASTNode GetCallerExpression();
+ public Token GetLeftBracket();
+ public ASTNode GetIndexExpression();
+ public Token GetRightBracket();
+}
+
+public class ArrayExpression:ASTNode,IArrayExpression
+{
+ public ASTNode caller;
+ public Token leftBracket;
+ public ASTNode indexExpression;
+ public Token rightBracket;
+
+ public void InitializeArrayExpression( ASTNode caller, Token leftBracket, ASTNode indexExpression, Token rightBracket )
+ {
+ this.caller = caller;
+ this.leftBracket = leftBracket;
+ this.indexExpression = indexExpression;
+ this.rightBracket = rightBracket;
+ }
+
+ public ASTNode GetCallerExpression()
+ {
+ return caller;
+ }
+
+ public Token GetLeftBracket()
+ {
+ return leftBracket;
+ }
+
+ public ASTNode GetIndexExpression()
+ {
+ return indexExpression;
+ }
+
+ public Token GetRightBracket()
+ {
+ return rightBracket;
+ }
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/Expressions/Operators/ArrayExpression.cs.uid b/Runtime/Text/Parsing/Expressions/Operators/ArrayExpression.cs.uid
new file mode 100644
index 0000000..461a598
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/ArrayExpression.cs.uid
@@ -0,0 +1 @@
+uid://hxennrht20l0
diff --git a/Runtime/Text/Parsing/Expressions/Operators/ArrayOperator.cs b/Runtime/Text/Parsing/Expressions/Operators/ArrayOperator.cs
new file mode 100644
index 0000000..dbcb9a3
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/ArrayOperator.cs
@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Rokojori;
+
+public class ArrayOperator:ExpressionOperator where T:ASTNode,IArrayExpression, new()
+{
+ bool _fromLeft = false;
+ TokenPredicateData endTokenPredicate;
+
+ public ArrayOperator()
+ {
+ startTokenPredicate = TokenPredicateData.Create( LexerMatcherLibrary.BracketMatcher.type, "[" );
+ endTokenPredicate = TokenPredicateData.Create( LexerMatcherLibrary.BracketMatcher.type, "]" );
+ }
+
+ public override bool IsFromLeft()
+ {
+ return _fromLeft;
+ }
+
+ public override bool ProcessStartNode( ASTNode parent, int startChildIndex )
+ {
+ var callerIndex = parent.PreviousIndex( startChildIndex );
+
+ var closingIndex = parent.FindBracketCloserIndex( "[" , "]", startChildIndex );
+
+ if ( callerIndex < 0 || closingIndex == -1 )
+ {
+ parent.parser.AddError( "Could not find caller expressions for " + this + " in parent:" + parent + " child start: " + startChildIndex );
+ return false;
+ }
+
+ var caller = parent.children[ callerIndex ];
+ var leftBracket = parent.children[ startChildIndex ] as Token;
+ var rightBracket = parent.children[ closingIndex ] as Token;
+
+ var arrayExpression = parent.MergeOuter( caller, rightBracket );
+ var indexExpression = arrayExpression.MergeInner( leftBracket, rightBracket );
+ arrayExpression.InitializeArrayExpression( caller, leftBracket, indexExpression, rightBracket );
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/Expressions/Operators/ArrayOperator.cs.uid b/Runtime/Text/Parsing/Expressions/Operators/ArrayOperator.cs.uid
new file mode 100644
index 0000000..443c131
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/ArrayOperator.cs.uid
@@ -0,0 +1 @@
+uid://md8g11odugrx
diff --git a/Runtime/Text/Parsing/Expressions/Operators/ExpressionOperator.cs b/Runtime/Text/Parsing/Expressions/Operators/ExpressionOperator.cs
index dc5ce79..cf783dd 100644
--- a/Runtime/Text/Parsing/Expressions/Operators/ExpressionOperator.cs
+++ b/Runtime/Text/Parsing/Expressions/Operators/ExpressionOperator.cs
@@ -6,6 +6,7 @@ namespace Rokojori;
public abstract class ExpressionOperator
{
public TokenPredicateData startTokenPredicate;
+ // public ExpressionParser expressionParser;
public virtual bool IsFromLeft()
{
diff --git a/Runtime/Text/Parsing/Expressions/Operators/FunctionExpression.cs b/Runtime/Text/Parsing/Expressions/Operators/FunctionExpression.cs
new file mode 100644
index 0000000..f29298e
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/FunctionExpression.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Rokojori;
+
+public interface IFunctionExpression:OperatorExpression
+{
+ public void InitializeFunctionExpression( Token name, GroupExpression group );
+ public Token GetFunctionName();
+ public GroupExpression GetFunctionGroup();
+}
+
+public class FunctionExpression:ASTNode,IFunctionExpression
+{
+ public Token functionName;
+ public GroupExpression functionGroup;
+
+ public void InitializeFunctionExpression( Token name, GroupExpression group )
+ {
+ this.functionName = name;
+ this.functionGroup = group;
+ }
+
+ public Token GetFunctionName()
+ {
+ return functionName;
+ }
+
+ public GroupExpression GetFunctionGroup()
+ {
+ return functionGroup;
+ }
+}
diff --git a/Runtime/Text/Parsing/Expressions/Operators/FunctionExpression.cs.uid b/Runtime/Text/Parsing/Expressions/Operators/FunctionExpression.cs.uid
new file mode 100644
index 0000000..6c9f0fe
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/FunctionExpression.cs.uid
@@ -0,0 +1 @@
+uid://dsrmqy8g0u1na
diff --git a/Runtime/Text/Parsing/Expressions/Operators/FunctionOperator.cs b/Runtime/Text/Parsing/Expressions/Operators/FunctionOperator.cs
new file mode 100644
index 0000000..de7f31c
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/FunctionOperator.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Rokojori;
+
+public class FunctionOperator:ExpressionOperator where T:ASTNode,IFunctionExpression, new()
+{
+
+ public FunctionOperator()
+ {
+ startTokenPredicate = TokenPredicateData.Create( LexerMatcherLibrary.CFunctionMatcher.type );
+ }
+
+ public override bool ProcessStartNode( ASTNode parent, int startChildIndex )
+ {
+ var next = parent.NextNode( startChildIndex );
+
+ if ( next == null || ! ( next is GroupExpression ) )
+ {
+ return false;
+ }
+
+ var functionName = parent.children[ startChildIndex ] as Token;
+ var functionGroup = next as GroupExpression;
+
+ var functionExpression = parent.MergeOuter( functionName, functionGroup );
+ functionExpression.InitializeFunctionExpression( functionName, functionGroup );
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/Expressions/Operators/FunctionOperator.cs.uid b/Runtime/Text/Parsing/Expressions/Operators/FunctionOperator.cs.uid
new file mode 100644
index 0000000..cb78413
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/FunctionOperator.cs.uid
@@ -0,0 +1 @@
+uid://bh3mwwxr8f7xm
diff --git a/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionExpression.cs b/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionExpression.cs
new file mode 100644
index 0000000..c129e0d
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionExpression.cs
@@ -0,0 +1,41 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Rokojori;
+
+public interface IGenericFunctionExpression:OperatorExpression
+{
+ public void InitializeGenericFunctionExpression( Token name, ASTNode genericType, GroupExpression group );
+ public Token GetFunctionName();
+ public ASTNode GetGenericType();
+ public GroupExpression GetFunctionGroup();
+}
+
+public class GenericFunctionExpression:ASTNode,IGenericFunctionExpression
+{
+ public Token functionName;
+ public ASTNode genericType;
+ public GroupExpression functionGroup;
+
+ public void InitializeGenericFunctionExpression( Token name, ASTNode genericType, GroupExpression group )
+ {
+ this.functionName = name;
+ this.genericType = genericType;
+ this.functionGroup = group;
+ }
+
+ public Token GetFunctionName()
+ {
+ return functionName;
+ }
+
+ public ASTNode GetGenericType()
+ {
+ return functionName;
+ }
+
+ public GroupExpression GetFunctionGroup()
+ {
+ return functionGroup;
+ }
+}
diff --git a/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionExpression.cs.uid b/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionExpression.cs.uid
new file mode 100644
index 0000000..2b07cbc
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionExpression.cs.uid
@@ -0,0 +1 @@
+uid://b3dbaycmkmvkh
diff --git a/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionOperator.cs b/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionOperator.cs
new file mode 100644
index 0000000..7653244
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionOperator.cs
@@ -0,0 +1,89 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Rokojori;
+
+public class GenericFunctionOperator:ExpressionOperator where T:ASTNode,IGenericFunctionExpression, new()
+{
+ public GenericFunctionOperator()
+ {
+ startTokenPredicate = TokenPredicateData.Create( LexerMatcherLibrary.CwordMatcher.type );
+ }
+
+ bool CanBeGenericType( ASTNode parent, int start, int length )
+ {
+ List tokenSymbols = [
+ ".", "<", ">", "[", "]", "*", ","
+ ];
+
+ for ( int i = 0; i < length; i++ )
+ {
+ var child = parent.children[ start + i ];
+
+ if ( child.IsIgnoreToken() )
+ {
+ continue;
+ }
+ else if ( child.IsToken( LexerMatcherLibrary.CwordMatcher ) )
+ {
+ continue;
+ }
+ else if ( child is Token tk )
+ {
+ if ( tokenSymbols.IndexOf( tk.match ) != -1 )
+ {
+ continue;
+ }
+ }
+
+
+ return false;
+ }
+
+ return false;
+ }
+
+ public override bool ProcessStartNode( ASTNode parent, int startChildIndex )
+ {
+ var next = parent.NextNode( startChildIndex );
+
+ if ( next == null || ! next.IsToken( LexerMatcherLibrary.OperatorMatcher, "<" ) )
+ {
+ return false;
+ }
+
+
+ var closerIndex = parent.FindBracketCloserIndex( "<", ">", next.childIndex );
+
+ if ( closerIndex == -1 )
+ {
+ return false;
+ }
+
+ var startIndex = next.childIndex;
+ var length = ( closerIndex - startIndex ) - 1;
+
+ if ( ! CanBeGenericType( parent, startIndex + 1, length ) )
+ {
+ return false;
+ }
+
+
+
+ var group = parent.NextNode( closerIndex );
+
+ if ( group == null || ! ( group is GroupExpression ) )
+ {
+ return false;
+ }
+
+ var functionName = parent.children[ startChildIndex ] as Token;
+ var functionGroup = group as GroupExpression;
+
+ var genericFunctionExpression = parent.MergeOuter( functionName, functionGroup );
+ var genericType = genericFunctionExpression.MergeInner( functionName, functionGroup );
+ genericFunctionExpression.InitializeGenericFunctionExpression( functionName, genericType, functionGroup );
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionOperator.cs.uid b/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionOperator.cs.uid
new file mode 100644
index 0000000..6386ba8
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/GenericFunctionOperator.cs.uid
@@ -0,0 +1 @@
+uid://dbajt0qt2oxc3
diff --git a/Runtime/Text/Parsing/Expressions/Operators/GroupOperator.cs b/Runtime/Text/Parsing/Expressions/Operators/GroupOperator.cs
index a3bba34..bc65e9a 100644
--- a/Runtime/Text/Parsing/Expressions/Operators/GroupOperator.cs
+++ b/Runtime/Text/Parsing/Expressions/Operators/GroupOperator.cs
@@ -28,6 +28,7 @@ public class GroupOperator:ExpressionOperator where T:ASTNode,IGroupExpressio
var start = parent.children[ startChildIndex ];
var end = parent.children[ endIndex ];
+ RJLog.Log( "Group:", start, end, startChildIndex, endIndex );
var groupBodyExpression = parent.MergeInner( start, end );
var groupExpression = parent.MergeOuter( start, end );
diff --git a/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceExpression.cs b/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceExpression.cs
new file mode 100644
index 0000000..407686b
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceExpression.cs
@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Rokojori;
+
+public interface ISeparatedSequenceExpression:OperatorExpression
+{
+ public void InitializeSeparatedSequenceExpression( List expressions );
+ public List GetExpressions();
+
+}
+
+public class SeparatedSequenceExpression:ASTNode,ISeparatedSequenceExpression
+{
+ public List expressions;
+
+ public void InitializeSeparatedSequenceExpression( List expressions )
+ {
+ this.expressions = expressions;
+ }
+
+ public List GetExpressions()
+ {
+ return expressions;
+ }
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceExpression.cs.uid b/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceExpression.cs.uid
new file mode 100644
index 0000000..f6681ed
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceExpression.cs.uid
@@ -0,0 +1 @@
+uid://brh7y1ya7b4fq
diff --git a/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceOperator.cs b/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceOperator.cs
new file mode 100644
index 0000000..0f99b7b
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceOperator.cs
@@ -0,0 +1,64 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Rokojori;
+
+public class SeparatedSequenceOperator:ExpressionOperator where T:ASTNode,ISeparatedSequenceExpression, new()
+{
+ public SeparatedSequenceOperator()
+ {
+ startTokenPredicate = TokenPredicateData.Create( LexerMatcherLibrary.OperatorMatcher.type, "," );
+ }
+
+ public override bool ProcessStartNode( ASTNode parent, int startChildIndex )
+ {
+ var firstSeparator = parent.children[ startChildIndex ];
+ var nodes = parent.children.Filter( c => ! c.IsIgnoreToken() );
+ var index = nodes.IndexOf( firstSeparator );
+
+ if ( index != 1 )
+ {
+ parent.parser.AddError( "Unexpected separator position. Expected 1, but got: "+ index+ " at " + parent );
+ return false;
+ }
+
+ List expressions = [];
+
+ for ( int i = 0; i < nodes.Count; i++ )
+ {
+ var node = nodes[ i ];
+ var indexModulo2 = i % 2;
+
+ var shouldBeExpression = indexModulo2 == 0;
+ var shouldBeSeperator = indexModulo2 == 1;
+
+ var isSeparator = startTokenPredicate.Matches( node );
+
+ if ( shouldBeSeperator && ! isSeparator )
+ {
+ parent.parser.AddError( "Expected separator" );
+ return false;
+ }
+ else if ( shouldBeExpression && isSeparator )
+ {
+ parent.parser.AddError( "Expected separator" );
+ return false;
+ }
+
+ if ( shouldBeSeperator )
+ {
+ continue;
+ }
+
+ expressions.Add( node );
+
+ }
+
+ var sequence = parent.MergeOuter( nodes[ 0 ], nodes.Last() );
+ sequence.InitializeSeparatedSequenceExpression( expressions );
+
+ return true;
+ }
+
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceOperator.cs.uid b/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceOperator.cs.uid
new file mode 100644
index 0000000..3f599df
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/SeparatedSequenceOperator.cs.uid
@@ -0,0 +1 @@
+uid://dcq26co5w17o8
diff --git a/Runtime/Text/Parsing/Expressions/Operators/TernaryExpression.cs b/Runtime/Text/Parsing/Expressions/Operators/TernaryExpression.cs
new file mode 100644
index 0000000..1428433
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/TernaryExpression.cs
@@ -0,0 +1,58 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Rokojori;
+
+public interface ITernaryExpression:OperatorExpression
+{
+ public void InitializeTernaryExpression( ASTNode conditionalExpression, Token symbol, ASTNode trueExpression, Token seperator, ASTNode falseExpression );
+ public ASTNode GetConditionalExpression();
+ public Token GetSymbol();
+ public ASTNode GetTrueExpression();
+ public Token GetSeperator();
+ public ASTNode GetFalseExpression();
+
+}
+
+public class TernaryExpression:ASTNode,ITernaryExpression
+{
+ public ASTNode conditionalExpression;
+ public Token symbol;
+ public ASTNode trueExpression;
+ public Token seperator;
+ public ASTNode falseExpression;
+
+ public void InitializeTernaryExpression( ASTNode conditionalExpression, Token symbol, ASTNode trueExpression, Token seperator, ASTNode falseExpression )
+ {
+ this.conditionalExpression = conditionalExpression;
+ this.symbol = symbol;
+ this.trueExpression = trueExpression;
+ this.seperator = seperator;
+ this.falseExpression = falseExpression;
+ }
+
+ public ASTNode GetConditionalExpression()
+ {
+ return conditionalExpression;
+ }
+
+ public Token GetSymbol()
+ {
+ return symbol;
+ }
+
+ public ASTNode GetTrueExpression()
+ {
+ return trueExpression;
+ }
+
+ public Token GetSeperator()
+ {
+ return seperator;
+ }
+
+ public ASTNode GetFalseExpression()
+ {
+ return falseExpression;
+ }
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/Expressions/Operators/TernaryExpression.cs.uid b/Runtime/Text/Parsing/Expressions/Operators/TernaryExpression.cs.uid
new file mode 100644
index 0000000..59f7e86
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/TernaryExpression.cs.uid
@@ -0,0 +1 @@
+uid://bxd4gytorurt8
diff --git a/Runtime/Text/Parsing/Expressions/Operators/TernaryOperator.cs b/Runtime/Text/Parsing/Expressions/Operators/TernaryOperator.cs
new file mode 100644
index 0000000..a47c91d
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/TernaryOperator.cs
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Rokojori;
+
+public class TernaryOperator:ExpressionOperator where T:ASTNode,ITernaryExpression, new()
+{
+ public override bool IsFromLeft()
+ {
+ return false;
+ }
+
+ public TernaryOperator()
+ {
+ startTokenPredicate = TokenPredicateData.Create( LexerMatcherLibrary.OperatorMatcher.type, "?" );
+ }
+
+ public override bool ProcessStartNode( ASTNode parent, int startChildIndex )
+ {
+ var separatorIndex = parent.FindTriggerTokenIndex( startChildIndex,
+ [ startTokenPredicate ],
+ TokenPredicateData.BlockPredicates
+ );
+
+ var conditional = parent.PreviousNode( startChildIndex );
+ var symbol = parent.children[ startChildIndex ] as Token;
+ var trueExpression = parent.PreviousNode( separatorIndex );
+ var separator = parent.children[ separatorIndex ] as Token;
+ var falseExpression = parent.NextNode( separatorIndex );
+
+ var ternaryExpression = parent.MergeOuter( conditional, falseExpression );
+ ternaryExpression.InitializeTernaryExpression( conditional, symbol, trueExpression, separator, falseExpression );
+
+ return true;
+ }
+
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/Expressions/Operators/TernaryOperator.cs.uid b/Runtime/Text/Parsing/Expressions/Operators/TernaryOperator.cs.uid
new file mode 100644
index 0000000..f3bd907
--- /dev/null
+++ b/Runtime/Text/Parsing/Expressions/Operators/TernaryOperator.cs.uid
@@ -0,0 +1 @@
+uid://crsr4mtgogmwy
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/CSCommentGrabber.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/CSCommentGrabber.cs
new file mode 100644
index 0000000..9db364a
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/CSCommentGrabber.cs
@@ -0,0 +1,96 @@
+using System.Collections.Generic;
+
+namespace Rokojori;
+
+public class CSCommentGrabber
+{
+ public static List Get( ASTNode start )
+ {
+ var p = start.parent;
+
+ for ( int i = start.childIndex - 1; i >= 0; i -- )
+ {
+ var n = p.children[ i ];
+
+ if ( ! n.IsIgnoreToken() )
+ {
+ return null;
+ }
+
+ if (
+ ! n.IsAnyTokenOf(
+ [ LexerMatcherLibrary.MultiLineCommentMatcher,
+ LexerMatcherLibrary.SingleLineCommentMatcher ]
+ )
+ )
+ {
+ continue;
+ }
+
+ if ( n.IsToken( LexerMatcherLibrary.MultiLineCommentMatcher ) )
+ {
+ var tk = n as Token;
+
+ if ( tk.match.StartsWith( "/**" ) )
+ {
+ return [ tk ];
+ }
+
+ return null;
+ }
+ else if ( IsSingleLineCommentLine( n ) )
+ {
+ var tokens = GetCompleteSingleLineComments( n as Token );
+
+ if ( tokens != null )
+ {
+ return tokens;
+ }
+
+ return null;
+ }
+
+ }
+
+ return null;
+ }
+
+ static bool IsSingleLineCommentLine( ASTNode node )
+ {
+ if ( ! node.IsToken( LexerMatcherLibrary.SingleLineCommentMatcher ) )
+ {
+ return false;
+ }
+
+ var tk = node as Token;
+
+ return tk.match.StartsWith( "///" );
+ }
+
+ static List GetCompleteSingleLineComments( Token lastLine )
+ {
+ var list = new List();
+ var p = lastLine.parent;
+
+ for ( int i = lastLine.childIndex; i >= 0; i -- )
+ {
+ var n = p.children[ i ];
+
+ if ( IsSingleLineCommentLine( n ) )
+ {
+ list.Add( n as Token );
+ }
+ else if ( n.IsAnyTokenOf( [ LexerMatcherLibrary.WhiteSpaceMatcher, LexerMatcherLibrary.BreakMatcher ]) )
+ {
+ continue;
+ }
+ else
+ {
+ i = -1;
+ }
+ }
+
+ list.Reverse();
+ return list;
+ }
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/CSCommentGrabber.cs.uid b/Runtime/Text/Parsing/ParserLibrary/CSharp/CSCommentGrabber.cs.uid
new file mode 100644
index 0000000..c143edd
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/CSCommentGrabber.cs.uid
@@ -0,0 +1 @@
+uid://cf37yn2r2o8re
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/CSParser.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/CSParser.cs
index 96ab705..49fa06b 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/CSParser.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/CSParser.cs
@@ -23,4 +23,9 @@ public class CSParser:Parser
Parse( FilesSync.LoadUTF8( filePath ) );
}
+
+ public override ExpressionParser GetExpressionParser()
+ {
+ return CSExpressionParser.instance;
+ }
}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/CSParserTest.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/CSParserTest.cs
index a0e560f..e72a3cf 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/CSParserTest.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/CSParserTest.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using Godot;
+using Rokojori.DocGenerator;
namespace Rokojori;
@@ -25,8 +26,21 @@ public partial class CSParserTest:Node
[Export]
public bool createGD = false;
+ [Export]
+ public bool createDocInfo = false;
+
+ [Export]
+ public bool createASTView = false;
+
+ [Export]
+ public ASTViewContext.ViewType viewType = ASTViewContext.ViewType.Tree_Structure;
+
+
+ [Export]
+ public string docInfoPath = "res://.rokojori/cache/docs";
+
[ExportToolButton( "Parse" )]
public Callable parseButton => Callable.From(
()=>
@@ -56,8 +70,42 @@ public partial class CSParserTest:Node
{
CreateGDClass( root );
}
+
+ if ( createDocInfo )
+ {
+ CreateDocInfo( root );
+ }
+
+ if ( createASTView )
+ {
+ CreateASTView( root );
+ }
}
+ void CreateASTView( CSFileRoot root )
+ {
+ var astView = this.GetOrCreateChild( "AST View");
+ astView.viewType = viewType;
+ astView.Create( root );
+ }
+
+ void CreateDocInfo( CSFileRoot root )
+ {
+ var objects = root.walker.FilterType( root );
+
+ var originalPath = FilePath.Absolute( root.GetFilePath() );
+
+ var name = originalPath.fullFileName + ".json";
+
+ var outputPath = FilePath.Join( ProjectSettings.GlobalizePath( docInfoPath ), name );
+
+ var doc = ClassDocFromParser.CreateFrom( objects[ 0 ] );
+
+ this.LogInfo( "saving:", outputPath, JSON.StringifyObject( doc ) );
+ FilesSync.SaveJSON( outputPath, doc );
+ }
+
+
void CreateGDClass( CSFileRoot root )
{
var originalPath = FilePath.Absolute( root.GetFilePath() );
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSFileRoot.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSFileRoot.cs
index 8535a8e..56b64b1 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSFileRoot.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSFileRoot.cs
@@ -22,6 +22,11 @@ public class CSFileRoot:ASTNode, ASTFileRoot
return _parser.source;
}
+ public List GetObjectDeclarations()
+ {
+ return walker.FilterType( this );
+ }
+
TextLinesMapper _textLinesMapper = null;
public TextLinesMapper GetTextLinesMapper()
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSImportDeclaration.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSImportDeclaration.cs
index e0c8093..1cfc0ea 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSImportDeclaration.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSImportDeclaration.cs
@@ -34,7 +34,7 @@ public class CSImportDeclaration: ASTNode, ImportDeclaration
var usingIndex = imp.FindTokenIndex( LexerMatcherLibrary.UsingMatcher );
var endIndex = imp.ReverseFindTokenIndex( LexerMatcherLibrary.OperatorMatcher );
- RJLog.Log( "Endindex:", endIndex );
+ RJLog.Log( "Endindex:", endIndex, usingIndex );
imp.usingToken = imp.children[ usingIndex ] as Token;
imp.end = imp.children[ endIndex ] as Token;
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSNamespaceBlock.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSNamespaceBlock.cs
index cbbf2de..eb275fe 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSNamespaceBlock.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSNamespaceBlock.cs
@@ -5,12 +5,74 @@ namespace Rokojori;
public class CSNamespaceBlock: ASTNode, NamespaceBlock
{
public Token namespaceToken;
- public List namespacePath;
+ public List namespacePath = [];
public Token blockStart;
public Token blockEnd;
+ public ASTNodeList blockContent;
public string GetNamespace()
{
return namespacePath.Map( tk => tk.match ).Join( "" );
}
+
+ public static ASTMatcherResolver Resolver()
+ {
+ var namespaceMR = new ASTMatcherResolver();
+
+ var sequenceMatcher = TokenRepeatSequenceASTMatcher.CreateWithLexer( new CSLexer(),
+ "namespace cword",".cword","{"
+ );
+
+ namespaceMR.matcher = sequenceMatcher;
+
+ namespaceMR.initializer = ( nsb, matcher ) =>
+ {
+ var parent = nsb.parent;
+ var blockStartIndex = nsb.childIndex;
+ var blockEndIndex = parent.FindBracketCloserIndex( "{", "}", blockStartIndex );
+ var blockEnd = parent.children[ blockEndIndex ];
+
+ nsb.ExpandToNext( blockEnd );
+
+ blockStartIndex = nsb.FindTokenIndex( LexerMatcherLibrary.BracketMatcher, "{" );
+ blockEndIndex = blockEnd.childIndex;
+
+ var nsIndex = nsb.FindTokenIndex( LexerMatcherLibrary.NamespaceMatcher );
+
+
+
+ RJLog.Log( "Matched ns block:", blockStartIndex, blockEndIndex );
+ nsb.namespaceToken = nsb.children[ nsIndex ] as Token;
+ nsb.blockStart = nsb.children[ blockStartIndex ] as Token;
+ nsb.blockEnd = blockEnd as Token;
+
+ var inbetween = nsb.children.Sub( nsIndex + 1, blockStartIndex - 1 );
+ nsb.namespacePath = inbetween.Filter( n => ! n.IsIgnoreToken() ).Map( n => n as Token );
+
+ nsb.blockContent = nsb.MergeInner( nsb.blockStart, nsb.blockEnd );
+
+ var parser = CSRootFileParser.CreateParser();
+ parser.root = nsb.blockContent;
+ parser.Process();
+
+
+ RJLog.Log(
+ "INIT NAMESPACE BLOCK:", nsb.namespaceToken, ">>", inbetween.Join( ", " ),
+ "path only:",nsb.namespacePath.Join( "|| ") );
+
+ var root = nsb.GetParentWithType();
+
+ if ( root == null )
+ {
+ return nsb.childIndex;
+ }
+
+ root.parsedNodes.Add( nsb );
+ root.blocks.Add( nsb );
+
+ return nsb.childIndex;
+ };
+
+ return namespaceMR;
+ }
}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSNamespaceDeclaration.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSNamespaceDeclaration.cs
index 9d0e81b..5333cdf 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSNamespaceDeclaration.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSNamespaceDeclaration.cs
@@ -41,7 +41,7 @@ public class CSNamespaceDeclaration: ASTNode, NamespaceDeclaration
nsd.namespacePath = inbetween.Filter( n => ! n.IsIgnoreToken() ).Map( n => n as Token );
RJLog.Log(
- "INIT IMPORT:", nsd.namespaceToken, ">>", inbetween.Join( ", " ), ">>", nsd.end,
+ "INIT NAMESPACE FILE DECLARATION:", nsd.namespaceToken, ">>", inbetween.Join( ", " ), ">>", nsd.end,
nsd.children.Last(),
"path only:",nsd.namespacePath.Join( "|| ") );
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSTypeDefinition.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSTypeDefinition.cs
index 3feb2cd..00b981d 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSTypeDefinition.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/CSTypeDefinition.cs
@@ -4,10 +4,67 @@ namespace Rokojori;
public class CSTypeDefinition: ASTNode
{
+
public string GetTypeDefinition()
{
return CombinedMatch().Trim();
}
+ public string GetBaseType()
+ {
+ var stringType = GetTypeDefinition();
+
+ var bracketStart = stringType.IndexOf( "<" );
+ bracketStart = bracketStart == -1 ? stringType.IndexOf( "[" ) : bracketStart;
+
+ var end = bracketStart == -1 ? stringType.Length : bracketStart;
+
+ return stringType.Substring( 0, end );
+ }
+
+ public bool IsGenericList()
+ {
+ return GetBaseType() == "List" && IsGeneric();
+ }
+
+
+ public bool IsGeneric()
+ {
+ var stringType = GetTypeDefinition();
+ var bracketStart = stringType.IndexOf( "<" );
+
+ return bracketStart != -1;
+ }
+
+ public string GetGenericType()
+ {
+ if ( ! IsGeneric() )
+ {
+ return null;
+ }
+
+ var genericStartIndex = FindTokenIndex( LexerMatcherLibrary.BracketMatcher, "<" );
+ var genericEndIndex = FindBracketCloserIndex( "<", ">", genericStartIndex );
+
+ return GetInnerRangeMatch( genericStartIndex, genericEndIndex );
+ }
+
+ public bool IsArrayType()
+ {
+ var stringType = GetTypeDefinition();
+
+ if ( stringType.EndsWith( "]" ) )
+ {
+ return true;
+ }
+
+ // if ( stringType.StartsWith( "List<" ) )
+ // {
+ // return true;
+ // }
+
+ return false;
+ }
+
}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/MemberDeclarations/CSMemberDeclaration.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/MemberDeclarations/CSMemberDeclaration.cs
index 71cd34e..379a216 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/MemberDeclarations/CSMemberDeclaration.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/MemberDeclarations/CSMemberDeclaration.cs
@@ -1,17 +1,49 @@
using System.Collections.Generic;
+using System.Text;
namespace Rokojori;
public abstract class CSMemberDeclaration: ASTNode, MemberDeclaration
{
+ public List docComment;
public List attributeBrackets;
public List modifiers;
public Token memberName;
public CSTypeDefinition memberType;
+ public string GetDocumentation()
+ {
+ if ( docComment == null )
+ {
+ return "";
+ }
+
+ if ( docComment.Count == 1 && docComment[ 0 ].IsToken( LexerMatcherLibrary.MultiLineCommentMatcher ) )
+ {
+ var match = docComment[ 0 ].match;
+ return match.Substring( 3, match.Length - 5 );
+ }
+
+ var sb = new StringBuilder();
+
+ docComment.ForEach(
+ ( tk )=>
+ {
+ sb.Append( tk.match.Substring( 3 ) );
+ }
+ );
+
+ return sb.ToString();
+ }
+
public List GetMemberModifiers()
{
- return new List();
+ return modifiers.Map( m => m.match );
+ }
+
+ public List GetMemberAttributes()
+ {
+ return CSModifierAttributesParser.GetAttributes( attributeBrackets );
}
public string GetMemberName()
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/ObjectDeclarations/CSObjectDeclaration.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/ObjectDeclarations/CSObjectDeclaration.cs
index 5426afd..49f3d6b 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/ObjectDeclarations/CSObjectDeclaration.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Nodes/ObjectDeclarations/CSObjectDeclaration.cs
@@ -1,9 +1,11 @@
using System.Collections.Generic;
+using System.Text;
namespace Rokojori;
public abstract class CSObjectDeclaration: ASTNode
{
+ public List docComment;
public List attributeBrackets = [];
public List modifiers = [];
public Token objectType;
@@ -15,6 +17,62 @@ public abstract class CSObjectDeclaration: ASTNode
public ASTNode objectBody;
public Token blockEnd;
+
+ public List GetMemberModifiers()
+ {
+ return modifiers.Map( m => m.match );
+ }
+
+ public List GetMemberAttributes()
+ {
+ return CSModifierAttributesParser.GetAttributes( attributeBrackets );
+ }
+
+ public string GetDocumentation()
+ {
+ if ( docComment == null )
+ {
+ return "";
+ }
+
+ if ( docComment.Count == 1 && docComment[ 0 ].IsToken( LexerMatcherLibrary.MultiLineCommentMatcher ) )
+ {
+ var match = docComment[ 0 ].match;
+ return match.Substring( 3, match.Length - 5 );
+ }
+
+ var sb = new StringBuilder();
+
+ docComment.ForEach(
+ ( tk )=>
+ {
+ sb.Append( tk.match.Substring( 3 ) );
+ }
+ );
+
+ return sb.ToString();
+ }
+
+ public string GetNamespace()
+ {
+ var nestedNSBlock = walker.GetParentWithType( this );
+
+ if ( nestedNSBlock != null )
+ {
+ return nestedNSBlock.GetNamespace();
+ }
+
+ var nsDeclaration = walker.FindAnyChildOfType( parser.root );
+
+ if ( nsDeclaration != null )
+ {
+ return nsDeclaration.GetNamespace();
+ }
+
+ return null;
+ }
+
+
public override string ToString()
{
var modsInfo = "";
@@ -74,6 +132,8 @@ public abstract class CSObjectDeclaration: ASTNode
var parent = t.parent;
var parentIndex = parent.children.IndexOf( t );
+
+
// for ( int i = 0; i < parent.children.Count; i++ )
// {
// RJLog.Log( i, parent.children[ i ].CombinedMatch(), parent.children[ i ].parent?.GetType().Name );
@@ -111,6 +171,8 @@ public abstract class CSObjectDeclaration: ASTNode
}
}
+ t.docComment = CSCommentGrabber.Get( t );
+
t.objectType = t.FindToken( odPredicate );
t.objectName = t.FindToken( LexerMatcherLibrary.CwordMatcher, t.children.IndexOf( t.objectType ) + 1 );
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSExpressions/CSExpressionParser.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSExpressions/CSExpressionParser.cs
new file mode 100644
index 0000000..be0699b
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSExpressions/CSExpressionParser.cs
@@ -0,0 +1,281 @@
+using System;
+using System.Collections.Generic;
+
+namespace Rokojori;
+
+
+public class CSExpressionParser:ExpressionParser
+{
+ public static CSExpressionParser instance = new CSExpressionParser();
+
+ // GENERIC (3)
+ public ConstantOperator boolConstantOperator;
+
+ public GroupOperator groupOperator;
+
+ public VariableOperator variableOperator;
+
+ public BinaryOperator memberOperator;
+ public ArrayOperator arrayOperator;
+
+ public FunctionOperator functionOperator;
+ public GenericFunctionOperator genericFunctionOperator;
+
+
+ // BOOLEANS (5)
+ public BinaryOperator andOperator;
+ public BinaryOperator orOperator;
+
+ public BinaryOperator equalsOperator;
+ public BinaryOperator notEqualsOperator;
+
+ public UnaryOperator notOperator;
+
+ // ARITHMETIC A (6)
+
+ public UnaryOperator postfixIncrementOperator;
+ public UnaryOperator postfixDecrementOperator;
+
+ public UnaryOperator prefixIncrementOperator;
+ public UnaryOperator prefixDecrementOperator;
+
+ public UnaryOperator unaryPlusOperator;
+ public UnaryOperator unaryMinusOperator;
+
+ // ARITHMETIC B (5)
+ public BinaryOperator plusOperator;
+ public BinaryOperator multiplyOperator;
+ public BinaryOperator minusOperator;
+ public BinaryOperator divisionOperator;
+ public BinaryOperator moduloOperator;
+
+ // RELATIONAL (4)
+ public BinaryOperator lessThanOperator;
+ public BinaryOperator lessThanOrEqualOperator;
+
+ public BinaryOperator greaterThanOperator;
+ public BinaryOperator greaterThanOrEqualOperator;
+
+ // BITWISE LOGIC (6)
+ public UnaryOperator bitwiseNotOperator;
+
+ public BinaryOperator bitwiseOrOperator;
+ public BinaryOperator bitwiseAndOperator;
+ public BinaryOperator bitwiseXorOperator;
+
+ public BinaryOperator bitwiseShiftLeftOperator;
+ public BinaryOperator bitwiseShiftRightOperator;
+
+ // ASSIGNEMENTS
+
+ // =, =>
+ public BinaryOperator assignmentOperator;
+ public BinaryOperator arrowAssignmentOperator;
+ public TernaryOperator ternaryOperator;
+
+
+ // +, -, *, /, %
+
+ public List combinedAssignmentSymbols =
+ [
+ "+", "-", "*", "/", "%",
+ "<<", ">>",
+ "&", "^","|",
+ "&&", "||"
+ ];
+
+ public List> combinedAssignmentOperators;
+
+
+ // SEPERATOR
+ public SeparatedSequenceOperator separatedSequenceOperator;
+
+
+ public CSExpressionParser()
+ {
+ // GENERIC
+ boolConstantOperator = new ConstantOperator(
+ TokenPredicateData.Create( LexerMatcherLibrary.BoolMatcher.type )
+ );
+
+ groupOperator = new GroupOperator( "(", ")" );
+ // groupOperator.expressionParser = this;
+
+ variableOperator = new VariableOperator();
+
+ memberOperator = new BinaryOperator( "." );
+ arrayOperator = new ArrayOperator();
+
+ functionOperator = new FunctionOperator();
+ genericFunctionOperator = new GenericFunctionOperator();
+
+
+ // BOOLEANS (5)
+ andOperator = new BinaryOperator( "&&" );
+ orOperator = new BinaryOperator( "||" );
+
+ equalsOperator = new BinaryOperator( "==" );
+ notEqualsOperator = new BinaryOperator( "!=" );
+
+ notOperator = new UnaryOperator( "!" );
+
+ // ARITHMETIC A (6)
+
+ postfixIncrementOperator = new UnaryOperator( "++" );
+ postfixDecrementOperator = new UnaryOperator( "--" );
+
+ prefixIncrementOperator = new UnaryOperator( "++" );
+ prefixDecrementOperator = new UnaryOperator( "--" );
+
+ unaryPlusOperator = new UnaryOperator( "+" );
+ unaryMinusOperator = new UnaryOperator( "-" );
+
+ // ARITHMETIC B (5)
+ plusOperator = new BinaryOperator( "+" );
+ multiplyOperator = new BinaryOperator( "*" );
+ minusOperator = new BinaryOperator( "-" );
+ divisionOperator = new BinaryOperator( "/" );
+ moduloOperator = new BinaryOperator( "%" );
+
+ // RELATIONAL (4)
+ lessThanOperator = new BinaryOperator( "<" );
+ lessThanOrEqualOperator = new BinaryOperator( "<=" );
+
+ greaterThanOperator = new BinaryOperator( ">" );
+ greaterThanOrEqualOperator = new BinaryOperator( ">=" );
+
+ // BITWISE LOGIC (6)
+ bitwiseNotOperator = new UnaryOperator( "~" );
+
+ bitwiseOrOperator = new BinaryOperator( "|" );
+ bitwiseAndOperator = new BinaryOperator( "&" );
+ bitwiseXorOperator = new BinaryOperator( "^" );
+
+ bitwiseShiftLeftOperator = new BinaryOperator( "<<" );
+ bitwiseShiftRightOperator = new BinaryOperator( ">>" );
+
+ // ASSIGNEMENTS
+
+ assignmentOperator = new BinaryOperator( "=", false );
+ arrowAssignmentOperator = new BinaryOperator( "=>", false );
+ ternaryOperator = new TernaryOperator();
+
+ combinedAssignmentOperators = combinedAssignmentSymbols.Map(
+ s => new BinaryOperator( s + "=", false )
+ );
+
+ // SEPARATOR
+
+ separatedSequenceOperator = new SeparatedSequenceOperator();
+ // separatedSequenceOperator.expressionParser = this;
+
+
+ SetPrecedenceLevels();
+
+ }
+
+
+ void SetPrecedenceLevels()
+ {
+ levels = [];
+
+ AddPrecedenceLevel(
+ boolConstantOperator
+ );
+
+ AddPrecedenceLevel(
+ groupOperator
+ );
+
+ AddPrecedenceLevel(
+ variableOperator
+ );
+
+ AddPrecedenceLevel(
+ memberOperator,
+ arrayOperator,
+ functionOperator,
+ genericFunctionOperator
+ );
+
+ AddPrecedenceLevel(
+ postfixIncrementOperator,
+ postfixDecrementOperator
+ );
+
+ AddPrecedenceLevel(
+ prefixIncrementOperator,
+ prefixDecrementOperator,
+ notOperator,
+ bitwiseNotOperator,
+ unaryPlusOperator,
+ unaryMinusOperator
+ );
+
+ AddPrecedenceLevel(
+ multiplyOperator,
+ divisionOperator,
+ moduloOperator
+ );
+
+ AddPrecedenceLevel(
+ plusOperator,
+ minusOperator
+ );
+
+ AddPrecedenceLevel(
+ lessThanOperator,
+ lessThanOrEqualOperator,
+ greaterThanOperator,
+ greaterThanOrEqualOperator
+ );
+
+ AddPrecedenceLevel(
+ equalsOperator,
+ notEqualsOperator
+ );
+
+ AddPrecedenceLevel(
+ equalsOperator,
+ notEqualsOperator
+ );
+
+ AddPrecedenceLevel(
+ bitwiseAndOperator
+ );
+
+ AddPrecedenceLevel(
+ bitwiseXorOperator
+ );
+
+ AddPrecedenceLevel(
+ bitwiseOrOperator
+ );
+
+ AddPrecedenceLevel(
+ andOperator
+ );
+
+ AddPrecedenceLevel(
+ andOperator
+ );
+
+ AddPrecedenceLevel(
+ orOperator
+ );
+
+ var assginments = new List();
+
+ assginments.AddRange( [ assignmentOperator, arrowAssignmentOperator, ternaryOperator ] );
+ assginments.AddRange( combinedAssignmentOperators );
+
+ AddPrecedenceLevel(
+ assginments.ToArray()
+ );
+
+ AddPrecedenceLevel(
+ separatedSequenceOperator
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSExpressions/CSExpressionParser.cs.uid b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSExpressions/CSExpressionParser.cs.uid
new file mode 100644
index 0000000..2bf9b46
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSExpressions/CSExpressionParser.cs.uid
@@ -0,0 +1 @@
+uid://qd5m0kkoxaw7
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSMemberResolver.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSMemberResolver.cs
index 8bd00c3..1efecf7 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSMemberResolver.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSMemberResolver.cs
@@ -78,6 +78,8 @@ public class CSMemberResolver:ASTMatcherResolver
var typeFirstIndex = atts.nextNode.childIndex;
var typeLastIndex = parent.PreviousIndex( mc.childIndex );
var memberType = parent.MergeOuter( typeFirstIndex, typeLastIndex );
+
+ RJLog.Log( "MemberType:", typeFirstIndex, typeLastIndex, memberType.GetTypeDefinition() );
mc.memberType = memberType;
if ( earliestNode == null )
@@ -89,9 +91,30 @@ public class CSMemberResolver:ASTMatcherResolver
{
var mm = mc as CSMethodMemberDeclaration;
mm.isContructor = true;
+
}
- mc.ExpandToPrevious( earliestNode );
+ if ( earliestNode.parent != mc.parent )
+ {
+ var walker = mc.walker;
+
+ if ( walker.IsChildOf( earliestNode, mc.parent ) )
+ {
+ earliestNode = walker.ResolveToCommonParent( earliestNode, mc.parent );
+ }
+ }
+
+ var commentStart = earliestNode != null ? earliestNode : mc;
+ var comment = CSCommentGrabber.Get( commentStart );
+ mc.docComment = comment;
+
+
+ if ( earliestNode != null )
+ {
+ mc.ExpandToPrevious( earliestNode );
+ }
+
+
RJLog.Log( "Found member", mc.memberType?.GetTypeDefinition() ?? "(constructor)" , mc.memberName );
@@ -206,6 +229,9 @@ public class CSMemberResolver:ASTMatcherResolver
var memberDeclaration = parent.MergeOuter( name, blockEnd );
memberDeclaration.parametersStart = parametersStart;
memberDeclaration.parametersEnd = parametersEnd;
+ memberDeclaration.blockStart = blockStart;
+ memberDeclaration.blockEnd = blockEnd;
+
var hasParameterTokens = memberDeclaration.NextNode( parametersStart.childIndex ) != parametersEnd;
@@ -236,6 +262,14 @@ public class CSMemberResolver:ASTMatcherResolver
}
memberDeclaration.memberName = name;
+ memberDeclaration.blockContent = memberDeclaration.MergeInner( blockStart, blockEnd );
+
+ var statementsParser = new CSStatementsParser( memberDeclaration.blockContent );
+
+ RJLog.Log( "Processing statements:", memberDeclaration.blockContent.children.Count, memberDeclaration.blockContent.CombinedMatch() );
+ statementsParser.Process();
+
+
return memberDeclaration;
}
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSObjectParser.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSObjectParser.cs
index ec49e5f..8a1f1e5 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSObjectParser.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSObjectParser.cs
@@ -2,8 +2,6 @@ using System.Collections.Generic;
namespace Rokojori;
-
-
public class CSObjectParser:ASTParserPhase
{
ASTNode objectRoot;
@@ -22,6 +20,8 @@ public class CSObjectParser:ASTParserPhase
List resolvers =
[
+ CSImportDeclaration.Resolver(),
+
CSClassDeclaration.Resolver(),
CSStructDeclaration.Resolver(),
CSEnumDeclaration.Resolver(),
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSRootFileParser.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSRootFileParser.cs
index e5bab43..c0c180f 100644
--- a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSRootFileParser.cs
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSRootFileParser.cs
@@ -12,6 +12,7 @@ public class CSRootFileParser:ASTParserPhase
[
CSImportDeclaration.Resolver(),
CSNamespaceDeclaration.Resolver(),
+ CSNamespaceBlock.Resolver(),
CSClassDeclaration.Resolver(),
CSStructDeclaration.Resolver(),
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSBlockStatementResolver.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSBlockStatementResolver.cs
new file mode 100644
index 0000000..0d5ffc5
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSBlockStatementResolver.cs
@@ -0,0 +1,42 @@
+using System.Collections.Generic;
+
+namespace Rokojori;
+
+public class CSBlockStatement:ASTNode,Statement
+{
+ public ASTNode start;
+ public ASTNode body;
+ public ASTNode end;
+}
+
+public class CSBlockStatementResolver:CSStatementResolver
+{
+ public CSBlockStatementResolver():base(
+ TokenPredicateData.Create(
+ LexerMatcherLibrary.BracketMatcher.type, "{" )
+ )
+ {}
+
+ public override int Resolve( ASTMatchResult result, ASTMatcher matcher )
+ {
+ var parent = result.parent;
+ var start = parent.children[ result.resultStart ];
+ var end = result.parent.FindBracketCloser( "{", "}", result.resultStart );
+
+ var blockStatement = parent.MergeOuter( start, end );
+ var next = blockStatement.NextNode( start.childIndex );
+ var body = next != end ? next : null;
+
+ blockStatement.start = start;
+ blockStatement.body = body;
+ blockStatement.end = end;
+
+ if ( blockStatement.body != null )
+ {
+ new CSStatementsParser( body ).Process();
+ }
+
+ return blockStatement.childIndex;
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSBlockStatementResolver.cs.uid b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSBlockStatementResolver.cs.uid
new file mode 100644
index 0000000..ceffc06
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSBlockStatementResolver.cs.uid
@@ -0,0 +1 @@
+uid://oogxfm0od0bs
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSElseIfStatementResolver.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSElseIfStatementResolver.cs
new file mode 100644
index 0000000..8a84afe
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSElseIfStatementResolver.cs
@@ -0,0 +1,116 @@
+using System.Collections.Generic;
+
+namespace Rokojori;
+
+public class CSElseIfStatement:ASTNode,Statement
+{
+ public Token elseToken;
+ public Token ifToken;
+ public Token conditionStart;
+ public ASTNode condition;
+ public Token conditionEnd;
+ public ASTNode statement;
+}
+
+public class CSElseIfStatementResolver:CSStatementResolver
+{
+ string symbol = "";
+ public CSElseIfStatementResolver( string symbol ):base(
+ TokenPredicateData.Create( LexerMatcherLibrary.LogicMatcher.type, symbol )
+ )
+ {
+ this.symbol = symbol;
+ }
+
+ public override int Resolve( ASTMatchResult result, ASTMatcher matcher )
+ {
+ var parent = result.parent;
+ var start = parent.children[ result.resultStart ];
+
+ Token elseToken = null;
+ Token ifToken = null;
+
+
+ ASTNode lastNode = null;
+
+
+ if ( symbol == "if" )
+ {
+ ifToken = start as Token;
+ lastNode = ifToken;
+ }
+ else
+ {
+ elseToken = start as Token;
+ lastNode = elseToken;
+
+ var next = parent.NextNode( elseToken.childIndex );
+
+
+ if ( next.IsToken( LexerMatcherLibrary.LogicMatcher, "if" ) )
+ {
+ ifToken = next as Token;
+ lastNode = ifToken;
+ }
+ }
+
+ var hasConditional = ifToken != null;
+
+
+
+ Token conditionStart = null;
+ Token conditionEnd = null;
+ ASTNode condition = null;
+
+ if ( hasConditional )
+ {
+ var openBracketIndex = parent.FindTokenIndex( LexerMatcherLibrary.BracketMatcher, "(", start.childIndex );
+ var closeBracketIndex = parent.FindBracketCloserIndex( "(", ")", openBracketIndex );
+
+ conditionStart = parent.children[ openBracketIndex ] as Token;
+ conditionEnd = parent.children[ closeBracketIndex ] as Token;
+
+ condition = parent.MergeInner( conditionStart, conditionEnd );
+
+ lastNode = conditionEnd;
+
+ var expressionParser = parent.parser.GetExpressionParser();
+ expressionParser.ProcessExpression( condition );
+
+ }
+
+
+ var elseIfStatement = parent.MergeOuter( start, lastNode );
+ elseIfStatement.ifToken = ifToken;
+ elseIfStatement.elseToken = elseToken;
+
+ if ( hasConditional )
+ {
+ elseIfStatement.conditionStart = conditionStart;
+ elseIfStatement.conditionEnd = conditionEnd;
+ elseIfStatement.condition = condition;
+ }
+
+ var parser = new CSStatementsParser( parent );
+ var matchResult = new ASTMatchResult();
+ matchResult.parent = parent;
+ matchResult.childOffset = parent.NextNode( elseIfStatement.childIndex ).childIndex;
+
+ var nextStatementIndex = parser.ResolveNext( matchResult );
+
+ if ( nextStatementIndex == -1 )
+ {
+ RJLog.Error( "No statement found:", ifToken, symbol, hasConditional, ( start as Token ).lineInfo );
+ parser.ResolveNext( matchResult, true );
+
+ }
+
+ var nextStatement = parent.children[ nextStatementIndex ];
+
+ elseIfStatement.ExpandToNext( nextStatement );
+ elseIfStatement.statement = nextStatement;
+
+ return elseIfStatement.childIndex;
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSElseIfStatementResolver.cs.uid b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSElseIfStatementResolver.cs.uid
new file mode 100644
index 0000000..f7b526b
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSElseIfStatementResolver.cs.uid
@@ -0,0 +1 @@
+uid://c38c6xnmvpwea
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSExpressionStatementResolver.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSExpressionStatementResolver.cs
new file mode 100644
index 0000000..85ea8a9
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSExpressionStatementResolver.cs
@@ -0,0 +1,39 @@
+using System.Collections.Generic;
+
+namespace Rokojori;
+
+public class CSExpressionStatement:ASTNode,Statement
+{
+ public ASTNode expression;
+ public Token statementEnd;
+}
+
+public class CSExpressionStatementResolver:CSStatementResolver
+{
+ public CSExpressionStatementResolver():base( null )
+ {}
+
+ public override int Resolve( ASTMatchResult result, ASTMatcher matcher )
+ {
+ var parent = result.parent;
+ var endIndex = parent.FindSemicolonIndex( result.resultStart );
+
+ if ( endIndex == -1 )
+ {
+ return -1;
+ }
+
+ var end = parent.children[ endIndex ] as Token;
+
+ var expression = parent.MergeOuter( result.resultStart, endIndex );
+ expression.statementEnd = end;
+ expression.expression = new ASTNodeList();
+ expression.expression.parent = expression;
+ expression.MergeChildren( 0, expression.statementEnd.childIndex, expression.expression );
+
+ parent.parser.GetExpressionParser().ProcessExpression( expression.expression );
+
+ return expression.childIndex;
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSExpressionStatementResolver.cs.uid b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSExpressionStatementResolver.cs.uid
new file mode 100644
index 0000000..dfd49e3
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSExpressionStatementResolver.cs.uid
@@ -0,0 +1 @@
+uid://g8mbldjmjpv4
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForEachStatementResolver.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForEachStatementResolver.cs
new file mode 100644
index 0000000..0bd0ed1
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForEachStatementResolver.cs
@@ -0,0 +1,64 @@
+using System.Collections.Generic;
+
+namespace Rokojori;
+
+public class CSForEachStatement:ASTNode,Statement
+{
+ public Token forEachToken;
+ public Token conditionStart;
+ public ASTNode condition;
+ public Token conditionEnd;
+ public ASTNode statement;
+}
+
+public class CSForEachStatementResolver:CSStatementResolver
+{
+ public CSForEachStatementResolver():base(
+ TokenPredicateData.Create(
+ LexerMatcherLibrary.LogicMatcher.type, "foreach" )
+ )
+ {}
+
+ public override int Resolve( ASTMatchResult result, ASTMatcher matcher )
+ {
+ var parent = result.parent;
+ var start = parent.children[ result.resultStart ];
+
+ var forEachToken = start as Token;
+
+ var openBracketIndex = parent.FindTokenIndex( LexerMatcherLibrary.BracketMatcher, "(", start.childIndex );
+ var closeBracketIndex = parent.FindBracketCloserIndex( "(", ")", openBracketIndex );
+
+ var conditionStart = parent.children[ openBracketIndex ] as Token;
+ var conditionEnd = parent.children[ closeBracketIndex ] as Token;
+
+ var condition = parent.MergeInner( conditionStart, conditionEnd );
+
+ var lastNode = conditionEnd;
+
+ var expressionParser = new CSExpressionParser();
+ expressionParser.ProcessExpression( condition );
+
+ var forEachStatement = parent.MergeOuter( start, lastNode );
+ forEachStatement.forEachToken = forEachToken;
+
+ forEachStatement.conditionStart = conditionStart;
+ forEachStatement.conditionEnd = conditionEnd;
+ forEachStatement.condition = condition;
+
+
+ var parser = new CSStatementsParser( parent );
+ var matchResult = new ASTMatchResult();
+ matchResult.parent = parent;
+ matchResult.childOffset = parent.NextNode( forEachStatement.childIndex ).childIndex;
+
+ var nextStatementIndex = parser.ResolveNext( matchResult );
+ var nextStatement = parent.children[ nextStatementIndex ];
+
+ forEachStatement.ExpandToNext( nextStatement );
+ forEachStatement.statement = nextStatement;
+
+ return forEachStatement.childIndex;
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForEachStatementResolver.cs.uid b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForEachStatementResolver.cs.uid
new file mode 100644
index 0000000..cb91c97
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForEachStatementResolver.cs.uid
@@ -0,0 +1 @@
+uid://ccf10760cnijg
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForStatementResolver.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForStatementResolver.cs
new file mode 100644
index 0000000..d63d568
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForStatementResolver.cs
@@ -0,0 +1,78 @@
+using System.Collections.Generic;
+
+namespace Rokojori;
+
+public class CSForStatement:ASTNode,Statement
+{
+ public Token forToken;
+
+ public Token conditionStart;
+
+ public ASTNode init;
+ public ASTNode condition;
+ public ASTNode update;
+
+ public Token conditionEnd;
+
+ public ASTNode statement;
+}
+
+public class CSForStatementResolver:CSStatementResolver
+{
+ public CSForStatementResolver():base(
+ TokenPredicateData.Create(
+ LexerMatcherLibrary.LogicMatcher.type, "for" )
+ )
+ {}
+
+ public override int Resolve( ASTMatchResult result, ASTMatcher matcher )
+ {
+ var parent = result.parent;
+ var start = parent.children[ result.resultStart ];
+
+ var forToken = start as Token;
+
+ var openBracketIndex = parent.FindTokenIndex( LexerMatcherLibrary.BracketMatcher, "(", start.childIndex );
+ var closeBracketIndex = parent.FindBracketCloserIndex( "(", ")", openBracketIndex );
+
+ var conditionStart = parent.children[ openBracketIndex ] as Token;
+ var conditionEnd = parent.children[ closeBracketIndex ] as Token;
+
+ var lastNode = conditionEnd;
+
+ var expressionParser = new CSExpressionParser();
+
+ var forStatement = parent.MergeOuter( start, lastNode );
+ forStatement.forToken = forToken;
+ forStatement.conditionStart = conditionStart;
+ forStatement.conditionEnd = conditionEnd;
+
+ var firstSeparatorIndex = forStatement.FindSemicolonIndex( forStatement.conditionStart.childIndex );
+ var nextSeparatorIndex = forStatement.FindSemicolonIndex( firstSeparatorIndex + 1 );
+
+ var firstS = forStatement.children[ firstSeparatorIndex ];
+ var secondS = forStatement.children[ nextSeparatorIndex ];
+
+ forStatement.init = forStatement.MergeInner( conditionStart, firstS );
+ forStatement.condition = forStatement.MergeInner( firstS, secondS );
+ forStatement.update = forStatement.MergeInner( secondS, conditionEnd );
+
+ expressionParser.ProcessExpression( forStatement.init );
+ expressionParser.ProcessExpression( forStatement.condition );
+ expressionParser.ProcessExpression( forStatement.update );
+
+ var parser = new CSStatementsParser( parent );
+ var matchResult = new ASTMatchResult();
+ matchResult.parent = parent;
+ matchResult.childOffset = parent.NextNode( forStatement.childIndex ).childIndex;
+
+ var nextStatementIndex = parser.ResolveNext( matchResult );
+ var nextStatement = parent.children[ nextStatementIndex ];
+
+ forStatement.ExpandToNext( nextStatement );
+ forStatement.statement = nextStatement;
+
+ return forStatement.childIndex;
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForStatementResolver.cs.uid b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForStatementResolver.cs.uid
new file mode 100644
index 0000000..5bb95c0
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSForStatementResolver.cs.uid
@@ -0,0 +1 @@
+uid://cdjcmyg0ummtm
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementResolver.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementResolver.cs
new file mode 100644
index 0000000..4281f09
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementResolver.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+
+namespace Rokojori;
+
+public abstract class CSStatementResolver:ASTMatcherResolver
+{
+ public TokenPredicateData triggerToken;
+
+ public CSStatementResolver( TokenPredicateData triggerToken )
+ {
+ this.triggerToken = triggerToken;
+
+ if ( this.triggerToken == null )
+ {
+ matcher = new NotIgnoreNodeMatcher();
+ }
+ else
+ {
+ var tokenMatcher = new TokenMatcher();
+ tokenMatcher.matchData = triggerToken;
+
+ matcher = tokenMatcher;
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementResolver.cs.uid b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementResolver.cs.uid
new file mode 100644
index 0000000..3471d01
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementResolver.cs.uid
@@ -0,0 +1 @@
+uid://cw1xxsluowuok
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementsParser.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementsParser.cs
new file mode 100644
index 0000000..3a183ad
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementsParser.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+
+namespace Rokojori;
+
+public class CSStatementsParser:ASTParser
+{
+ public static List statementResolvers =
+ [
+ new CSBlockStatementResolver(),
+
+ new CSStopStatementResolver( "return", true ),
+ new CSStopStatementResolver( "throw", true ),
+
+ new CSStopStatementResolver( "break", false ),
+ new CSStopStatementResolver( "continue", false ),
+
+ new CSElseIfStatementResolver( "if" ),
+ new CSElseIfStatementResolver( "else" ),
+
+ new CSForStatementResolver(),
+ new CSForEachStatementResolver(),
+
+ new CSExpressionStatementResolver()
+ ];
+
+ public CSStatementsParser( ASTNode root )
+ {
+ this.root = root;
+ resolvers = statementResolvers;
+ }
+
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementsParser.cs.uid b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementsParser.cs.uid
new file mode 100644
index 0000000..6c57d9d
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStatementsParser.cs.uid
@@ -0,0 +1 @@
+uid://l08jw4vp71u2
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStopStatementResolver.cs b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStopStatementResolver.cs
new file mode 100644
index 0000000..70ab8c0
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStopStatementResolver.cs
@@ -0,0 +1,64 @@
+using System.Collections.Generic;
+
+namespace Rokojori;
+
+public class CSStopStatement:ASTNode,Statement
+{
+ public Token stopToken;
+ public ASTNodeList expression;
+ public Token endToken;
+}
+
+public class CSStopStatementResolver:CSStatementResolver
+{
+ bool postExpression;
+
+ public CSStopStatementResolver( string symbol, bool postExpression ):base(
+ TokenPredicateData.Create(
+ LexerMatcherLibrary.LogicMatcher.type, symbol )
+ )
+ {
+ this.postExpression = postExpression;
+ }
+
+ public override int Resolve( ASTMatchResult result, ASTMatcher matcher )
+ {
+ var parent = result.parent;
+ var start = parent.children[ result.resultStart ];
+
+ var endIndex = parent.FindSemicolonIndex( result.resultStart );
+
+
+ if ( ! postExpression )
+ {
+ var next = parent.NextNode( start.childIndex );
+
+ if ( next.childIndex != endIndex )
+ {
+ RJLog.Error( "Unexpected type:", next );
+ throw new System.Exception( "Unexpected type:" );
+ }
+ }
+
+ var end = parent.children[ endIndex ] as Token;
+ var csStopStatement = parent.MergeOuter( start.childIndex, endIndex );
+ csStopStatement.stopToken = start as Token;
+ csStopStatement.endToken = end;
+
+ if ( postExpression && ( end.childIndex - 1 ) > start.childIndex + 1 )
+ {
+ csStopStatement.expression = csStopStatement.MergeInner(
+ csStopStatement.stopToken,
+ csStopStatement.endToken
+ );
+ }
+
+ if ( csStopStatement.expression != null )
+ {
+ new CSStatementsParser( csStopStatement.expression ).Process();
+ }
+
+ return csStopStatement.childIndex;
+ }
+
+}
\ No newline at end of file
diff --git a/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStopStatementResolver.cs.uid b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStopStatementResolver.cs.uid
new file mode 100644
index 0000000..aa98d88
--- /dev/null
+++ b/Runtime/Text/Parsing/ParserLibrary/CSharp/Parsers/CSStatements/CSStopStatementResolver.cs.uid
@@ -0,0 +1 @@
+uid://drcldxarg5lw6
diff --git a/Runtime/Text/Parsing/Statements/ASTStatement.cs b/Runtime/Text/Parsing/Statements/ASTStatement.cs
new file mode 100644
index 0000000..caac1dd
--- /dev/null
+++ b/Runtime/Text/Parsing/Statements/ASTStatement.cs
@@ -0,0 +1,8 @@
+using System.Collections.Generic;
+
+namespace Rokojori;
+
+public interface Statement
+{
+
+}
diff --git a/Runtime/Text/Parsing/Statements/ASTStatement.cs.uid b/Runtime/Text/Parsing/Statements/ASTStatement.cs.uid
new file mode 100644
index 0000000..6e9f2c9
--- /dev/null
+++ b/Runtime/Text/Parsing/Statements/ASTStatement.cs.uid
@@ -0,0 +1 @@
+uid://plrsvtf0xr3v
diff --git a/Runtime/Text/TextLinesMapper.cs b/Runtime/Text/TextLinesMapper.cs
index f9b0a43..c78fa0f 100644
--- a/Runtime/Text/TextLinesMapper.cs
+++ b/Runtime/Text/TextLinesMapper.cs
@@ -78,7 +78,11 @@ namespace Rokojori
public TextAnchor GetAnchor( int characterIndex, bool forTextEditor )
{
var line = GetLine( characterIndex );
- if ( line == null ) { return null; }
+
+ if ( line == null )
+ {
+ return null;
+ }
return forTextEditor ? line.GetTextEditorAnchor( characterIndex ) : line.GetRawAnchor( characterIndex );
}
diff --git a/Runtime/Tools/TestNode.cs b/Runtime/Tools/TestNode.cs
new file mode 100644
index 0000000..1caa3ac
--- /dev/null
+++ b/Runtime/Tools/TestNode.cs
@@ -0,0 +1,39 @@
+using System.Collections;
+using System.Collections.Generic;
+
+using Godot;
+
+namespace Rokojori;
+
+[GlobalClass][Tool]
+public partial class TestNode:Node
+{
+ /**
+
+ The value of the other int
+
+ */
+ [Export]
+ public int otherValue = 1;
+
+ /**
+
+ The value of the int
+
+ */
+ [Export]
+ public int intValue = 0;
+
+ /**
+
+ The value of the float
+
+ */
+ [Export]
+ public float floatValue = 0;
+
+
+ [Export]
+ public TestResource testResource;
+
+}
diff --git a/Runtime/Tools/TestNode.cs.uid b/Runtime/Tools/TestNode.cs.uid
new file mode 100644
index 0000000..8d99ff2
--- /dev/null
+++ b/Runtime/Tools/TestNode.cs.uid
@@ -0,0 +1 @@
+uid://dhrut5oecuo3n
diff --git a/Runtime/Tools/TestResource.cs b/Runtime/Tools/TestResource.cs
new file mode 100644
index 0000000..9a8c930
--- /dev/null
+++ b/Runtime/Tools/TestResource.cs
@@ -0,0 +1,31 @@
+using System.Collections;
+using System.Collections.Generic;
+
+using Godot;
+
+namespace Rokojori;
+
+[GlobalClass][Tool]
+public partial class TestResource:Resource
+{
+ /**
+
+ The value of the other int
+
+ */
+ [Export]
+ public int otherValue = 1;
+
+ /**
+
+ The value of the int
+
+ */
+ [Export]
+ public int intValue = 0;
+
+
+
+ [Export]
+ public TestResource testResource;
+}
diff --git a/Runtime/Tools/TestResource.cs.uid b/Runtime/Tools/TestResource.cs.uid
new file mode 100644
index 0000000..8af983b
--- /dev/null
+++ b/Runtime/Tools/TestResource.cs.uid
@@ -0,0 +1 @@
+uid://c8y868kh2knwx
diff --git a/Runtime/XML/Nodes/XMLAttributeNode.cs b/Runtime/XML/Nodes/XMLAttributeNode.cs
index 3a7df07..40cbcd5 100644
--- a/Runtime/XML/Nodes/XMLAttributeNode.cs
+++ b/Runtime/XML/Nodes/XMLAttributeNode.cs
@@ -25,6 +25,7 @@ namespace Rokojori
public string nameSpace => _nameSpace;
public override string nodeValue => value;
+ public override string textContent => value;
public string fullName
{
diff --git a/Runtime/XML/Nodes/XMLDocument.cs b/Runtime/XML/Nodes/XMLDocument.cs
index ac51c66..c8f078a 100644
--- a/Runtime/XML/Nodes/XMLDocument.cs
+++ b/Runtime/XML/Nodes/XMLDocument.cs
@@ -55,6 +55,8 @@ namespace Rokojori
}
}
+ public override string textContent => documentElement?.textContent ?? "";
+
public string Serialize()
{
var serializer = new XMLSerializer();
diff --git a/Runtime/XML/Nodes/XMLElementNode.cs b/Runtime/XML/Nodes/XMLElementNode.cs
index 4074268..e3d03b1 100644
--- a/Runtime/XML/Nodes/XMLElementNode.cs
+++ b/Runtime/XML/Nodes/XMLElementNode.cs
@@ -1,5 +1,6 @@
using System.Collections;
using System.Collections.Generic;
+using System.Text;
using System.Text.RegularExpressions;
namespace Rokojori
@@ -12,6 +13,21 @@ namespace Rokojori
_nameSpace = nameSpace;
}
+ public override string textContent
+ {
+ get
+ {
+ var sb = new StringBuilder();
+
+ for ( int i = 0; i < _children.Count; i++ )
+ {
+ sb.Append( _children[ i ].textContent );
+ }
+
+ return sb.ToString();
+ }
+ }
+
string _nodeName;
public string nodeName => _nodeName;
diff --git a/Runtime/XML/Nodes/XMLTextNode.cs b/Runtime/XML/Nodes/XMLTextNode.cs
index a015ca8..bbe088c 100644
--- a/Runtime/XML/Nodes/XMLTextNode.cs
+++ b/Runtime/XML/Nodes/XMLTextNode.cs
@@ -14,5 +14,6 @@ namespace Rokojori
string _textContent;
public override string nodeValue => _textContent;
+ public override string textContent => _textContent;
}
}
\ No newline at end of file
diff --git a/Runtime/XML/XMLNode.cs b/Runtime/XML/XMLNode.cs
index b637838..f75a657 100644
--- a/Runtime/XML/XMLNode.cs
+++ b/Runtime/XML/XMLNode.cs
@@ -1,5 +1,6 @@
using System.Collections;
using System.Collections.Generic;
+using System.Text;
using System.Text.RegularExpressions;
namespace Rokojori
diff --git a/Runtime/XML/XMLReader.cs b/Runtime/XML/XMLReader.cs
index b403a1f..fdad71d 100644
--- a/Runtime/XML/XMLReader.cs
+++ b/Runtime/XML/XMLReader.cs
@@ -43,7 +43,7 @@
errorLine += "~";
- RJLog.Error( line.GetContent( text ) + "\n" + errorLine );
+ RJLog.Error( "Line " + line.lineIndex + " >> \n" + line.GetContent( text ) + "\n" + errorLine );
return null;
diff --git a/Tools/analysis/ClassDocFromParser.cs b/Tools/analysis/ClassDocFromParser.cs
new file mode 100644
index 0000000..cd77bc8
--- /dev/null
+++ b/Tools/analysis/ClassDocFromParser.cs
@@ -0,0 +1,113 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Text;
+using System.Reflection;
+
+namespace Rokojori.DocGenerator;
+
+public class ClassDocFromParser
+{
+ public ClassDocInfo objectInfo = new ClassDocInfo();
+
+ public static ClassDocInfo CreateFrom( CSObjectDeclaration csClass )
+ {
+ var cd = new ClassDocFromParser();
+ cd.Create( csClass );
+
+ return cd.objectInfo;
+ }
+
+ public void Create( CSObjectDeclaration csClass )
+ {
+ var walker = csClass.parser.root.walker;
+
+ objectInfo.name = csClass.objectName.match;
+ objectInfo.csNameSpace = csClass.GetNamespace();
+ objectInfo.doc = csClass.GetDocumentation();
+ objectInfo.attributes = csClass.GetMemberAttributes();
+ objectInfo.modifiers = csClass.GetMemberModifiers();
+
+
+ if ( csClass.objectTail != null && csClass.objectTail.inheritanceDeclaration != null )
+ {
+ objectInfo.extendingClasses = [ csClass.objectTail.GetExtendingObject() ];
+ }
+
+ objectInfo.attributes = CSModifierAttributesParser.GetAttributes( csClass.attributeBrackets );
+
+
+ var members = new List();
+
+ walker.Iterate( csClass,
+ n =>
+ {
+ // if ( n is CSEnumDeclaration en )
+ // {
+ // var enumType = new GDScriptGeneratorEnum();
+ // enumType.name = en.objectName.match;
+
+ // var values = en.objectBody.children.FilterType( );
+ // enumType.values =values.Map( v => v.GetEnumName() );
+
+ // gdClass.members.Add( enumType );
+
+ // return;
+ // }
+
+ if ( ! ( n is CSMemberDeclaration ) )
+ {
+ return;
+ }
+
+
+ var m = n as CSMemberDeclaration;
+
+ MemberInfo member = new MemberInfo();
+ member.name = m.GetMemberName();
+ member.dataType = m.GetMemberType();
+ member.doc = m.GetDocumentation();
+ member.attributes = m.GetMemberAttributes();
+ member.modifiers = m.GetMemberModifiers();
+
+ if ( m is CSFieldDeclaration f )
+ {
+ member.memberType = MemberInfo.Field;
+ }
+ else if ( m is CSMethodMemberDeclaration me )
+ {
+ member.memberType = me.isContructor ? MemberInfo.Constructor : MemberInfo.Method;
+
+ if ( me.parametersContent != null )
+ {
+ me.parametersContent.children.ForEach(
+ ( c ) =>
+ {
+ var p = c as CSParameterDeclaration;
+
+ var parameter = new ParameterType();
+ parameter.name = p.GetParameterName();
+ parameter.type = p.GetParameterType();
+
+ if ( p.parameterValue != null )
+ {
+ parameter.value = p.GetParameterValue();
+ }
+
+ member.parameters.Add( parameter );
+
+
+ }
+ );
+ }
+
+ }
+
+ objectInfo.memberInfos.Add( member );
+
+ },
+ false
+ );
+
+ }
+}
\ No newline at end of file
diff --git a/Tools/analysis/ClassDocFromParser.cs.uid b/Tools/analysis/ClassDocFromParser.cs.uid
new file mode 100644
index 0000000..b42cff5
--- /dev/null
+++ b/Tools/analysis/ClassDocFromParser.cs.uid
@@ -0,0 +1 @@
+uid://yos5dvjtt8xu
diff --git a/Tools/analysis/LibraryDependencies.cs b/Tools/analysis/LibraryDependencies.cs
new file mode 100644
index 0000000..66176d8
--- /dev/null
+++ b/Tools/analysis/LibraryDependencies.cs
@@ -0,0 +1,8 @@
+using System.Collections.Generic;
+
+namespace Rokojori.Analysis;
+
+public class LibraryDependencies
+{
+
+}
diff --git a/Tools/analysis/LibraryDependencies.cs.uid b/Tools/analysis/LibraryDependencies.cs.uid
new file mode 100644
index 0000000..2595199
--- /dev/null
+++ b/Tools/analysis/LibraryDependencies.cs.uid
@@ -0,0 +1 @@
+uid://cr2i2cr15uoyg
diff --git a/Tools/core-generation/CoreCSGeneratorSettings.cs b/Tools/core-generation/CoreCSGeneratorSettings.cs
new file mode 100644
index 0000000..550e35b
--- /dev/null
+++ b/Tools/core-generation/CoreCSGeneratorSettings.cs
@@ -0,0 +1,21 @@
+
+using Godot;
+
+using Rokojori;
+using System.Collections.Generic;
+using System;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Linq;
+using System.IO;
+
+namespace Rokojori.CoreGeneration;
+
+[Tool]
+public partial class CoreCSGeneratorSettings:RokojoriActionCoreSettings
+{
+ public override void Generate( Node context )
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Tools/core-generation/CoreCSGeneratorSettings.cs.uid b/Tools/core-generation/CoreCSGeneratorSettings.cs.uid
new file mode 100644
index 0000000..90851b2
--- /dev/null
+++ b/Tools/core-generation/CoreCSGeneratorSettings.cs.uid
@@ -0,0 +1 @@
+uid://b2vox5o5e8wwy
diff --git a/Tools/core-generation/RokojoriActionCoreExport.cs b/Tools/core-generation/RokojoriActionCoreExport.cs
new file mode 100644
index 0000000..f888d95
--- /dev/null
+++ b/Tools/core-generation/RokojoriActionCoreExport.cs
@@ -0,0 +1,7 @@
+using System;
+namespace Rokojori;
+
+public class RokojoriActionCoreExport : Attribute
+{
+
+}
\ No newline at end of file
diff --git a/Tools/core-generation/RokojoriActionCoreExport.cs.uid b/Tools/core-generation/RokojoriActionCoreExport.cs.uid
new file mode 100644
index 0000000..4f78e0a
--- /dev/null
+++ b/Tools/core-generation/RokojoriActionCoreExport.cs.uid
@@ -0,0 +1 @@
+uid://xyhglylgr8s2
diff --git a/Tools/core-generation/RokojoriActionCoreGenerator.cs b/Tools/core-generation/RokojoriActionCoreGenerator.cs
new file mode 100644
index 0000000..d126dfa
--- /dev/null
+++ b/Tools/core-generation/RokojoriActionCoreGenerator.cs
@@ -0,0 +1,31 @@
+
+using Godot;
+
+using Rokojori;
+using System.Collections.Generic;
+using System;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Linq;
+using System.IO;
+
+namespace Rokojori.CoreGeneration;
+
+[Tool]
+public partial class RokojoriActionCoreGenerator : Node
+{
+ [ExportToolButton( "Generate" )]
+ public Callable generateButton => Callable.From(
+ ()=>
+ {
+ settings.Generate( this );
+ }
+ );
+
+ [Export]
+ public RokojoriActionCoreSettings settings;
+
+
+
+
+}
\ No newline at end of file
diff --git a/Tools/core-generation/RokojoriActionCoreGenerator.cs.uid b/Tools/core-generation/RokojoriActionCoreGenerator.cs.uid
new file mode 100644
index 0000000..7bd15a3
--- /dev/null
+++ b/Tools/core-generation/RokojoriActionCoreGenerator.cs.uid
@@ -0,0 +1 @@
+uid://86waecsiy8wg
diff --git a/Tools/core-generation/RokojoriActionCoreSettings.cs b/Tools/core-generation/RokojoriActionCoreSettings.cs
new file mode 100644
index 0000000..1173677
--- /dev/null
+++ b/Tools/core-generation/RokojoriActionCoreSettings.cs
@@ -0,0 +1,27 @@
+
+using Godot;
+
+using Rokojori;
+using System.Collections.Generic;
+using System;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Linq;
+using System.IO;
+
+namespace Rokojori.CoreGeneration;
+
+[Tool]
+public partial class RokojoriActionCoreSettings: Resource
+{
+ [Export]
+ public string outputProjectPath;
+
+ [Export]
+ public string addonPath;
+
+ public virtual void Generate( Node context )
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Tools/core-generation/RokojoriActionCoreSettings.cs.uid b/Tools/core-generation/RokojoriActionCoreSettings.cs.uid
new file mode 100644
index 0000000..cc3d8b7
--- /dev/null
+++ b/Tools/core-generation/RokojoriActionCoreSettings.cs.uid
@@ -0,0 +1 @@
+uid://bq4unyccjiqyn
diff --git a/Tools/docs/ClassDocInfo.cs b/Tools/docs/ClassDocInfo.cs
index 8ed86f6..522343a 100644
--- a/Tools/docs/ClassDocInfo.cs
+++ b/Tools/docs/ClassDocInfo.cs
@@ -8,6 +8,7 @@ namespace Rokojori.DocGenerator
{
public string name;
public string type;
+ public string value;
public string csNameSpace;
public List modifiers = [];
public List generics = [];
@@ -86,7 +87,9 @@ namespace Rokojori.DocGenerator
public string sourcePath;
public string definitionType;
public ISOTimeStamp modificationTime;
-
+
+ public List modifiers = new List();
+ public List attributes = new List();
public List generics = new List();
public List interfaces = new List();
public List extendingClasses = new List();
diff --git a/Tools/gd-only-generator/GDLibraryGenerator.cs b/Tools/gd-only-generator/GDLibraryGenerator.cs
new file mode 100644
index 0000000..5208b46
--- /dev/null
+++ b/Tools/gd-only-generator/GDLibraryGenerator.cs
@@ -0,0 +1,171 @@
+
+using Godot;
+
+using Rokojori;
+using System.Collections.Generic;
+using System;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Linq;
+using System.IO;
+
+namespace Rokojori.GDLibraryGeneration
+{
+ [Tool][GlobalClass]
+ public partial class GDLibraryGenerator:Node
+ {
+ [Export]
+ public string path = "rokojori_action_library_gd";
+
+ [Export]
+ public bool scanForGDExport = true;
+
+ [Export]
+ public string[] files = [];
+
+ [ExportToolButton( "Generate" )]
+ public Callable generateButton => Callable.From(
+ ()=>
+ {
+ GenerateGDLibrary();
+ }
+ );
+
+ HashSet defines = new HashSet();
+
+ void GenerateGDLibrary()
+ {
+ defines = new HashSet();
+ defines.Add( GDScriptGenerator.GD_SCRIPT_TRANSPILING );
+
+ var codeFilePaths = GetCodeFilePaths();
+
+
+
+
+ var rokojoriProPath = FilePath.Absolute( ProjectSettings.GlobalizePath( RokojoriPlugin.path ) );
+ var rokojoriGDPath = FilePath.Absolute( ProjectSettings.GlobalizePath( "res://addons/" + path ) );
+
+
+ codeFilePaths.ForEach(
+ ( c )=>
+ {
+ var parser = new CSParser( c.absolutePath, defines );
+ var root = parser.root as CSFileRoot;
+
+ var originalPath = FilePath.Absolute( root.GetFilePath() );
+ var relativePath = rokojoriProPath.MakeAbsolutePathRelative( originalPath.parentAbsolutePath );
+ var gdPath = rokojoriGDPath.MakeRelative( relativePath.path );
+
+ var converter = new GDScriptFromCSAST();
+ converter.Convert( root );
+ var gdclass = converter.gdClass;
+
+ var gdgenerator = new GDScriptGenerator();
+ gdgenerator.gdClasses = [ gdclass ];
+
+ FilesSync.EnsureDirectoryExists( gdPath.absolutePath );
+ gdgenerator.Generate( gdPath.absolutePath );
+ }
+ );
+
+
+
+
+ }
+
+ List GetCodeFilePaths()
+ {
+ var codeFilePaths = new List();
+
+ var map = new HashSet();
+
+ var combinedFiles = new List();
+
+ combinedFiles.AddRange( files );
+
+ if ( scanForGDExport )
+ {
+ var absPath = ProjectSettings.GlobalizePath( RokojoriPlugin.path );
+ var scannedExportfiles = FilesSync.GetFilesRecursive( absPath, f => f.HasFileExtension( ".cs" ) );
+ scannedExportfiles = scannedExportfiles.Filter(
+ ( f, i ) =>
+ {
+ var text = f.LoadUTF8();
+
+ if ( ! text.Contains( "GDExport" ) )
+ {
+ return false;
+ }
+
+ var parser = new CSParser( f.absolutePath, defines );
+ var csRoot = parser.root as CSFileRoot;
+ var cd = csRoot.GetObjectDeclarations().Find( c => c.objectName.match == f.fileName );
+
+ return cd?.GetMemberAttributes().Contains( "GDExport" ) ?? false;
+ }
+ );
+
+
+ var scannedPaths = scannedExportfiles.Map( f => f.absolutePath );
+
+ RJLog.Log( "Found paths:", scannedPaths );
+ combinedFiles.AddRange( scannedPaths );
+
+ }
+
+ combinedFiles.ForEach(
+ ( fileString )=>
+ {
+ FilePath filePath;
+
+ if ( fileString.StartsWith( "res://" ) )
+ {
+ filePath = FilePath.Absolute( ProjectSettings.GlobalizePath( fileString ) );
+ }
+ else if ( ! fileString.EndsWith( ".cs" ) )
+ {
+ filePath = FindFilePathOf( fileString );
+ }
+ else
+ {
+ filePath = FilePath.Absolute( fileString );
+ }
+
+ if ( filePath == null || ! filePath.Exists() )
+ {
+ return;
+ }
+
+ var absolutePath = filePath.absolutePath;
+
+ if ( map.Contains( absolutePath ) )
+ {
+ return;
+ }
+
+ codeFilePaths.Add( filePath );
+ map.Add( absolutePath );
+ }
+ );
+
+ return codeFilePaths;
+ }
+
+
+
+ List filePaths;
+
+ FilePath FindFilePathOf( string type )
+ {
+ if ( filePaths == null )
+ {
+ var rokojoriPath = ProjectSettings.GlobalizePath( RokojoriPlugin.path );
+ filePaths = FilesSync.GetFilesRecursive( rokojoriPath, fp => fp.HasFileExtension( ".cs" ) );
+ }
+
+ return filePaths.Find( fp => fp.fileName == type );
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Tools/gd-only-generator/GDLibraryGenerator.cs.uid b/Tools/gd-only-generator/GDLibraryGenerator.cs.uid
new file mode 100644
index 0000000..d81eaa9
--- /dev/null
+++ b/Tools/gd-only-generator/GDLibraryGenerator.cs.uid
@@ -0,0 +1 @@
+uid://bosqs73jx5m0m
diff --git a/Tools/godot-editor-inspector-tools/CSInspectors/CSDocEditorInspector.cs b/Tools/godot-editor-inspector-tools/CSInspectors/CSDocEditorInspector.cs
new file mode 100644
index 0000000..d026cb0
--- /dev/null
+++ b/Tools/godot-editor-inspector-tools/CSInspectors/CSDocEditorInspector.cs
@@ -0,0 +1,123 @@
+#if TOOLS
+using System.Collections.Generic;
+using Godot;
+
+namespace Rokojori.Tools;
+using Rokojori.DocGenerator;
+
+public partial class CSDocEditorInspector : EditorInspectorPlugin
+{
+ public override bool _CanHandle( GodotObject obj )
+ {
+ return obj is TestNode || obj is TestResource;
+ }
+
+
+ public static HashSet godotBuiltInInts = new HashSet()
+ {
+ "process_mode",
+ "process_priority",
+ "process_physics_priority",
+ "process_thread_group",
+ "physics_interpolation_mode",
+ "auto_translate_mode"
+ };
+
+ public MultiMap objectComments = new MultiMap