rokojori_action_library/Runtime/Text/Parsing/AST/ASTWalker.cs

141 lines
2.7 KiB
C#

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<ASTNode>
{
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<ASTNode>
{
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<Type,List<FieldInfo>> _typeFieldInfos = new Dictionary<Type, List<FieldInfo>>();
void GrabInfo( ASTNode node )
{
if ( node == null )
{
return;
}
var type = node.GetType();
if ( _typeFieldInfos.ContainsKey( type ) )
{
return;
}
_typeFieldInfos[ type ] = ReflectionHelper.GetFieldInfosOfType<ASTNode>( node );
}
}