Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/api-doc-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiao Luo <basehello@icloud.com>2021-04-14 18:20:54 +0300
committerGitHub <noreply@github.com>2021-04-14 18:20:54 +0300
commit806f222aad9a217efc587776915ffba95f92a20f (patch)
tree3f0aa84640e4c842a92aa3744b7f836d2282cb87
parent38d866cbbf3eb19b0a1a523153a3303a9ac2b1f3 (diff)
Improve argument value formatter (#539)
https://dev.azure.com/ceapex/Engineering/_workitems/edit/366340
-rw-r--r--mdoc/Mono.Documentation/MDocUpdater.cs4
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/ApplePlatformEnumFormatter.cs95
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/AttributeFormatter.cs35
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/AttributeValueFormatter.cs389
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/DefaultAttributeValueFormatter.cs13
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/StandardFlagsEnumFormatter.cs36
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs2
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppFullMemberFormatter.cs2
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/FSharpFormatter.cs2
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/ILFullMemberFormatter.cs2
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/JsFormatter.cs2
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/MemberFormatter.cs70
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/SlashDocMemberFormatter.cs2
-rw-r--r--mdoc/Mono.Documentation/Updater/Formatters/VBFullMemberFormatter.cs2
-rw-r--r--mdoc/Mono.Documentation/Updater/ResolvedTypeInfo.cs29
-rw-r--r--mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Circle.xml4
-rw-r--r--mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Prism.xml4
-rw-r--r--mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Rectangle.xml4
-rw-r--r--mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+FirstLast.xml4
-rw-r--r--mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+FirstOnly.xml4
-rw-r--r--mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+LastOnly.xml4
-rw-r--r--mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+Shape+Circle.xml4
-rw-r--r--mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+Shape+Rectangle.xml4
-rw-r--r--mdoc/mdoc.Test/AttributeValueFormatterTest.cs168
-rw-r--r--mdoc/mdoc.Test/SampleClasses/ApplePlatformEnum.cs48
-rw-r--r--mdoc/mdoc.Test/SampleClasses/AttributeDataTypeAttribute.cs57
-rw-r--r--mdoc/mdoc.Test/SampleClasses/NotApplyAttributeInvalidFlagsEnum.cs10
-rw-r--r--mdoc/mdoc.Test/SampleClasses/NotApplyAttributeValidFlagsEnum.cs12
-rw-r--r--mdoc/mdoc.Test/SampleClasses/SomeAttribute.cs450
-rw-r--r--mdoc/mdoc.Test/SampleClasses/SomeFlagsEnum.cs14
-rw-r--r--mdoc/mdoc.Test/SampleClasses/SomeIteratorStateMachine.cs44
-rw-r--r--mdoc/mdoc.Test/SampleClasses/SomeNestedTypes.cs34
-rw-r--r--mdoc/mdoc.Test/mdoc.Test.csproj9
-rw-r--r--mdoc/mdoc.csproj4
34 files changed, 1266 insertions, 301 deletions
diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs
index 8d7463e0..d75db09e 100644
--- a/mdoc/Mono.Documentation/MDocUpdater.cs
+++ b/mdoc/Mono.Documentation/MDocUpdater.cs
@@ -4408,9 +4408,9 @@ namespace Mono.Documentation
return docTypeFormatter.GetName (type, useTypeProjection: useTypeProjection);
}
- internal static string GetDocTypeFullName (TypeReference type, bool useTypeProjection = true)
+ internal static string GetDocTypeFullName (TypeReference type, bool useTypeProjection = true, bool isTypeofOperator = false)
{
- return DocTypeFullMemberFormatter.Default.GetName (type, useTypeProjection: useTypeProjection);
+ return DocTypeFullMemberFormatter.Default.GetName (type, useTypeProjection: useTypeProjection, isTypeofOperator: isTypeofOperator);
}
internal static string GetXPathForMember (DocumentationMember member)
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/ApplePlatformEnumFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/ApplePlatformEnumFormatter.cs
deleted file mode 100644
index 55dd508f..00000000
--- a/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/ApplePlatformEnumFormatter.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-using Mono.Cecil;
-
-namespace Mono.Documentation.Updater
-{
- /// <summary>A custom formatter for the ObjCRuntime.Platform enumeration.</summary>
- class ApplePlatformEnumFormatter : AttributeValueFormatter
- {
- public override bool TryFormatValue (object v, ResolvedTypeInfo type, out string returnvalue)
- {
- TypeReference valueType = type.Reference;
- string typename = MDocUpdater.GetDocTypeFullName (valueType);
- TypeDefinition valueDef = type.Definition;
- if (typename.Contains ("ObjCRuntime.Platform") && valueDef.CustomAttributes.Any (ca => ca.AttributeType.FullName == "System.FlagsAttribute"))
- {
-
- var values = GetEnumerationValues (valueDef);
- long c = ToInt64 (v);
-
- returnvalue = Format (c, values, typename);
- return true;
- }
-
- returnvalue = null;
- return false;
- }
-
- string Format (long c, IDictionary<long, string> values, string typename)
- {
- int iosarch, iosmajor, iosminor, iossubminor;
- int macarch, macmajor, macminor, macsubminor;
- GetEncodingiOS (c, out iosarch, out iosmajor, out iosminor, out iossubminor);
- GetEncodingMac ((ulong)c, out macarch, out macmajor, out macminor, out macsubminor);
-
- if (iosmajor == 0 & iosminor == 0 && iossubminor == 0)
- {
- return FormatValues ("Mac", macarch, macmajor, macminor, macsubminor);
- }
-
- if (macmajor == 0 & macminor == 0 && macsubminor == 0)
- {
- return FormatValues ("iOS", iosarch, iosmajor, iosminor, iossubminor);
- }
-
- return string.Format ("(Platform){0}", c);
- }
-
- string FormatValues (string plat, int arch, int major, int minor, int subminor)
- {
- string archstring = "";
- switch (arch)
- {
- case 1:
- archstring = "32";
- break;
- case 2:
- archstring = "64";
- break;
- }
- return string.Format ("Platform.{4}_{0}_{1}{2} | Platform.{4}_Arch{3}",
- major,
- minor,
- subminor == 0 ? "" : "_" + subminor.ToString (),
- archstring,
- plat
- );
- }
-
- void GetEncodingiOS (long entireLong, out int archindex, out int major, out int minor, out int subminor)
- {
- long lowerBits = entireLong & 0xffffffff;
- int lowerBitsAsInt = (int)lowerBits;
- GetEncoding (lowerBitsAsInt, out archindex, out major, out minor, out subminor);
- }
-
- void GetEncodingMac (ulong entireLong, out int archindex, out int major, out int minor, out int subminor)
- {
- ulong higherBits = entireLong & 0xffffffff00000000;
- int higherBitsAsInt = (int)((higherBits) >> 32);
- GetEncoding (higherBitsAsInt, out archindex, out major, out minor, out subminor);
- }
-
- void GetEncoding (Int32 encodedBits, out int archindex, out int major, out int minor, out int subminor)
- {
- // format is AAJJNNSS
- archindex = (int)((encodedBits & 0xFF000000) >> 24);
- major = (int)((encodedBits & 0x00FF0000) >> 16);
- minor = (int)((encodedBits & 0x0000FF00) >> 8);
- subminor = (int)((encodedBits & 0x000000FF) >> 0);
- }
- }
-} \ No newline at end of file
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/AttributeFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/AttributeFormatter.cs
index 1378675a..b8076d73 100644
--- a/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/AttributeFormatter.cs
+++ b/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/AttributeFormatter.cs
@@ -2,13 +2,14 @@
using Mono.Documentation.Util;
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
namespace Mono.Documentation.Updater.Formatters
{
public class AttributeFormatter
{
+ private AttributeValueFormatter valueFormatter = new AttributeValueFormatter();
+
public virtual string PrefixBrackets { get; } = "";
public virtual string SurfixBrackets { get; } = "";
public virtual string Language { get; } = "";
@@ -119,37 +120,9 @@ namespace Mono.Documentation.Updater.Formatters
return $"{name}={value}";
}
- public virtual string MakeAttributesValueString(object v, TypeReference valueType)
+ public virtual string MakeAttributesValueString(object argumentValue, TypeReference argumentType)
{
- var formatters = new[] {
- new AttributeValueFormatter (),
- new ApplePlatformEnumFormatter (),
- new StandardFlagsEnumFormatter (),
- new DefaultAttributeValueFormatter (),
- };
-
- ResolvedTypeInfo type = new ResolvedTypeInfo(valueType);
-
- if (valueType is ArrayType && v is CustomAttributeArgument[])
- {
- ArrayType atype = valueType as ArrayType;
- CustomAttributeArgument[] args = v as CustomAttributeArgument[];
- var returnvalue = $"new {atype.FullName}{(atype.FullName.EndsWith("[]") ? "" : "[]")} {{ { string.Join(", ", args.Select(a => MakeAttributesValueString(a.Value, a.Type)).ToArray()) } }}";
- return returnvalue;
- }
-
- foreach (var formatter in formatters)
- {
- string formattedValue;
- if (formatter.TryFormatValue(v, type, out formattedValue))
- {
- return formattedValue;
- }
- }
-
- // this should never occur because the DefaultAttributeValueFormatter will always
- // successfully format the value ... but this is needed to satisfy the compiler :)
- throw new InvalidDataException(string.Format("Unable to format attribute value ({0})", v.ToString()));
+ return valueFormatter.Format(argumentType, argumentValue);
}
private bool IsIgnoredAttribute(CustomAttribute customAttribute)
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/AttributeValueFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/AttributeValueFormatter.cs
index a9e092bb..41566740 100644
--- a/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/AttributeValueFormatter.cs
+++ b/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/AttributeValueFormatter.cs
@@ -1,92 +1,385 @@
-using System;
+using Mono.Cecil;
+using System;
using System.Collections.Generic;
using System.Linq;
-using Mono.Cecil;
-
-using Mono.Documentation.Util;
namespace Mono.Documentation.Updater
{
- /// <summary>Formats attribute values. Should return true if it is able to format the value.</summary>
- class AttributeValueFormatter
- {
- public virtual bool TryFormatValue (object v, ResolvedTypeInfo type, out string returnvalue)
+ public class AttributeValueFormatter
+ {
+ public string Format(TypeReference argumentType, object argumentValue)
{
- TypeReference valueType = type.Reference;
- if (v == null)
+ // When a property type of an attribute is an object type you can assign any type to it,
+ // so we need to convert the object type to a concrete object type.
+ if (argumentValue is CustomAttributeArgument attributeArgument)
{
- returnvalue = "null";
- return true;
+ return Format(attributeArgument.Type, attributeArgument.Value);
}
- if (valueType.FullName == "System.Type")
+
+ return FormatValue(argumentType, argumentValue);
+ }
+
+ // The types of positional and named parameters for an attribute class are limited to the attribute parameter types, which are:
+ // https://github.com/dotnet/csharplang/blob/main/spec/attributes.md#attribute-parameter-types
+ private string FormatValue(TypeReference argumentType, object argumentValue)
+ {
+ if (IsNull(argumentValue))
{
- var vTypeRef = v as TypeReference;
- if (vTypeRef != null)
- returnvalue = "typeof(" + NativeTypeManager.GetTranslatedName (vTypeRef) + ")"; // TODO: drop NS handling
- else
- returnvalue = "typeof(" + v.ToString () + ")";
+ return "null";
+ }
- return true;
+ if (IsArrayType(argumentType, argumentValue))
+ {
+ return ConvertToArrayType(argumentType, argumentValue);
}
- if (valueType.FullName == "System.String")
+
+ if (IsTypeType(argumentType, argumentValue))
{
- returnvalue = "\"" + FilterSpecialChars (v.ToString ()) + "\"";
- return true;
+ return ConvertToType(argumentType, argumentValue);
}
- if (valueType.FullName == "System.Char")
+
+ if (IsStringType(argumentType, argumentValue))
{
- returnvalue = "'" + FilterSpecialChars (v.ToString ()) + "'";
- return true;
+ return ConvertToString(argumentType, argumentValue);
}
- if (v is Boolean)
+
+ if (IsCharType(argumentType, argumentValue))
{
- returnvalue = (bool)v ? "true" : "false";
- return true;
+ return ConvertToChar(argumentType, argumentValue);
}
- TypeDefinition valueDef = type.Definition;
- if (valueDef == null || !valueDef.IsEnum)
+ if (IsBoolType(argumentType, argumentValue))
{
- returnvalue = v.ToString ();
- return true;
+ return ConvertToBool(argumentType, argumentValue);
}
- string typename = MDocUpdater.GetDocTypeFullName (valueType);
- var values = GetEnumerationValues (valueDef);
- long c = ToInt64 (v);
- if (values.ContainsKey (c))
+ if (IsEnumType(argumentType, argumentValue))
{
- returnvalue = typename + "." + values[c];
- return true;
+ return ConvertToEnum(argumentType, argumentValue);
+ }
+
+ return ConvertUnhandledTypeToString(argumentValue);
+ }
+
+ private bool IsNull(object argumentValue)
+ {
+ return argumentValue == null;
+ }
+
+ private bool IsEnumType(TypeReference argumentType, object argumentValue)
+ {
+ return argumentType.Resolve().IsEnum;
+ }
+
+ private bool IsTypeType(TypeReference argumentType, object argumentValue)
+ {
+ return IsType("System.Type", argumentType, argumentValue);
+ }
+
+ private bool IsStringType(TypeReference argumentType, object argumentValue)
+ {
+ return IsType("System.String", argumentType, argumentValue);
+ }
+
+ private bool IsCharType(TypeReference argumentType, object argumentValue)
+ {
+ return IsType("System.Char", argumentType, argumentValue);
+ }
+
+ private bool IsBoolType(TypeReference argumentType, object argumentValue)
+ {
+ return IsType("System.Boolean", argumentType, argumentValue);
+ }
+
+ private bool IsType(string typeFullName, TypeReference argumentType, object argumentValue)
+ {
+ return argumentType.FullName.Equals(typeFullName);
+ }
+
+ private bool IsArrayType(TypeReference argumentType, object argumentValue)
+ {
+ return argumentType is ArrayType && argumentValue is CustomAttributeArgument[];
+ }
+
+ private string ConvertToArrayType(TypeReference argumentType, object argumentValue)
+ {
+ var arrayType = argumentType as ArrayType;
+ var arrayArguments = argumentValue as CustomAttributeArgument[];
+ var arrayTypeFullName = $"new {arrayType.FullName}{(arrayType.FullName.EndsWith("[]") ? "" : "[]")}";
+ var arrayArgumentValues = arrayArguments.Select(i => FormatValue(i.Type, i.Value));
+
+ return $"{arrayTypeFullName} {{ {string.Join(", ", arrayArgumentValues)} }}";
+ }
+
+ private bool IsFlagsEnum(TypeReference argumentType, object argumentValue)
+ {
+ var argumentTypeDefinition = argumentType.Resolve();
+ var isApplyFlagsAttributeEnumType = argumentTypeDefinition.CustomAttributes.Any(a => a.AttributeType.FullName == "System.FlagsAttribute");
+ var isNotApplyAttributeFlagsEnumType = IsNotApplyAttributeFlagsEnumType(argumentTypeDefinition, argumentValue);
+
+ return isApplyFlagsAttributeEnumType || isNotApplyAttributeFlagsEnumType;
+ }
+
+ /// <summary>
+ /// We have a few legacy flags enum type not apply FlagsAttribute to it.
+ /// For example, Microsoft.JScript.JSFunctionAttributeEnum in .NET Framework 1.1 but the issue has been fixed in the newer version.
+ /// </summary>
+ private bool IsNotApplyAttributeFlagsEnumType(TypeDefinition argumentType, object argumentValue)
+ {
+ (var typeFullName, var enumConstants, var enumValue) = ExtractEnumTypeData(argumentType, argumentValue);
+ if (enumConstants.ContainsKey(enumValue))
+ {
+ // Not is a combinations of values.
+ return false;
+ }
+
+ var flagsEnumValues = enumConstants.Keys.ToList();
+ flagsEnumValues.Remove(0); // The zero value is not a valid flags enum value.
+
+ // The following example is an invalid and valid flags enum type.
+ // None = 0, Read = 1, Write = 2, ReadWrite = 3 maybe is a flags enum type but sometimes it is not.
+ // Read = 1, Write = 2, Open = 4, Close = 8 actually is a flags enum type.
+ var minFlagsEnumValueCount = 4;
+ if (flagsEnumValues.Count() >= minFlagsEnumValueCount)
+ {
+ long allEnumLogicalOrValue = 0;
+ foreach (var item in flagsEnumValues)
+ {
+ allEnumLogicalOrValue = allEnumLogicalOrValue | item;
+ }
+
+ var isFlagsEnumType = !flagsEnumValues.Any(i => (i & allEnumLogicalOrValue) != i);
+ var isCombinationValue = flagsEnumValues.Count(i => (i & enumValue) != i) > 1;
+
+ return isFlagsEnumType && isCombinationValue;
}
- returnvalue = null;
return false;
}
- internal static IDictionary<long, string> GetEnumerationValues(TypeDefinition type)
+ private bool IsApplePlatformEnum(TypeReference argumentType, object argumentValue)
+ {
+ return MDocUpdater.GetDocTypeFullName(argumentType).Contains("ObjCRuntime.Platform");
+ }
+
+ private string ConvertToType(TypeReference argumentType, object argumentValue)
{
+ var valueResult = GetArgumentValue("System.Type", argumentType, argumentValue);
+ var typeFullName = MDocUpdater.GetDocTypeFullName((TypeReference)valueResult, isTypeofOperator: true);
+
+ return $"typeof({typeFullName})";
+ }
+
+ private string ConvertToString(TypeReference argumentType, object argumentValue)
+ {
+ var valueResult = GetArgumentValue("System.String", argumentType, argumentValue);
+ if (valueResult == null)
+ {
+ return "null";
+ }
+
+ return string.Format("\"{0}\"", FilterSpecialChars(valueResult.ToString()));
+ }
+
+ private string ConvertToBool(TypeReference argumentType, object argumentValue)
+ {
+ return GetArgumentValue("System.Boolean", argumentType, argumentValue).ToString().ToLower();
+ }
+
+ private string ConvertToChar(TypeReference argumentType, object argumentValue)
+ {
+ var valueResult = GetArgumentValue("System.Char", argumentType, argumentValue).ToString();
+
+ return string.Format("'{0}'", FilterSpecialChars(valueResult));
+ }
+
+ private string ConvertUnhandledTypeToString(object argumentValue)
+ {
+ return argumentValue.ToString();
+ }
+
+ private string ConvertToEnum(TypeReference argumentType, object argumentValue)
+ {
+ if (IsFlagsEnum(argumentType, argumentValue))
+ {
+ if (IsApplePlatformEnum(argumentType, argumentValue))
+ {
+ return ConvertToApplePlatformEnum(argumentType, argumentValue);
+ }
+
+ return ConvertToFlagsEnum(argumentType, argumentValue);
+ }
+
+ return ConvertToNormalEnum(argumentType, argumentValue);
+ }
+
+ private string ConvertToNormalEnum(TypeReference argumentType, object argumentValue)
+ {
+ (var typeFullName, var enumConstants, var enumValue) = ExtractEnumTypeData(argumentType, argumentValue);
+ if (enumConstants.ContainsKey(enumValue))
+ {
+ return typeFullName + "." + enumConstants[enumValue];
+ }
+
+ return ConvertToUnknownEnum(argumentType, argumentValue);
+ }
+
+ private string ConvertToUnknownEnum(TypeReference argumentType, object argumentValue)
+ {
+ (var typeFullName, var enumConstants, var enumValue) = ExtractEnumTypeData(argumentType, argumentValue);
+
+ return $"({typeFullName}) {enumValue}";
+ }
+
+ private string ConvertToFlagsEnum(TypeReference argumentType, object argumentValue)
+ {
+ (var typeFullName, var enumConstants, var enumValue) = ExtractEnumTypeData(argumentType, argumentValue);
+ if (enumConstants.ContainsKey(enumValue))
+ {
+ // Not is a combinations of values.
+ return $"{typeFullName}.{enumConstants[enumValue]}";
+ }
+
+ var flagsEnumValues = enumConstants.Keys.Where(i => (enumValue & i) == i && i != 0).ToList();
+ var duplicateEnumValues = flagsEnumValues.Where(i => flagsEnumValues.Any(a => (a & i) == i && a > i));
+
+ flagsEnumValues.RemoveAll(i => duplicateEnumValues.Contains(i));
+ var flagsEnumNames = flagsEnumValues
+ .Select(i => $"{typeFullName}.{enumConstants[i]}")
+ .OrderBy(val => val) // to maintain a consistent list across frameworks/versions
+ .ToArray();
+
+ if (flagsEnumNames.Length > 0)
+ {
+ return string.Join(" | ", flagsEnumNames);
+ }
+
+ return ConvertToUnknownEnum(argumentType, argumentValue);
+ }
+
+ private string ConvertToApplePlatformEnum(TypeReference argumentType, object argumentValue)
+ {
+ (var typeFullName, var enumConstants, var enumValue) = ExtractEnumTypeData(argumentType, argumentValue);
+ if (enumConstants.ContainsKey(enumValue))
+ {
+ return typeFullName + "." + enumConstants[enumValue];
+ }
+
+ return FormatApplePlatformEnum(enumValue);
+ }
+
+ private (string typeFullName, IDictionary<long, string> enumConstants, long enumValue) ExtractEnumTypeData(TypeReference argumentType, object argumentValue)
+ {
+ var argumentTypeDefinition = argumentType.Resolve();
+ var typeFullName = MDocUpdater.GetDocTypeFullName(argumentTypeDefinition);
+ var enumConstants = GetEnumerationValues(argumentTypeDefinition);
+ var enumValue = ToInt64(argumentValue);
+
+ return (typeFullName, enumConstants, enumValue);
+ }
+
+ private string FormatApplePlatformEnum(long enumValue)
+ {
+ int iosarch, iosmajor, iosminor, iossubminor;
+ int macarch, macmajor, macminor, macsubminor;
+ GetEncodingiOS(enumValue, out iosarch, out iosmajor, out iosminor, out iossubminor);
+ GetEncodingMac((ulong)enumValue, out macarch, out macmajor, out macminor, out macsubminor);
+
+ if (iosmajor == 0 & iosminor == 0 && iossubminor == 0)
+ {
+ return FormatApplePlatformEnumValue("Mac", macarch, macmajor, macminor, macsubminor);
+ }
+
+ if (macmajor == 0 & macminor == 0 && macsubminor == 0)
+ {
+ return FormatApplePlatformEnumValue("iOS", iosarch, iosmajor, iosminor, iossubminor);
+ }
+
+ return string.Format("(Platform){0}", enumValue);
+ }
+
+ private string FormatApplePlatformEnumValue(string plat, int arch, int major, int minor, int subminor)
+ {
+ var archstring = string.Empty;
+ switch (arch)
+ {
+ case 1:
+ archstring = "32";
+ break;
+ case 2:
+ archstring = "64";
+ break;
+ }
+
+ return string.Format("Platform.{4}_{0}_{1}{2} | Platform.{4}_Arch{3}",
+ major,
+ minor,
+ subminor == 0 ? "" : "_" + subminor.ToString(),
+ archstring,
+ plat
+ );
+ }
+
+ private void GetEncodingiOS(long entireLong, out int archindex, out int major, out int minor, out int subminor)
+ {
+ long lowerBits = entireLong & 0xffffffff;
+ int lowerBitsAsInt = (int)lowerBits;
+ GetEncodingApplePlatform(lowerBitsAsInt, out archindex, out major, out minor, out subminor);
+ }
+
+ private void GetEncodingMac(ulong entireLong, out int archindex, out int major, out int minor, out int subminor)
+ {
+ ulong higherBits = entireLong & 0xffffffff00000000;
+ int higherBitsAsInt = (int)((higherBits) >> 32);
+ GetEncodingApplePlatform(higherBitsAsInt, out archindex, out major, out minor, out subminor);
+ }
+
+ private void GetEncodingApplePlatform(Int32 encodedBits, out int archindex, out int major, out int minor, out int subminor)
+ {
+ // format is AAJJNNSS
+ archindex = (int)((encodedBits & 0xFF000000) >> 24);
+ major = (int)((encodedBits & 0x00FF0000) >> 16);
+ minor = (int)((encodedBits & 0x0000FF00) >> 8);
+ subminor = (int)((encodedBits & 0x000000FF) >> 0);
+ }
+
+ private object GetArgumentValue(string argumentTypeFullName, TypeReference argumentType, object argumentValue)
+ {
+ if (argumentType.FullName.Equals(argumentTypeFullName))
+ {
+ return argumentValue;
+ }
+
+ throw new ArgumentException($"The argument type does not match {argumentTypeFullName}.");
+ }
+
+ private IDictionary<long, string> GetEnumerationValues(TypeDefinition argumentType)
+ {
+ var enumValues = from f in argumentType.Fields
+ where !(f.IsRuntimeSpecialName || f.IsSpecialName)
+ select f;
+
var values = new Dictionary<long, string>();
- foreach (var f in
- (from f in type.Fields
- where !(f.IsRuntimeSpecialName || f.IsSpecialName)
- select f))
+ foreach (var item in enumValues)
{
- values[ToInt64(f.Constant)] = f.Name;
+ values[ToInt64(item.Constant)] = item.Name;
}
+
return values;
}
- internal static long ToInt64(object value)
+ private long ToInt64(object value)
{
if (value is ulong)
return (long)(ulong)value;
+
return Convert.ToInt64(value);
}
- public static string FilterSpecialChars(string value)
+ private string FilterSpecialChars(string value)
{
- return value.Replace("\0", "\\0")
+ return value
+ .Replace("\0", "\\0")
.Replace("\t", "\\t")
.Replace("\n", "\\n")
.Replace("\r", "\\r")
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/DefaultAttributeValueFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/DefaultAttributeValueFormatter.cs
deleted file mode 100644
index d0a2f8ec..00000000
--- a/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/DefaultAttributeValueFormatter.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Mono.Documentation.Updater
-{
- /// <summary>The final value formatter in the pipeline ... if no other formatter formats the value,
- /// then this one will serve as the default implementation.</summary>
- class DefaultAttributeValueFormatter : AttributeValueFormatter
- {
- public override bool TryFormatValue (object v, ResolvedTypeInfo type, out string returnvalue)
- {
- returnvalue = "(" + MDocUpdater.GetDocTypeFullName (type.Reference) + ") " + FilterSpecialChars(v.ToString ());
- return true;
- }
- }
-} \ No newline at end of file
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/StandardFlagsEnumFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/StandardFlagsEnumFormatter.cs
deleted file mode 100644
index 16a1ebe0..00000000
--- a/mdoc/Mono.Documentation/Updater/Formatters/AttributeFormatters/StandardFlagsEnumFormatter.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Linq;
-
-using Mono.Cecil;
-
-namespace Mono.Documentation.Updater
-{
- /// <summary>Flags enum formatter that assumes powers of two values.</summary>
- /// <remarks>As described here: https://msdn.microsoft.com/en-us/library/vstudio/ms229062(v=vs.100).aspx</remarks>
- class StandardFlagsEnumFormatter : AttributeValueFormatter
- {
- public override bool TryFormatValue (object v, ResolvedTypeInfo type, out string returnvalue)
- {
- TypeReference valueType = type.Reference;
- TypeDefinition valueDef = type.Definition;
- if (valueDef.CustomAttributes.Any (ca => ca.AttributeType.FullName == "System.FlagsAttribute"))
- {
-
- string typename = MDocUpdater.GetDocTypeFullName (valueType);
- var values = GetEnumerationValues (valueDef);
- long c = ToInt64 (v);
- returnvalue = string.Join (" | ",
- (from i in values.Keys
- where (c & i) == i && i != 0
- select typename + "." + values[i])
- .DefaultIfEmpty (c.ToString ())
- .OrderBy (val => val) // to maintain a consistent list across frameworks/versions
- .ToArray ());
-
- return true;
- }
-
- returnvalue = null;
- return false;
- }
- }
-} \ No newline at end of file
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs
index 34749cc5..d0d674db 100644
--- a/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs
+++ b/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs
@@ -107,7 +107,7 @@ namespace Mono.Documentation.Updater.Formatters
return buf;
}
- protected override string GetTypeName (TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true)
+ protected override string GetTypeName (TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true, bool isTypeofOperator = false)
{
GenericInstanceType genType = type as GenericInstanceType;
if (IsSpecialGenericNullableValueType (genType))
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppFullMemberFormatter.cs
index 757b6431..1ae7b91a 100644
--- a/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppFullMemberFormatter.cs
+++ b/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppFullMemberFormatter.cs
@@ -553,7 +553,7 @@ namespace Mono.Documentation.Updater.Formatters.CppFormatters
return AppendConstraints (buf, method.GenericParameters);
}
- protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false)
+ protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false, bool isTypeofOperator = false)
{
List<TypeReference> decls = DocUtils.GetDeclaringTypes(
type is GenericInstanceType ? type.GetElementType() : type);
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/FSharpFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/FSharpFormatter.cs
index 0589c7f9..25b78bf8 100644
--- a/mdoc/Mono.Documentation/Updater/Formatters/FSharpFormatter.cs
+++ b/mdoc/Mono.Documentation/Updater/Formatters/FSharpFormatter.cs
@@ -308,7 +308,7 @@ namespace Mono.Documentation.Updater
return "class";
}
- protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false)
+ protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false, bool isTypeofOperator = false)
{
List<TypeReference> decls = DocUtils.GetDeclaringTypes(
type is GenericInstanceType ? type.GetElementType() : type);
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/ILFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/ILFullMemberFormatter.cs
index 1ad73548..ad30e238 100644
--- a/mdoc/Mono.Documentation/Updater/Formatters/ILFullMemberFormatter.cs
+++ b/mdoc/Mono.Documentation/Updater/Formatters/ILFullMemberFormatter.cs
@@ -203,7 +203,7 @@ namespace Mono.Documentation.Updater.Formatters
return buf.ToString ();
}
- protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false)
+ protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false, bool isTypeofOperator = false)
{
List<TypeReference> decls = DocUtils.GetDeclaringTypes (
type is GenericInstanceType ? type.GetElementType () : type);
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/JsFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/JsFormatter.cs
index 8664d1ba..dabceb3e 100644
--- a/mdoc/Mono.Documentation/Updater/Formatters/JsFormatter.cs
+++ b/mdoc/Mono.Documentation/Updater/Formatters/JsFormatter.cs
@@ -151,7 +151,7 @@ namespace Mono.Documentation.Updater.Formatters
return CamelCase(method.Name);
}
- protected override string GetTypeName(TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false)
+ protected override string GetTypeName(TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false, bool isTypeofOperator = false)
{
int n = type.Name.IndexOf("`");
if (n >= 0)
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/MemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/MemberFormatter.cs
index faf87874..d5f634e1 100644
--- a/mdoc/Mono.Documentation/Updater/Formatters/MemberFormatter.cs
+++ b/mdoc/Mono.Documentation/Updater/Formatters/MemberFormatter.cs
@@ -1,12 +1,10 @@
-using System;
+using Mono.Cecil;
+using Mono.Documentation.Util;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
-
-using Mono.Documentation.Util;
-using Mono.Cecil;
-
namespace Mono.Documentation.Updater
{
public abstract class MemberFormatter
@@ -25,16 +23,16 @@ namespace Mono.Documentation.Updater
get { return "//"; }
}
- public string GetName (MemberReference member, bool appendGeneric = true, bool useTypeProjection = true)
+ public string GetName (MemberReference member, bool appendGeneric = true, bool useTypeProjection = true, bool isTypeofOperator = false)
{
- return GetName (member, EmptyAttributeParserContext.Empty(), appendGeneric, useTypeProjection: useTypeProjection);
+ return GetName (member, EmptyAttributeParserContext.Empty(), appendGeneric, useTypeProjection, isTypeofOperator);
}
- public virtual string GetName (MemberReference member, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true)
+ public virtual string GetName (MemberReference member, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true, bool isTypeofOperator = false)
{
TypeReference type = member as TypeReference;
if (type != null)
- return GetTypeName (type, context, appendGeneric, useTypeProjection: useTypeProjection);
+ return GetTypeName (type, context, appendGeneric, useTypeProjection, isTypeofOperator);
MethodReference method = member as MethodReference;
if (method != null && method.Name == ".ctor") // method.IsConstructor
return GetConstructorName (method);
@@ -58,12 +56,12 @@ namespace Mono.Documentation.Updater
return GetTypeName (type, EmptyAttributeParserContext.Empty(), appendGeneric, useTypeProjection: useTypeProjection);
}
- protected virtual string GetTypeName (TypeReference type, IAttributeParserContext context, bool appendGeneric=true, bool useTypeProjection = true)
+ protected virtual string GetTypeName (TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true, bool isTypeofOperator = false)
{
if (type == null)
throw new ArgumentNullException (nameof (type));
- var typeName = _AppendTypeName (new StringBuilder (type.Name.Length), type, context, appendGeneric, useTypeProjection: useTypeProjection).ToString ();
+ var typeName = _AppendTypeName (new StringBuilder (type.Name.Length), type, context, appendGeneric, useTypeProjection, isTypeofOperator).ToString ();
return RemoveMod (typeName);
}
@@ -138,7 +136,7 @@ namespace Mono.Documentation.Updater
get => true;
}
- protected StringBuilder _AppendTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection =false)
+ protected StringBuilder _AppendTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false, bool isTypeofOperator = false)
{
if (type == null)
return buf;
@@ -206,7 +204,7 @@ namespace Mono.Documentation.Updater
AppendFullTypeName (interimBuilder, type, context);
return SetBuffer(buf, interimBuilder, useTypeProjection: useTypeProjection);
}
- AppendGenericType (interimBuilder, type, context, appendGeneric, useTypeProjection: useTypeProjection);
+ AppendGenericType (interimBuilder, type, context, appendGeneric, useTypeProjection, isTypeofOperator);
return SetBuffer(buf, interimBuilder, useTypeProjection: useTypeProjection);
}
@@ -320,7 +318,7 @@ namespace Mono.Documentation.Updater
get { return "."; }
}
- protected virtual StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true)
+ protected virtual StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true, bool isTypeofOperator = false)
{
int argIdx = 0;
int prev = 0;
@@ -344,22 +342,54 @@ namespace Mono.Documentation.Updater
if (appendGeneric && c > 0)
{
buf.Append (GenericTypeContainer[0]);
- var origState = MemberFormatterState;
- MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters;
- AppendGenericTypeParameter (buf, genArgs[argIdx++], context, useTypeProjection);
- for (int i = 1; i < c; ++i)
+
+ var currentTypeArguments = genArgs.Skip(argIdx).Take(c);
+ if (IsTypeOfOperatorWithUnboundGenericType(decl, currentTypeArguments, isTypeofOperator))
{
- buf.Append (",");
+ buf.Append(string.Join(string.Empty, Enumerable.Repeat(",", currentTypeArguments.Count() - 1)));
+ }
+ else
+ {
+ var origState = MemberFormatterState;
+ MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters;
AppendGenericTypeParameter (buf, genArgs[argIdx++], context, useTypeProjection);
+ for (int i = 1; i < c; ++i)
+ {
+ buf.Append (",");
+ AppendGenericTypeParameter (buf, genArgs[argIdx++], context, useTypeProjection);
+ }
+
+ MemberFormatterState = origState;
}
- MemberFormatterState = origState;
buf.Append (GenericTypeContainer[1]);
}
}
+
return buf;
}
+ private bool IsTypeOfOperatorWithUnboundGenericType(TypeReference type, IEnumerable<TypeReference> genericArguments, bool isTypeofOperator)
+ {
+ if (isTypeofOperator)
+ {
+ var argumentCount = genericArguments.Count() > 0 ? genericArguments.Count().ToString() : string.Empty;
+ var genericTypeSeparator = $"`{argumentCount}";
+ var genericTypeSeparatorIndex = type.FullName.LastIndexOf(genericTypeSeparator);
+
+ var leftAngleBracketIndex = type.FullName.IndexOf("<", genericTypeSeparatorIndex);
+ var validLeftAngleBracketIndex = genericTypeSeparatorIndex + genericTypeSeparator.Length + 1;
+
+ // If the type is an unbound generic type that type hasn't angle brackets after its full name.
+ var notExistParameterType = genericTypeSeparatorIndex >= 0 && leftAngleBracketIndex != validLeftAngleBracketIndex;
+ var notPassParameterType = genericArguments.All(i => i is GenericParameter);
+
+ return notExistParameterType && notPassParameterType;
+ }
+
+ return false;
+ }
+
private void AppendGenericTypeParameter (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool useTypeProjection = true)
{
var isNullableType = false;
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/SlashDocMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/SlashDocMemberFormatter.cs
index 4bb986fc..2a5dfa51 100644
--- a/mdoc/Mono.Documentation/Updater/Formatters/SlashDocMemberFormatter.cs
+++ b/mdoc/Mono.Documentation/Updater/Formatters/SlashDocMemberFormatter.cs
@@ -102,7 +102,7 @@ namespace Mono.Documentation.Updater
return buf.Append (ArrayDelimeters[1]);
}
- protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false)
+ protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false, bool isTypeofOperator = false)
{
if (!AddTypeCount)
base.AppendGenericType (buf, type, context);
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/VBFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/VBFullMemberFormatter.cs
index 92a74cec..6d9761f8 100644
--- a/mdoc/Mono.Documentation/Updater/Formatters/VBFullMemberFormatter.cs
+++ b/mdoc/Mono.Documentation/Updater/Formatters/VBFullMemberFormatter.cs
@@ -209,7 +209,7 @@ namespace Mono.Documentation.Updater
}
}
- protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false)
+ protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false, bool isTypeofOperator = false)
{
List<TypeReference> decls = DocUtils.GetDeclaringTypes(
type is GenericInstanceType ? type.GetElementType() : type);
diff --git a/mdoc/Mono.Documentation/Updater/ResolvedTypeInfo.cs b/mdoc/Mono.Documentation/Updater/ResolvedTypeInfo.cs
deleted file mode 100644
index 0db9b6da..00000000
--- a/mdoc/Mono.Documentation/Updater/ResolvedTypeInfo.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-
-using Mono.Cecil;
-
-namespace Mono.Documentation.Updater
-{
- class ResolvedTypeInfo
- {
- TypeDefinition typeDef;
-
- public ResolvedTypeInfo (TypeReference value)
- {
- Reference = value;
- }
-
- public TypeReference Reference { get; private set; }
-
- public TypeDefinition Definition
- {
- get
- {
- if (typeDef == null)
- {
- typeDef = Reference.Resolve ();
- }
- return typeDef;
- }
- }
- }
-} \ No newline at end of file
diff --git a/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Circle.xml b/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Circle.xml
index 0df6e8c0..1cf1d136 100644
--- a/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Circle.xml
+++ b/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Circle.xml
@@ -16,8 +16,8 @@
<AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerDisplay("{__DebugDisplay(),nq}")&gt;]</AttributeName>
</Attribute>
<Attribute>
- <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions/Shape/Circle@DebugTypeProxy))]</AttributeName>
- <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions/Shape/Circle@DebugTypeProxy))&gt;]</AttributeName>
+ <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions+Shape+Circle@DebugTypeProxy))]</AttributeName>
+ <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions+Shape+Circle@DebugTypeProxy))&gt;]</AttributeName>
</Attribute>
<Attribute>
<AttributeName Language="C#">[System.Serializable]</AttributeName>
diff --git a/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Prism.xml b/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Prism.xml
index 6b82ea56..d692ac3a 100644
--- a/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Prism.xml
+++ b/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Prism.xml
@@ -16,8 +16,8 @@
<AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerDisplay("{__DebugDisplay(),nq}")&gt;]</AttributeName>
</Attribute>
<Attribute>
- <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions/Shape/Prism@DebugTypeProxy))]</AttributeName>
- <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions/Shape/Prism@DebugTypeProxy))&gt;]</AttributeName>
+ <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions+Shape+Prism@DebugTypeProxy))]</AttributeName>
+ <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions+Shape+Prism@DebugTypeProxy))&gt;]</AttributeName>
</Attribute>
<Attribute>
<AttributeName Language="C#">[System.Serializable]</AttributeName>
diff --git a/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Rectangle.xml b/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Rectangle.xml
index af196c39..fe657c9b 100644
--- a/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Rectangle.xml
+++ b/mdoc/Test/en.expected-fsharp/DiscriminatedUnions+Shape+Rectangle.xml
@@ -16,8 +16,8 @@
<AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerDisplay("{__DebugDisplay(),nq}")&gt;]</AttributeName>
</Attribute>
<Attribute>
- <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions/Shape/Rectangle@DebugTypeProxy))]</AttributeName>
- <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions/Shape/Rectangle@DebugTypeProxy))&gt;]</AttributeName>
+ <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions+Shape+Rectangle@DebugTypeProxy))]</AttributeName>
+ <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(DiscriminatedUnions+Shape+Rectangle@DebugTypeProxy))&gt;]</AttributeName>
</Attribute>
<Attribute>
<AttributeName Language="C#">[System.Serializable]</AttributeName>
diff --git a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+FirstLast.xml b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+FirstLast.xml
index b7b7a2de..e31b131c 100644
--- a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+FirstLast.xml
+++ b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+FirstLast.xml
@@ -16,8 +16,8 @@
<AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerDisplay("{__DebugDisplay(),nq}")&gt;]</AttributeName>
</Attribute>
<Attribute>
- <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples/PersonName/FirstLast@DebugTypeProxy))]</AttributeName>
- <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples/PersonName/FirstLast@DebugTypeProxy))&gt;]</AttributeName>
+ <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples+PersonName+FirstLast@DebugTypeProxy))]</AttributeName>
+ <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples+PersonName+FirstLast@DebugTypeProxy))&gt;]</AttributeName>
</Attribute>
<Attribute>
<AttributeName Language="C#">[System.Serializable]</AttributeName>
diff --git a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+FirstOnly.xml b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+FirstOnly.xml
index c50cd03a..8bc63289 100644
--- a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+FirstOnly.xml
+++ b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+FirstOnly.xml
@@ -16,8 +16,8 @@
<AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerDisplay("{__DebugDisplay(),nq}")&gt;]</AttributeName>
</Attribute>
<Attribute>
- <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples/PersonName/FirstOnly@DebugTypeProxy))]</AttributeName>
- <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples/PersonName/FirstOnly@DebugTypeProxy))&gt;]</AttributeName>
+ <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples+PersonName+FirstOnly@DebugTypeProxy))]</AttributeName>
+ <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples+PersonName+FirstOnly@DebugTypeProxy))&gt;]</AttributeName>
</Attribute>
<Attribute>
<AttributeName Language="C#">[System.Serializable]</AttributeName>
diff --git a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+LastOnly.xml b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+LastOnly.xml
index 9039e514..b9346976 100644
--- a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+LastOnly.xml
+++ b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+PersonName+LastOnly.xml
@@ -16,8 +16,8 @@
<AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerDisplay("{__DebugDisplay(),nq}")&gt;]</AttributeName>
</Attribute>
<Attribute>
- <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples/PersonName/LastOnly@DebugTypeProxy))]</AttributeName>
- <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples/PersonName/LastOnly@DebugTypeProxy))&gt;]</AttributeName>
+ <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples+PersonName+LastOnly@DebugTypeProxy))]</AttributeName>
+ <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples+PersonName+LastOnly@DebugTypeProxy))&gt;]</AttributeName>
</Attribute>
<Attribute>
<AttributeName Language="C#">[System.Serializable]</AttributeName>
diff --git a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+Shape+Circle.xml b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+Shape+Circle.xml
index 538409b3..cfc60932 100644
--- a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+Shape+Circle.xml
+++ b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+Shape+Circle.xml
@@ -16,8 +16,8 @@
<AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerDisplay("{__DebugDisplay(),nq}")&gt;]</AttributeName>
</Attribute>
<Attribute>
- <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples/Shape/Circle@DebugTypeProxy))]</AttributeName>
- <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples/Shape/Circle@DebugTypeProxy))&gt;]</AttributeName>
+ <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples+Shape+Circle@DebugTypeProxy))]</AttributeName>
+ <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples+Shape+Circle@DebugTypeProxy))&gt;]</AttributeName>
</Attribute>
<Attribute>
<AttributeName Language="C#">[System.Serializable]</AttributeName>
diff --git a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+Shape+Rectangle.xml b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+Shape+Rectangle.xml
index f22cf1ab..418a8add 100644
--- a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+Shape+Rectangle.xml
+++ b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples+Shape+Rectangle.xml
@@ -16,8 +16,8 @@
<AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerDisplay("{__DebugDisplay(),nq}")&gt;]</AttributeName>
</Attribute>
<Attribute>
- <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples/Shape/Rectangle@DebugTypeProxy))]</AttributeName>
- <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples/Shape/Rectangle@DebugTypeProxy))&gt;]</AttributeName>
+ <AttributeName Language="C#">[System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples+Shape+Rectangle@DebugTypeProxy))]</AttributeName>
+ <AttributeName Language="F#">[&lt;System.Diagnostics.DebuggerTypeProxy(typeof(PatternMatching.PatternMatchingExamples+Shape+Rectangle@DebugTypeProxy))&gt;]</AttributeName>
</Attribute>
<Attribute>
<AttributeName Language="C#">[System.Serializable]</AttributeName>
diff --git a/mdoc/mdoc.Test/AttributeValueFormatterTest.cs b/mdoc/mdoc.Test/AttributeValueFormatterTest.cs
new file mode 100644
index 00000000..78d93872
--- /dev/null
+++ b/mdoc/mdoc.Test/AttributeValueFormatterTest.cs
@@ -0,0 +1,168 @@
+using mdoc.Test.SampleClasses;
+using Mono.Cecil;
+using Mono.Documentation.Updater;
+using Mono.Documentation.Updater.Formatters;
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace mdoc.Test
+{
+ [TestFixture()]
+ public class AttributeValueFormatterTest : BasicTests
+ {
+ [TestCase("PropertyTypeType", "typeof(Mono.Cecil.TypeReference)")]
+ [TestCase("PropertyTypeTypeWithNull", "null")]
+ [TestCase("PropertyTypeTypeWithNestedType", "typeof(mdoc.Test.SampleClasses.SomeNestedTypes+NestedClass)")]
+ [TestCase("PropertyTypeTypeWithUnboundCollection", "typeof(System.Collections.Generic.ICollection<>)")]
+ [TestCase("PropertyTypeTypeWithCollectionOfInt", "typeof(System.Collections.Generic.ICollection<System.Int32>)")]
+ [TestCase("PropertyTypeTypeWithUnboundDictionary", "typeof(System.Collections.Generic.IDictionary<,>)")]
+ [TestCase("PropertyTypeTypeWithDictionaryOfInt", "typeof(System.Collections.Generic.IDictionary<System.Int32,System.Int32>)")]
+ [TestCase("PropertyTypeTypeWithUnboundCustomGenericType", "typeof(mdoc.Test.SampleClasses.SomeGenericClass<>)")]
+ [TestCase("PropertyTypeTypeWithCustomGenericTypeOfInt", "typeof(mdoc.Test.SampleClasses.SomeGenericClass<System.Int32>)")]
+ [TestCase("PropertyTypeTypeWithUnboundNestedGenericType", "typeof(mdoc.Test.SampleClasses.SomeNestedTypes+NestedGenericType<>)")]
+ [TestCase("PropertyTypeTypeWithNestedGenericTypeOfInt", "typeof(mdoc.Test.SampleClasses.SomeNestedTypes+NestedGenericType<System.Int32>)")]
+ [TestCase("PropertyTypeTypeWithUnboundInnerNestedGenericType", "typeof(mdoc.Test.SampleClasses.SomeNestedTypes+NestedGenericType<>+InnerNestedGenericType<>)")]
+ [TestCase("PropertyTypeTypeWithInnerNestedGenericTypeOfInt", "typeof(mdoc.Test.SampleClasses.SomeNestedTypes+NestedGenericType<System.String>+InnerNestedGenericType<System.Int32>)")]
+ [TestCase("PropertyBoolType", "true")]
+ [TestCase("PropertySByteType", SByte.MinValue)]
+ [TestCase("PropertyByteType", Byte.MaxValue)]
+ [TestCase("PropertyInt16Type", Int16.MinValue)]
+ [TestCase("PropertyUInt16Type", UInt16.MaxValue)]
+ [TestCase("PropertyInt32Type", Int32.MinValue)]
+ [TestCase("PropertyUInt32Type", UInt32.MaxValue)]
+ [TestCase("PropertyInt64Type", Int64.MinValue)]
+ [TestCase("PropertyUInt64Type", UInt64.MaxValue)]
+ [TestCase("PropertySingleType", Single.MinValue)]
+ [TestCase("PropertyDoubleType", Double.MinValue)]
+ [TestCase("PropertyCharType", "'C'")]
+ [TestCase("PropertyStringType", "\"This is a string argument.\"")]
+ [TestCase("PropertyStringTypeWithEmptyString", "\"\"")]
+ [TestCase("PropertyStringTypeWithNull", "null")]
+ [TestCase("PropertyEnumType", "System.ConsoleColor.Red")]
+ [TestCase("PropertyEnumTypeWithUnknownValue", "(System.ConsoleColor) 2147483647")]
+ [TestCase("PropertyNestedEnumType", "mdoc.Test.SampleClasses.SomeNestedTypes+NestedEnum.Read")]
+ [TestCase("PropertyNestedEnumTypeWithUnknownValue", "(mdoc.Test.SampleClasses.SomeNestedTypes+NestedEnum) 2147483647")]
+ [TestCase("PropertyFlagsEnumType", "System.AttributeTargets.Class | System.AttributeTargets.Enum")]
+ [TestCase("PropertyFlagsEnumTypeWithAllValue", "System.AttributeTargets.All")]
+ [TestCase("PropertyFlagsEnumTypeWithUndefineValueZero", "(System.AttributeTargets) 0")]
+ [TestCase("PropertyDuplicateFlagsEnumTypeWithCombinationValue", "mdoc.Test.SampleClasses.SomeFlagsEnum.Open | mdoc.Test.SampleClasses.SomeFlagsEnum.ReadWrite")]
+ [TestCase("PropertyNestedFlagsEnumType", "mdoc.Test.SampleClasses.SomeNestedTypes+NestedFlagsEnum.Class | mdoc.Test.SampleClasses.SomeNestedTypes+NestedFlagsEnum.Enum")]
+ [TestCase("PropertyNestedFlagsEnumTypeWithUndefineValueZero", "(mdoc.Test.SampleClasses.SomeNestedTypes+NestedFlagsEnum) 0")]
+ [TestCase("PropertyFlagsEnumTypeWithNotApplyAttributeValidTypeAndCombinationValue", "mdoc.Test.SampleClasses.NotApplyAttributeValidFlagsEnum.Class | mdoc.Test.SampleClasses.NotApplyAttributeValidFlagsEnum.Enum")]
+ [TestCase("PropertyFlagsEnumTypeWithNotApplyAttributeValidTypeAndSingleValue", "mdoc.Test.SampleClasses.NotApplyAttributeValidFlagsEnum.Class")]
+ [TestCase("PropertyFlagsEnumTypeWithNotApplyAttributeInvalidTypeAndUnknownCombinationValue", "(mdoc.Test.SampleClasses.NotApplyAttributeInvalidFlagsEnum) 5")]
+ [TestCase("PropertyFlagsEnumTypeWithApplePlatformType", "Platform.Mac_10_8 | Platform.Mac_Arch64")]
+ [TestCase("PropertyFlagsEnumTypeWithApplePlatformAndNoneValue", "ObjCRuntime.Platform.None")]
+ [TestCase("PropertyArrayOfIntType", "new System.Int32[] { 0, 0, 7 }")]
+ [TestCase("PropertyArrayOfIntTypeWithNull", "null")]
+ [TestCase("PropertyObjectWithNull", "null")]
+ [TestCase("PropertyObjectWithTypeType", "typeof(Mono.Cecil.TypeReference)")]
+ [TestCase("PropertyObjectWithNestedTypeType", "typeof(mdoc.Test.SampleClasses.SomeNestedTypes+NestedClass)")]
+ [TestCase("PropertyObjectWithUnboundCollectionType", "typeof(System.Collections.Generic.ICollection<>)")]
+ [TestCase("PropertyObjectWithCollectionTypeOfInt", "typeof(System.Collections.Generic.ICollection<System.Int32>)")]
+ [TestCase("PropertyObjectWithUnboundDictionaryType", "typeof(System.Collections.Generic.IDictionary<,>)")]
+ [TestCase("PropertyObjectWithDictionaryTypeOfInt", "typeof(System.Collections.Generic.IDictionary<System.Int32,System.Int32>)")]
+ [TestCase("PropertyObjectWithUnboundCustomGenericType", "typeof(mdoc.Test.SampleClasses.SomeGenericClass<>)")]
+ [TestCase("PropertyObjectWithCustomGenericTypeOfInt", "typeof(mdoc.Test.SampleClasses.SomeGenericClass<System.Int32>)")]
+ [TestCase("PropertyObjectWithUnboundNestedGenericType", "typeof(mdoc.Test.SampleClasses.SomeNestedTypes+NestedGenericType<>)")]
+ [TestCase("PropertyObjectWithNestedGenericTypeOfInt", "typeof(mdoc.Test.SampleClasses.SomeNestedTypes+NestedGenericType<System.Int32>)")]
+ [TestCase("PropertyObjectWithUnboundInnerNestedGenericType", "typeof(mdoc.Test.SampleClasses.SomeNestedTypes+NestedGenericType<>+InnerNestedGenericType<>)")]
+ [TestCase("PropertyObjectWithInnerNestedGenericTypeOfInt", "typeof(mdoc.Test.SampleClasses.SomeNestedTypes+NestedGenericType<System.String>+InnerNestedGenericType<System.Int32>)")]
+ [TestCase("PropertyObjectWithBoolType", "true")]
+ [TestCase("PropertyObjectWithSByteType", SByte.MinValue)]
+ [TestCase("PropertyObjectWithByteType", Byte.MaxValue)]
+ [TestCase("PropertyObjectWithInt16Type", Int16.MinValue)]
+ [TestCase("PropertyObjectWithUInt16Type", UInt16.MaxValue)]
+ [TestCase("PropertyObjectWithInt32Type", Int32.MinValue)]
+ [TestCase("PropertyObjectWithUInt32Type", UInt32.MaxValue)]
+ [TestCase("PropertyObjectWithInt64Type", Int64.MinValue)]
+ [TestCase("PropertyObjectWithUInt64Type", UInt64.MaxValue)]
+ [TestCase("PropertyObjectWithSingleType", Single.MinValue)]
+ [TestCase("PropertyObjectWithDoubleType", Double.MinValue)]
+ [TestCase("PropertyObjectWithCharType", "'C'")]
+ [TestCase("PropertyObjectWithStringType", "\"This is a string argument.\"")]
+ [TestCase("PropertyObjectWithStringTypeAndEmptyString", "\"\"")]
+ [TestCase("PropertyObjectWithEnumType", "System.ConsoleColor.Red")]
+ [TestCase("PropertyObjectWithEnumTypeAndUnknownValue", "(System.ConsoleColor) 2147483647")]
+ [TestCase("PropertyObjectWithNestedEnumType", "mdoc.Test.SampleClasses.SomeNestedTypes+NestedEnum.Read")]
+ [TestCase("PropertyObjectWithNestedEnumTypeAndUnknownValue", "(mdoc.Test.SampleClasses.SomeNestedTypes+NestedEnum) 2147483647")]
+ [TestCase("PropertyObjectWithFlagsEnumType", "System.AttributeTargets.Class | System.AttributeTargets.Enum")]
+ [TestCase("PropertyObjectWithFlagsEnumTypeAndAllValue", "System.AttributeTargets.All")]
+ [TestCase("PropertyObjectWithFlagsEnumTypeAndUndefineValueZero", "(System.AttributeTargets) 0")]
+ [TestCase("PropertyObjectWithDuplicateFlagsEnumTypeAndCombinationValue", "mdoc.Test.SampleClasses.SomeFlagsEnum.Open | mdoc.Test.SampleClasses.SomeFlagsEnum.ReadWrite")]
+ [TestCase("PropertyObjectWithNestedFlagsEnumType", "mdoc.Test.SampleClasses.SomeNestedTypes+NestedFlagsEnum.Class | mdoc.Test.SampleClasses.SomeNestedTypes+NestedFlagsEnum.Enum")]
+ [TestCase("PropertyObjectWithNestedFlagsEnumTypeAndUndefineValueZero", "(mdoc.Test.SampleClasses.SomeNestedTypes+NestedFlagsEnum) 0")]
+ [TestCase("PropertyObjectWithNotApplyAttributeValidFlagsEnumTypeAndCombinationValue", "mdoc.Test.SampleClasses.NotApplyAttributeValidFlagsEnum.Class | mdoc.Test.SampleClasses.NotApplyAttributeValidFlagsEnum.Enum")]
+ [TestCase("PropertyObjectWithNotApplyAttributeValidFlagsEnumTypeAndSingleValue", "mdoc.Test.SampleClasses.NotApplyAttributeValidFlagsEnum.Class")]
+ [TestCase("PropertyObjectWithNotApplyAttributeInvalidFlagsEnumTypeAndUnknownCombinationValue", "(mdoc.Test.SampleClasses.NotApplyAttributeInvalidFlagsEnum) 5")]
+ [TestCase("PropertyObjectWithApplePlatformFlagsEnumType", "Platform.Mac_10_8 | Platform.Mac_Arch64")]
+ [TestCase("PropertyObjectWithApplePlatformFlagsEnumTypeAndNoneValue", "ObjCRuntime.Platform.None")]
+ [TestCase("PropertyObjectWithArrayOfIntType", "new System.Int32[] { 0, 0, 7 }")]
+ public void TestFormatValueWithDifferentTypes(string methodName, object argumentValue)
+ {
+ TestAttributeValueFormatter(typeof(SomeAttribute), methodName, argumentValue);
+ }
+
+ [TestCase("GetEnumerator", "typeof(mdoc.Test.SampleClasses.SomeIteratorStateMachine<,>+<GetEnumerator>d__0)", typeof(SomeIteratorStateMachine<,>))]
+ [TestCase("GetEnumerator", "typeof(mdoc.Test.SampleClasses.SomeIteratorStateMachine<,>+SomeNestedIteratorStateMachine<,>+<GetEnumerator>d__0)", typeof(SomeIteratorStateMachine<,>.SomeNestedIteratorStateMachine<,>))]
+ [TestCase("WithParameterType", "typeof(mdoc.Test.SampleClasses.SomeIteratorStateMachine<,>+<WithParameterType>d__2<,>)", typeof(SomeIteratorStateMachine<,>))]
+ [TestCase("WithParameterType", "typeof(mdoc.Test.SampleClasses.SomeIteratorStateMachine<,>+SomeNestedIteratorStateMachine<,>+<WithParameterType>d__2<,>)", typeof(SomeIteratorStateMachine<,>.SomeNestedIteratorStateMachine<,>))]
+ public void TestFormartValueWithIteratorStateMachineAttribute(string methodName, object argumentValue, Type type)
+ {
+ TestAttributeValueFormatter(type, methodName, argumentValue);
+ }
+
+ private void TestAttributeValueFormatter(Type type, string memberName, object expectedValue)
+ {
+ var (argumentType, argumentValue) = GetAttributeArguments(type, memberName);
+
+ var attributeFormatter = new AttributeValueFormatter();
+ var formatValue = attributeFormatter.Format(argumentType, argumentValue);
+
+ Assert.AreEqual(expectedValue.ToString(), formatValue);
+ }
+
+ private (TypeReference argumentType, object argumentValue) GetAttributeArguments(Type type, string memberName)
+ {
+ var methodDefinition = GetMethod(type, memberName);
+ var methodAttribute = AttributeFormatter.GetCustomAttributes(methodDefinition).First();
+ CustomAttribute customAttribute = methodAttribute.Item1;
+
+ var customAttributeList = new List<(TypeReference, object)>();
+ for (int i = 0; i < customAttribute.ConstructorArguments.Count; ++i)
+ {
+ customAttributeList.Add((customAttribute.ConstructorArguments[i].Type, customAttribute.ConstructorArguments[i].Value));
+ }
+
+ foreach (var item in GetAttributeArgumentsFromFieldsAndProperties(customAttribute))
+ {
+ customAttributeList.Add((item.argumentType, item.argumentValue));
+ }
+
+ return customAttributeList.First();
+ }
+
+ private IEnumerable<(string argumentName, TypeReference argumentType, object argumentValue)> GetAttributeArgumentsFromFieldsAndProperties(CustomAttribute customAttribute)
+ {
+ return (from namedArg in customAttribute.Fields
+ select (namedArg.Name, namedArg.Argument.Type, namedArg.Argument.Value))
+ .Concat(from namedArg in customAttribute.Properties
+ select (namedArg.Name, namedArg.Argument.Type, namedArg.Argument.Value))
+ .OrderBy(v => v.Name);
+ }
+
+ protected override TypeDefinition GetType(Type type)
+ {
+ var moduleName = type.Module.FullyQualifiedName;
+ return GetType(moduleName, ConvertNestedTypeFullName(type.FullName));
+ }
+
+ private string ConvertNestedTypeFullName(string fullName)
+ {
+ // Simply of implementation for help nested class convert the full name from .NET style to mono.cecil style.
+ return fullName.Replace("+", "/");
+ }
+ }
+}
diff --git a/mdoc/mdoc.Test/SampleClasses/ApplePlatformEnum.cs b/mdoc/mdoc.Test/SampleClasses/ApplePlatformEnum.cs
new file mode 100644
index 00000000..490c7978
--- /dev/null
+++ b/mdoc/mdoc.Test/SampleClasses/ApplePlatformEnum.cs
@@ -0,0 +1,48 @@
+using System;
+
+namespace ObjCRuntime
+{
+ [Flags]
+ public enum Platform : ulong
+ {
+ None = 0,
+ iOS_2_0 = 0x0000000000020000,
+ iOS_2_2 = 0x0000000000020200,
+ iOS_3_0 = 0x0000000000030000,
+ iOS_3_1 = 0x0000000000030100,
+ iOS_3_2 = 0x0000000000030200,
+ iOS_4_0 = 0x0000000000040000,
+ iOS_4_1 = 0x0000000000040100,
+ iOS_4_2 = 0x0000000000040200,
+ iOS_4_3 = 0x0000000000040300,
+ iOS_5_0 = 0x0000000000050000,
+ iOS_5_1 = 0x0000000000050100,
+ iOS_6_0 = 0x0000000000060000,
+ iOS_6_1 = 0x0000000000060100,
+ iOS_7_0 = 0x0000000000070000,
+ iOS_7_1 = 0x0000000000070100,
+ iOS_8_0 = 0x0000000000080000,
+ iOS_8_1 = 0x0000000000080100,
+ iOS_8_2 = 0x0000000000080200,
+ iOS_8_3 = 0x0000000000080300,
+ Mac_10_0 = 0x000A000000000000,
+ Mac_10_1 = 0x000A010000000000,
+ Mac_10_2 = 0x000A020000000000,
+ Mac_10_3 = 0x000A030000000000,
+ Mac_10_4 = 0x000A040000000000,
+ Mac_10_5 = 0x000A050000000000,
+ Mac_10_6 = 0x000A060000000000,
+ Mac_10_7 = 0x000A070000000000,
+ Mac_10_8 = 0x000A080000000000,
+ Mac_10_9 = 0x000A090000000000,
+ Mac_10_10 = 0x000A0A0000000000,
+ iOS_Version = 0x0000000000FFFFFF,
+ Mac_Version = 0x00FFFFFF00000000,
+ Mac_Arch32 = 0x0100000000000000,
+ Mac_Arch64 = 0x0200000000000000,
+ Mac_Arch = 0xFF00000000000000,
+ iOS_Arch32 = 0x0000000001000000,
+ iOS_Arch64 = 0x0000000002000000,
+ iOS_Arch = 0x00000000FF000000
+ }
+}
diff --git a/mdoc/mdoc.Test/SampleClasses/AttributeDataTypeAttribute.cs b/mdoc/mdoc.Test/SampleClasses/AttributeDataTypeAttribute.cs
new file mode 100644
index 00000000..ce49992e
--- /dev/null
+++ b/mdoc/mdoc.Test/SampleClasses/AttributeDataTypeAttribute.cs
@@ -0,0 +1,57 @@
+using System;
+
+namespace mdoc.Test.SampleClasses
+{
+ public class AttributeDataTypeAttribute : Attribute
+ {
+ public object ObjectType { get; set; }
+
+ public Type TypeType { get; set; }
+
+ public bool BoolType { get; set; }
+
+ public SByte SByteType { get; set; }
+
+ public Byte ByteType { get; set; }
+
+ public Int16 Int16Type { get; set; }
+
+ public UInt16 UInt16Type { get; set; }
+
+ public Int32 Int32Type { get; set; }
+
+ public Int32? NullableOfInt32Type { get; set; }
+
+ public UInt32 UInt32Type { get; set; }
+
+ public Int64 Int64Type { get; set; }
+
+ public UInt64 UInt64Type { get; set; }
+
+ public Single SingleType { get; set; }
+
+ public Double DoubleType { get; set; }
+
+ public char CharType { get; set; }
+
+ public string StringType { get; set; }
+
+ public int[] ArrayOfIntType { get; set; }
+
+ public ConsoleColor EnumType { get; set; }
+
+ public SomeNestedTypes.NestedEnum NestedEnumType { get; set; }
+
+ public SomeNestedTypes.NestedFlagsEnum NestedFlagsEnumType { get; set; }
+
+ public SomeFlagsEnum DuplicateFlagsEnumType { get; set; }
+
+ public AttributeTargets FlagsEnumType { get; set; }
+
+ public NotApplyAttributeValidFlagsEnum NotApplyAttributeFlagsEnumType { get; set; }
+
+ public NotApplyAttributeInvalidFlagsEnum NotApplyAttributeInvalidFlagsEnumType { get; set; }
+
+ public ObjCRuntime.Platform ApplePlatformFlagsEnumType { get; set; }
+ }
+}
diff --git a/mdoc/mdoc.Test/SampleClasses/NotApplyAttributeInvalidFlagsEnum.cs b/mdoc/mdoc.Test/SampleClasses/NotApplyAttributeInvalidFlagsEnum.cs
new file mode 100644
index 00000000..e0ad0455
--- /dev/null
+++ b/mdoc/mdoc.Test/SampleClasses/NotApplyAttributeInvalidFlagsEnum.cs
@@ -0,0 +1,10 @@
+namespace mdoc.Test.SampleClasses
+{
+ public enum NotApplyAttributeInvalidFlagsEnum
+ {
+ None = 0,
+ Read = 1,
+ Write = 2,
+ ReadWrite = 3
+ }
+}
diff --git a/mdoc/mdoc.Test/SampleClasses/NotApplyAttributeValidFlagsEnum.cs b/mdoc/mdoc.Test/SampleClasses/NotApplyAttributeValidFlagsEnum.cs
new file mode 100644
index 00000000..de4fa77e
--- /dev/null
+++ b/mdoc/mdoc.Test/SampleClasses/NotApplyAttributeValidFlagsEnum.cs
@@ -0,0 +1,12 @@
+namespace mdoc.Test.SampleClasses
+{
+ public enum NotApplyAttributeValidFlagsEnum
+ {
+ None = 0,
+ Assembly = 1,
+ Module = 2,
+ Class = 4,
+ Struct = 8,
+ Enum = 16
+ }
+}
diff --git a/mdoc/mdoc.Test/SampleClasses/SomeAttribute.cs b/mdoc/mdoc.Test/SampleClasses/SomeAttribute.cs
new file mode 100644
index 00000000..2b7850ce
--- /dev/null
+++ b/mdoc/mdoc.Test/SampleClasses/SomeAttribute.cs
@@ -0,0 +1,450 @@
+using Mono.Cecil;
+using System;
+using System.Collections.Generic;
+
+namespace mdoc.Test.SampleClasses
+{
+ public class SomeAttribute
+ {
+ [AttributeDataType(TypeType = typeof(TypeReference))]
+ public void PropertyTypeType()
+ {
+ }
+
+ [AttributeDataType(TypeType = null)]
+ public void PropertyTypeTypeWithNull()
+ {
+ }
+
+ [AttributeDataType(TypeType = typeof(SomeNestedTypes.NestedClass))]
+ public void PropertyTypeTypeWithNestedType()
+ {
+ }
+
+ [AttributeDataType(TypeType = typeof(ICollection<>))]
+ public void PropertyTypeTypeWithUnboundCollection()
+ {
+ }
+
+ [AttributeDataType(TypeType = typeof(ICollection<int>))]
+ public void PropertyTypeTypeWithCollectionOfInt()
+ {
+ }
+
+ [AttributeDataType(TypeType = typeof(IDictionary<,>))]
+ public void PropertyTypeTypeWithUnboundDictionary()
+ {
+ }
+
+ [AttributeDataType(TypeType = typeof(IDictionary<int, int>))]
+ public void PropertyTypeTypeWithDictionaryOfInt()
+ {
+ }
+
+ [AttributeDataType(TypeType = typeof(SomeGenericClass<>))]
+ public void PropertyTypeTypeWithUnboundCustomGenericType()
+ {
+ }
+
+ [AttributeDataType(TypeType = typeof(SomeGenericClass<int>))]
+ public void PropertyTypeTypeWithCustomGenericTypeOfInt()
+ {
+ }
+
+ [AttributeDataType(TypeType = typeof(SomeNestedTypes.NestedGenericType<>))]
+ public void PropertyTypeTypeWithUnboundNestedGenericType()
+ {
+ }
+
+ [AttributeDataType(TypeType = typeof(SomeNestedTypes.NestedGenericType<int>))]
+ public void PropertyTypeTypeWithNestedGenericTypeOfInt()
+ {
+ }
+
+
+ [AttributeDataType(TypeType = typeof(SomeNestedTypes.NestedGenericType<>.InnerNestedGenericType<>))]
+ public void PropertyTypeTypeWithUnboundInnerNestedGenericType()
+ {
+ }
+
+ [AttributeDataType(TypeType = typeof(SomeNestedTypes.NestedGenericType<string>.InnerNestedGenericType<int>))]
+ public void PropertyTypeTypeWithInnerNestedGenericTypeOfInt()
+ {
+ }
+
+ [AttributeDataType(BoolType = true)]
+ public void PropertyBoolType()
+ {
+ }
+
+ [AttributeDataType(SByteType = SByte.MinValue)]
+ public void PropertySByteType()
+ {
+ }
+
+ [AttributeDataType(ByteType = Byte.MaxValue)]
+ public void PropertyByteType()
+ {
+ }
+
+ [AttributeDataType(Int16Type = Int16.MinValue)]
+ public void PropertyInt16Type()
+ {
+ }
+
+ [AttributeDataType(UInt16Type = UInt16.MaxValue)]
+ public void PropertyUInt16Type()
+ {
+ }
+
+ [AttributeDataType(Int32Type = Int32.MinValue)]
+ public void PropertyInt32Type()
+ {
+ }
+
+ [AttributeDataType(UInt32Type = UInt32.MaxValue)]
+ public void PropertyUInt32Type()
+ {
+ }
+
+ [AttributeDataType(Int64Type = Int64.MinValue)]
+ public void PropertyInt64Type()
+ {
+ }
+
+ [AttributeDataType(UInt64Type = UInt64.MaxValue)]
+ public void PropertyUInt64Type()
+ {
+ }
+
+ [AttributeDataType(SingleType = Single.MinValue)]
+ public void PropertySingleType()
+ {
+ }
+
+ [AttributeDataType(DoubleType = Double.MinValue)]
+ public void PropertyDoubleType()
+ {
+ }
+
+ [AttributeDataType(CharType = 'C')]
+ public void PropertyCharType()
+ {
+ }
+
+ [AttributeDataType(StringType = "This is a string argument.")]
+ public void PropertyStringType()
+ {
+ }
+
+ [AttributeDataType(StringType = null)]
+ public void PropertyStringTypeWithNull()
+ {
+ }
+
+ [AttributeDataType(StringType = "")]
+ public void PropertyStringTypeWithEmptyString()
+ {
+ }
+
+ [AttributeDataType(ArrayOfIntType = new[] { 0, 0, 7 })]
+ public void PropertyArrayOfIntType()
+ {
+ }
+
+ [AttributeDataType(ArrayOfIntType = null)]
+ public void PropertyArrayOfIntTypeWithNull()
+ {
+ }
+
+ [AttributeDataType(EnumType = ConsoleColor.Red)]
+ public void PropertyEnumType()
+ {
+ }
+
+ [AttributeDataType(EnumType = (ConsoleColor)int.MaxValue)]
+ public void PropertyEnumTypeWithUnknownValue()
+ {
+ }
+
+ [AttributeDataType(NestedEnumType = SomeNestedTypes.NestedEnum.Read)]
+ public void PropertyNestedEnumType()
+ {
+ }
+
+ [AttributeDataType(NestedEnumType = (SomeNestedTypes.NestedEnum)int.MaxValue)]
+ public void PropertyNestedEnumTypeWithUnknownValue()
+ {
+ }
+
+ [AttributeDataType(FlagsEnumType = AttributeTargets.Class | AttributeTargets.Enum)]
+ public void PropertyFlagsEnumType()
+ {
+ }
+
+ [AttributeDataType(FlagsEnumType = AttributeTargets.All)]
+ public void PropertyFlagsEnumTypeWithAllValue()
+ {
+ }
+
+ [AttributeDataType(FlagsEnumType = (AttributeTargets)0)]
+ public void PropertyFlagsEnumTypeWithUndefineValueZero()
+ {
+ }
+
+ [AttributeDataType(DuplicateFlagsEnumType = SomeFlagsEnum.Read | SomeFlagsEnum.Write | SomeFlagsEnum.Open)]
+ public void PropertyDuplicateFlagsEnumTypeWithCombinationValue()
+ {
+ }
+
+ [AttributeDataType(NestedFlagsEnumType = SomeNestedTypes.NestedFlagsEnum.Class | SomeNestedTypes.NestedFlagsEnum.Enum)]
+ public void PropertyNestedFlagsEnumType()
+ {
+ }
+
+ [AttributeDataType(NestedFlagsEnumType = (SomeNestedTypes.NestedFlagsEnum)0)]
+ public void PropertyNestedFlagsEnumTypeWithUndefineValueZero()
+ {
+ }
+
+ [AttributeDataType(NotApplyAttributeFlagsEnumType = NotApplyAttributeValidFlagsEnum.Class | NotApplyAttributeValidFlagsEnum.Enum)]
+ public void PropertyFlagsEnumTypeWithNotApplyAttributeValidTypeAndCombinationValue()
+ {
+ }
+
+ [AttributeDataType(NotApplyAttributeFlagsEnumType = NotApplyAttributeValidFlagsEnum.Class)]
+ public void PropertyFlagsEnumTypeWithNotApplyAttributeValidTypeAndSingleValue()
+ {
+ }
+
+ [AttributeDataType(NotApplyAttributeInvalidFlagsEnumType = (NotApplyAttributeInvalidFlagsEnum)5)]
+ public void PropertyFlagsEnumTypeWithNotApplyAttributeInvalidTypeAndUnknownCombinationValue()
+ {
+ }
+
+ [AttributeDataType(ApplePlatformFlagsEnumType = ObjCRuntime.Platform.Mac_10_8 | ObjCRuntime.Platform.Mac_Arch64)]
+ public void PropertyFlagsEnumTypeWithApplePlatformType()
+ {
+ }
+
+ [AttributeDataType(ApplePlatformFlagsEnumType = ObjCRuntime.Platform.None)]
+ public void PropertyFlagsEnumTypeWithApplePlatformAndNoneValue()
+ {
+ }
+
+ [AttributeDataType(ObjectType = null)]
+ public void PropertyObjectWithNull()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(TypeReference))]
+ public void PropertyObjectWithTypeType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(SomeNestedTypes.NestedClass))]
+ public void PropertyObjectWithNestedTypeType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(ICollection<>))]
+ public void PropertyObjectWithUnboundCollectionType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(ICollection<int>))]
+ public void PropertyObjectWithCollectionTypeOfInt()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(IDictionary<,>))]
+ public void PropertyObjectWithUnboundDictionaryType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(IDictionary<int, int>))]
+ public void PropertyObjectWithDictionaryTypeOfInt()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(SomeGenericClass<>))]
+ public void PropertyObjectWithUnboundCustomGenericType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(SomeGenericClass<int>))]
+ public void PropertyObjectWithCustomGenericTypeOfInt()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(SomeNestedTypes.NestedGenericType<>))]
+ public void PropertyObjectWithUnboundNestedGenericType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(SomeNestedTypes.NestedGenericType<int>))]
+ public void PropertyObjectWithNestedGenericTypeOfInt()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(SomeNestedTypes.NestedGenericType<>.InnerNestedGenericType<>))]
+ public void PropertyObjectWithUnboundInnerNestedGenericType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = typeof(SomeNestedTypes.NestedGenericType<string>.InnerNestedGenericType<int>))]
+ public void PropertyObjectWithInnerNestedGenericTypeOfInt()
+ {
+ }
+
+ [AttributeDataType(ObjectType = true)]
+ public void PropertyObjectWithBoolType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = SByte.MinValue)]
+ public void PropertyObjectWithSByteType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = Byte.MaxValue)]
+ public void PropertyObjectWithByteType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = Int16.MinValue)]
+ public void PropertyObjectWithInt16Type()
+ {
+ }
+
+ [AttributeDataType(ObjectType = UInt16.MaxValue)]
+ public void PropertyObjectWithUInt16Type()
+ {
+ }
+
+ [AttributeDataType(ObjectType = Int32.MinValue)]
+ public void PropertyObjectWithInt32Type()
+ {
+ }
+
+ [AttributeDataType(ObjectType = UInt32.MaxValue)]
+ public void PropertyObjectWithUInt32Type()
+ {
+ }
+
+ [AttributeDataType(ObjectType = Int64.MinValue)]
+ public void PropertyObjectWithInt64Type()
+ {
+ }
+
+ [AttributeDataType(ObjectType = UInt64.MaxValue)]
+ public void PropertyObjectWithUInt64Type()
+ {
+ }
+
+ [AttributeDataType(ObjectType = Single.MinValue)]
+ public void PropertyObjectWithSingleType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = Double.MinValue)]
+ public void PropertyObjectWithDoubleType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = 'C')]
+ public void PropertyObjectWithCharType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = "This is a string argument.")]
+ public void PropertyObjectWithStringType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = "")]
+ public void PropertyObjectWithStringTypeAndEmptyString()
+ {
+ }
+
+ [AttributeDataType(ObjectType = new[] { 0, 0, 7 })]
+ public void PropertyObjectWithArrayOfIntType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = ConsoleColor.Red)]
+ public void PropertyObjectWithEnumType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = (ConsoleColor)int.MaxValue)]
+ public void PropertyObjectWithEnumTypeAndUnknownValue()
+ {
+ }
+
+ [AttributeDataType(ObjectType = SomeNestedTypes.NestedEnum.Read)]
+ public void PropertyObjectWithNestedEnumType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = (SomeNestedTypes.NestedEnum)int.MaxValue)]
+ public void PropertyObjectWithNestedEnumTypeAndUnknownValue()
+ {
+ }
+
+ [AttributeDataType(ObjectType = AttributeTargets.Class | AttributeTargets.Enum)]
+ public void PropertyObjectWithFlagsEnumType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = AttributeTargets.All)]
+ public void PropertyObjectWithFlagsEnumTypeAndAllValue()
+ {
+ }
+
+ [AttributeDataType(ObjectType = (AttributeTargets)0)]
+ public void PropertyObjectWithFlagsEnumTypeAndUndefineValueZero()
+ {
+ }
+
+ [AttributeDataType(ObjectType = SomeFlagsEnum.Read | SomeFlagsEnum.Write | SomeFlagsEnum.Open)]
+ public void PropertyObjectWithDuplicateFlagsEnumTypeAndCombinationValue()
+ {
+ }
+
+ [AttributeDataType(ObjectType = SomeNestedTypes.NestedFlagsEnum.Class | SomeNestedTypes.NestedFlagsEnum.Enum)]
+ public void PropertyObjectWithNestedFlagsEnumType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = (SomeNestedTypes.NestedFlagsEnum)0)]
+ public void PropertyObjectWithNestedFlagsEnumTypeAndUndefineValueZero()
+ {
+ }
+
+ [AttributeDataType(ObjectType = NotApplyAttributeValidFlagsEnum.Class | NotApplyAttributeValidFlagsEnum.Enum)]
+ public void PropertyObjectWithNotApplyAttributeValidFlagsEnumTypeAndCombinationValue()
+ {
+ }
+
+ [AttributeDataType(ObjectType = NotApplyAttributeValidFlagsEnum.Class)]
+ public void PropertyObjectWithNotApplyAttributeValidFlagsEnumTypeAndSingleValue()
+ {
+ }
+
+ [AttributeDataType(ObjectType = (NotApplyAttributeInvalidFlagsEnum)5)]
+ public void PropertyObjectWithNotApplyAttributeInvalidFlagsEnumTypeAndUnknownCombinationValue()
+ {
+ }
+
+ [AttributeDataType(ObjectType = ObjCRuntime.Platform.Mac_10_8 | ObjCRuntime.Platform.Mac_Arch64)]
+ public void PropertyObjectWithApplePlatformFlagsEnumType()
+ {
+ }
+
+ [AttributeDataType(ObjectType = ObjCRuntime.Platform.None)]
+ public void PropertyObjectWithApplePlatformFlagsEnumTypeAndNoneValue()
+ {
+ }
+ }
+}
diff --git a/mdoc/mdoc.Test/SampleClasses/SomeFlagsEnum.cs b/mdoc/mdoc.Test/SampleClasses/SomeFlagsEnum.cs
new file mode 100644
index 00000000..a95365d3
--- /dev/null
+++ b/mdoc/mdoc.Test/SampleClasses/SomeFlagsEnum.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace mdoc.Test.SampleClasses
+{
+ [Flags]
+ public enum SomeFlagsEnum
+ {
+ Read = 1,
+ Write = 2,
+ ReadWrite = Read | Write,
+ Open = 4,
+ Close = 8
+ }
+}
diff --git a/mdoc/mdoc.Test/SampleClasses/SomeIteratorStateMachine.cs b/mdoc/mdoc.Test/SampleClasses/SomeIteratorStateMachine.cs
new file mode 100644
index 00000000..3dbf6032
--- /dev/null
+++ b/mdoc/mdoc.Test/SampleClasses/SomeIteratorStateMachine.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace mdoc.Test.SampleClasses
+{
+ public class SomeIteratorStateMachine<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
+ {
+ public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+ {
+ yield return new KeyValuePair<TKey, TValue>();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerator<KeyValuePair<T1, T2>> WithParameterType<T1, T2>()
+ {
+ yield return new KeyValuePair<T1, T2>();
+
+ }
+
+ public class SomeNestedIteratorStateMachine<NestedTKey, NestedTValue> : IEnumerable<KeyValuePair<NestedTKey, NestedTValue>>
+ {
+ public IEnumerator<KeyValuePair<NestedTKey, NestedTValue>> GetEnumerator()
+ {
+ yield return new KeyValuePair<NestedTKey, NestedTValue>();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerator<KeyValuePair<NestedT1, NestedT2>> WithParameterType<NestedT1, NestedT2>()
+ {
+ yield return new KeyValuePair<NestedT1, NestedT2>();
+
+ }
+ }
+ }
+}
diff --git a/mdoc/mdoc.Test/SampleClasses/SomeNestedTypes.cs b/mdoc/mdoc.Test/SampleClasses/SomeNestedTypes.cs
new file mode 100644
index 00000000..1c8f332e
--- /dev/null
+++ b/mdoc/mdoc.Test/SampleClasses/SomeNestedTypes.cs
@@ -0,0 +1,34 @@
+using System;
+
+namespace mdoc.Test.SampleClasses
+{
+ public class SomeNestedTypes
+ {
+ public class NestedClass
+ {
+ }
+
+ public class NestedGenericType<T>
+ {
+ public class InnerNestedGenericType<T1>
+ {
+ }
+ }
+
+ public enum NestedEnum
+ {
+ Read = 1,
+ Write = 2,
+ }
+
+ [Flags]
+ public enum NestedFlagsEnum
+ {
+ Assembly = 1,
+ Module = 2,
+ Class = 4,
+ Struct = 8,
+ Enum = 16
+ }
+ }
+}
diff --git a/mdoc/mdoc.Test/mdoc.Test.csproj b/mdoc/mdoc.Test/mdoc.Test.csproj
index 5daf4464..11960802 100644
--- a/mdoc/mdoc.Test/mdoc.Test.csproj
+++ b/mdoc/mdoc.Test/mdoc.Test.csproj
@@ -72,6 +72,7 @@
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="AttributeValueFormatterTest.cs" />
<Compile Include="BasicFormatterTests.cs" />
<Compile Include="BasicTests.cs" />
<Compile Include="CppWinRtMembersTests.cs" />
@@ -94,11 +95,19 @@
<Compile Include="MDocFileSourceTests.cs" />
<Compile Include="MDocUpdaterTests.cs" />
<Compile Include="NullableReferenceTypesTests.cs" />
+ <Compile Include="SampleClasses\ApplePlatformEnum.cs" />
<Compile Include="SampleClasses\EiiImplementclass.cs" />
<Compile Include="SampleClasses\Interface_A.cs" />
<Compile Include="SampleClasses\Interface_B.cs" />
<Compile Include="SampleClasses\InternalEIICalss.cs" />
+ <Compile Include="SampleClasses\SomeFlagsEnum.cs" />
+ <Compile Include="SampleClasses\SomeIteratorStateMachine.cs" />
+ <Compile Include="SampleClasses\NotApplyAttributeValidFlagsEnum.cs" />
+ <Compile Include="SampleClasses\NotApplyAttributeInvalidFlagsEnum.cs" />
<Compile Include="SampleClasses\NullablesAndTuples.cs" />
+ <Compile Include="SampleClasses\AttributeDataTypeAttribute.cs" />
+ <Compile Include="SampleClasses\SomeAttribute.cs" />
+ <Compile Include="SampleClasses\SomeNestedTypes.cs" />
<Compile Include="SampleClasses\StaticClass.cs" />
<Compile Include="SampleClasses\TestClassThree.cs" />
<Compile Include="SpanSpecial.cs" />
diff --git a/mdoc/mdoc.csproj b/mdoc/mdoc.csproj
index f9b0d745..9de40804 100644
--- a/mdoc/mdoc.csproj
+++ b/mdoc/mdoc.csproj
@@ -59,7 +59,6 @@
<Compile Include="Mono.Documentation\Framework\FrameworkTypeModel.cs" />
<Compile Include="Mono.Documentation\Framework\FrameworkNamespaceModel.cs" />
<Compile Include="Mono.Documentation\Updater\IAttributeParserContext.cs" />
- <Compile Include="Mono.Documentation\Updater\Formatters\AttributeFormatters\ApplePlatformEnumFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\AttributeFormatters\AttributeFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\AttributeFormatters\CppWinRtAttributeFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\AttributeFormatters\FSharpAttributeFormatter.cs" />
@@ -81,12 +80,9 @@
<Compile Include="Mono.Documentation\Updater\Formatters\CSharpMemberFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\SlashDocCSharpMemberFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\MsxdocSlashDocMemberFormatter.cs" />
- <Compile Include="Mono.Documentation\Updater\Formatters\AttributeFormatters\StandardFlagsEnumFormatter.cs" />
- <Compile Include="Mono.Documentation\Updater\Formatters\AttributeFormatters\DefaultAttributeValueFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\AttributeFormatters\AttributeValueFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\VBFullMemberFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\VBMemberFormatter.cs" />
- <Compile Include="Mono.Documentation\Updater\ResolvedTypeInfo.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\FileNameMemberFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\SlashDocMemberFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\DocTypeMemberFormatter.cs" />