feat#550375: Support ref struct and readonly ref struct syntaxes (#608)

* Support `ref struct` and `readonly ref struct` syntaxes.

* update

* Refactor code

* Update
This commit is contained in:
Min Huang 2022-02-15 16:22:34 +08:00 коммит произвёл GitHub
Родитель b0c005e123
Коммит e942ab5362
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 77 добавлений и 6 удалений

Просмотреть файл

@ -38,12 +38,15 @@ namespace Mono.Documentation
public const string VoidFullName = "System.Void";
public const string RefTypeObsoleteString = "Types with embedded references are not supported in this version of your compiler.";
public const string FrameworksIndexFolderName = "FrameworksIndex";
public const string CompilerGeneratedAttribute = "System.Runtime.CompilerServices.CompilerGeneratedAttribute";
public const string CompilationMappingAttribute = "Microsoft.FSharp.Core.CompilationMappingAttribute";
public const string FrameworksIndex = "FrameworksIndex";
public const string FrameworkAlternate = "FrameworkAlternate";
public const string Index = "Index";
public static bool CollapseInheritedInterfaces = true;
public const string CompilationMappingAttribute = "Microsoft.FSharp.Core.CompilationMappingAttribute";
public const string CompilerGeneratedAttribute = "System.Runtime.CompilerServices.CompilerGeneratedAttribute";
public const string IsByRefLikeAttribute = "System.Runtime.CompilerServices.IsByRefLikeAttribute";
public const string IsReadOnlyAttribute = "System.Runtime.CompilerServices.IsReadOnlyAttribute";
}
}

Просмотреть файл

@ -945,5 +945,18 @@ namespace Mono.Documentation.Updater
return type;
}
public static bool HasCustomAttribute(ICustomAttributeProvider customAttrProvider, string attributeName)
{
if (customAttrProvider == null)
{
return false;
}
else
{
return customAttrProvider.HasCustomAttributes
&& customAttrProvider.CustomAttributes.Any(attr => attr.AttributeType.FullName == attributeName);
}
}
}
}

Просмотреть файл

@ -238,7 +238,19 @@ namespace Mono.Documentation.Updater.Formatters
if (t.IsEnum)
return "enum";
if (t.IsValueType)
return "struct";
{
StringBuilder buf = new StringBuilder();
if (DocUtils.HasCustomAttribute(t, Consts.IsReadOnlyAttribute))
{
buf.Append("readonly ");
}
if (DocUtils.HasCustomAttribute(t, Consts.IsByRefLikeAttribute))
{
buf.Append("ref ");
}
buf.Append("struct");
return buf.ToString();
}
if (t.IsClass || t.FullName == "System.Enum")
return "class";
if (t.IsInterface)
@ -508,8 +520,7 @@ namespace Mono.Documentation.Updater.Formatters
modifiers += " ref";
}
if (method.ReturnType.IsRequiredModifier
&& method.MethodReturnType.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.Runtime.CompilerServices.IsReadOnlyAttribute"))
if (method.ReturnType.IsRequiredModifier && DocUtils.HasCustomAttribute(method.MethodReturnType, Consts.IsReadOnlyAttribute))
{
modifiers += " readonly";
}

Просмотреть файл

@ -1,7 +1,7 @@
using System.Linq;
using mdoc.Test.SampleClasses;
using Mono.Documentation;
using Mono.Documentation.Updater;
using Mono.Documentation.Updater.Frameworks;
using NUnit.Framework;
using System.Xml;
@ -144,5 +144,19 @@ random text
var result = DocUtils.IsEiiIgnoredMethod(member, member.Overrides[0]);
Assert.IsTrue(result);
}
[Test]
public void HasCustomAttributeTest()
{
Assert.IsFalse(DocUtils.HasCustomAttribute(null, ""));
var type = GetType(typeof(SampleClasses.RefStruct));
Assert.IsFalse(DocUtils.HasCustomAttribute(type, Consts.IsReadOnlyAttribute));
Assert.IsTrue(DocUtils.HasCustomAttribute(type, Consts.IsByRefLikeAttribute));
type = GetType(typeof(SampleClasses.ReadOnlyRefStruct));
Assert.IsTrue(DocUtils.HasCustomAttribute(type, Consts.IsReadOnlyAttribute));
Assert.IsTrue(DocUtils.HasCustomAttribute(type, Consts.IsByRefLikeAttribute));
}
}
}

Просмотреть файл

@ -387,6 +387,22 @@ namespace mdoc.Test
Assert.AreEqual(true, flag);
}
[Test]
public void CSharpRefStructTest()
{
var type = GetType(typeof(SampleClasses.RefStruct));
var typeSignature = formatter.GetDeclaration(type);
Assert.AreEqual("public ref struct RefStruct", typeSignature);
}
[Test]
public void CSharpReadOnlyRefStructTest()
{
var type = GetType(typeof(SampleClasses.ReadOnlyRefStruct));
var typeSignature = formatter.GetDeclaration(type);
Assert.AreEqual("public readonly ref struct ReadOnlyRefStruct", typeSignature);
}
#region Helper Methods
string RealTypeName(string name){
switch (name) {

Просмотреть файл

@ -0,0 +1,7 @@
namespace mdoc.Test.SampleClasses
{
public readonly ref struct ReadOnlyRefStruct
{
}
}

Просмотреть файл

@ -0,0 +1,7 @@
namespace mdoc.Test.SampleClasses
{
public ref struct RefStruct
{
}
}