Files
ironjava/IronJava.Core/AST/Transformation/AstTransformer.cs
Dave Friedel 5439aeb081 Resolved build errors
1. Fixed constructor calls in AstTransformer.cs by adding missing nestedTypes parameter
  2. Fixed constructor calls in AstJsonSerializer.cs by adding logic to deserialize nestedTypes
  3. Fixed constructor calls in AstBuilder.cs by adding empty nestedTypes lists and correct parameters
  4. Fixed test files by updating ClassDeclaration constructors with proper parameters
2025-07-23 05:24:18 -04:00

409 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using MarketAlly.IronJava.Core.AST.Nodes;
using MarketAlly.IronJava.Core.AST.Visitors;
namespace MarketAlly.IronJava.Core.AST.Transformation
{
/// <summary>
/// Base class for AST transformations that create modified copies of nodes.
/// </summary>
public abstract class AstTransformer : JavaVisitorBase<JavaNode?>
{
protected override JavaNode? DefaultVisit(JavaNode node)
{
// By default, return null to indicate no transformation
return null;
}
/// <summary>
/// Transform a list of nodes, filtering out nulls.
/// </summary>
protected List<T> TransformList<T>(IReadOnlyList<T> nodes) where T : JavaNode
{
return nodes
.Select(n => n.Accept(this) as T)
.Where(n => n != null)
.Cast<T>()
.ToList();
}
/// <summary>
/// Transform a node or return the original if no transformation.
/// </summary>
protected T TransformOrOriginal<T>(T node) where T : JavaNode
{
var transformed = node.Accept(this) as T;
return transformed ?? node;
}
/// <summary>
/// Transform an optional node.
/// </summary>
protected T? TransformOptional<T>(T? node) where T : JavaNode
{
if (node == null) return null;
return node.Accept(this) as T ?? node;
}
}
/// <summary>
/// Transformer that renames all occurrences of a specific identifier.
/// </summary>
public class IdentifierRenamer : AstTransformer
{
private readonly string _oldName;
private readonly string _newName;
public IdentifierRenamer(string oldName, string newName)
{
_oldName = oldName;
_newName = newName;
}
public override JavaNode? VisitIdentifierExpression(IdentifierExpression node)
{
if (node.Name == _oldName)
{
return new IdentifierExpression(node.Location, _newName);
}
return null;
}
public override JavaNode? VisitFieldDeclaration(FieldDeclaration node)
{
var hasChanges = false;
var transformedVariables = node.Variables
.Select(v => {
if (v.Name == _oldName) {
hasChanges = true;
return new VariableDeclarator(v.Location, _newName, v.ArrayDimensions, TransformOptional(v.Initializer));
}
return TransformOrOriginal(v);
})
.ToList();
var transformedType = TransformOrOriginal(node.Type);
if (transformedType != node.Type) hasChanges = true;
if (!hasChanges) return null;
return new FieldDeclaration(
node.Location,
node.Modifiers,
node.Annotations,
transformedType,
transformedVariables,
node.JavaDoc
);
}
public override JavaNode? VisitMethodDeclaration(MethodDeclaration node)
{
var needsTransform = node.Name == _oldName ||
node.Parameters.Any(p => p.Name == _oldName);
if (!needsTransform) return null;
var newName = node.Name == _oldName ? _newName : node.Name;
var transformedParams = node.Parameters
.Select(p => p.Name == _oldName
? new Parameter(p.Location, TransformOrOriginal(p.Type), _newName, p.IsVarArgs, p.IsFinal, p.Annotations)
: TransformOrOriginal(p))
.ToList();
return new MethodDeclaration(
node.Location,
newName,
node.Modifiers,
node.Annotations,
TransformOptional(node.ReturnType),
node.TypeParameters,
transformedParams,
node.Throws,
TransformOptional(node.Body),
node.JavaDoc,
node.IsConstructor
);
}
public override JavaNode? VisitClassDeclaration(ClassDeclaration node)
{
var transformedMembers = node.Members
.Select(m => TransformOrOriginal(m))
.Cast<MemberDeclaration>()
.ToList();
if (transformedMembers.SequenceEqual(node.Members))
{
return null;
}
return new ClassDeclaration(
node.Location,
node.Name,
node.Modifiers,
node.Annotations,
node.TypeParameters,
node.SuperClass,
node.Interfaces,
transformedMembers,
node.NestedTypes,
node.JavaDoc,
node.IsRecord
);
}
}
/// <summary>
/// Transformer that adds or removes modifiers from declarations.
/// </summary>
public class ModifierTransformer : AstTransformer
{
private readonly Func<Modifiers, Modifiers> _transform;
public ModifierTransformer(Func<Modifiers, Modifiers> transform)
{
_transform = transform;
}
public static ModifierTransformer AddModifier(Modifiers modifier)
{
return new ModifierTransformer(m => m | modifier);
}
public static ModifierTransformer RemoveModifier(Modifiers modifier)
{
return new ModifierTransformer(m => m & ~modifier);
}
public override JavaNode? VisitClassDeclaration(ClassDeclaration node)
{
var newModifiers = _transform(node.Modifiers);
var transformedMembers = node.Members
.Select(m => TransformOrOriginal(m))
.Cast<MemberDeclaration>()
.ToList();
// Only create new node if something changed
if (newModifiers == node.Modifiers &&
transformedMembers.SequenceEqual(node.Members))
{
return null;
}
return new ClassDeclaration(
node.Location,
node.Name,
newModifiers,
node.Annotations,
node.TypeParameters,
node.SuperClass,
node.Interfaces,
transformedMembers,
node.NestedTypes,
node.JavaDoc,
node.IsRecord
);
}
public override JavaNode? VisitMethodDeclaration(MethodDeclaration node)
{
var newModifiers = _transform(node.Modifiers);
if (newModifiers == node.Modifiers) return null;
return new MethodDeclaration(
node.Location,
node.Name,
newModifiers,
node.Annotations,
node.ReturnType,
node.TypeParameters,
node.Parameters,
node.Throws,
node.Body,
node.JavaDoc,
node.IsConstructor
);
}
public override JavaNode? VisitFieldDeclaration(FieldDeclaration node)
{
var newModifiers = _transform(node.Modifiers);
if (newModifiers == node.Modifiers) return null;
return new FieldDeclaration(
node.Location,
newModifiers,
node.Annotations,
node.Type,
node.Variables,
node.JavaDoc
);
}
public override JavaNode? VisitCompilationUnit(CompilationUnit node)
{
var transformedTypes = node.Types
.Select(t => TransformOrOriginal(t))
.Cast<TypeDeclaration>()
.ToList();
if (transformedTypes.SequenceEqual(node.Types))
{
return null;
}
return new CompilationUnit(
node.Location,
node.Package,
node.Imports,
transformedTypes
);
}
}
/// <summary>
/// Transformer that removes nodes based on a predicate.
/// </summary>
public class NodeRemover : AstTransformer
{
private readonly Func<JavaNode, bool> _shouldRemove;
private static readonly JavaNode RemovedMarker = new RemovedNode();
public NodeRemover(Func<JavaNode, bool> shouldRemove)
{
_shouldRemove = shouldRemove;
}
protected override JavaNode? DefaultVisit(JavaNode node)
{
if (_shouldRemove(node))
{
return RemovedMarker;
}
return null;
}
public override JavaNode? VisitCompilationUnit(CompilationUnit node)
{
var transformedTypes = node.Types
.Select(t => t.Accept(this) ?? t)
.Where(t => t != RemovedMarker)
.Cast<TypeDeclaration>()
.ToList();
var transformedImports = node.Imports
.Select(i => i.Accept(this) ?? i)
.Where(i => i != RemovedMarker)
.Cast<ImportDeclaration>()
.ToList();
if (transformedTypes.Count == node.Types.Count &&
transformedImports.Count == node.Imports.Count)
{
return null;
}
return new CompilationUnit(
node.Location,
node.Package,
transformedImports,
transformedTypes
);
}
public override JavaNode? VisitClassDeclaration(ClassDeclaration node)
{
if (_shouldRemove(node)) return RemovedMarker;
var transformedMembers = node.Members
.Select(m => m.Accept(this) ?? m)
.Where(m => m != RemovedMarker)
.Cast<MemberDeclaration>()
.ToList();
if (transformedMembers.Count == node.Members.Count)
{
return null;
}
return new ClassDeclaration(
node.Location,
node.Name,
node.Modifiers,
node.Annotations,
node.TypeParameters,
node.SuperClass,
node.Interfaces,
transformedMembers,
node.NestedTypes,
node.JavaDoc,
node.IsRecord
);
}
private class RemovedNode : JavaNode
{
public RemovedNode() : base(new SourceRange(
new SourceLocation(0, 0, 0, 0),
new SourceLocation(0, 0, 0, 0))) { }
public override T Accept<T>(IJavaVisitor<T> visitor) => default!;
public override void Accept(IJavaVisitor visitor) { }
}
}
/// <summary>
/// Builder for creating complex transformations.
/// </summary>
public class TransformationBuilder
{
private readonly List<AstTransformer> _transformers = new();
public TransformationBuilder AddTransformer(AstTransformer transformer)
{
_transformers.Add(transformer);
return this;
}
public TransformationBuilder RenameIdentifier(string oldName, string newName)
{
_transformers.Add(new IdentifierRenamer(oldName, newName));
return this;
}
public TransformationBuilder AddModifier(Modifiers modifier)
{
_transformers.Add(ModifierTransformer.AddModifier(modifier));
return this;
}
public TransformationBuilder RemoveModifier(Modifiers modifier)
{
_transformers.Add(ModifierTransformer.RemoveModifier(modifier));
return this;
}
public TransformationBuilder RemoveNodes(Func<JavaNode, bool> predicate)
{
_transformers.Add(new NodeRemover(predicate));
return this;
}
public JavaNode Transform(JavaNode node)
{
var current = node;
foreach (var transformer in _transformers)
{
var transformed = current.Accept(transformer);
if (transformed != null)
{
current = transformed;
}
}
return current;
}
}
}