using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Text; using System.Globalization; using Godot; using System; using System.Reflection; namespace Rokojori; public class ASTWalker:TreeWalker { public static readonly ASTWalker instance = new ASTWalker(); public override ASTNode Parent( ASTNode node ) { return node?.parent; } public override ASTNode ChildAt( ASTNode node, int index ) { if ( node == null || index < 0 || index >= node.children.Count ) { return null; } return node.children[ index ]; } public override int NumChildren( ASTNode node ) { return node?.children.Count ?? 0; } } 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 ); } }