Smdn.Reflection.ReverseGenerating version 1.1.4
·
334 commits
to main
since this release
Released package
Release notes
The full release notes are available at gist.
Change log
Change log in this release:
- 2022-07-24 update assembly version
- 2022-07-24 refactor
- 2022-07-24 add support for formatting 'class?' constraints
- 2022-07-24 refactor
API changes
API changes in this release:
diff --git a/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net45.apilist.cs b/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net45.apilist.cs
index bc58591..85046de 100644
--- a/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net45.apilist.cs
+++ b/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net45.apilist.cs
@@ -1,125 +1,125 @@
-// Smdn.Reflection.ReverseGenerating.dll (Smdn.Reflection.ReverseGenerating-1.1.3)
+// Smdn.Reflection.ReverseGenerating.dll (Smdn.Reflection.ReverseGenerating-1.1.4)
// Name: Smdn.Reflection.ReverseGenerating
-// AssemblyVersion: 1.1.3.0
-// InformationalVersion: 1.1.3+f6167551bdfd2449c464509449137c454604db0f
+// AssemblyVersion: 1.1.4.0
+// InformationalVersion: 1.1.4+474aa1799ff8a98167dc9760f2acafaa15b81d4c
// TargetFramework: .NETFramework,Version=v4.5
// Configuration: Release
#nullable enable annotations
using System;
using System.Collections.Generic;
using System.Reflection;
using Smdn.Reflection;
using Smdn.Reflection.ReverseGenerating;
namespace Smdn.Reflection.ReverseGenerating {
public delegate bool AttributeTypeFilter(Type type, ICustomAttributeProvider attributeProvider);
public enum AttributeSectionFormat : int {
Discrete = 1,
List = 0,
}
public enum MethodBodyOption : int {
EmptyImplementation = 1,
None = 0,
ThrowNotImplementedException = 2,
ThrowNull = 3,
}
public static class CSharpFormatter {
public static string EscapeString(string s, bool escapeSingleQuote = false, bool escapeDoubleQuote = false) {}
public static string FormatAccessibility(Accessibility accessibility) {}
public static string FormatParameter(ParameterInfo p, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(MethodBase m, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(ParameterInfo[] parameterList, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatSpecialNameMethod(MethodBase methodOrConstructor, out MethodSpecialName nameType) {}
public static string FormatTypeName(this EventInfo ev, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this FieldInfo f, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this ParameterInfo p, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this PropertyInfo p, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this Type t, ICustomAttributeProvider? attributeProvider = null, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatValueDeclaration(object? val, Type typeOfValue, bool typeWithNamespace = true, bool findConstantField = false, bool useDefaultLiteral = false) {}
public static bool IsLanguagePrimitiveType(Type t, out string primitiveTypeName) {}
public static IEnumerable<string> ToNamespaceList(Type t) {}
}
public static class Generator {
public static IEnumerable<string> GenerateAttributeList(ICustomAttributeProvider attributeProvider, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static IEnumerable<string> GenerateExplicitBaseTypeAndInterfaces(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
[Obsolete("Use GenerateGenericParameterConstraintDeclaration instead.")]
public static string GenerateGenericArgumentConstraintDeclaration(Type genericArgument, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string GenerateGenericParameterConstraintDeclaration(Type genericParameter, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string? GenerateMemberDeclaration(MemberInfo member, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string GenerateTypeDeclaration(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static IEnumerable<string> GenerateTypeDeclarationWithExplicitBaseTypeAndInterfaces(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
}
public class GeneratorOptions : ICloneable {
public class AttributeDeclarationOptions {
public AttributeDeclarationOptions() {}
public AttributeSectionFormat AccessorFormat { get; set; }
public AttributeSectionFormat AccessorParameterFormat { get; set; }
public AttributeSectionFormat BackingFieldFormat { get; set; }
public AttributeSectionFormat DelegateParameterFormat { get; set; }
public AttributeSectionFormat GenericParameterFormat { get; set; }
public AttributeSectionFormat MethodParameterFormat { get; set; }
public bool OmitAttributeSuffix { get; set; }
public AttributeTypeFilter? TypeFilter { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamedArguments { get; set; }
public bool WithNamespace { get; set; }
}
public class MemberDeclarationOptions {
public MemberDeclarationOptions() {}
public MethodBodyOption AccessorBody { get; set; }
public MethodBodyOption MethodBody { get; set; }
public bool OmitEndOfStatement { get; set; }
public bool WithAccessibility { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithEnumTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class ParameterDeclarationOptions {
public ParameterDeclarationOptions() {}
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class TypeDeclarationOptions {
public TypeDeclarationOptions() {}
public bool OmitEndOfStatement { get; set; }
public bool WithAccessibility { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class ValueDeclarationOptions {
public ValueDeclarationOptions() {}
public bool UseDefaultLiteral { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public GeneratorOptions() {}
public GeneratorOptions.AttributeDeclarationOptions AttributeDeclaration { get; init; }
public bool IgnorePrivateOrAssembly { get; set; }
public string? Indent { get; set; }
public GeneratorOptions.MemberDeclarationOptions MemberDeclaration { get; init; }
public GeneratorOptions.ParameterDeclarationOptions ParameterDeclaration { get; init; }
public bool TranslateLanguagePrimitiveTypeDeclaration { get; set; }
public GeneratorOptions.TypeDeclarationOptions TypeDeclaration { get; init; }
public GeneratorOptions.ValueDeclarationOptions ValueDeclaration { get; init; }
public virtual GeneratorOptions Clone() {}
object ICloneable.Clone() {}
}
}
diff --git a/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net47.apilist.cs b/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net47.apilist.cs
index 84062b4..eb6e730 100644
--- a/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net47.apilist.cs
+++ b/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net47.apilist.cs
@@ -1,125 +1,125 @@
-// Smdn.Reflection.ReverseGenerating.dll (Smdn.Reflection.ReverseGenerating-1.1.3)
+// Smdn.Reflection.ReverseGenerating.dll (Smdn.Reflection.ReverseGenerating-1.1.4)
// Name: Smdn.Reflection.ReverseGenerating
-// AssemblyVersion: 1.1.3.0
-// InformationalVersion: 1.1.3+f6167551bdfd2449c464509449137c454604db0f
+// AssemblyVersion: 1.1.4.0
+// InformationalVersion: 1.1.4+474aa1799ff8a98167dc9760f2acafaa15b81d4c
// TargetFramework: .NETFramework,Version=v4.7
// Configuration: Release
#nullable enable annotations
using System;
using System.Collections.Generic;
using System.Reflection;
using Smdn.Reflection;
using Smdn.Reflection.ReverseGenerating;
namespace Smdn.Reflection.ReverseGenerating {
public delegate bool AttributeTypeFilter(Type type, ICustomAttributeProvider attributeProvider);
public enum AttributeSectionFormat : int {
Discrete = 1,
List = 0,
}
public enum MethodBodyOption : int {
EmptyImplementation = 1,
None = 0,
ThrowNotImplementedException = 2,
ThrowNull = 3,
}
public static class CSharpFormatter {
public static string EscapeString(string s, bool escapeSingleQuote = false, bool escapeDoubleQuote = false) {}
public static string FormatAccessibility(Accessibility accessibility) {}
public static string FormatParameter(ParameterInfo p, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(MethodBase m, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(ParameterInfo[] parameterList, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatSpecialNameMethod(MethodBase methodOrConstructor, out MethodSpecialName nameType) {}
public static string FormatTypeName(this EventInfo ev, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this FieldInfo f, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this ParameterInfo p, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this PropertyInfo p, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this Type t, ICustomAttributeProvider? attributeProvider = null, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatValueDeclaration(object? val, Type typeOfValue, bool typeWithNamespace = true, bool findConstantField = false, bool useDefaultLiteral = false) {}
public static bool IsLanguagePrimitiveType(Type t, out string primitiveTypeName) {}
public static IEnumerable<string> ToNamespaceList(Type t) {}
}
public static class Generator {
public static IEnumerable<string> GenerateAttributeList(ICustomAttributeProvider attributeProvider, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static IEnumerable<string> GenerateExplicitBaseTypeAndInterfaces(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
[Obsolete("Use GenerateGenericParameterConstraintDeclaration instead.")]
public static string GenerateGenericArgumentConstraintDeclaration(Type genericArgument, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string GenerateGenericParameterConstraintDeclaration(Type genericParameter, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string? GenerateMemberDeclaration(MemberInfo member, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string GenerateTypeDeclaration(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static IEnumerable<string> GenerateTypeDeclarationWithExplicitBaseTypeAndInterfaces(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
}
public class GeneratorOptions : ICloneable {
public class AttributeDeclarationOptions {
public AttributeDeclarationOptions() {}
public AttributeSectionFormat AccessorFormat { get; set; }
public AttributeSectionFormat AccessorParameterFormat { get; set; }
public AttributeSectionFormat BackingFieldFormat { get; set; }
public AttributeSectionFormat DelegateParameterFormat { get; set; }
public AttributeSectionFormat GenericParameterFormat { get; set; }
public AttributeSectionFormat MethodParameterFormat { get; set; }
public bool OmitAttributeSuffix { get; set; }
public AttributeTypeFilter? TypeFilter { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamedArguments { get; set; }
public bool WithNamespace { get; set; }
}
public class MemberDeclarationOptions {
public MemberDeclarationOptions() {}
public MethodBodyOption AccessorBody { get; set; }
public MethodBodyOption MethodBody { get; set; }
public bool OmitEndOfStatement { get; set; }
public bool WithAccessibility { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithEnumTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class ParameterDeclarationOptions {
public ParameterDeclarationOptions() {}
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class TypeDeclarationOptions {
public TypeDeclarationOptions() {}
public bool OmitEndOfStatement { get; set; }
public bool WithAccessibility { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class ValueDeclarationOptions {
public ValueDeclarationOptions() {}
public bool UseDefaultLiteral { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public GeneratorOptions() {}
public GeneratorOptions.AttributeDeclarationOptions AttributeDeclaration { get; init; }
public bool IgnorePrivateOrAssembly { get; set; }
public string? Indent { get; set; }
public GeneratorOptions.MemberDeclarationOptions MemberDeclaration { get; init; }
public GeneratorOptions.ParameterDeclarationOptions ParameterDeclaration { get; init; }
public bool TranslateLanguagePrimitiveTypeDeclaration { get; set; }
public GeneratorOptions.TypeDeclarationOptions TypeDeclaration { get; init; }
public GeneratorOptions.ValueDeclarationOptions ValueDeclaration { get; init; }
public virtual GeneratorOptions Clone() {}
object ICloneable.Clone() {}
}
}
diff --git a/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net5.0.apilist.cs b/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net5.0.apilist.cs
index 6d4f4bc..c1bb8e2 100644
--- a/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net5.0.apilist.cs
+++ b/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net5.0.apilist.cs
@@ -1,126 +1,126 @@
-// Smdn.Reflection.ReverseGenerating.dll (Smdn.Reflection.ReverseGenerating-1.1.3)
+// Smdn.Reflection.ReverseGenerating.dll (Smdn.Reflection.ReverseGenerating-1.1.4)
// Name: Smdn.Reflection.ReverseGenerating
-// AssemblyVersion: 1.1.3.0
-// InformationalVersion: 1.1.3+f6167551bdfd2449c464509449137c454604db0f
+// AssemblyVersion: 1.1.4.0
+// InformationalVersion: 1.1.4+474aa1799ff8a98167dc9760f2acafaa15b81d4c
// TargetFramework: .NETCoreApp,Version=v5.0
// Configuration: Release
#nullable enable annotations
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Smdn.Reflection;
using Smdn.Reflection.ReverseGenerating;
namespace Smdn.Reflection.ReverseGenerating {
public delegate bool AttributeTypeFilter(Type type, ICustomAttributeProvider attributeProvider);
public enum AttributeSectionFormat : int {
Discrete = 1,
List = 0,
}
public enum MethodBodyOption : int {
EmptyImplementation = 1,
None = 0,
ThrowNotImplementedException = 2,
ThrowNull = 3,
}
public static class CSharpFormatter {
public static string EscapeString(string s, bool escapeSingleQuote = false, bool escapeDoubleQuote = false) {}
public static string FormatAccessibility(Accessibility accessibility) {}
public static string FormatParameter(ParameterInfo p, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(MethodBase m, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(ParameterInfo[] parameterList, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatSpecialNameMethod(MethodBase methodOrConstructor, out MethodSpecialName nameType) {}
public static string FormatTypeName(this EventInfo ev, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this FieldInfo f, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this ParameterInfo p, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this PropertyInfo p, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this Type t, ICustomAttributeProvider? attributeProvider = null, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatValueDeclaration(object? val, Type typeOfValue, bool typeWithNamespace = true, bool findConstantField = false, bool useDefaultLiteral = false) {}
public static bool IsLanguagePrimitiveType(Type t, [MaybeNullWhen(false)] out string? primitiveTypeName) {}
public static IEnumerable<string> ToNamespaceList(Type t) {}
}
public static class Generator {
public static IEnumerable<string> GenerateAttributeList(ICustomAttributeProvider attributeProvider, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static IEnumerable<string> GenerateExplicitBaseTypeAndInterfaces(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
[Obsolete("Use GenerateGenericParameterConstraintDeclaration instead.")]
public static string GenerateGenericArgumentConstraintDeclaration(Type genericArgument, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string GenerateGenericParameterConstraintDeclaration(Type genericParameter, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string? GenerateMemberDeclaration(MemberInfo member, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string GenerateTypeDeclaration(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static IEnumerable<string> GenerateTypeDeclarationWithExplicitBaseTypeAndInterfaces(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
}
public class GeneratorOptions : ICloneable {
public class AttributeDeclarationOptions {
public AttributeDeclarationOptions() {}
public AttributeSectionFormat AccessorFormat { get; set; }
public AttributeSectionFormat AccessorParameterFormat { get; set; }
public AttributeSectionFormat BackingFieldFormat { get; set; }
public AttributeSectionFormat DelegateParameterFormat { get; set; }
public AttributeSectionFormat GenericParameterFormat { get; set; }
public AttributeSectionFormat MethodParameterFormat { get; set; }
public bool OmitAttributeSuffix { get; set; }
public AttributeTypeFilter? TypeFilter { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamedArguments { get; set; }
public bool WithNamespace { get; set; }
}
public class MemberDeclarationOptions {
public MemberDeclarationOptions() {}
public MethodBodyOption AccessorBody { get; set; }
public MethodBodyOption MethodBody { get; set; }
public bool OmitEndOfStatement { get; set; }
public bool WithAccessibility { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithEnumTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class ParameterDeclarationOptions {
public ParameterDeclarationOptions() {}
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class TypeDeclarationOptions {
public TypeDeclarationOptions() {}
public bool OmitEndOfStatement { get; set; }
public bool WithAccessibility { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class ValueDeclarationOptions {
public ValueDeclarationOptions() {}
public bool UseDefaultLiteral { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public GeneratorOptions() {}
public GeneratorOptions.AttributeDeclarationOptions AttributeDeclaration { get; init; }
public bool IgnorePrivateOrAssembly { get; set; }
public string? Indent { get; set; }
public GeneratorOptions.MemberDeclarationOptions MemberDeclaration { get; init; }
public GeneratorOptions.ParameterDeclarationOptions ParameterDeclaration { get; init; }
public bool TranslateLanguagePrimitiveTypeDeclaration { get; set; }
public GeneratorOptions.TypeDeclarationOptions TypeDeclaration { get; init; }
public GeneratorOptions.ValueDeclarationOptions ValueDeclaration { get; init; }
public virtual GeneratorOptions Clone() {}
object ICloneable.Clone() {}
}
}
diff --git a/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net6.0.apilist.cs b/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net6.0.apilist.cs
index 639194d..e5f02c6 100644
--- a/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net6.0.apilist.cs
+++ b/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-net6.0.apilist.cs
@@ -1,135 +1,135 @@
-// Smdn.Reflection.ReverseGenerating.dll (Smdn.Reflection.ReverseGenerating-1.1.3)
+// Smdn.Reflection.ReverseGenerating.dll (Smdn.Reflection.ReverseGenerating-1.1.4)
// Name: Smdn.Reflection.ReverseGenerating
-// AssemblyVersion: 1.1.3.0
-// InformationalVersion: 1.1.3+f6167551bdfd2449c464509449137c454604db0f
+// AssemblyVersion: 1.1.4.0
+// InformationalVersion: 1.1.4+474aa1799ff8a98167dc9760f2acafaa15b81d4c
// TargetFramework: .NETCoreApp,Version=v6.0
// Configuration: Release
#nullable enable annotations
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Smdn.Reflection;
using Smdn.Reflection.ReverseGenerating;
namespace Smdn.Reflection.ReverseGenerating {
public delegate bool AttributeTypeFilter(Type type, ICustomAttributeProvider attributeProvider);
public enum AttributeSectionFormat : int {
Discrete = 1,
List = 0,
}
public enum MethodBodyOption : int {
EmptyImplementation = 1,
None = 0,
ThrowNotImplementedException = 2,
ThrowNull = 3,
}
public static class CSharpFormatter {
public static string EscapeString(string s, bool escapeSingleQuote = false, bool escapeDoubleQuote = false) {}
public static string FormatAccessibility(Accessibility accessibility) {}
public static string FormatParameter(ParameterInfo p, NullabilityInfoContext? nullabilityInfoContext, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameter(ParameterInfo p, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(MethodBase m, NullabilityInfoContext? nullabilityInfoContext, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(MethodBase m, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(ParameterInfo[] parameterList, NullabilityInfoContext? nullabilityInfoContext, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(ParameterInfo[] parameterList, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatSpecialNameMethod(MethodBase methodOrConstructor, out MethodSpecialName nameType) {}
public static string FormatTypeName(this EventInfo ev, NullabilityInfoContext? nullabilityInfoContext, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this EventInfo ev, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this FieldInfo f, NullabilityInfoContext? nullabilityInfoContext, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this FieldInfo f, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this ParameterInfo p, NullabilityInfoContext? nullabilityInfoContext, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this ParameterInfo p, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this PropertyInfo p, NullabilityInfoContext? nullabilityInfoContext, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this PropertyInfo p, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this Type t, ICustomAttributeProvider? attributeProvider = null, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatValueDeclaration(object? val, Type typeOfValue, bool typeWithNamespace = true, bool findConstantField = false, bool useDefaultLiteral = false) {}
public static bool IsLanguagePrimitiveType(Type t, [MaybeNullWhen(false)] out string? primitiveTypeName) {}
public static IEnumerable<string> ToNamespaceList(Type t) {}
}
public static class Generator {
public static IEnumerable<string> GenerateAttributeList(ICustomAttributeProvider attributeProvider, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static IEnumerable<string> GenerateExplicitBaseTypeAndInterfaces(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
[Obsolete("Use GenerateGenericParameterConstraintDeclaration instead.")]
public static string GenerateGenericArgumentConstraintDeclaration(Type genericArgument, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string GenerateGenericParameterConstraintDeclaration(Type genericParameter, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string? GenerateMemberDeclaration(MemberInfo member, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string GenerateTypeDeclaration(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static IEnumerable<string> GenerateTypeDeclarationWithExplicitBaseTypeAndInterfaces(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
}
public class GeneratorOptions : ICloneable {
public class AttributeDeclarationOptions {
public AttributeDeclarationOptions() {}
public AttributeSectionFormat AccessorFormat { get; set; }
public AttributeSectionFormat AccessorParameterFormat { get; set; }
public AttributeSectionFormat BackingFieldFormat { get; set; }
public AttributeSectionFormat DelegateParameterFormat { get; set; }
public AttributeSectionFormat GenericParameterFormat { get; set; }
public AttributeSectionFormat MethodParameterFormat { get; set; }
public bool OmitAttributeSuffix { get; set; }
public AttributeTypeFilter? TypeFilter { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamedArguments { get; set; }
public bool WithNamespace { get; set; }
}
public class MemberDeclarationOptions {
public MemberDeclarationOptions() {}
public MethodBodyOption AccessorBody { get; set; }
public MethodBodyOption MethodBody { get; set; }
public NullabilityInfoContext? NullabilityInfoContext { get; set; }
public bool OmitEndOfStatement { get; set; }
public bool WithAccessibility { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithEnumTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class ParameterDeclarationOptions {
public ParameterDeclarationOptions() {}
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class TypeDeclarationOptions {
public TypeDeclarationOptions() {}
public NullabilityInfoContext? NullabilityInfoContext { get; set; }
public bool OmitEndOfStatement { get; set; }
public bool WithAccessibility { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class ValueDeclarationOptions {
public ValueDeclarationOptions() {}
public bool UseDefaultLiteral { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public GeneratorOptions() {}
public GeneratorOptions.AttributeDeclarationOptions AttributeDeclaration { get; init; }
public bool IgnorePrivateOrAssembly { get; set; }
public string? Indent { get; set; }
public GeneratorOptions.MemberDeclarationOptions MemberDeclaration { get; init; }
public GeneratorOptions.ParameterDeclarationOptions ParameterDeclaration { get; init; }
public bool TranslateLanguagePrimitiveTypeDeclaration { get; set; }
public GeneratorOptions.TypeDeclarationOptions TypeDeclaration { get; init; }
public GeneratorOptions.ValueDeclarationOptions ValueDeclaration { get; init; }
public virtual GeneratorOptions Clone() {}
object ICloneable.Clone() {}
}
}
diff --git a/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-netstandard2.0.apilist.cs b/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-netstandard2.0.apilist.cs
index ce55469..915ef7d 100644
--- a/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-netstandard2.0.apilist.cs
+++ b/doc/api-list/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating-netstandard2.0.apilist.cs
@@ -1,125 +1,125 @@
-// Smdn.Reflection.ReverseGenerating.dll (Smdn.Reflection.ReverseGenerating-1.1.3)
+// Smdn.Reflection.ReverseGenerating.dll (Smdn.Reflection.ReverseGenerating-1.1.4)
// Name: Smdn.Reflection.ReverseGenerating
-// AssemblyVersion: 1.1.3.0
-// InformationalVersion: 1.1.3+f6167551bdfd2449c464509449137c454604db0f
+// AssemblyVersion: 1.1.4.0
+// InformationalVersion: 1.1.4+474aa1799ff8a98167dc9760f2acafaa15b81d4c
// TargetFramework: .NETStandard,Version=v2.0
// Configuration: Release
#nullable enable annotations
using System;
using System.Collections.Generic;
using System.Reflection;
using Smdn.Reflection;
using Smdn.Reflection.ReverseGenerating;
namespace Smdn.Reflection.ReverseGenerating {
public delegate bool AttributeTypeFilter(Type type, ICustomAttributeProvider attributeProvider);
public enum AttributeSectionFormat : int {
Discrete = 1,
List = 0,
}
public enum MethodBodyOption : int {
EmptyImplementation = 1,
None = 0,
ThrowNotImplementedException = 2,
ThrowNull = 3,
}
public static class CSharpFormatter {
public static string EscapeString(string s, bool escapeSingleQuote = false, bool escapeDoubleQuote = false) {}
public static string FormatAccessibility(Accessibility accessibility) {}
public static string FormatParameter(ParameterInfo p, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(MethodBase m, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatParameterList(ParameterInfo[] parameterList, bool typeWithNamespace = true, bool useDefaultLiteral = false) {}
public static string FormatSpecialNameMethod(MethodBase methodOrConstructor, out MethodSpecialName nameType) {}
public static string FormatTypeName(this EventInfo ev, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this FieldInfo f, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this ParameterInfo p, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this PropertyInfo p, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatTypeName(this Type t, ICustomAttributeProvider? attributeProvider = null, bool typeWithNamespace = true, bool withDeclaringTypeName = true, bool translateLanguagePrimitiveType = true) {}
public static string FormatValueDeclaration(object? val, Type typeOfValue, bool typeWithNamespace = true, bool findConstantField = false, bool useDefaultLiteral = false) {}
public static bool IsLanguagePrimitiveType(Type t, out string primitiveTypeName) {}
public static IEnumerable<string> ToNamespaceList(Type t) {}
}
public static class Generator {
public static IEnumerable<string> GenerateAttributeList(ICustomAttributeProvider attributeProvider, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static IEnumerable<string> GenerateExplicitBaseTypeAndInterfaces(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
[Obsolete("Use GenerateGenericParameterConstraintDeclaration instead.")]
public static string GenerateGenericArgumentConstraintDeclaration(Type genericArgument, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string GenerateGenericParameterConstraintDeclaration(Type genericParameter, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string? GenerateMemberDeclaration(MemberInfo member, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static string GenerateTypeDeclaration(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
public static IEnumerable<string> GenerateTypeDeclarationWithExplicitBaseTypeAndInterfaces(Type t, ISet<string>? referencingNamespaces, GeneratorOptions options) {}
}
public class GeneratorOptions : ICloneable {
public class AttributeDeclarationOptions {
public AttributeDeclarationOptions() {}
public AttributeSectionFormat AccessorFormat { get; set; }
public AttributeSectionFormat AccessorParameterFormat { get; set; }
public AttributeSectionFormat BackingFieldFormat { get; set; }
public AttributeSectionFormat DelegateParameterFormat { get; set; }
public AttributeSectionFormat GenericParameterFormat { get; set; }
public AttributeSectionFormat MethodParameterFormat { get; set; }
public bool OmitAttributeSuffix { get; set; }
public AttributeTypeFilter? TypeFilter { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamedArguments { get; set; }
public bool WithNamespace { get; set; }
}
public class MemberDeclarationOptions {
public MemberDeclarationOptions() {}
public MethodBodyOption AccessorBody { get; set; }
public MethodBodyOption MethodBody { get; set; }
public bool OmitEndOfStatement { get; set; }
public bool WithAccessibility { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithEnumTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class ParameterDeclarationOptions {
public ParameterDeclarationOptions() {}
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class TypeDeclarationOptions {
public TypeDeclarationOptions() {}
public bool OmitEndOfStatement { get; set; }
public bool WithAccessibility { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public class ValueDeclarationOptions {
public ValueDeclarationOptions() {}
public bool UseDefaultLiteral { get; set; }
public bool WithDeclaringTypeName { get; set; }
public bool WithNamespace { get; set; }
}
public GeneratorOptions() {}
public GeneratorOptions.AttributeDeclarationOptions AttributeDeclaration { get; init; }
public bool IgnorePrivateOrAssembly { get; set; }
public string? Indent { get; set; }
public GeneratorOptions.MemberDeclarationOptions MemberDeclaration { get; init; }
public GeneratorOptions.ParameterDeclarationOptions ParameterDeclaration { get; init; }
public bool TranslateLanguagePrimitiveTypeDeclaration { get; set; }
public GeneratorOptions.TypeDeclarationOptions TypeDeclaration { get; init; }
public GeneratorOptions.ValueDeclarationOptions ValueDeclaration { get; init; }
public virtual GeneratorOptions Clone() {}
object ICloneable.Clone() {}
}
}Full changes
Full changes in this release:
diff --git a/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating.csproj b/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating.csproj
index 4acc473..a414626 100644
--- a/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating.csproj
+++ b/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating.csproj
@@ -6,7 +6,7 @@ SPDX-License-Identifier: MIT
<PropertyGroup>
<TargetFrameworks>net6.0;net5.0;net47;net45;netstandard2.0</TargetFrameworks>
<RootNamespace>Smdn.Reflection.ReverseGenerating</RootNamespace>
- <VersionPrefix>1.1.3</VersionPrefix>
+ <VersionPrefix>1.1.4</VersionPrefix>
<VersionSuffix></VersionSuffix>
<PackageValidationBaselineVersion>1.0.0</PackageValidationBaselineVersion>
<Nullable>enable</Nullable>
diff --git a/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating/Generator.cs b/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating/Generator.cs
index d32235f..9b961ca 100644
--- a/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating/Generator.cs
+++ b/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating/Generator.cs
@@ -184,13 +184,26 @@ public static partial class Generator {
if (options is null)
throw new ArgumentNullException(nameof(options));
- static bool HasUnmanagedConstraint(Type genericParameter)
- => genericParameter.CustomAttributes.Any(
- static attr => attr.AttributeType.FullName.Equals("System.Runtime.CompilerServices.IsUnmanagedAttribute", StringComparison.Ordinal)
+ static bool ConstraintTypesContainsValueType(Type genericParameter, out IEnumerable<Type> constraintTypesExceptForValueType)
+ {
+ var constraintTypes = genericParameter.GetGenericParameterConstraints();
+
+ var indexOfValueType = Array.FindIndex(
+ constraintTypes,
+ static t => string.Equals(t.FullName, typeof(ValueType).FullName, StringComparison.Ordinal)
);
- static bool IsValueType(Type t) => string.Equals(t.FullName, typeof(ValueType).FullName, StringComparison.Ordinal);
- static bool IsNotValueType(Type t) => !string.Equals(t.FullName, typeof(ValueType).FullName, StringComparison.Ordinal);
+ if (indexOfValueType < 0) {
+ constraintTypesExceptForValueType = constraintTypes;
+ return false;
+ }
+
+ constraintTypesExceptForValueType = constraintTypes
+ .Take(indexOfValueType)
+ .Concat(constraintTypes.Skip(indexOfValueType + 1));
+
+ return true;
+ }
static IEnumerable<string> GetGenericParameterConstraintsOf(
Type genericParameter,
@@ -199,51 +212,40 @@ public static partial class Generator {
)
{
var constraintAttrs = genericParameter.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
- IEnumerable<Type> constraintTypes = genericParameter.GetGenericParameterConstraints();
- IEnumerable<Type> constraintTypesExceptValueType = constraintTypes;
-
- referencingNns?.UnionWith(constraintTypes.Where(IsNotValueType).SelectMany(CSharpFormatter.ToNamespaceList));
+ var hasDefaultConstructorConstraint = constraintAttrs.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint);
+ IEnumerable<Type>? constraintTypes = null;
- if (
- constraintAttrs == GenericParameterAttributes.None &&
- genericParameter.HasGenericParameterNotNullConstraint()
- ) {
+ if (constraintAttrs == GenericParameterAttributes.None) {
+ if (genericParameter.HasGenericParameterNotNullConstraint())
yield return "notnull";
}
+ else if (constraintAttrs.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) {
+ yield return genericParameter.HasGenericParameterUnmanagedConstraint()
+ ? "unmanaged"
+ : "struct";
- if (
- constraintAttrs.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint) &&
- constraintAttrs.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint) &&
- constraintTypes.Any(IsValueType)
- ) {
- constraintAttrs &= ~GenericParameterAttributes.NotNullableValueTypeConstraint;
- constraintAttrs &= ~GenericParameterAttributes.DefaultConstructorConstraint;
- constraintTypesExceptValueType = constraintTypes.Where(IsNotValueType);
-
- if (HasUnmanagedConstraint(genericParameter))
- yield return "unmanaged";
- else
- yield return "struct";
+ if (hasDefaultConstructorConstraint && ConstraintTypesContainsValueType(genericParameter, out constraintTypes))
+ hasDefaultConstructorConstraint = false; // contraint type of System.ValueType implies `new()`
}
else if (constraintAttrs.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint)) {
- yield return "class";
- }
- else if (constraintAttrs.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) {
- if (HasUnmanagedConstraint(genericParameter))
- yield return "unmanaged";
- else
- yield return "struct";
+ yield return genericParameter.GetNullableAttributeMetadataValue() == NullableMetadataValue.Annotated
+ ? "class?"
+ : "class";
}
- var orderedConstraintTypeNames = constraintTypesExceptValueType
- .Select(i => i.FormatTypeName(typeWithNamespace: typeWithNamespace))
+ constraintTypes ??= genericParameter.GetGenericParameterConstraints();
+
+ var orderedConstraintTypeNames = constraintTypes
+ .Select(constraintType => constraintType.FormatTypeName(typeWithNamespace: typeWithNamespace))
.OrderBy(static name => name, StringComparer.Ordinal);
foreach (var ctn in orderedConstraintTypeNames)
yield return ctn;
- if (constraintAttrs.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint))
+ if (hasDefaultConstructorConstraint)
yield return "new()";
+
+ referencingNns?.UnionWith(constraintTypes.SelectMany(CSharpFormatter.ToNamespaceList));
}
var constraints = string.Join(
diff --git a/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection/MemberInfoNullableMetadataExtensions.cs b/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection/MemberInfoNullableMetadataExtensions.cs
new file mode 100644
index 0000000..fcbbdb0
--- /dev/null
+++ b/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection/MemberInfoNullableMetadataExtensions.cs
@@ -0,0 +1,67 @@
+// SPDX-FileCopyrightText: 2022 smdn <smdn@smdn.jp>
+// SPDX-License-Identifier: MIT
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace Smdn.Reflection;
+
+internal static class MemberInfoNullableMetadataExtensions {
+ private static bool IsNullableAttribute(CustomAttributeData attr)
+ => "System.Runtime.CompilerServices.NullableAttribute".Equals(attr.AttributeType.FullName, StringComparison.Ordinal);
+
+ private static bool IsNullableContextAttribute(CustomAttributeData attr)
+ => "System.Runtime.CompilerServices.NullableContextAttribute".Equals(attr.AttributeType.FullName, StringComparison.Ordinal);
+
+ internal static NullableMetadataValue? GetNullableAttributeMetadataValue(this MemberInfo memberOrType)
+ {
+ var data = memberOrType.CustomAttributes.FirstOrDefault(IsNullableAttribute);
+
+ if (data is null)
+ return null;
+
+ return (NullableMetadataValue?)(byte?)data.ConstructorArguments[0].Value;
+ }
+
+ internal static NullableMetadataValue? GetNullableContextAttributeMetadataValue(this MemberInfo memberOrType)
+ {
+ if (
+ memberOrType is Type genericParameter &&
+#if SYSTEM_TYPE_ISGENERICMETHODPARAMETER
+ genericParameter.IsGenericMethodParameter &&
+#else
+ genericParameter.DeclaringMethod is not null &&
+ genericParameter.IsGenericParameter &&
+#endif
+ GetMetadataValue(genericParameter.DeclaringMethod!, out var valueOfGenericParameter)
+ ) {
+ return valueOfGenericParameter;
+ }
+
+ MemberInfo? m = memberOrType;
+
+ for (; ; ) {
+ if (GetMetadataValue(m, out var value))
+ return value;
+ if ((m = m!.DeclaringType) is null)
+ return null;
+
+ // retry against to the outer type
+ continue;
+ }
+
+ static bool GetMetadataValue(MemberInfo memberOrType, out NullableMetadataValue? value)
+ {
+ var data = memberOrType.CustomAttributes.FirstOrDefault(IsNullableContextAttribute);
+
+ if (data is null) {
+ value = null;
+ return false;
+ }
+
+ value = (NullableMetadataValue?)(byte?)data.ConstructorArguments[0].Value;
+
+ return value.HasValue;
+ }
+ }
+}
diff --git a/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection/NullableMetadataValue.cs b/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection/NullableMetadataValue.cs
new file mode 100644
index 0000000..0ea0cb2
--- /dev/null
+++ b/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection/NullableMetadataValue.cs
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2022 smdn <smdn@smdn.jp>
+// SPDX-License-Identifier: MIT
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace Smdn.Reflection;
+
+// ref: https://github.com/dotnet/roslyn/blob/main/docs/features/nullable-metadata.md
+internal enum NullableMetadataValue : byte {
+ Oblivious = 0,
+ NotAnnotated = 1,
+ Annotated = 2,
+}
diff --git a/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection/TypeGenericParameterExtensions.cs b/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection/TypeGenericParameterExtensions.cs
index 705dc86..77f85ee 100644
--- a/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection/TypeGenericParameterExtensions.cs
+++ b/src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection/TypeGenericParameterExtensions.cs
@@ -18,68 +18,26 @@ internal static class TypeGenericParameterExtensions {
throw new InvalidOperationException($"{paramName} must be a generic parameter or generic argument");
}
- // ref: https://github.com/dotnet/roslyn/blob/main/docs/features/nullable-metadata.md#type-parameters
- public static bool HasGenericParameterNotNullConstraint(this Type genericParameter)
+ public static bool HasGenericParameterUnmanagedConstraint(this Type genericParameter)
{
ValidateGenericParameterArgument(genericParameter, nameof(genericParameter));
- var attrNullable = genericParameter.CustomAttributes.FirstOrDefault(IsNullableAttribute);
- var attrNullableContext = FindNullableContextAttribute(genericParameter);
+ return genericParameter.CustomAttributes.Any(
+ static attr => string.Equals("System.Runtime.CompilerServices.IsUnmanagedAttribute", attr.AttributeType.FullName, StringComparison.Ordinal)
+ );
+ }
- const byte notAnnotated = 1;
+ // ref: https://github.com/dotnet/roslyn/blob/main/docs/features/nullable-metadata.md#type-parameters
+ public static bool HasGenericParameterNotNullConstraint(this Type genericParameter)
+ {
+ ValidateGenericParameterArgument(genericParameter, nameof(genericParameter));
- if (attrNullableContext is not null && notAnnotated.Equals(attrNullableContext.ConstructorArguments[0].Value))
+ if (genericParameter.GetNullableContextAttributeMetadataValue() == NullableMetadataValue.NotAnnotated)
// `#nullable enable` context
- return attrNullable is null;
+ return genericParameter.GetNullableAttributeMetadataValue() == null;
else
// `#nullable disable` context
- return attrNullable is not null && notAnnotated.Equals(attrNullable.ConstructorArguments[0].Value);
- }
-
- private static bool IsNullableAttribute(CustomAttributeData attr)
- => "System.Runtime.CompilerServices.NullableAttribute".Equals(attr.AttributeType.FullName, StringComparison.Ordinal);
-
- private static bool IsNullableContextAttribute(CustomAttributeData attr)
- => "System.Runtime.CompilerServices.NullableContextAttribute".Equals(attr.AttributeType.FullName, StringComparison.Ordinal);
-
- private static bool TryGetNullableContextAttribute(
- MemberInfo member,
-#if NULL_STATE_STATIC_ANALYSIS_ATTRIBUTES
- [NotNullWhen(true)]
-#endif
- out CustomAttributeData? attrNullableContext
- )
- {
- attrNullableContext = member.CustomAttributes.FirstOrDefault(IsNullableContextAttribute);
-
- return attrNullableContext is not null;
- }
-
- private static CustomAttributeData? FindNullableContextAttribute(Type genericParameter)
- {
- if (
-#if SYSTEM_TYPE_ISGENERICMETHODPARAMETER
- genericParameter.IsGenericMethodParameter &&
-#else
- genericParameter.DeclaringMethod is not null &&
- genericParameter.IsGenericParameter &&
-#endif
- TryGetNullableContextAttribute(genericParameter.DeclaringMethod!, out var methodAttr)
- ) {
- return methodAttr;
- }
-
- Type? t = genericParameter;
-
- for (; ; ) {
- if ((t = t!.DeclaringType) is null)
- return null;
- if (TryGetNullableContextAttribute(t, out var typeAttr))
- return typeAttr;
-
- // retry against to the outer type
- continue;
- }
+ return genericParameter.GetNullableAttributeMetadataValue() == NullableMetadataValue.NotAnnotated;
}
public static bool HasGenericParameterNoConstraints(this Type genericParameter)Full Changelog: releases/Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks-1.1.3...releases/Smdn.Reflection.ReverseGenerating-1.1.4