From 3a27cbef063bc29bc826e3c701b3fd49a0e705eb Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 13 Dec 2025 10:14:46 +0100 Subject: [PATCH] Fix #3617: Order of XML comments in types with primary constructors --- .../Syntax/GeneralScope/TypeDeclaration.cs | 18 ++++++++++++------ ...TransformFieldAndConstructorInitializers.cs | 14 +++++++++++++- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/TypeDeclaration.cs b/ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/TypeDeclaration.cs index d336843f9..54fd27ab4 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/TypeDeclaration.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/TypeDeclaration.cs @@ -100,24 +100,30 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax get { return GetChildByRole(Roles.RChevron); } } - - public CSharpTokenNode ColonToken { get { return GetChildByRole(Roles.Colon); } } - public AstNodeCollection BaseTypes { - get { return GetChildrenByRole(Roles.BaseType); } - } - public bool HasPrimaryConstructor { get; set; } + public CSharpTokenNode LParToken { + get { return GetChildByRole(Roles.LPar); } + } + public AstNodeCollection PrimaryConstructorParameters { get { return GetChildrenByRole(Roles.Parameter); } } + public CSharpTokenNode RParToken { + get { return GetChildByRole(Roles.RPar); } + } + + public AstNodeCollection BaseTypes { + get { return GetChildrenByRole(Roles.BaseType); } + } + public AstNodeCollection Constraints { get { return GetChildrenByRole(Roles.Constraint); } } diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs b/ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs index b79483880..3a0e19769 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs @@ -598,7 +598,19 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms || !PrimaryConstructorDecl.Initializer.IsNull || TypeDefinition.Kind == TypeKind.Struct; - PrimaryConstructorDecl.Parameters.MoveTo(this.TypeDeclaration.PrimaryConstructorParameters); + // HACK: because our current AST model doesn't allow specifying an explicit order of roles, + // we have to explicitly insert the primary constructor parameters, + // MoveTo would just append the parameters to the list of children + if (PrimaryConstructorDecl.Parameters.Count > 0) + { + var insertionPoint = (AstNode?)this.TypeDeclaration.TypeParameters.LastOrDefault() ?? this.TypeDeclaration.NameToken; + foreach (var param in PrimaryConstructorDecl.Parameters) + { + param.Remove(); + this.TypeDeclaration.InsertChildAfter(insertionPoint, param, Roles.Parameter); + insertionPoint = param; + } + } Debug.Assert(PrimaryConstructorParameterToBackingStoreMap != null);