Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mdoc/Mono.Documentation/MDocUpdater.Member.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ internal static void MakeTypeParameterConstraints(XmlElement root, XmlElement e,
AppendElementText(ce, "ParameterAttribute", "NotNullableValueTypeConstraint");
if ((attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
AppendElementText(ce, "ParameterAttribute", "ReferenceTypeConstraint");
// Check for 'allows ref struct' constraint
if ((attrs & (GenericParameterAttributes)0x0020) != 0) // Assuming 0x0020 is the flag for 'allows ref struct'
AppendElementText(ce, "ParameterAttribute", "AllowByRefLike");

#if NEW_CECIL
foreach (GenericParameterConstraint c in constraints)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,10 @@ private StringBuilder AppendConstraints (StringBuilder buf, IList<GenericParamet
bool isref = (attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0;
bool isvt = (attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0;
bool isnew = (attrs & GenericParameterAttributes.DefaultConstructorConstraint) != 0;
bool isAllowsRefStruct = (attrs & (GenericParameterAttributes)0x0020) != 0; // Assuming 0x0020 is the flag for 'allows ref struct'
bool comma = false;

if (!isref && !isvt && !isnew && constraints.Count == 0)
if (!isref && !isvt && !isAllowsRefStruct && !isnew && constraints.Count == 0)
continue;
buf.Append (" where ").Append (genArg.Name).Append (" : ");
if (isref)
Expand Down Expand Up @@ -350,6 +351,14 @@ private StringBuilder AppendConstraints (StringBuilder buf, IList<GenericParamet
buf.Append (", ");
buf.Append ("new()");
}

// Handle 'allows ref struct' constraint
if (isAllowsRefStruct)
{
if (comma || constraints.Count > 0 || isref || isvt || isnew)
buf.Append(", ");
buf.Append("allows ref struct");
}
}
return buf;
}
Expand Down
36 changes: 36 additions & 0 deletions mdoc/mdoc.Test/MDocUpdaterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,5 +253,41 @@ public void Run_WithOptionsOAndFx_ShouldProcessFrameworks()
Assert.IsTrue(File.Exists(Path.Combine(outputDir, "index.xml")));
Assert.IsTrue(File.Exists(Path.Combine(outputDir, "ns-TestLibrary.xml")));
}

[Test]
public void Test_RunWithRefStructValidation()
{
// Arrange
var baseDir = Path.Combine(Path.GetDirectoryName(this.GetType().Module.Assembly.Location), "SampleClasses/TestUpdate");
var outputDir = Path.Combine(baseDir, "outputDir");
Directory.CreateDirectory(outputDir);

var args = new List<string> { "update", "-o", outputDir, "-fx", Path.Combine(baseDir) };
var updater = new MDocUpdater();

// Act
updater.Run(args);

// Assert
var iRefStructProcessorPath = Path.Combine(outputDir, "RefStructDemo", "IRefStructProcessor`1.xml");
var refStructHandlerPath = Path.Combine(outputDir, "RefStructDemo", "RefStructHandler.xml");

Assert.IsTrue(File.Exists(iRefStructProcessorPath));
Assert.IsTrue(File.Exists(refStructHandlerPath));

var iRefStructProcessorDoc = new XmlDocument();
iRefStructProcessorDoc.Load(iRefStructProcessorPath);
var iRefStructProcessorNode = iRefStructProcessorDoc.SelectSingleNode("//TypeParameters/TypeParameter/Constraints/ParameterAttribute[text()='AllowByRefLike']");
Assert.IsNotNull(iRefStructProcessorNode, "Missing <ParameterAttribute>AllowByRefLike</ParameterAttribute> in IRefStructProcessor`1.xml");
var iRefStructProcessorTypeSignatureNode = iRefStructProcessorDoc.SelectSingleNode("//TypeSignature[@Language='C#' and contains(@Value, 'where T : allows ref struct')]");
Assert.IsNotNull(iRefStructProcessorTypeSignatureNode, "Missing TypeSignature with 'where T : allows ref struct' in IRefStructProcessor`1.xml");

var refStructHandlerDoc = new XmlDocument();
refStructHandlerDoc.Load(refStructHandlerPath);
var refStructHandlerNode = refStructHandlerDoc.SelectSingleNode("//Members/Member/TypeParameters/TypeParameter/Constraints/ParameterAttribute[text()='AllowByRefLike']");
Assert.IsNotNull(refStructHandlerNode, "Missing <ParameterAttribute>AllowByRefLike</ParameterAttribute> in RefStructHandler.xml");
var refStructHandlerMemberSignatureNode = refStructHandlerDoc.SelectSingleNode("//Members/Member/MemberSignature[@Language='C#' and contains(@Value, 'where T : allows ref struct')]");
Assert.IsNotNull(refStructHandlerMemberSignatureNode, "Missing MemberSignature with 'where T : allows ref struct' in RefStructHandler.xml");
}
}
}
3 changes: 3 additions & 0 deletions mdoc/mdoc.Test/SampleClasses/TestUpdate/frameworks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
<Framework Name="net-8.0" Source="net-8.0">
<assemblySearchPath>dependencies\net-8.0</assemblySearchPath>
</Framework>
<Framework Name="net-9.0" Source="net-9.0">
<assemblySearchPath>dependencies\net-9.0</assemblySearchPath>
</Framework>
</Frameworks>
Binary file not shown.
4 changes: 4 additions & 0 deletions mdoc/mdoc.Test/mdoc.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
<Link>SampleClasses\TestUpdate\net-8.0\TestLibrary.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="SampleClasses\TestUpdate\net-9.0\RefStructDemo.dll">
<Link>SampleClasses\TestUpdate\net-9.0\RefStructDemo.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="SampleClasses\TestUpdate\frameworks.xml">
<Link>SampleClasses\TestUpdate\frameworks.xml</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
Expand Down