Skip to content

CSharpAmbience.ConvertSymbol does not behave as expected for record struct and init properties #3159

@Doraku

Description

@Doraku

Hello there, first let me thank you for your excellent work on ILSpy as a long time user of the extension, it has been a huge help on both professional and personal projects.

I'm the author of package that auto generate documentation for csharp projects based on xml comments and metadata provided by your excellent ICSharpCode.Decompiler api. I have been using the CSharpAmbience.ConvertSymbol successfully to generate code definition in the auto generated pages for each members. I recently tried to add support for record and stumbled on a non expected result:

Steps to reproduce

namespace DefaultDocumentation
{
    public sealed class AssemblyInfo
    {
        public readonly record struct StructRecord(
            int Property);

        private static readonly CSharpDecompiler _decompiler = new(typeof(AssemblyInfo).Assembly.Location, new DecompilerSettings { ThrowOnAssemblyResolveErrors = false });
        private static readonly CSharpResolver _resolver = new(_decompiler.TypeSystem);

        public static T Get<T>(string id) => (T)IdStringProvider.FindEntity(id.Replace('+', '.'), _resolver);

        public static readonly ITypeDefinition StructRecordDefinition = Get<ITypeDefinition>($"T:{typeof(AssemblyInfo).FullName}.{nameof(ClassRecord)}");
        public static readonly IProperty RecordPropertyDefinition = Get<IProperty>($"P:{typeof(AssemblyInfo).FullName}.{nameof(ClassRecord)}.{nameof(ClassRecord.Property)}");
    }

    public class Test
    {
        private static readonly CSharpAmbience _typeAmbience = new()
        {
            ConversionFlags =
                ConversionFlags.ShowAccessibility
                | ConversionFlags.ShowDeclaringType
                | ConversionFlags.ShowDefinitionKeyword
                | ConversionFlags.ShowModifiers
                | ConversionFlags.ShowTypeParameterList
                | ConversionFlags.ShowTypeParameterVarianceModifier
                | ConversionFlags.SupportRecordClasses
                | ConversionFlags.SupportRecordStructs
        };

        private static readonly CSharpAmbience _propertyAmbience = new()
        {
            ConversionFlags =
                ConversionFlags.ShowAccessibility
                | ConversionFlags.ShowBody
                | ConversionFlags.ShowModifiers
                | ConversionFlags.ShowParameterDefaultValues
                | ConversionFlags.ShowParameterList
                | ConversionFlags.ShowParameterModifiers
                | ConversionFlags.ShowParameterNames
                | ConversionFlags.ShowReturnType
                | ConversionFlags.UseFullyQualifiedTypeNames
                | ConversionFlags.SupportInitAccessors
        };

        public void TestStructRecord()
        {
            _typeAmbience.ConvertSymbol(AssemblyInfo.StructRecordDefinition);
            // produce: public readonly recordstruct AssemblyInfo.StructRecord
        }

        public void TestRecordProperty()
        {
            _propertyAmbience.ConvertSymbol(AssemblyInfo.RecordPropertyDefinition);
            // produce: public int Property { get; set; }
        }
    }
}

For the first issue, note the missing space between the record and struct keywords, I believe this is because we should add an explicit writer.Space() call here

writer.WriteKeyword(Roles.RecordKeyword, "record");

For the second issue, note the set; instead of the expected init;, I believe there is some missing specific handling here

Details

  • Product in use: ICSharpCode.Decompiler nuget package
  • Version in use: 8.2.0.7535

I expect this is probably low priority as people using your API like this are probably few and far between but thanks anyway for your hard work :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions