From 1f344e676a9934d47805434e5d1bceee1db65adf Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Sun, 27 Apr 2025 10:07:06 +0800 Subject: [PATCH 01/14] update --- mdoc/Mono.Documentation/MDocUpdater.Member.cs | 3 +++ .../Updater/Formatters/CSharpFullMemberFormatter.cs | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/mdoc/Mono.Documentation/MDocUpdater.Member.cs b/mdoc/Mono.Documentation/MDocUpdater.Member.cs index 22b0f4ff0..5f9806776 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.Member.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.Member.cs @@ -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 0x1000 is the flag for 'allows ref struct' + AppendElementText(ce, "ParameterAttribute", "AllowsRefStruct"); #if NEW_CECIL foreach (GenericParameterConstraint c in constraints) diff --git a/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs index ec0f20573..c02a9f7d0 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs @@ -314,9 +314,10 @@ private StringBuilder AppendConstraints (StringBuilder buf, IList 0 || isref || isvt || isnew) + buf.Append(", "); + buf.Append("allows ref struct"); + } } return buf; } From 1bc01ee45de4dfd03920cb2c75b4c3f769c2f690 Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Sun, 27 Apr 2025 16:13:56 +0800 Subject: [PATCH 02/14] add unit test --- mdoc/mdoc.Test/MDocUpdaterTests.cs | 36 ++++++++++++++++++ .../SampleClasses/TestUpdate/frameworks.xml | 3 ++ .../TestUpdate/net-9.0/RefStructDemo.dll | Bin 0 -> 4096 bytes mdoc/mdoc.Test/mdoc.Test.csproj | 4 ++ 4 files changed, 43 insertions(+) create mode 100644 mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/RefStructDemo.dll diff --git a/mdoc/mdoc.Test/MDocUpdaterTests.cs b/mdoc/mdoc.Test/MDocUpdaterTests.cs index d7d0a5e6f..e05cd52b0 100644 --- a/mdoc/mdoc.Test/MDocUpdaterTests.cs +++ b/mdoc/mdoc.Test/MDocUpdaterTests.cs @@ -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 { "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()='AllowsRefStruct']"); + Assert.IsNotNull(iRefStructProcessorNode, "Missing AllowsRefStruct 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()='AllowsRefStruct']"); + Assert.IsNotNull(refStructHandlerNode, "Missing AllowsRefStruct 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"); + } } } \ No newline at end of file diff --git a/mdoc/mdoc.Test/SampleClasses/TestUpdate/frameworks.xml b/mdoc/mdoc.Test/SampleClasses/TestUpdate/frameworks.xml index c7fc11dae..7424c78da 100644 --- a/mdoc/mdoc.Test/SampleClasses/TestUpdate/frameworks.xml +++ b/mdoc/mdoc.Test/SampleClasses/TestUpdate/frameworks.xml @@ -3,4 +3,7 @@ dependencies\net-8.0 + + dependencies\net-9.0 + \ No newline at end of file diff --git a/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/RefStructDemo.dll b/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/RefStructDemo.dll new file mode 100644 index 0000000000000000000000000000000000000000..d8233d0dfd57962df77fb7d8671f0d6214984cee GIT binary patch literal 4096 zcmeHK-ES0C6hG6Cr7ch>6+}&Npa=zJvZX~SAF|tSON;$-cUuuRwzJ#2%fRf+GBaDc zFUpHP_+Zrkz(nH%KJ)<%nh+CWFeVaXj4=d_`a&?8$cqp1VEvstv)$cR2>N7*XM4}R z=i{Dx&bepqy&XOA2GtW$1KQ#u(M9wO5sB}P&OzMz=*O*eq5108i^|B=t;v&ys}>wP z=jeGgqg$5kscE4)MN2g-H8!45^Y*OJ)~;>Y9+;jOAR1BX>36sHyYgy3(l&Lq5+-T_ zC**VEJJG9X5j3Lpa$M*8%?$Qm!Z~2@8R}`~6;|cHN*|ESVu0Oo?juAoPQ-GUAzB08 znjJ*R<+8ics_%YTr3v&Zp-YD$znCk;2S>0WGw9TU{p>#-J~8 ztWOCnv0rmNT3G82cX#!&;YKonZ(*U1mxxmEH;LAf@EpU+xva5(SUKE|$pl@%fVZ*Z z=;Uw={imRRWxCI_)94v6T{*gusF^3-R=R1EAICb7ytUk*Bh$h>j*%Plh|Vj1%pq!0 z+Ur8(O1vN9b<_=&5Ebc7B}6Bb&w;-p#;;3!UgA#4e^HKa5nG5#3nOxTtnRWj|Darp zv+_3LQRq6jOevs#R<0|DG4lN(y3*KJ*8zG$v7HrfqY!lyRh#`+wQLYJhCOG-0> zR;Ud)L=OSC&@SNh)FpAR#8HWdC4N@o=OxyG6*7P~(iw?Mz#)7dFVOd-(Q4WY+)f99 zAE6V#9h3on9C2vWO&5R<(kH|2^uS!W-TY`x+0%8OG(44R!r(nPI!Yj+{9ViIbE?( z)*m!XF(n+=u&tHCVJmApdEJ9hH}9y`Z(CU-S9GLa#Rx~MXN6aaBRsdl@3->>!<5Q# zVe0d8R3$Hah9u1*SCxt7ps^kwMHNAL23yvxQbiD?Q1U$^ZJ35vC9Tb~7Q}~7nU*#x zCi1p6Yno(WM}m!6+8>cMMTT=zt6!n~{d7pnc(zlX7BlpmWxJk{am%d0P0i1Ya1z3q zGf*JG*25#z2*{vpXgqxi3;RWdQ>nTBwJ&pTjeW4`hw0BI=l4*9swhqMDk+T^w6!tW z%BZnv;mGvMZQryU2!UGPPOHKS`Ykv;@#-KOUpy)b551M?YC-~f{+9s8`S zKyMWap6IYbo3*ilWWVi*Xrb^#kh;Tjy;>LsS|3;{xR~JRoly#2l0E=|t)Wy%|O9ElCZ|v%7892z`&C>lHMb{QJX6#y z(@4dHd)l)LseT(JZF|$voUptyC5aIu?dVP^Wv5R;8((tD5+0I}s>y&>m`zh+D7tsw zlN7A|(`>Ld;v2lN?_zRC>xc2hkEV`v2KOJk+s9*-M=POxPx_K+>{ZM(M|H!Zyqm$s z30c@IU3?5SmZxE*!T%(OZy}=1MCWSVlhr~fp%r}AA-ve9~41RyaC*=KKWma-yQfrEIa$v{6J3_#wMOm_? ze7l^Lgj5IDgcOD za*Yxq(m@GnK8`*c*e>G6^C$*RUV0akbIV>c--QPIP^j_oZZ^U=V3Z|)r(nZ@l}dbF zxPQY-4R1%<0DaDoCv`3OYF2rC=e0DNg(kn#I&nZKG=lj#Ih&&|;Dlh$b954xNq#yb za;@=z&za@5%JDMgXX#$n^z%FcTQ>agGkLFh4&%Lsms8E$<(aDFiDSampleClasses\TestUpdate\net-8.0\TestLibrary.dll PreserveNewest + + SampleClasses\TestUpdate\net-9.0\RefStructDemo.dll + PreserveNewest + SampleClasses\TestUpdate\frameworks.xml PreserveNewest From 73a7e4687b22f78eea5fcfdb664d7170770024d9 Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Mon, 28 Apr 2025 10:00:15 +0800 Subject: [PATCH 03/14] update --- mdoc/Mono.Documentation/MDocUpdater.Member.cs | 2 +- mdoc/mdoc.Test/MDocUpdaterTests.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mdoc/Mono.Documentation/MDocUpdater.Member.cs b/mdoc/Mono.Documentation/MDocUpdater.Member.cs index 5f9806776..c5c497fd1 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.Member.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.Member.cs @@ -46,7 +46,7 @@ internal static void MakeTypeParameterConstraints(XmlElement root, XmlElement e, AppendElementText(ce, "ParameterAttribute", "ReferenceTypeConstraint"); // Check for 'allows ref struct' constraint if ((attrs & (GenericParameterAttributes)0x0020) != 0) // Assuming 0x1000 is the flag for 'allows ref struct' - AppendElementText(ce, "ParameterAttribute", "AllowsRefStruct"); + AppendElementText(ce, "ParameterAttribute", "AllowByRefLike"); #if NEW_CECIL foreach (GenericParameterConstraint c in constraints) diff --git a/mdoc/mdoc.Test/MDocUpdaterTests.cs b/mdoc/mdoc.Test/MDocUpdaterTests.cs index e05cd52b0..3f0a146d0 100644 --- a/mdoc/mdoc.Test/MDocUpdaterTests.cs +++ b/mdoc/mdoc.Test/MDocUpdaterTests.cs @@ -277,15 +277,15 @@ public void Test_RunWithRefStructValidation() var iRefStructProcessorDoc = new XmlDocument(); iRefStructProcessorDoc.Load(iRefStructProcessorPath); - var iRefStructProcessorNode = iRefStructProcessorDoc.SelectSingleNode("//TypeParameters/TypeParameter/Constraints/ParameterAttribute[text()='AllowsRefStruct']"); - Assert.IsNotNull(iRefStructProcessorNode, "Missing AllowsRefStruct in IRefStructProcessor`1.xml"); + var iRefStructProcessorNode = iRefStructProcessorDoc.SelectSingleNode("//TypeParameters/TypeParameter/Constraints/ParameterAttribute[text()='AllowByRefLike']"); + Assert.IsNotNull(iRefStructProcessorNode, "Missing AllowByRefLike 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()='AllowsRefStruct']"); - Assert.IsNotNull(refStructHandlerNode, "Missing AllowsRefStruct in RefStructHandler.xml"); + var refStructHandlerNode = refStructHandlerDoc.SelectSingleNode("//Members/Member/TypeParameters/TypeParameter/Constraints/ParameterAttribute[text()='AllowByRefLike']"); + Assert.IsNotNull(refStructHandlerNode, "Missing AllowByRefLike 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"); } From af027b8ea30aedda78be85aa493b9405d9a825fa Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Tue, 29 Apr 2025 09:55:18 +0800 Subject: [PATCH 04/14] update --- mdoc/Mono.Documentation/MDocUpdater.Member.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdoc/Mono.Documentation/MDocUpdater.Member.cs b/mdoc/Mono.Documentation/MDocUpdater.Member.cs index c5c497fd1..5e065ae01 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.Member.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.Member.cs @@ -45,7 +45,7 @@ internal static void MakeTypeParameterConstraints(XmlElement root, XmlElement e, if ((attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0) AppendElementText(ce, "ParameterAttribute", "ReferenceTypeConstraint"); // Check for 'allows ref struct' constraint - if ((attrs & (GenericParameterAttributes)0x0020) != 0) // Assuming 0x1000 is the flag for 'allows ref struct' + if ((attrs & (GenericParameterAttributes)0x0020) != 0) // Assuming 0x0020 is the flag for 'allows ref struct' AppendElementText(ce, "ParameterAttribute", "AllowByRefLike"); #if NEW_CECIL From 8ae4996574eb10b4adaa793d55dbbbdc3a8a0e58 Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Wed, 30 Apr 2025 15:28:24 +0800 Subject: [PATCH 05/14] update --- mdoc/Mono.Documentation/MDocUpdater.cs | 1 + .../Formatters/CSharpFullMemberFormatter.cs | 2 +- mdoc/mdoc.Test/MDocUpdaterTests.cs | 6 +++--- .../TestUpdate/net-8.0/AllowsRefStructDemo.dll | Bin 0 -> 4096 bytes .../TestUpdate/net-9.0/AllowsRefStructDemo.dll | Bin 0 -> 4096 bytes .../TestUpdate/net-9.0/RefStructDemo.dll | Bin 4096 -> 0 bytes mdoc/mdoc.Test/mdoc.Test.csproj | 8 ++++---- 7 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 mdoc/mdoc.Test/SampleClasses/TestUpdate/net-8.0/AllowsRefStructDemo.dll create mode 100644 mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/AllowsRefStructDemo.dll delete mode 100644 mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/RefStructDemo.dll diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs index ae11ab8a4..e20d032e3 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.cs @@ -4166,6 +4166,7 @@ private void MakeTypeParameters (FrameworkTypeEntry entry, XmlElement root, ILis xElement.RemoveAttribute(Consts.FrameworkAlternate); xElement.SetAttribute(Consts.FrameworkAlternate, fxaValue); MakeParamsAttributes(existing.Element, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member); + MakeTypeParameterConstraints(root, e, xElement, t); } else { diff --git a/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs index c02a9f7d0..2bc1d7dab 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs @@ -355,7 +355,7 @@ private StringBuilder AppendConstraints (StringBuilder buf, IList 0 || isref || isvt || isnew) + if (comma || constraints.Count > 0 || isnew) buf.Append(", "); buf.Append("allows ref struct"); } diff --git a/mdoc/mdoc.Test/MDocUpdaterTests.cs b/mdoc/mdoc.Test/MDocUpdaterTests.cs index 3f0a146d0..4a9edc926 100644 --- a/mdoc/mdoc.Test/MDocUpdaterTests.cs +++ b/mdoc/mdoc.Test/MDocUpdaterTests.cs @@ -269,8 +269,8 @@ public void Test_RunWithRefStructValidation() updater.Run(args); // Assert - var iRefStructProcessorPath = Path.Combine(outputDir, "RefStructDemo", "IRefStructProcessor`1.xml"); - var refStructHandlerPath = Path.Combine(outputDir, "RefStructDemo", "RefStructHandler.xml"); + var iRefStructProcessorPath = Path.Combine(outputDir, "AllowsRefStructDemo", "IRefStructProcessor`1.xml"); + var refStructHandlerPath = Path.Combine(outputDir, "AllowsRefStructDemo", "RefStructHandler.xml"); Assert.IsTrue(File.Exists(iRefStructProcessorPath)); Assert.IsTrue(File.Exists(refStructHandlerPath)); @@ -286,7 +286,7 @@ public void Test_RunWithRefStructValidation() refStructHandlerDoc.Load(refStructHandlerPath); var refStructHandlerNode = refStructHandlerDoc.SelectSingleNode("//Members/Member/TypeParameters/TypeParameter/Constraints/ParameterAttribute[text()='AllowByRefLike']"); Assert.IsNotNull(refStructHandlerNode, "Missing AllowByRefLike in RefStructHandler.xml"); - var refStructHandlerMemberSignatureNode = refStructHandlerDoc.SelectSingleNode("//Members/Member/MemberSignature[@Language='C#' and contains(@Value, 'where T : allows ref struct')]"); + var refStructHandlerMemberSignatureNode = refStructHandlerDoc.SelectSingleNode("//Members/Member/MemberSignature[@Language='C#' and contains(@Value, 'where T : new(), allows ref struct')]"); Assert.IsNotNull(refStructHandlerMemberSignatureNode, "Missing MemberSignature with 'where T : allows ref struct' in RefStructHandler.xml"); } } diff --git a/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-8.0/AllowsRefStructDemo.dll b/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-8.0/AllowsRefStructDemo.dll new file mode 100644 index 0000000000000000000000000000000000000000..5695b676d14c55ae60ca43c86317bcbfe6e89cf6 GIT binary patch literal 4096 zcmeHKU2GIp6#i!0E~Q9;@MF8^&YjurwjeS&VFt;^nR#oMz#TmFvG_u2BH{dQoM zeXrdCSRZdqfd#b{MGuH6c(YAdUwd68<>1|bleJWH(L-x6>$`AYkDeYS~2NGxt zTOD-M`;@O7kAmVWM%hGHD_b3O1DondJyeocg7}s|6Glwn<0ilm=5;^|?p%>rNy8j$ z%00Bnh&72{hu5UisjhTa=Q>f`1c&$n4YeNwM(FP-TYE0_ZMPVR#CwcY!foG~!-pKm zHnwlw*_&nm1?gXe-sE_B_5xgPY+Ve@mPNlCU04#uF^{Bdtu)H$vJTHKJBhm90TqJrm*B=#7e6MqT8&uV;9(gUU}I)N3qlXJOje9kIMC08WTf_!z;>9?m@dR-aw_`89Lke@Sns_1Z zC%zebh}%&hzKe0B(1mx2@5dS99(+aou;%B8yKoRcqMOp+a87Vea~db3>@$QIBo}fF zs&EtiuR(=q`AexD&mFgm6<^EMlt{GJxC$o*8D3E1_jskU?P%da zmyYNJ-@m*YgkmfZnlQNX8|E9r*(^U#+=|9bc!9|NPjtHx8WtVE%!VAED7SjOGRt zMiU1M76{oYsHyqX#(l>ZoNZa3BsG5_W~B}Gx9}#33;Gs0;X{cfkNQ@*-*Yz~EvT}D zIkewrZVbxJV(|kT478>CHxKoAzRHx#tKu|nIJ`EMrh?W*Q^l9HgR)~y^s^S5WrazJ zHUkT3Sav=Ft-=AaJr^IJy`=CZlpF21^}<@=M_SDsjP_RYz+PKb`4^&>k2o}Q7z zcaK*NRV>%BN3tq77<%Oq9oE$TOATEk%gZ025+3>ySB1<`v}{H>mdEnQZOg2_=U&8) zy}dMcjKLp#Bzxi5@s)+}<C7wXWri?C!>cbk%?Bj-J9cQ~`yC?+(?yk~j zAYOOrR;rnqrptBy;~aT~fHr<^OgE)#11y-!_#!9Y4!gR64tb7Z=xA8O(J=4&eZ-qF z$Wbr9wE9W+5^ssVy6}GEPk%)3fK-4$)NhOk{r*?q!oVCaeIBy}OoJT5xQ;knjsX?DYO4;NWub^pE%cL21^jm|x85269BKFe? z^l90p?e2*Al6|pT&4W-;CjYMeXkP}X*P~BSwy$Sj()`xrSJyN>GqYLCC9qcKJ;PiF mjJ?DvaTvA9x}UxSwKcL2{}C{w{~4aX??2+t|8D%N8Tb>b?PrVt literal 0 HcmV?d00001 diff --git a/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/AllowsRefStructDemo.dll b/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/AllowsRefStructDemo.dll new file mode 100644 index 0000000000000000000000000000000000000000..240fdbdb9481bc20a68161ac8463c261297e0337 GIT binary patch literal 4096 zcmeHKU2GIp6#nkEUD^T#EGlXO0|mvu&6d_5K%`5zNQIW#Ed{ZW&Tgm6$n4BIGh3*M z+6N`ZpwR~(e9@TrhDH*9LWo8a@h^t>lW2S~k@#ke@}LiDB7W!2Y`ZPhsEOglv%Tk@ zbMBe*chB5A?c4tp>HySpoIekoZW&a6JEcAZ&0bkGirvhNjr zvt$%Z*Y!dpZyA2YHEh?&?#>w{Z_G+9UfjGkHa*Y->{4~udHRFLtKPoB8e^eK1C5j< zBk9p=I2#;Y9KcddC!)ATAn|LMBBorR4x^8Xs{GB&F)JcMC++SQq6?UkLd=CxU=d}; z)xgl)wZGzxDEz8QBl#UwhI1;kj)a_#Eg&*DB-c1@QW^|kH01|=ft-%5i-aWF%uxef zj6UUCjz>j_6{8$ttA(Qmx`1sptR@diT?rCf0u2~3fYS|t65+pqW?Z)>v7U}eY|Gub zO~sZZu8Gc6I@OWxXx}J?8{iP1qocNmfDy(!%F&h!ecLStqVXnkm2}(o?WTfz}w(+iNLNcMS zj5vuah?{XO@lv#Fyiwzf#=RQfrSaVwo5Tt>@uj$5<4NKquE9O{7AY*m2I5w1CcX;$ ziQ7;hzMgrc(1BCLoADlTH$ErcspUE14jjVw=%V)5ToatrlKQD?<(Y&AsYO$j;d~|I zkHBCb7$no|8kq^bgVs2ErBVn7e6L^yf#;95 z4egSJtd*}6i)P-jG9f!HUkNSrR~%=yBohQyDep`U*#*k^nz2yT z-)=kBu;mA~=U%wj>yCSV$qcz@I)AFw?YZN2vEpmJ86%RdIc|lMgG?`&k#~Egvh8T) zLCZ0ZXsTwt8X1c;##+rhSWTM#-$(aRg8}O<`DN(EuRiK|=GB&$T3=|ZN4=p` zW1RujKw{Z4VOs<>G@jUc;NfLoG;d0hTiS{RX~lUZPZE8u11seXA4*)d*Eh@kp4)Sz zV3j4!p@Tkaqo}ul%@1r*Sdr@Q8S3_YD^o7t5SMYw#Ku&b23nR+H(%Bc%8ohN&t7bl zCk$$=P-vZ}+B}RE8g%FLf}pDnJcs#<!M(m}qhBOH7%*emPfRFqh4(dhq4$SC0LVdE)KKa%h+{k37sn>~XIH;rc7A;9&;wt7(l!#`nUc?h(1uVKLiKKqRt|7avyRhe z+Ac~#fg5b;*FaX!ucM8*WxCMde=d<*2v`A3&32`GgQxF>a?z7-hkaeZTDgv5SX@%P$WIHG~Au^qX}ryDVrWjQNaHR02a&F=_{ zHeHOv(;91eTgca%PYo9V*G+`f^T)%=T0f?qOGE~Bo!)S zQfE}eLFNSgs_fH#cgJ$6zWA-yLAa=r|I~l9F9WpeF{Y^6|7Ks({MO@F*DO18tJz*t u$6IyXGpu#M+)L~dhglo!(AhgMxBgKtUSw=U|1&&x%SDdkfA<%q0)GIrEoB}6 literal 0 HcmV?d00001 diff --git a/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/RefStructDemo.dll b/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/RefStructDemo.dll deleted file mode 100644 index d8233d0dfd57962df77fb7d8671f0d6214984cee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeHK-ES0C6hG6Cr7ch>6+}&Npa=zJvZX~SAF|tSON;$-cUuuRwzJ#2%fRf+GBaDc zFUpHP_+Zrkz(nH%KJ)<%nh+CWFeVaXj4=d_`a&?8$cqp1VEvstv)$cR2>N7*XM4}R z=i{Dx&bepqy&XOA2GtW$1KQ#u(M9wO5sB}P&OzMz=*O*eq5108i^|B=t;v&ys}>wP z=jeGgqg$5kscE4)MN2g-H8!45^Y*OJ)~;>Y9+;jOAR1BX>36sHyYgy3(l&Lq5+-T_ zC**VEJJG9X5j3Lpa$M*8%?$Qm!Z~2@8R}`~6;|cHN*|ESVu0Oo?juAoPQ-GUAzB08 znjJ*R<+8ics_%YTr3v&Zp-YD$znCk;2S>0WGw9TU{p>#-J~8 ztWOCnv0rmNT3G82cX#!&;YKonZ(*U1mxxmEH;LAf@EpU+xva5(SUKE|$pl@%fVZ*Z z=;Uw={imRRWxCI_)94v6T{*gusF^3-R=R1EAICb7ytUk*Bh$h>j*%Plh|Vj1%pq!0 z+Ur8(O1vN9b<_=&5Ebc7B}6Bb&w;-p#;;3!UgA#4e^HKa5nG5#3nOxTtnRWj|Darp zv+_3LQRq6jOevs#R<0|DG4lN(y3*KJ*8zG$v7HrfqY!lyRh#`+wQLYJhCOG-0> zR;Ud)L=OSC&@SNh)FpAR#8HWdC4N@o=OxyG6*7P~(iw?Mz#)7dFVOd-(Q4WY+)f99 zAE6V#9h3on9C2vWO&5R<(kH|2^uS!W-TY`x+0%8OG(44R!r(nPI!Yj+{9ViIbE?( z)*m!XF(n+=u&tHCVJmApdEJ9hH}9y`Z(CU-S9GLa#Rx~MXN6aaBRsdl@3->>!<5Q# zVe0d8R3$Hah9u1*SCxt7ps^kwMHNAL23yvxQbiD?Q1U$^ZJ35vC9Tb~7Q}~7nU*#x zCi1p6Yno(WM}m!6+8>cMMTT=zt6!n~{d7pnc(zlX7BlpmWxJk{am%d0P0i1Ya1z3q zGf*JG*25#z2*{vpXgqxi3;RWdQ>nTBwJ&pTjeW4`hw0BI=l4*9swhqMDk+T^w6!tW z%BZnv;mGvMZQryU2!UGPPOHKS`Ykv;@#-KOUpy)b551M?YC-~f{+9s8`S zKyMWap6IYbo3*ilWWVi*Xrb^#kh;Tjy;>LsS|3;{xR~JRoly#2l0E=|t)Wy%|O9ElCZ|v%7892z`&C>lHMb{QJX6#y z(@4dHd)l)LseT(JZF|$voUptyC5aIu?dVP^Wv5R;8((tD5+0I}s>y&>m`zh+D7tsw zlN7A|(`>Ld;v2lN?_zRC>xc2hkEV`v2KOJk+s9*-M=POxPx_K+>{ZM(M|H!Zyqm$s z30c@IU3?5SmZxE*!T%(OZy}=1MCWSVlhr~fp%r}AA-ve9~41RyaC*=KKWma-yQfrEIa$v{6J3_#wMOm_? ze7l^Lgj5IDgcOD za*Yxq(m@GnK8`*c*e>G6^C$*RUV0akbIV>c--QPIP^j_oZZ^U=V3Z|)r(nZ@l}dbF zxPQY-4R1%<0DaDoCv`3OYF2rC=e0DNg(kn#I&nZKG=lj#Ih&&|;Dlh$b954xNq#yb za;@=z&za@5%JDMgXX#$n^z%FcTQ>agGkLFh4&%Lsms8E$<(aDFiDSampleClasses\testImportDoc2.xml PreserveNewest - - SampleClasses\TestUpdate\net-8.0\TestLibrary.dll + + SampleClasses\TestUpdate\net-8.0\AllowsRefStructDemo.dll PreserveNewest - - SampleClasses\TestUpdate\net-9.0\RefStructDemo.dll + + SampleClasses\TestUpdate\net-9.0\AllowsRefStructDemo.dll PreserveNewest From 4c0ef9d2c15cdba2dec70f816399059040791d3d Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Wed, 30 Apr 2025 15:35:26 +0800 Subject: [PATCH 06/14] update --- mdoc/mdoc.Test/mdoc.Test.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mdoc/mdoc.Test/mdoc.Test.csproj b/mdoc/mdoc.Test/mdoc.Test.csproj index 527cc4f3f..7890d0928 100644 --- a/mdoc/mdoc.Test/mdoc.Test.csproj +++ b/mdoc/mdoc.Test/mdoc.Test.csproj @@ -68,6 +68,10 @@ SampleClasses\testImportDoc2.xml PreserveNewest + + SampleClasses\TestUpdate\net-8.0\TestLibrary.dll + PreserveNewest + SampleClasses\TestUpdate\net-8.0\AllowsRefStructDemo.dll PreserveNewest From bd829ec78a4f303aee74ffa561a7cf7ed3ec647f Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Tue, 6 May 2025 09:37:29 +0800 Subject: [PATCH 07/14] update --- mdoc/Mono.Documentation/MDocUpdater.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs index e20d032e3..3368d849b 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.cs @@ -4166,7 +4166,10 @@ private void MakeTypeParameters (FrameworkTypeEntry entry, XmlElement root, ILis xElement.RemoveAttribute(Consts.FrameworkAlternate); xElement.SetAttribute(Consts.FrameworkAlternate, fxaValue); MakeParamsAttributes(existing.Element, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member); - MakeTypeParameterConstraints(root, e, xElement, t); + if (((attrs & (GenericParameterAttributes)0x0020) != 0) && !xElement.SelectNodes("Constraints/ParameterAttribute[@Value='AllowsRefStruct']").Cast().Any()) + { + MakeTypeParameterConstraints(root, e, xElement, t); + } } else { From 8683a1720b3ce1cddba2a517209f0aa0c55f0be1 Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Tue, 6 May 2025 14:07:46 +0800 Subject: [PATCH 08/14] update --- mdoc/Mono.Documentation/MDocUpdater.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs index 3368d849b..065b160f2 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.cs @@ -4166,10 +4166,19 @@ private void MakeTypeParameters (FrameworkTypeEntry entry, XmlElement root, ILis xElement.RemoveAttribute(Consts.FrameworkAlternate); xElement.SetAttribute(Consts.FrameworkAlternate, fxaValue); MakeParamsAttributes(existing.Element, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member); - if (((attrs & (GenericParameterAttributes)0x0020) != 0) && !xElement.SelectNodes("Constraints/ParameterAttribute[@Value='AllowsRefStruct']").Cast().Any()) + + var constraintsElement = xElement.SelectSingleNode("Constraints") as XmlElement; + if (constraintsElement == null && ((attrs & (GenericParameterAttributes)0x0020) != 0)) { MakeTypeParameterConstraints(root, e, xElement, t); } + else if (constraintsElement != null && ((attrs & (GenericParameterAttributes)0x0020) != 0) + && !constraintsElement.SelectNodes("ParameterAttribute[@Value='AllowByRefLike']").Cast().Any()) + { + var parameterAttribute = constraintsElement.OwnerDocument.CreateElement("ParameterAttribute"); + parameterAttribute.SetAttribute("Value", "AllowByRefLike"); + constraintsElement.AppendChild(parameterAttribute); + } } else { From 7ed7657fe33f1c3e6664d0231da7b233fd9738b8 Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Tue, 6 May 2025 16:38:45 +0800 Subject: [PATCH 09/14] update --- mdoc/Mono.Documentation/MDocUpdater.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs index 065b160f2..6489b236f 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.cs @@ -4173,10 +4173,10 @@ private void MakeTypeParameters (FrameworkTypeEntry entry, XmlElement root, ILis MakeTypeParameterConstraints(root, e, xElement, t); } else if (constraintsElement != null && ((attrs & (GenericParameterAttributes)0x0020) != 0) - && !constraintsElement.SelectNodes("ParameterAttribute[@Value='AllowByRefLike']").Cast().Any()) + && !constraintsElement.SelectNodes("ParameterAttribute").Cast().Any(el => el.InnerText == "AllowByRefLike")) { var parameterAttribute = constraintsElement.OwnerDocument.CreateElement("ParameterAttribute"); - parameterAttribute.SetAttribute("Value", "AllowByRefLike"); + parameterAttribute.InnerText = "AllowByRefLike"; constraintsElement.AppendChild(parameterAttribute); } } From 427f5de59b165fcd1e55c651b6844ff1326298d2 Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Wed, 7 May 2025 10:24:06 +0800 Subject: [PATCH 10/14] update ut case --- mdoc/mdoc.Test/MDocUpdaterTests.cs | 26 ++++++++++++------ .../net-8.0/AllowsRefStructDemo.dll | Bin 4096 -> 4096 bytes .../net-9.0/AllowsRefStructDemo.dll | Bin 4096 -> 4096 bytes 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/mdoc/mdoc.Test/MDocUpdaterTests.cs b/mdoc/mdoc.Test/MDocUpdaterTests.cs index 4a9edc926..3eb8281bb 100644 --- a/mdoc/mdoc.Test/MDocUpdaterTests.cs +++ b/mdoc/mdoc.Test/MDocUpdaterTests.cs @@ -269,18 +269,19 @@ public void Test_RunWithRefStructValidation() updater.Run(args); // Assert - var iRefStructProcessorPath = Path.Combine(outputDir, "AllowsRefStructDemo", "IRefStructProcessor`1.xml"); + var IRefStructProcessorPath = Path.Combine(outputDir, "AllowsRefStructDemo", "IRefStructProcessor`1.xml"); var refStructHandlerPath = Path.Combine(outputDir, "AllowsRefStructDemo", "RefStructHandler.xml"); + var ImmutablePath = Path.Combine(outputDir, "AllowsRefStructDemo", "Immutable.xml"); - Assert.IsTrue(File.Exists(iRefStructProcessorPath)); + 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 AllowByRefLike 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 IRefStructProcessorDoc = new XmlDocument(); + IRefStructProcessorDoc.Load(IRefStructProcessorPath); + var IRefStructProcessorNode = IRefStructProcessorDoc.SelectSingleNode("//TypeParameters/TypeParameter/Constraints/ParameterAttribute[text()='AllowByRefLike']"); + Assert.IsNotNull(IRefStructProcessorNode, "Missing AllowByRefLike 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); @@ -288,6 +289,15 @@ public void Test_RunWithRefStructValidation() Assert.IsNotNull(refStructHandlerNode, "Missing AllowByRefLike in RefStructHandler.xml"); var refStructHandlerMemberSignatureNode = refStructHandlerDoc.SelectSingleNode("//Members/Member/MemberSignature[@Language='C#' and contains(@Value, 'where T : new(), allows ref struct')]"); Assert.IsNotNull(refStructHandlerMemberSignatureNode, "Missing MemberSignature with 'where T : allows ref struct' in RefStructHandler.xml"); + + var ImmutableDoc = new XmlDocument(); + ImmutableDoc.Load(ImmutablePath); + var constraintsNodes = ImmutableDoc.SelectNodes("//Members/Member/TypeParameters/TypeParameter/Constraints"); + Assert.IsTrue(constraintsNodes.Count == 1, "Multiple in Immutable.xml"); + var allowByRefLikeNode = ImmutableDoc.SelectSingleNode("//Members/Member/TypeParameters/TypeParameter/Constraints/ParameterAttribute[text()='AllowByRefLike']"); + var defaultConstructorNode = ImmutableDoc.SelectSingleNode("//Members/Member/TypeParameters/TypeParameter/Constraints/ParameterAttribute[text()='DefaultConstructorConstraint']"); + Assert.IsNotNull(allowByRefLikeNode, "Missing AllowByRefLike in Immutable.xml"); + Assert.IsNotNull(defaultConstructorNode, "Missing DefaultConstructorConstraint in Immutable.xml"); } } } \ No newline at end of file diff --git a/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-8.0/AllowsRefStructDemo.dll b/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-8.0/AllowsRefStructDemo.dll index 5695b676d14c55ae60ca43c86317bcbfe6e89cf6..e089f7f6cdb77df1f0378b535913fc5f9503d4e8 100644 GIT binary patch delta 909 zcmYk5Ur5tY6vw~ky8Y&~Y$BoNsOhw2PFqQcg~2SbCE;|AFcDh1Wa(z@&x1WQ6O$P| zI4<=X1(DIC^`?Oj2~n?+LiivRBvDb2AVHmbH=zUPbN+DeIp^Nr{Y^S19djAetH{)L z_O6{avrjM3JxSy;Pag#OWVLY1esa+dd5hBYT9PO;A2I-vS!;{*3r}0E0Gv00Ikp+) z2a@qfY$O4e3Nv70>kI~9XWyp$&YzeB|{aN{Vi4CJB;J0CzDmyqDm z3F$T6W{s?{3*ytO1(nPq)H7|oS+P~qtLfA1(d^d@F$odoUR>9lU>a~?0Gnt+G4F3e z8QPgu2r-?w%51=VnoTp7nJ4jgs&aXet@HJQl{;P;8h@U?PzWN1J+6 zv1B9~M)2BjD7o;>l%j$@Z(N3q=k>{WD3-V~9*>6O-uOr=8jdA%ZPp+6-1)FR(D}?i zRlh5``-XH|Y7GyO*bmuld3Ow52L>~s^M3vaxX-%E4}SH(k=2N0tS;6VBPN4|PFqKL zq;dAdhWGZDmp{*?-W-vc!r8`rvbrOmRHdKH&HfH7b=P@5|8*{@8hLpyPg$$@Pr7LJ UFO(E*7l^Md3#BFBDeJNP1Lk$9iU0rr delta 799 zcmXw%Ur5tY6vw~k=YGG!s)~X7px7_SS<0f+RGe2*QWXz1uFo^Eu~x?!D*!`Q4N=<($h{ zhHmw*W@mR&I{WZ6wF@Gb?%WHU5=~m02$G9t#SA4WBuJ~%-{}B}nW|3V*F4-4^QU3dV<6w<4N(NfsN*`p5(7{z4s?p zUppppZ$-x1Eb`Vb^@}$~et?eqc7VEZa9i`;c#!`|CMFxC@>14}T{PxoFe2}M?TTI5zY|~bL*RLx5Vy#_a^&gz$+ diff --git a/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/AllowsRefStructDemo.dll b/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/AllowsRefStructDemo.dll index 240fdbdb9481bc20a68161ac8463c261297e0337..0d77406e9fb6a41d17d9026919f616fe34aefb17 100644 GIT binary patch delta 909 zcmYk5Ur5tY6vw~ky8Y%9Y$B27is>>lm#rjJ!iQO8BP?@{un<~0#Xp<5{r2EXGZ2yT z!Es;eDJn31h$8DDu*eEQ@TG@9eTa~Jv9h3tK^AoG-2xAs&pGG2d(XM|ZX0!tx~3*9 z>Gxl^QFw=IG)2k9;MnlWK+X9QFeCLUzi!(trh0 zHDI8GP6z{IntqgvT?q0_1LJr=1_o$@xemp9n)8|sS|8Fm>Ah{5o#1Xs42n;>{~kSr zc=&xjYB|!Z{;w!o3054)7intbEOR_y(b@zz*BM*1c8kLhXmzQ293C9wm4QrE?Bolm z>k{I8bV71fk69%PDZ&qy3^lADvFKTvZhM0st=57pYjxY^W;tDoV zgM8j!gCaCBOA%ta(a)^LOp-$_7MLfo%shov<~htT1I$_s;1{c1_`QlOf}Il^F{~<2^&MNI2$;^(G?WsF@kl+<)us#@hP% zN7LKs`lIhYOONe<;UyCLAurfI9>-Gs?{0(U&+mER^%h{gMptA7-kI1 zV6NM7`AONc(xKTi(+f-GLbluGMDFB~tT^726;yY0)}+r~ Z%KxNJd&^uw-tQdot!}Qc;0L9=wts31uj&8* delta 799 zcmXw%T}YEr7{~w5>)v;pwK+4hFYsM&w#pdG2^JzXG)io;njdHqjg*q*ptc1DHN6pu z6^=s}T~r9&gh|jaD2fX0i!Q8)=%$O&RUzd?T~s$c=WHI{=l4AS=bZDL_k4_*W9HPP ztz+TU|%P2}$MQllX9>E&>7{j|t@56P>FGm6_){er}6h!>vbUnLYcD;2T&O$BPVDy zVQ7R(rhyI2a_nGwup1fa_9_ulY*##@*rym{5{8-8IIB3yG~mNAe1#vY(7>!hGjkLA znHEkm>v Date: Wed, 7 May 2025 11:01:07 +0800 Subject: [PATCH 11/14] update --- mdoc/Mono.Documentation/MDocUpdater.cs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs index 6489b236f..a2cdec099 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.cs @@ -4166,19 +4166,7 @@ private void MakeTypeParameters (FrameworkTypeEntry entry, XmlElement root, ILis xElement.RemoveAttribute(Consts.FrameworkAlternate); xElement.SetAttribute(Consts.FrameworkAlternate, fxaValue); MakeParamsAttributes(existing.Element, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member); - - var constraintsElement = xElement.SelectSingleNode("Constraints") as XmlElement; - if (constraintsElement == null && ((attrs & (GenericParameterAttributes)0x0020) != 0)) - { - MakeTypeParameterConstraints(root, e, xElement, t); - } - else if (constraintsElement != null && ((attrs & (GenericParameterAttributes)0x0020) != 0) - && !constraintsElement.SelectNodes("ParameterAttribute").Cast().Any(el => el.InnerText == "AllowByRefLike")) - { - var parameterAttribute = constraintsElement.OwnerDocument.CreateElement("ParameterAttribute"); - parameterAttribute.InnerText = "AllowByRefLike"; - constraintsElement.AppendChild(parameterAttribute); - } + MakeTypeParameterConstraints(root, xElement, xElement, t); } else { From 74f33a18be6497ea02ede7ef11f057f9ac7e5b17 Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Wed, 7 May 2025 15:18:28 +0800 Subject: [PATCH 12/14] update --- .../Test}/AllowsRefStructDemo.dll | Bin mdoc/Mono.Documentation/MDocUpdater.Member.cs | 7 ++- mdoc/Mono.Documentation/MDocUpdater.cs | 2 +- mdoc/mdoc.Test/FormatterTests.cs | 8 +++ mdoc/mdoc.Test/MDocUpdaterTests.cs | 46 ------------------ .../SampleClasses/TestUpdate/frameworks.xml | 3 -- .../net-8.0/AllowsRefStructDemo.dll | Bin 4096 -> 0 bytes mdoc/mdoc.Test/mdoc.Test.csproj | 8 --- 8 files changed, 15 insertions(+), 59 deletions(-) rename {mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0 => external/Test}/AllowsRefStructDemo.dll (100%) delete mode 100644 mdoc/mdoc.Test/SampleClasses/TestUpdate/net-8.0/AllowsRefStructDemo.dll diff --git a/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/AllowsRefStructDemo.dll b/external/Test/AllowsRefStructDemo.dll similarity index 100% rename from mdoc/mdoc.Test/SampleClasses/TestUpdate/net-9.0/AllowsRefStructDemo.dll rename to external/Test/AllowsRefStructDemo.dll diff --git a/mdoc/Mono.Documentation/MDocUpdater.Member.cs b/mdoc/Mono.Documentation/MDocUpdater.Member.cs index 5e065ae01..a32ddd53e 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.Member.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.Member.cs @@ -22,7 +22,12 @@ internal static void MakeTypeParameterConstraints(XmlElement root, XmlElement e, #endif GenericParameterAttributes attrs = typeParameter.Attributes; - XmlElement ce = (XmlElement)e.SelectSingleNode("Constraints"); + XmlElement ce = null; + var typeParameterNode = (XmlElement)e.SelectSingleNode($"TypeParameter[@Name='{typeParameter.Name}']"); + if (typeParameterNode != null) + { + ce = (XmlElement)typeParameterNode.SelectSingleNode("Constraints"); + } if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 0) { if (ce != null) diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs index a2cdec099..e20d032e3 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.cs @@ -4166,7 +4166,7 @@ private void MakeTypeParameters (FrameworkTypeEntry entry, XmlElement root, ILis xElement.RemoveAttribute(Consts.FrameworkAlternate); xElement.SetAttribute(Consts.FrameworkAlternate, fxaValue); MakeParamsAttributes(existing.Element, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member); - MakeTypeParameterConstraints(root, xElement, xElement, t); + MakeTypeParameterConstraints(root, e, xElement, t); } else { diff --git a/mdoc/mdoc.Test/FormatterTests.cs b/mdoc/mdoc.Test/FormatterTests.cs index 187c7fa27..29f1a0d14 100644 --- a/mdoc/mdoc.Test/FormatterTests.cs +++ b/mdoc/mdoc.Test/FormatterTests.cs @@ -601,6 +601,14 @@ public void CSharpStaticEventImplementation(string typeFullName, string eventNam TestEventSignature(staticVirtualMemberDllPath, typeFullName, eventName, expectedSignature); } + [TestCase("AllowsRefStructDemo.Immutable", "Update", + "public bool Update (TArg transformerArgument) where TArg : new(), allows ref struct;")] + public void CSharpAllowsRefStructTest(string typeFullName, string methodName, string expectedSignature) + { + var allowsRefStructDllPath = "../../../../external/Test/AllowsRefStructDemo.dll"; + TestMethodSignature(allowsRefStructDllPath, typeFullName, methodName, expectedSignature); + } + #region Helper Methods string RealTypeName(string name){ switch (name) { diff --git a/mdoc/mdoc.Test/MDocUpdaterTests.cs b/mdoc/mdoc.Test/MDocUpdaterTests.cs index 3eb8281bb..d7d0a5e6f 100644 --- a/mdoc/mdoc.Test/MDocUpdaterTests.cs +++ b/mdoc/mdoc.Test/MDocUpdaterTests.cs @@ -253,51 +253,5 @@ 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 { "update", "-o", outputDir, "-fx", Path.Combine(baseDir) }; - var updater = new MDocUpdater(); - - // Act - updater.Run(args); - - // Assert - var IRefStructProcessorPath = Path.Combine(outputDir, "AllowsRefStructDemo", "IRefStructProcessor`1.xml"); - var refStructHandlerPath = Path.Combine(outputDir, "AllowsRefStructDemo", "RefStructHandler.xml"); - var ImmutablePath = Path.Combine(outputDir, "AllowsRefStructDemo", "Immutable.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 AllowByRefLike 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 AllowByRefLike in RefStructHandler.xml"); - var refStructHandlerMemberSignatureNode = refStructHandlerDoc.SelectSingleNode("//Members/Member/MemberSignature[@Language='C#' and contains(@Value, 'where T : new(), allows ref struct')]"); - Assert.IsNotNull(refStructHandlerMemberSignatureNode, "Missing MemberSignature with 'where T : allows ref struct' in RefStructHandler.xml"); - - var ImmutableDoc = new XmlDocument(); - ImmutableDoc.Load(ImmutablePath); - var constraintsNodes = ImmutableDoc.SelectNodes("//Members/Member/TypeParameters/TypeParameter/Constraints"); - Assert.IsTrue(constraintsNodes.Count == 1, "Multiple in Immutable.xml"); - var allowByRefLikeNode = ImmutableDoc.SelectSingleNode("//Members/Member/TypeParameters/TypeParameter/Constraints/ParameterAttribute[text()='AllowByRefLike']"); - var defaultConstructorNode = ImmutableDoc.SelectSingleNode("//Members/Member/TypeParameters/TypeParameter/Constraints/ParameterAttribute[text()='DefaultConstructorConstraint']"); - Assert.IsNotNull(allowByRefLikeNode, "Missing AllowByRefLike in Immutable.xml"); - Assert.IsNotNull(defaultConstructorNode, "Missing DefaultConstructorConstraint in Immutable.xml"); - } } } \ No newline at end of file diff --git a/mdoc/mdoc.Test/SampleClasses/TestUpdate/frameworks.xml b/mdoc/mdoc.Test/SampleClasses/TestUpdate/frameworks.xml index 7424c78da..c7fc11dae 100644 --- a/mdoc/mdoc.Test/SampleClasses/TestUpdate/frameworks.xml +++ b/mdoc/mdoc.Test/SampleClasses/TestUpdate/frameworks.xml @@ -3,7 +3,4 @@ dependencies\net-8.0 - - dependencies\net-9.0 - \ No newline at end of file diff --git a/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-8.0/AllowsRefStructDemo.dll b/mdoc/mdoc.Test/SampleClasses/TestUpdate/net-8.0/AllowsRefStructDemo.dll deleted file mode 100644 index e089f7f6cdb77df1f0378b535913fc5f9503d4e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeHKU2GIp6h3#`ZcBmEhJPh6v_*b|ace;VMY`=4C_ioKZYxR&o!z}%24-iLnb|^p z(1w5kpLo$%qlwYP7an{d226O6#3+wONDMJVO(Z57O(Y@4`kgzo-EBdFJQyB4+k5Ug z=bn4+`ME#SeXpLUDk7>zo17%Nh@PQC;RmA$3^%O!w1GaEb#3KEvG>}_)DhFu3a*oL zjl7mIY}@g*wA9?9t(mr#=u2vOCoA>2bL(3})BW8ju>T4sfFWn7qLDMK%75iPWLX4w8+QAc=pdTlM9hQ{qB)SA zeu^kHbL>I97PwzhsRO^O#Gu!GdD2J!Yb}t5#<7NegHoUojp(lDX22=mIzVus^=K8) z0q=EJS`HN1R~kWMTMcLx&_UE$!7B0#&MSa@i%<;>YeZ|1bHTz#fO=Zj99e^fL3Ac} zcZ$#w`!%*vkLm5P_O>l-xP~m?R`}WSI?;LbXPHj=u4(5y)>u*#gxfNhq-CJFj4e9{ zdlKl^ga4EHPRmK7XTWr^b0N_z&e2`bPK$y#=7D7qH!d-!r3sB=*Mv?uc!m0`G{f)^t(}_yDffWFzYkalgj=o3x(VpqUJ~CCjiP zM=QwVq|gnu$_+7#mPG_&=kcY$^|Tha5px-DQ8=z}kHY&EennveSda<4kd7-n4jiS` zbdYY7PO~vzr}@}oIz34Sa0?v;ewsc4Zl^22FVI)OU33F@kCG>W+vynn4rzwIr=+4s z6rEAnQ- z7xy{Yq9tF#`R>W*i@uSzB<(WnEV|^l=gYi4P_%tBFKMulHGD}4nJ(sXtQYsOUDHL# zdW)7dT@v>^nNM5eDbuf1Oc`!Y`a5t#$`g)ztZbpAzr(cTkaRuMvF{!1u}2*@Z}=EA ztbf$%a_mtvS9FzL*$9Vkj7ooe0P%Wdd6$zfn3hr=kd|>$Q5EAQ&yck&l2@Ks3L5M2 zeO4YQ&0x!hJzgFNGpXdhnKmucuNa-4Zas_-_W`BiZjR!X<(%-QikOgjN6%UonW#}% zs;P>}QA=hxP4}BcQ#OJ+yQF7)$1P1xm`2WaJm1WCB~j?N9;8aTN$HN6*h1l6fQ#5g zV8e|?ed(iEo_yD^J+7E^5kN67ZNBsYH$T|_*0(ng?)`uxvx>RCPZD8Mxq8p zQxmfdjB4sGY(M-))7SM|qcI^O%P9(B<9wQw~cMqV=&OLU}|e7Os`-WU0a6-Jshs# zu??fe<3+=^%;ALej`>buSj9E9GkAABq{vAhg%R8d!?yI1q+r^Njata2DY+~D?55`^ zbZljJ=okn8;rVlaBro@^iv2j*ayfjIIi7Er)|k2%N{@Fiau^j&Sk^wnv?=dpP+qA{ zM>ubC70k>`(+r#Z?%>@enwUPI3P-5sJ#yCLZ-)aNc*{#q75LVwjle^=&kqB4(*UR* zd};N9?*ZNse09;~>RPdUY11eU&)vt;h|-B6?%=nP(wqaty8v^$U@uPvwZ=Fi zGQde?K8_VFjGn;S1CWh|>lE>x`ILYpuRQHnc1jVj+=B-DQ<&!O!`h4CCJ<9`48fiY zi{-f6@ao2<8c{zgEmY=wrE4Pwt0IzzTUV#7iWlFFIM0Ii!d6aM;tUmNTt$?lBZ!IA zPClU4?F;3ceO|Ye2j+rI{@e9~y7a@Y1D}FyKT2I<_|_B1PNkih*(~RhXtTSampleClasses\TestUpdate\net-8.0\TestLibrary.dll PreserveNewest - - SampleClasses\TestUpdate\net-8.0\AllowsRefStructDemo.dll - PreserveNewest - - - SampleClasses\TestUpdate\net-9.0\AllowsRefStructDemo.dll - PreserveNewest - SampleClasses\TestUpdate\frameworks.xml PreserveNewest From 7d91c75db0030c4bb952e05369503883077504fb Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Wed, 7 May 2025 16:09:20 +0800 Subject: [PATCH 13/14] update --- mdoc/Mono.Documentation/MDocUpdater.Member.cs | 7 +------ mdoc/Mono.Documentation/MDocUpdater.cs | 1 - mdoc/mdoc.Test/FormatterTests.cs | 12 +++++++++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/mdoc/Mono.Documentation/MDocUpdater.Member.cs b/mdoc/Mono.Documentation/MDocUpdater.Member.cs index a32ddd53e..5e065ae01 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.Member.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.Member.cs @@ -22,12 +22,7 @@ internal static void MakeTypeParameterConstraints(XmlElement root, XmlElement e, #endif GenericParameterAttributes attrs = typeParameter.Attributes; - XmlElement ce = null; - var typeParameterNode = (XmlElement)e.SelectSingleNode($"TypeParameter[@Name='{typeParameter.Name}']"); - if (typeParameterNode != null) - { - ce = (XmlElement)typeParameterNode.SelectSingleNode("Constraints"); - } + XmlElement ce = (XmlElement)e.SelectSingleNode("Constraints"); if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 0) { if (ce != null) diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs index e20d032e3..ae11ab8a4 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.cs @@ -4166,7 +4166,6 @@ private void MakeTypeParameters (FrameworkTypeEntry entry, XmlElement root, ILis xElement.RemoveAttribute(Consts.FrameworkAlternate); xElement.SetAttribute(Consts.FrameworkAlternate, fxaValue); MakeParamsAttributes(existing.Element, AttributeFormatter.PreProcessCustomAttributes(t.CustomAttributes), entry, member); - MakeTypeParameterConstraints(root, e, xElement, t); } else { diff --git a/mdoc/mdoc.Test/FormatterTests.cs b/mdoc/mdoc.Test/FormatterTests.cs index 29f1a0d14..71e86194a 100644 --- a/mdoc/mdoc.Test/FormatterTests.cs +++ b/mdoc/mdoc.Test/FormatterTests.cs @@ -601,9 +601,19 @@ public void CSharpStaticEventImplementation(string typeFullName, string eventNam TestEventSignature(staticVirtualMemberDllPath, typeFullName, eventName, expectedSignature); } + [TestCase("AllowsRefStructDemo.IRefStructProcessor`1", + "public interface IRefStructProcessor where T : allows ref struct")] + public void CSharpAllowsRefStructForTypeTest(string typeFullName, string expectedSignature) + { + var allowsRefStructDllPath = "../../../../external/Test/AllowsRefStructDemo.dll"; + TestTypeSignature(allowsRefStructDllPath, typeFullName, expectedSignature); + } + [TestCase("AllowsRefStructDemo.Immutable", "Update", "public bool Update (TArg transformerArgument) where TArg : new(), allows ref struct;")] - public void CSharpAllowsRefStructTest(string typeFullName, string methodName, string expectedSignature) + [TestCase("AllowsRefStructDemo.RefStructHandler", "Handle", + "public void Handle (ref T item) where T : new(), allows ref struct;")] + public void CSharpAllowsRefStructForMemberTest(string typeFullName, string methodName, string expectedSignature) { var allowsRefStructDllPath = "../../../../external/Test/AllowsRefStructDemo.dll"; TestMethodSignature(allowsRefStructDllPath, typeFullName, methodName, expectedSignature); From 7fe3a6415d78171cfc97e8a8a3f0067d665d02ad Mon Sep 17 00:00:00 2001 From: v-fuquanli Date: Thu, 8 May 2025 10:39:25 +0800 Subject: [PATCH 14/14] upgrade version --- mdoc/Consts.cs | 2 +- mdoc/mdoc.nuspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mdoc/Consts.cs b/mdoc/Consts.cs index e5ef8abdd..a0045b330 100644 --- a/mdoc/Consts.cs +++ b/mdoc/Consts.cs @@ -3,7 +3,7 @@ namespace Mono.Documentation { public static class Consts { - public static string MonoVersion = "5.9.3.8"; + public static string MonoVersion = "5.9.4"; public const string DocId = "DocId"; public const string CppCli = "C++ CLI"; public const string CppCx = "C++ CX"; diff --git a/mdoc/mdoc.nuspec b/mdoc/mdoc.nuspec index 1b49673cf..8257cc2cb 100644 --- a/mdoc/mdoc.nuspec +++ b/mdoc/mdoc.nuspec @@ -2,7 +2,7 @@ mdoc - 5.9.3.8 + 5.9.4 mdoc Microsoft Microsoft