diff --git a/IronJava.Core/AST/Builders/AstBuilder.cs b/IronJava.Core/AST/Builders/AstBuilder.cs index bb5058b..45b79b1 100644 --- a/IronJava.Core/AST/Builders/AstBuilder.cs +++ b/IronJava.Core/AST/Builders/AstBuilder.cs @@ -201,7 +201,7 @@ namespace MarketAlly.IronJava.Core.AST.Builders return new ClassDeclaration( location, name, modifiers, annotations, typeParameters, - superClass, interfaces, members, javaDoc + superClass, interfaces, members, new List(), javaDoc, false ); } @@ -218,7 +218,7 @@ namespace MarketAlly.IronJava.Core.AST.Builders return new InterfaceDeclaration( location, name, modifiers, annotations, typeParameters, - extendedInterfaces, members, javaDoc + extendedInterfaces, members, new List(), javaDoc ); } @@ -236,7 +236,7 @@ namespace MarketAlly.IronJava.Core.AST.Builders return new EnumDeclaration( location, name, modifiers, annotations, - interfaces, constants, members, javaDoc + interfaces, constants, members, new List(), javaDoc ); } @@ -250,7 +250,7 @@ namespace MarketAlly.IronJava.Core.AST.Builders var javaDoc = ExtractJavaDoc(context); return new AnnotationDeclaration( - location, name, modifiers, annotations, members, javaDoc + location, name, modifiers, annotations, members, new List(), javaDoc ); } @@ -1125,7 +1125,9 @@ namespace MarketAlly.IronJava.Core.AST.Builders null, new List(), members, - null + new List(), + null, + false ); } @@ -2108,7 +2110,9 @@ namespace MarketAlly.IronJava.Core.AST.Builders type, new List(), members, - null + new List(), + null, + false ); } @@ -2829,7 +2833,9 @@ namespace MarketAlly.IronJava.Core.AST.Builders type, new List(), members, - null + new List(), + null, + false ); } diff --git a/IronJava.Core/AST/Nodes/Annotations.cs b/IronJava.Core/AST/Nodes/Annotations.cs index 6db000f..cfb5e20 100644 --- a/IronJava.Core/AST/Nodes/Annotations.cs +++ b/IronJava.Core/AST/Nodes/Annotations.cs @@ -10,6 +10,11 @@ namespace MarketAlly.IronJava.Core.AST.Nodes { public TypeReference Type { get; } public IReadOnlyList Arguments { get; } + + /// + /// Gets the name of the annotation (e.g., "Override" for @Override). + /// + public string Name => Type.Name; public Annotation( SourceRange location, diff --git a/IronJava.Core/AST/Nodes/CompilationUnit.cs b/IronJava.Core/AST/Nodes/CompilationUnit.cs index a176265..c5cfcfc 100644 --- a/IronJava.Core/AST/Nodes/CompilationUnit.cs +++ b/IronJava.Core/AST/Nodes/CompilationUnit.cs @@ -38,6 +38,11 @@ namespace MarketAlly.IronJava.Core.AST.Nodes { public string PackageName { get; } public IReadOnlyList Annotations { get; } + + /// + /// Gets the package name. Alias for PackageName for consistency. + /// + public string Name => PackageName; public PackageDeclaration( SourceRange location, @@ -61,6 +66,13 @@ namespace MarketAlly.IronJava.Core.AST.Nodes public string ImportPath { get; } public bool IsStatic { get; } public bool IsWildcard { get; } + + /// + /// Gets the name of the imported type or package. + /// For "import java.util.List", returns "java.util.List" + /// For "import java.util.*", returns "java.util.*" + /// + public string Name => ImportPath; public ImportDeclaration( SourceRange location, diff --git a/IronJava.Core/AST/Nodes/TypeDeclarations.cs b/IronJava.Core/AST/Nodes/TypeDeclarations.cs index 4459f51..b679e23 100644 --- a/IronJava.Core/AST/Nodes/TypeDeclarations.cs +++ b/IronJava.Core/AST/Nodes/TypeDeclarations.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using MarketAlly.IronJava.Core.AST.Visitors; namespace MarketAlly.IronJava.Core.AST.Nodes @@ -13,6 +14,11 @@ namespace MarketAlly.IronJava.Core.AST.Nodes public IReadOnlyList Annotations { get; } public IReadOnlyList TypeParameters { get; } public JavaDoc? JavaDoc { get; } + + /// + /// Gets the body/members of this type declaration. + /// + public abstract IEnumerable Body { get; } protected TypeDeclaration( SourceRange location, @@ -42,6 +48,7 @@ namespace MarketAlly.IronJava.Core.AST.Nodes public TypeReference? SuperClass { get; } public IReadOnlyList Interfaces { get; } public IReadOnlyList Members { get; } + public IReadOnlyList NestedTypes { get; } public bool IsRecord { get; } public ClassDeclaration( @@ -53,6 +60,7 @@ namespace MarketAlly.IronJava.Core.AST.Nodes TypeReference? superClass, IReadOnlyList interfaces, IReadOnlyList members, + IReadOnlyList nestedTypes, JavaDoc? javaDoc, bool isRecord = false) : base(location, name, modifiers, annotations, typeParameters, javaDoc) @@ -60,13 +68,17 @@ namespace MarketAlly.IronJava.Core.AST.Nodes SuperClass = superClass; Interfaces = interfaces; Members = members; + NestedTypes = nestedTypes; IsRecord = isRecord; if (superClass != null) AddChild(superClass); AddChildren(interfaces); AddChildren(members); + AddChildren(nestedTypes); } + public override IEnumerable Body => Members.Cast().Concat(NestedTypes); + public override T Accept(IJavaVisitor visitor) => visitor.VisitClassDeclaration(this); public override void Accept(IJavaVisitor visitor) => visitor.VisitClassDeclaration(this); } @@ -78,6 +90,7 @@ namespace MarketAlly.IronJava.Core.AST.Nodes { public IReadOnlyList ExtendedInterfaces { get; } public IReadOnlyList Members { get; } + public IReadOnlyList NestedTypes { get; } public InterfaceDeclaration( SourceRange location, @@ -87,16 +100,21 @@ namespace MarketAlly.IronJava.Core.AST.Nodes IReadOnlyList typeParameters, IReadOnlyList extendedInterfaces, IReadOnlyList members, + IReadOnlyList nestedTypes, JavaDoc? javaDoc) : base(location, name, modifiers, annotations, typeParameters, javaDoc) { ExtendedInterfaces = extendedInterfaces; Members = members; + NestedTypes = nestedTypes; AddChildren(extendedInterfaces); AddChildren(members); + AddChildren(nestedTypes); } + public override IEnumerable Body => Members.Cast().Concat(NestedTypes); + public override T Accept(IJavaVisitor visitor) => visitor.VisitInterfaceDeclaration(this); public override void Accept(IJavaVisitor visitor) => visitor.VisitInterfaceDeclaration(this); } @@ -109,6 +127,7 @@ namespace MarketAlly.IronJava.Core.AST.Nodes public IReadOnlyList Interfaces { get; } public IReadOnlyList Constants { get; } public IReadOnlyList Members { get; } + public IReadOnlyList NestedTypes { get; } public EnumDeclaration( SourceRange location, @@ -118,18 +137,23 @@ namespace MarketAlly.IronJava.Core.AST.Nodes IReadOnlyList interfaces, IReadOnlyList constants, IReadOnlyList members, + IReadOnlyList nestedTypes, JavaDoc? javaDoc) : base(location, name, modifiers, annotations, new List(), javaDoc) { Interfaces = interfaces; Constants = constants; Members = members; + NestedTypes = nestedTypes; AddChildren(interfaces); AddChildren(constants); AddChildren(members); + AddChildren(nestedTypes); } + public override IEnumerable Body => Constants.Cast().Concat(Members).Concat(NestedTypes); + public override T Accept(IJavaVisitor visitor) => visitor.VisitEnumDeclaration(this); public override void Accept(IJavaVisitor visitor) => visitor.VisitEnumDeclaration(this); } @@ -140,6 +164,7 @@ namespace MarketAlly.IronJava.Core.AST.Nodes public class AnnotationDeclaration : TypeDeclaration { public IReadOnlyList Members { get; } + public IReadOnlyList NestedTypes { get; } public AnnotationDeclaration( SourceRange location, @@ -147,13 +172,18 @@ namespace MarketAlly.IronJava.Core.AST.Nodes Modifiers modifiers, IReadOnlyList annotations, IReadOnlyList members, + IReadOnlyList nestedTypes, JavaDoc? javaDoc) : base(location, name, modifiers, annotations, new List(), javaDoc) { Members = members; + NestedTypes = nestedTypes; AddChildren(members); + AddChildren(nestedTypes); } + public override IEnumerable Body => Members.Cast().Concat(NestedTypes); + public override T Accept(IJavaVisitor visitor) => visitor.VisitAnnotationDeclaration(this); public override void Accept(IJavaVisitor visitor) => visitor.VisitAnnotationDeclaration(this); } diff --git a/IronJava.Core/AST/Nodes/Types.cs b/IronJava.Core/AST/Nodes/Types.cs index 34aa485..2134654 100644 --- a/IronJava.Core/AST/Nodes/Types.cs +++ b/IronJava.Core/AST/Nodes/Types.cs @@ -9,6 +9,16 @@ namespace MarketAlly.IronJava.Core.AST.Nodes public abstract class TypeReference : JavaNode { protected TypeReference(SourceRange location) : base(location) { } + + /// + /// Gets the simple name of the type. + /// + public abstract string Name { get; } + + /// + /// Gets the fully qualified name of the type. + /// + public virtual string QualifiedName => Name; } /// @@ -17,6 +27,8 @@ namespace MarketAlly.IronJava.Core.AST.Nodes public class PrimitiveType : TypeReference { public PrimitiveTypeKind Kind { get; } + + public override string Name => Kind.ToString().ToLower(); public PrimitiveType(SourceRange location, PrimitiveTypeKind kind) : base(location) { @@ -45,7 +57,9 @@ namespace MarketAlly.IronJava.Core.AST.Nodes /// public class ClassOrInterfaceType : TypeReference { - public string Name { get; } + private readonly string _name; + + public override string Name => _name; public ClassOrInterfaceType? Scope { get; } public IReadOnlyList TypeArguments { get; } public IReadOnlyList Annotations { get; } @@ -57,7 +71,7 @@ namespace MarketAlly.IronJava.Core.AST.Nodes IReadOnlyList typeArguments, IReadOnlyList annotations) : base(location) { - Name = name; + _name = name; Scope = scope; TypeArguments = typeArguments; Annotations = annotations; @@ -68,6 +82,8 @@ namespace MarketAlly.IronJava.Core.AST.Nodes } public string FullName => Scope != null ? $"{Scope.FullName}.{Name}" : Name; + + public override string QualifiedName => FullName; public override T Accept(IJavaVisitor visitor) => visitor.VisitClassOrInterfaceType(this); public override void Accept(IJavaVisitor visitor) => visitor.VisitClassOrInterfaceType(this); @@ -80,6 +96,10 @@ namespace MarketAlly.IronJava.Core.AST.Nodes { public TypeReference ElementType { get; } public int Dimensions { get; } + + public override string Name => ElementType.Name + new string('[', Dimensions) + new string(']', Dimensions); + + public override string QualifiedName => ElementType.QualifiedName + new string('[', Dimensions) + new string(']', Dimensions); public ArrayType( SourceRange location, diff --git a/IronJava.Core/AST/Transformation/AstTransformer.cs b/IronJava.Core/AST/Transformation/AstTransformer.cs index 37181cb..2feb93d 100644 --- a/IronJava.Core/AST/Transformation/AstTransformer.cs +++ b/IronJava.Core/AST/Transformation/AstTransformer.cs @@ -149,6 +149,7 @@ namespace MarketAlly.IronJava.Core.AST.Transformation node.SuperClass, node.Interfaces, transformedMembers, + node.NestedTypes, node.JavaDoc, node.IsRecord ); @@ -201,6 +202,7 @@ namespace MarketAlly.IronJava.Core.AST.Transformation node.SuperClass, node.Interfaces, transformedMembers, + node.NestedTypes, node.JavaDoc, node.IsRecord ); @@ -336,6 +338,7 @@ namespace MarketAlly.IronJava.Core.AST.Transformation node.SuperClass, node.Interfaces, transformedMembers, + node.NestedTypes, node.JavaDoc, node.IsRecord ); diff --git a/IronJava.Core/Serialization/AstJsonSerializer.cs b/IronJava.Core/Serialization/AstJsonSerializer.cs index 79f8456..79d6b67 100644 --- a/IronJava.Core/Serialization/AstJsonSerializer.cs +++ b/IronJava.Core/Serialization/AstJsonSerializer.cs @@ -154,6 +154,7 @@ namespace MarketAlly.IronJava.Core.Serialization result["superClass"] = node.SuperClass?.Accept(this); result["interfaces"] = node.Interfaces.Select(i => i.Accept(this)).ToList(); result["members"] = node.Members.Select(m => m.Accept(this)).ToList(); + result["nestedTypes"] = node.NestedTypes.Select(t => t.Accept(this)).ToList(); result["isRecord"] = node.IsRecord; return result; } @@ -163,6 +164,7 @@ namespace MarketAlly.IronJava.Core.Serialization var result = CreateTypeDeclarationBase(node); result["extendedInterfaces"] = node.ExtendedInterfaces.Select(i => i.Accept(this)).ToList(); result["members"] = node.Members.Select(m => m.Accept(this)).ToList(); + result["nestedTypes"] = node.NestedTypes.Select(t => t.Accept(this)).ToList(); return result; } @@ -172,6 +174,7 @@ namespace MarketAlly.IronJava.Core.Serialization result["interfaces"] = node.Interfaces.Select(i => i.Accept(this)).ToList(); result["constants"] = node.Constants.Select(c => c.Accept(this)).ToList(); result["members"] = node.Members.Select(m => m.Accept(this)).ToList(); + result["nestedTypes"] = node.NestedTypes.Select(t => t.Accept(this)).ToList(); return result; } @@ -179,6 +182,7 @@ namespace MarketAlly.IronJava.Core.Serialization { var result = CreateTypeDeclarationBase(node); result["members"] = node.Members.Select(m => m.Accept(this)).ToList(); + result["nestedTypes"] = node.NestedTypes.Select(t => t.Accept(this)).ToList(); return result; } @@ -829,9 +833,14 @@ namespace MarketAlly.IronJava.Core.Serialization var interfaces = DeserializeList(element.GetProperty("interfaces")); var members = DeserializeList(element.GetProperty("members")); - var isRecord = element.GetProperty("isRecord").GetBoolean(); + var nestedTypes = element.TryGetProperty("nestedTypes", out var nestedTypesEl) + ? DeserializeList(nestedTypesEl) + : new List(); + var isRecord = element.TryGetProperty("isRecord", out var isRecordEl) + ? isRecordEl.GetBoolean() + : false; - return new ClassDeclaration(location, name, modifiers, annotations, typeParameters, superClass, interfaces, members, javaDoc, isRecord); + return new ClassDeclaration(location, name, modifiers, annotations, typeParameters, superClass, interfaces, members, nestedTypes, javaDoc, isRecord); } private InterfaceDeclaration DeserializeInterfaceDeclaration(JsonElement element, SourceRange location) @@ -846,8 +855,11 @@ namespace MarketAlly.IronJava.Core.Serialization var extendedInterfaces = DeserializeList(element.GetProperty("extendedInterfaces")); var members = DeserializeList(element.GetProperty("members")); + var nestedTypes = element.TryGetProperty("nestedTypes", out var nestedTypesEl) + ? DeserializeList(nestedTypesEl) + : new List(); - return new InterfaceDeclaration(location, name, modifiers, annotations, typeParameters, extendedInterfaces, members, javaDoc); + return new InterfaceDeclaration(location, name, modifiers, annotations, typeParameters, extendedInterfaces, members, nestedTypes, javaDoc); } private EnumDeclaration DeserializeEnumDeclaration(JsonElement element, SourceRange location) @@ -862,8 +874,11 @@ namespace MarketAlly.IronJava.Core.Serialization var interfaces = DeserializeList(element.GetProperty("interfaces")); var constants = DeserializeList(element.GetProperty("constants")); var members = DeserializeList(element.GetProperty("members")); + var nestedTypes = element.TryGetProperty("nestedTypes", out var nestedTypesEl) + ? DeserializeList(nestedTypesEl) + : new List(); - return new EnumDeclaration(location, name, modifiers, annotations, interfaces, constants, members, javaDoc); + return new EnumDeclaration(location, name, modifiers, annotations, interfaces, constants, members, nestedTypes, javaDoc); } private AnnotationDeclaration DeserializeAnnotationDeclaration(JsonElement element, SourceRange location) @@ -876,8 +891,11 @@ namespace MarketAlly.IronJava.Core.Serialization : null; var members = DeserializeList(element.GetProperty("members")); + var nestedTypes = element.TryGetProperty("nestedTypes", out var nestedTypesEl) + ? DeserializeList(nestedTypesEl) + : new List(); - return new AnnotationDeclaration(location, name, modifiers, annotations, members, javaDoc); + return new AnnotationDeclaration(location, name, modifiers, annotations, members, nestedTypes, javaDoc); } private FieldDeclaration DeserializeFieldDeclaration(JsonElement element, SourceRange location) diff --git a/IronJava.Tests/AstQueryAndTransformationTests.cs b/IronJava.Tests/AstQueryAndTransformationTests.cs index 58e1523..c61ab8c 100644 --- a/IronJava.Tests/AstQueryAndTransformationTests.cs +++ b/IronJava.Tests/AstQueryAndTransformationTests.cs @@ -246,7 +246,9 @@ namespace MarketAlly.IronJava.Tests null ) }, - null + new List(), + null, + false ); var builder = new TransformationBuilder() @@ -348,7 +350,9 @@ namespace MarketAlly.IronJava.Tests null, new List(), new List { mainMethod, helperMethod, field }, - null + new List(), + null, + false ); return new CompilationUnit( @@ -393,7 +397,9 @@ namespace MarketAlly.IronJava.Tests null, new List { serializableInterface }, new List { serializeMethod }, - null + new List(), + null, + false ); return new CompilationUnit( diff --git a/IronJava.Tests/AstVisitorPatternTests.cs b/IronJava.Tests/AstVisitorPatternTests.cs index 189ee9a..03a20a2 100644 --- a/IronJava.Tests/AstVisitorPatternTests.cs +++ b/IronJava.Tests/AstVisitorPatternTests.cs @@ -55,7 +55,9 @@ namespace MarketAlly.IronJava.Tests null, new List(), new List { mainMethod }, - null + new List(), + null, + false ); var compilationUnit = new CompilationUnit( @@ -137,7 +139,9 @@ namespace MarketAlly.IronJava.Tests null, new List(), new List(), - null + new List(), + null, + false ); var outerClass = new ClassDeclaration( @@ -149,7 +153,9 @@ namespace MarketAlly.IronJava.Tests null, new List(), new List(), - null + new List(), + null, + false ); // Navigate the AST @@ -194,7 +200,9 @@ namespace MarketAlly.IronJava.Tests null, new List(), new List { field }, - null + new List(), + null, + false ); var compilationUnit = new CompilationUnit(