diff options
author | anmeng10101 <33647870+anmeng10101@users.noreply.github.com> | 2021-04-02 16:19:26 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-02 16:19:26 +0300 |
commit | 24ba59fcca3d1acacdb0f71acbdf401d5ce3fb96 (patch) | |
tree | cf6fdb02ef41b32b8fa271278a1e67cf15e5f0c0 /mdoc | |
parent | 5f850662b2c0b81f3e21680e8039100179a02169 (diff) | |
parent | 35c9e2ba3d6b3ae2824a673c0235d275686861fd (diff) |
Merge pull request #544 from mono/develop
🚢 5.8.2
Diffstat (limited to 'mdoc')
74 files changed, 3368 insertions, 232 deletions
diff --git a/mdoc/Consts.cs b/mdoc/Consts.cs index 0b2b0581..a77b295e 100644 --- a/mdoc/Consts.cs +++ b/mdoc/Consts.cs @@ -3,7 +3,7 @@ namespace Mono.Documentation { public static class Consts { - public static string MonoVersion = "5.8"; + public static string MonoVersion = "5.8.2"; public const string DocId = "DocId"; public const string CppCli = "C++ CLI"; public const string CppCx = "C++ CX"; diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs index 2b355471..3e24f500 100644 --- a/mdoc/Mono.Documentation/MDocUpdater.cs +++ b/mdoc/Mono.Documentation/MDocUpdater.cs @@ -3801,7 +3801,7 @@ namespace Mono.Documentation XmlElement e = (XmlElement)root.SelectSingleNode("Attributes"); if (e == null) e = root.OwnerDocument.CreateElement("Attributes"); - if (isFirstFramework) + if (isFirstFramework && typeEntry?.TimesProcessed == 1) { e.RemoveAll(); } diff --git a/mdoc/Mono.Documentation/Updater/AttributeParserContext.cs b/mdoc/Mono.Documentation/Updater/AttributeParserContext.cs new file mode 100644 index 00000000..de9ee35d --- /dev/null +++ b/mdoc/Mono.Documentation/Updater/AttributeParserContext.cs @@ -0,0 +1,92 @@ +using mdoc.Mono.Documentation.Updater; +using Mono.Cecil; +using Mono.Documentation.Util; +using System; +using System.Collections.ObjectModel; + +namespace Mono.Documentation.Updater +{ + public class AttributeParserContext : IAttributeParserContext + { + private int nullableAttributeIndex; + private int dynamicAttributeIndex; + private ICustomAttributeProvider provider; + private ReadOnlyCollection<bool?> nullableAttributeFlags; + private ReadOnlyCollection<bool> dynamicAttributeFlags; + + private AttributeParserContext(ICustomAttributeProvider provider) + { + this.provider = provider; + + ReadDynamicAttribute(); + ReadNullableAttribute(); + } + + private bool ExistsNullableAttribute + { + get + { + return nullableAttributeFlags.Count > 0; + } + } + + private bool HasSameNullableValue + { + get + { + return nullableAttributeFlags.Count == 1; + } + } + + public static IAttributeParserContext Create(ICustomAttributeProvider provider) + { + return new AttributeParserContext(provider); + } + + public void NextDynamicFlag() + { + dynamicAttributeIndex++; + } + + public bool IsDynamic() + { + return dynamicAttributeFlags != null && (dynamicAttributeFlags.Count == 0 || dynamicAttributeFlags[dynamicAttributeIndex]); + } + + public bool IsNullable() + { + if (ExistsNullableAttribute) + { + if (HasSameNullableValue) + { + return nullableAttributeFlags[0].IsTrue(); + } + + if (nullableAttributeIndex < nullableAttributeFlags.Count) + { + return nullableAttributeFlags[nullableAttributeIndex++].IsTrue(); + } + + throw new IndexOutOfRangeException("You are out of range in the nullable attribute values, please call the method for each nullable checking only once."); + } + + return false; + } + + private void ReadDynamicAttribute() + { + DynamicTypeProvider dynamicTypeProvider = new DynamicTypeProvider(provider); + var dynamicTypeFlags = dynamicTypeProvider.GetDynamicTypeFlags(); + if (dynamicTypeFlags != null) + { + dynamicAttributeFlags = new ReadOnlyCollection<bool>(dynamicTypeFlags); + } + } + + private void ReadNullableAttribute() + { + NullableReferenceTypeProvider nullableReferenceTypeProvider = new NullableReferenceTypeProvider(provider); + nullableAttributeFlags = new ReadOnlyCollection<bool?>(nullableReferenceTypeProvider.GetNullableReferenceTypeFlags()); + } + } +}
\ No newline at end of file diff --git a/mdoc/Mono.Documentation/Updater/DocUtils.cs b/mdoc/Mono.Documentation/Updater/DocUtils.cs index 718c26c9..8a29d010 100644 --- a/mdoc/Mono.Documentation/Updater/DocUtils.cs +++ b/mdoc/Mono.Documentation/Updater/DocUtils.cs @@ -928,5 +928,22 @@ namespace Mono.Documentation.Updater return false;
}
+
+ public static TypeDefinition FixUnnamedParameters(TypeDefinition type)
+ {
+ foreach (var method in type.Methods)
+ {
+ var unnamedParameterIndex = 1;
+ foreach (var item in method.Parameters)
+ {
+ if (string.IsNullOrEmpty(item.Name))
+ {
+ item.Name = $"unnamedParam{unnamedParameterIndex++}";
+ }
+ }
+ }
+
+ return type;
+ }
}
}
diff --git a/mdoc/Mono.Documentation/Updater/DocumentationEnumerator.cs b/mdoc/Mono.Documentation/Updater/DocumentationEnumerator.cs index 3be0636f..90f533ef 100644 --- a/mdoc/Mono.Documentation/Updater/DocumentationEnumerator.cs +++ b/mdoc/Mono.Documentation/Updater/DocumentationEnumerator.cs @@ -27,7 +27,7 @@ namespace Mono.Documentation.Updater continue; if (seen != null && seen.Contains (type.FullName)) continue; - yield return type; + yield return DocUtils.FixUnnamedParameters (type); } } diff --git a/mdoc/Mono.Documentation/Updater/DynamicParserContext.cs b/mdoc/Mono.Documentation/Updater/DynamicParserContext.cs deleted file mode 100644 index 53e36935..00000000 --- a/mdoc/Mono.Documentation/Updater/DynamicParserContext.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Collections.ObjectModel; -using System.Linq; - -using Mono.Cecil; - -using Mono.Documentation.Util; -
-namespace Mono.Documentation.Updater -{
- public class DynamicParserContext - { - public ReadOnlyCollection<bool> TransformFlags; - public int TransformIndex;
- public bool IsNullableAttribute; - public DynamicParserContext (ICustomAttributeProvider provider) - { - CustomAttribute da; - if (provider.HasCustomAttributes && - (da = (provider.CustomAttributes.SafeCast<CustomAttribute> () - .SingleOrDefault (ca => ca.GetDeclaringType () == "System.Runtime.CompilerServices.DynamicAttribute"))) != null) - { - CustomAttributeArgument[] values = da.ConstructorArguments.Count == 0 - ? new CustomAttributeArgument[0] - : (CustomAttributeArgument[])da.ConstructorArguments[0].Value; - - TransformFlags = new ReadOnlyCollection<bool> (values.Select (t => (bool)t.Value).ToArray ()); - } - - IsNullableAttribute = provider.HasCustomAttributes &&
- provider.CustomAttributes.Any(ca => ca.AttributeType.FullName == "System.Runtime.CompilerServices.NullableAttribute"); - } - } -}
\ No newline at end of file diff --git a/mdoc/Mono.Documentation/Updater/DynamicTypeProvider.cs b/mdoc/Mono.Documentation/Updater/DynamicTypeProvider.cs new file mode 100644 index 00000000..1d370d58 --- /dev/null +++ b/mdoc/Mono.Documentation/Updater/DynamicTypeProvider.cs @@ -0,0 +1,47 @@ +using Mono.Cecil; +using Mono.Documentation.Updater; +using Mono.Documentation.Util; +using System.Collections.Generic; +using System.Linq; + +namespace mdoc.Mono.Documentation.Updater +{ + public class DynamicTypeProvider + { + private const string DynamicAttributeFulleName = "System.Runtime.CompilerServices.DynamicAttribute"; + + private ICustomAttributeProvider provider; + + public DynamicTypeProvider(ICustomAttributeProvider provider) + { + this.provider = provider; + } + + public IList<bool> GetDynamicTypeFlags() + { + CustomAttribute dynamicAttribute = FindDynamicAttribute(); + if (dynamicAttribute != null) + { + CustomAttributeArgument[] attributeValues = new CustomAttributeArgument[0]; + if (dynamicAttribute.ConstructorArguments.Count > 0) + { + attributeValues = (CustomAttributeArgument[])dynamicAttribute.ConstructorArguments[0].Value; + } + + return attributeValues.Select(t => (bool)t.Value).ToList(); + } + + return null; + } + + private CustomAttribute FindDynamicAttribute() + { + if (provider.HasCustomAttributes) + { + return provider.CustomAttributes.SafeCast<CustomAttribute>().SingleOrDefault(ca => ca.GetDeclaringType() == DynamicAttributeFulleName); + } + + return null; + } + } +} diff --git a/mdoc/Mono.Documentation/Updater/EmptyAttributeParserContext.cs b/mdoc/Mono.Documentation/Updater/EmptyAttributeParserContext.cs new file mode 100644 index 00000000..87aecaa4 --- /dev/null +++ b/mdoc/Mono.Documentation/Updater/EmptyAttributeParserContext.cs @@ -0,0 +1,30 @@ +namespace Mono.Documentation.Updater +{ + public class EmptyAttributeParserContext : IAttributeParserContext + { + private static readonly EmptyAttributeParserContext singletonInstance = new EmptyAttributeParserContext(); + + private EmptyAttributeParserContext() + { + } + + public static IAttributeParserContext Empty() + { + return singletonInstance; + } + + public void NextDynamicFlag() + { + } + + public bool IsDynamic() + { + return false; + } + + public bool IsNullable() + { + return false; + } + } +} diff --git a/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs index 4dee7151..34749cc5 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/CSharpFullMemberFormatter.cs @@ -1,12 +1,10 @@ -using System; +using Mono.Cecil; +using Mono.Documentation.Util; +using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Text; -using Mono.Cecil; -using Mono.Documentation.Util; - namespace Mono.Documentation.Updater.Formatters { public class CSharpFullMemberFormatter : MemberFormatter @@ -21,7 +19,6 @@ namespace Mono.Documentation.Updater.Formatters protected override StringBuilder AppendNamespace (StringBuilder buf, TypeReference type) { - string ns = DocUtils.GetNamespace (type); if (GetCSharpType (type.FullName) == null && ns != null && ns.Length > 0 && ns != "System") buf.Append (ns).Append ('.'); @@ -70,12 +67,11 @@ namespace Mono.Documentation.Updater.Formatters return typeToCompare == t ? null : typeToCompare; } - protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context) { - if (context != null && context.TransformFlags != null && - (context.TransformFlags.Count == 0 || context.TransformFlags[context.TransformIndex])) + if (context.IsDynamic()) { - context.TransformIndex++; + context.NextDynamicFlag(); return buf.Append ("dynamic"); } @@ -90,15 +86,14 @@ namespace Mono.Documentation.Updater.Formatters string s = GetCSharpType (t); if (s != null) { - if (context != null) - context.TransformIndex++; + context.NextDynamicFlag(); return buf.Append (s); } return base.AppendTypeName (buf, type, context); } - private StringBuilder AppendGenericParameterConstraints (StringBuilder buf, GenericParameter type, DynamicParserContext context) + private StringBuilder AppendGenericParameterConstraints (StringBuilder buf, GenericParameter type, IAttributeParserContext context) { if (MemberFormatterState != MemberFormatterState.WithinGenericTypeParameters) return buf; @@ -112,40 +107,55 @@ namespace Mono.Documentation.Updater.Formatters return buf; } - protected override string GetTypeName(TypeReference type, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection = true) + protected override string GetTypeName (TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true) { GenericInstanceType genType = type as GenericInstanceType; - if (genType != null) + if (IsSpecialGenericNullableValueType (genType)) { - if (genType.Name.StartsWith("Nullable`") && genType.HasGenericArguments) - { - - var underlyingTypeName = base.GetTypeName(genType.GenericArguments.First(), context, appendGeneric, useTypeProjection); - return underlyingTypeName + "?"; - } - - if (genType.Name.StartsWith("Tuple`") || genType.Name.StartsWith("ValueTuple`")) - { - StringBuilder sb = new StringBuilder(); - sb.Append("("); + return AppendSpecialGenericNullableValueTypeName (new StringBuilder (), genType, context, appendGeneric, useTypeProjection).ToString (); + } - var genArgList = genType.GenericArguments.Select(genArg => base.GetTypeName(genArg, context, appendGeneric, useTypeProjection)).ToArray(); + return base.GetTypeName (type, context, appendGeneric, useTypeProjection); + } - sb.Append(string.Join(",", genArgList)); + protected override bool IsSpecialGenericNullableValueType (GenericInstanceType genInst) + { + return genInst != null && (genInst.Name.StartsWith("ValueTuple`") || + (genInst.Name.StartsWith("Nullable`") && genInst.HasGenericArguments)); + } - sb.Append(")"); + protected override StringBuilder AppendSpecialGenericNullableValueTypeName (StringBuilder buf, GenericInstanceType genInst, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true) + { + if (genInst.Name.StartsWith ("Nullable`") && genInst.HasGenericArguments) + { + var underlyingTypeName = GetTypeName (genInst.GenericArguments.First (), context, appendGeneric, useTypeProjection); + buf.Append (underlyingTypeName + "?"); - return sb.ToString(); - } + return buf; } - if (context != null && context.IsNullableAttribute) + if (genInst.Name.StartsWith ("ValueTuple`")) { - var TypeName = base.GetTypeName(type, context, appendGeneric, useTypeProjection); - return TypeName + "?"; + buf.Append ("("); + var genArgList = new List<string> (); + foreach (var item in genInst.GenericArguments) + { + var isNullableType = false; + if (!item.IsValueType) + { + isNullableType = context.IsNullable (); + } + + var underlyingTypeName = GetTypeName (item, context, appendGeneric, useTypeProjection) + GetTypeNullableSymbol (item, isNullableType); + genArgList.Add (underlyingTypeName); + } + buf.Append (string.Join (",", genArgList)); + buf.Append (")"); + + return buf; } - return base.GetTypeName(type, context, appendGeneric, useTypeProjection); + return buf; } protected override string GetTypeDeclaration (TypeDefinition type) @@ -165,7 +175,11 @@ namespace Mono.Documentation.Updater.Formatters { buf.Append ("delegate "); MethodDefinition invoke = type.GetMethod ("Invoke"); - buf.Append (full.GetName (invoke.ReturnType, new DynamicParserContext (invoke.MethodReturnType))).Append (" "); + var context = AttributeParserContext.Create (invoke.MethodReturnType); + var isNullableType = context.IsNullable (); + buf.Append (full.GetName (invoke.ReturnType, context)); + buf.Append (GetTypeNullableSymbol (invoke.ReturnType, isNullableType)); + buf.Append (" "); buf.Append (GetName (type)); AppendParameters (buf, invoke, invoke.Parameters); AppendGenericTypeConstraints (buf, type); @@ -414,6 +428,31 @@ namespace Mono.Documentation.Updater.Formatters return base.AppendMethodName (buf, method); } + protected override string GetTypeNullableSymbol(TypeReference type, bool? isNullableType) + { + if (isNullableType.IsTrue() && !IsValueTypeOrDefineByReference(type) && !type.FullName.Equals("System.Void")) + { + return "?"; + } + + return string.Empty; + } + + private bool IsValueTypeOrDefineByReference(TypeReference type) + { + if (type.IsValueType) + { + return true; + } + + if (type is ByReferenceType byRefType) + { + return byRefType.ElementType.IsValueType; + } + + return false; + } + protected override StringBuilder AppendGenericMethodConstraints (StringBuilder buf, MethodDefinition method) { if (method.GenericParameters.Count == 0) @@ -543,8 +582,14 @@ namespace Mono.Documentation.Updater.Formatters if (isParams) buf.AppendFormat ("params "); } - buf.Append (GetTypeName (parameter.ParameterType, new DynamicParserContext (parameter))).Append (" "); + + var context = AttributeParserContext.Create (parameter); + var isNullableType = context.IsNullable (); + buf.Append (GetTypeName (parameter.ParameterType, context)); + buf.Append (GetTypeNullableSymbol (parameter.ParameterType, isNullableType)); + buf.Append (" "); buf.Append (parameter.Name); + if (parameter.HasDefault && parameter.IsOptional && parameter.HasConstant) { var ReturnVal = new AttributeFormatter().MakeAttributesValueString(parameter.Constant, parameter.ParameterType); @@ -606,7 +651,12 @@ namespace Mono.Documentation.Updater.Formatters if (property.PropertyType.IsByReference) buf.Append("ref "); - buf.Append (GetTypeName (property.PropertyType, new DynamicParserContext (property))).Append (' '); + var context = AttributeParserContext.Create (property); + var isNullableType = context.IsNullable (); + var propertyReturnTypeName = GetTypeName (property.PropertyType, context); + buf.Append (propertyReturnTypeName); + buf.Append (GetTypeNullableSymbol (property.PropertyType, isNullableType)); + buf.Append (' '); IEnumerable<MemberReference> defs = property.DeclaringType.GetDefaultMembers (); string name = property.Name; @@ -664,7 +714,12 @@ namespace Mono.Documentation.Updater.Formatters if (field.IsLiteral) buf.Append (" const"); - buf.Append (' ').Append (GetTypeName (field.FieldType, new DynamicParserContext (field))).Append (' '); + buf.Append (' '); + var context = AttributeParserContext.Create (field); + var isNullableType = context.IsNullable (); + buf.Append (GetTypeName (field.FieldType, context)); + buf.Append (GetTypeNullableSymbol (field.FieldType, isNullableType)); + buf.Append (' '); buf.Append (field.Name); DocUtils.AppendFieldValue (buf, field); buf.Append (';'); @@ -702,8 +757,12 @@ namespace Mono.Documentation.Updater.Formatters AppendModifiers (buf, e.AddMethod); + var context = AttributeParserContext.Create (e.AddMethod.Parameters[0]); + var isNullableType = context.IsNullable (); buf.Append (buf.Length == 0 ? "event " : " event "); - buf.Append (GetTypeName (e.EventType, new DynamicParserContext (e.AddMethod.Parameters[0]))).Append (' '); + buf.Append (GetTypeName(e.EventType, context)); + buf.Append (GetTypeNullableSymbol (e.EventType, isNullableType)); + buf.Append (' '); buf.Append (e.Name).Append (';'); return buf.ToString (); diff --git a/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppCxFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppCxFullMemberFormatter.cs index 7f8d1145..efba11be 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppCxFullMemberFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppCxFullMemberFormatter.cs @@ -141,7 +141,7 @@ namespace Mono.Documentation.Updater.Formatters.CppFormatters } protected override StringBuilder AppendArrayTypeName(StringBuilder buf, TypeReference type, - DynamicParserContext context) + IAttributeParserContext context) { buf.Append("Platform::Array <"); diff --git a/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppFullMemberFormatter.cs index d5bcceaa..757b6431 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppFullMemberFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppFullMemberFormatter.cs @@ -107,7 +107,7 @@ namespace Mono.Documentation.Updater.Formatters.CppFormatters return typeToCompare == t ? null : typeToCompare; } - protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context) { string typeFullName = type.FullName; if (string.IsNullOrWhiteSpace (typeFullName)) @@ -275,7 +275,7 @@ namespace Mono.Documentation.Updater.Formatters.CppFormatters protected virtual string GetTypeNameWithOptions(TypeReference type, bool appendHat, bool appendGeneric = true) { - var typeName = GetTypeName(type, null, appendGeneric); + var typeName = GetTypeName(type, EmptyAttributeParserContext.Empty(), appendGeneric); var hatTypeName = !type.IsByReference && !type.IsPointer ? AppendHat(typeName, type, appendHat) @@ -553,7 +553,7 @@ namespace Mono.Documentation.Updater.Formatters.CppFormatters return AppendConstraints (buf, method.GenericParameters); } - protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection = false) + protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false) { List<TypeReference> decls = DocUtils.GetDeclaringTypes( type is GenericInstanceType ? type.GetElementType() : type); @@ -755,7 +755,7 @@ namespace Mono.Documentation.Updater.Formatters.CppFormatters return buf; } - protected override StringBuilder AppendArrayTypeName(StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendArrayTypeName(StringBuilder buf, TypeReference type, IAttributeParserContext context) { buf.Append("cli::array <"); @@ -777,7 +777,7 @@ namespace Mono.Documentation.Updater.Formatters.CppFormatters return buf; } - protected override StringBuilder AppendRefTypeName(StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendRefTypeName(StringBuilder buf, TypeReference type, IAttributeParserContext context) { TypeSpecification spec = type as TypeSpecification; _AppendTypeName(buf, spec != null ? spec.ElementType : type.GetElementType(), context); @@ -787,7 +787,7 @@ namespace Mono.Documentation.Updater.Formatters.CppFormatters return buf; } - protected override StringBuilder AppendPointerTypeName(StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendPointerTypeName(StringBuilder buf, TypeReference type, IAttributeParserContext context) { TypeSpecification spec = type as TypeSpecification; _AppendTypeName(buf, spec != null ? spec.ElementType : type.GetElementType(), context); diff --git a/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppWinRtFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppWinRtFullMemberFormatter.cs index c35a1e99..a7f7d3ec 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppWinRtFullMemberFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/CppFormatters/CppWinRtFullMemberFormatter.cs @@ -123,7 +123,7 @@ namespace Mono.Documentation.Updater.Formatters.CppFormatters } protected override StringBuilder AppendArrayTypeName(StringBuilder buf, TypeReference type, - DynamicParserContext context) + IAttributeParserContext context) { buf.Append("std::Array <"); diff --git a/mdoc/Mono.Documentation/Updater/Formatters/FSharpFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/FSharpFormatter.cs index 51ec7533..0589c7f9 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/FSharpFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/FSharpFormatter.cs @@ -162,7 +162,7 @@ namespace Mono.Documentation.Updater return typeToCompare == type.FullName ? null : typeToCompare; } - protected override StringBuilder AppendTypeName(StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendTypeName(StringBuilder buf, TypeReference type, IAttributeParserContext context) { if (type == null) return buf; @@ -308,7 +308,7 @@ namespace Mono.Documentation.Updater return "class"; } - protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection = false) + protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false) { List<TypeReference> decls = DocUtils.GetDeclaringTypes( type is GenericInstanceType ? type.GetElementType() : type); @@ -613,7 +613,7 @@ namespace Mono.Documentation.Updater return buf; } - protected override StringBuilder AppendRefTypeName(StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendRefTypeName(StringBuilder buf, TypeReference type, IAttributeParserContext context) { ByReferenceType reftype = type as ByReferenceType; return AppendTypeName(buf, reftype?.ElementType, context); @@ -656,7 +656,7 @@ namespace Mono.Documentation.Updater if (property.PropertyType.FullName != "System.Object") { - var typeName = GetTypeName(property.PropertyType, new DynamicParserContext(property)); + var typeName = GetTypeName(property.PropertyType, AttributeParserContext.Create(property)); if (hasParameterName) buf.Append(" : "); buf.Append(typeName); @@ -698,7 +698,7 @@ namespace Mono.Documentation.Updater bool isFSharpFunction = IsFSharpFunction(parameter.ParameterType); if (isFSharpFunction) buf.Append("("); - var typeName = GetTypeName(parameter.ParameterType, new DynamicParserContext(parameter)); + var typeName = GetTypeName(parameter.ParameterType, AttributeParserContext.Create(parameter)); buf.Append(typeName); if (isFSharpFunction) buf.Append(")"); @@ -784,7 +784,7 @@ namespace Mono.Documentation.Updater buf.Append(" "); buf.Append(field.Name); buf.Append(" : "); - buf.Append(GetTypeName(field.FieldType, new DynamicParserContext(field))); + buf.Append(GetTypeName(field.FieldType, AttributeParserContext.Create(field))); return buf.ToString(); } @@ -802,7 +802,7 @@ namespace Mono.Documentation.Updater if (visibilityBuf.Length > 0) buf.Append(visibilityBuf).Append(' '); buf.Append(e.Name).Append(" : "); - buf.Append(GetTypeName(e.EventType, new DynamicParserContext(e.AddMethod.Parameters[0]))).Append(' '); + buf.Append(GetTypeName(e.EventType, AttributeParserContext.Create(e.AddMethod.Parameters[0]))).Append(' '); return buf.ToString(); } @@ -906,7 +906,7 @@ namespace Mono.Documentation.Updater return false; } - protected override StringBuilder AppendPointerTypeName(StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendPointerTypeName(StringBuilder buf, TypeReference type, IAttributeParserContext context) { TypeSpecification spec = type as TypeSpecification; buf.Append("nativeptr<"); diff --git a/mdoc/Mono.Documentation/Updater/Formatters/FSharpUsageFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/FSharpUsageFormatter.cs index c0297ffb..cad07d31 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/FSharpUsageFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/FSharpUsageFormatter.cs @@ -32,7 +32,7 @@ namespace Mono.Documentation.Updater } else { - var typeName = AppendTypeName(new StringBuilder(), method.DeclaringType, null).ToString(); + var typeName = AppendTypeName(new StringBuilder(), method.DeclaringType, EmptyAttributeParserContext.Empty()).ToString(); buf.Append($"{CamelCase(typeName)}.{method.Name} "); } diff --git a/mdoc/Mono.Documentation/Updater/Formatters/ILFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/ILFullMemberFormatter.cs index 4718f560..1ad73548 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/ILFullMemberFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/ILFullMemberFormatter.cs @@ -77,7 +77,7 @@ namespace Mono.Documentation.Updater.Formatters return buf.Append (typename); } - protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context) { if (type is GenericParameter) { @@ -203,7 +203,7 @@ namespace Mono.Documentation.Updater.Formatters return buf.ToString (); } - protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection = false) + protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false) { List<TypeReference> decls = DocUtils.GetDeclaringTypes ( type is GenericInstanceType ? type.GetElementType () : type); @@ -303,7 +303,7 @@ namespace Mono.Documentation.Updater.Formatters buf.Append ("virtual "); if (!method.IsStatic) buf.Append ("instance "); - _AppendTypeName (buf, method.ReturnType, new DynamicParserContext (method.MethodReturnType)); + _AppendTypeName (buf, method.ReturnType, AttributeParserContext.Create (method.MethodReturnType)); buf.Append (' ') .Append (method.Name); if (method.IsGenericMethod ()) @@ -334,7 +334,7 @@ namespace Mono.Documentation.Updater.Formatters if (param.IsOut) buf.Append ("[out] "); else if (param.IsIn) buf.Append ("[in]"); - _AppendTypeName (buf, param.ParameterType, new DynamicParserContext (param)); + _AppendTypeName (buf, param.ParameterType, AttributeParserContext.Create (param)); if (param.ParameterType.IsByReference) buf.Append ("&"); buf.Append (' '); buf.Append (param.Name); @@ -475,7 +475,7 @@ namespace Mono.Documentation.Updater.Formatters .Append (".property "); if (!(gm ?? sm).IsStatic) buf.Append ("instance "); - _AppendTypeName (buf, property.PropertyType, new DynamicParserContext (property)); + _AppendTypeName (buf, property.PropertyType, AttributeParserContext.Create (property)); buf.Append (' ').Append (property.Name); if (!property.HasParameters || property.Parameters.Count == 0) return buf.ToString (); @@ -487,7 +487,7 @@ namespace Mono.Documentation.Updater.Formatters if (!first) buf.Append (", "); first = false; - _AppendTypeName (buf, p.ParameterType, new DynamicParserContext (p)); + _AppendTypeName (buf, p.ParameterType, AttributeParserContext.Create (p)); } buf.Append (')'); @@ -513,7 +513,7 @@ namespace Mono.Documentation.Updater.Formatters buf.Append ("initonly "); if (field.IsLiteral) buf.Append ("literal "); - _AppendTypeName (buf, field.FieldType, new DynamicParserContext (field)); + _AppendTypeName (buf, field.FieldType, AttributeParserContext.Create (field)); buf.Append (' ').Append (field.Name); AppendFieldValue (buf, field); diff --git a/mdoc/Mono.Documentation/Updater/Formatters/JsFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/JsFormatter.cs index 0198463c..8664d1ba 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, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection = false) + protected override string GetTypeName(TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = 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 e4eb22d0..faf87874 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/MemberFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/MemberFormatter.cs @@ -27,10 +27,10 @@ namespace Mono.Documentation.Updater public string GetName (MemberReference member, bool appendGeneric = true, bool useTypeProjection = true) { - return GetName (member, null, appendGeneric, useTypeProjection: useTypeProjection); + return GetName (member, EmptyAttributeParserContext.Empty(), appendGeneric, useTypeProjection: useTypeProjection); } - public virtual string GetName (MemberReference member, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection = true) + public virtual string GetName (MemberReference member, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true) { TypeReference type = member as TypeReference; if (type != null) @@ -55,21 +55,17 @@ namespace Mono.Documentation.Updater protected virtual string GetTypeName (TypeReference type, bool appendGeneric = true, bool useTypeProjection = true) { - return GetTypeName (type, null, appendGeneric, useTypeProjection: useTypeProjection); + return GetTypeName (type, EmptyAttributeParserContext.Empty(), appendGeneric, useTypeProjection: useTypeProjection); } - protected virtual string GetTypeName (TypeReference type, DynamicParserContext context, bool appendGeneric=true, bool useTypeProjection = true) + protected virtual string GetTypeName (TypeReference type, IAttributeParserContext context, bool appendGeneric=true, bool useTypeProjection = true) { if (type == null) throw new ArgumentNullException (nameof (type)); var typeName = _AppendTypeName (new StringBuilder (type.Name.Length), type, context, appendGeneric, useTypeProjection: useTypeProjection).ToString (); - typeName = RemoveMod (typeName); - - - - return typeName; + return RemoveMod (typeName); } public static string RemoveMod (string typeName) @@ -107,21 +103,34 @@ namespace Mono.Documentation.Updater protected virtual MemberFormatterState MemberFormatterState { get; set; } - protected virtual StringBuilder AppendRequiredModifierTypeName(StringBuilder buf, RequiredModifierType type, DynamicParserContext context) + protected virtual StringBuilder AppendRequiredModifierTypeName(StringBuilder buf, RequiredModifierType type, IAttributeParserContext context) { return _AppendTypeName (buf, type.ElementType, context); } - protected virtual StringBuilder AppendOptionalModifierTypeName(StringBuilder buf, OptionalModifierType type, DynamicParserContext context) + protected virtual StringBuilder AppendOptionalModifierTypeName(StringBuilder buf, OptionalModifierType type, IAttributeParserContext context) { return _AppendTypeName(buf, type.ElementType, context); } - protected virtual StringBuilder AppendArrayTypeName(StringBuilder buf, TypeReference type, DynamicParserContext context) + protected virtual StringBuilder AppendArrayTypeName(StringBuilder buf, TypeReference type, IAttributeParserContext context) { - TypeSpecification spec = type as TypeSpecification; - _AppendTypeName(buf, spec != null ? spec.ElementType : type.GetElementType(), context); - return AppendArrayModifiers(buf, (ArrayType)type); + var elementType = type.GetElementType (); + if (type is TypeSpecification typeSpecification) + { + elementType = typeSpecification.ElementType; + } + + var isNullableType = false; + if (!elementType.IsValueType) + { + isNullableType = context.IsNullable (); + } + + _AppendTypeName (buf, elementType, context); + AppendNullableSymbol (buf, elementType, isNullableType); + + return AppendArrayModifiers (buf, (ArrayType)type); } protected virtual bool ShouldStripModFromTypeName @@ -129,7 +138,7 @@ namespace Mono.Documentation.Updater get => true; } - protected StringBuilder _AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection =false) + protected StringBuilder _AppendTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection =false) { if (type == null) return buf; @@ -167,9 +176,7 @@ namespace Mono.Documentation.Updater return SetBuffer(buf, interimBuilder, useTypeProjection: useTypeProjection); } - AppendNamespace (interimBuilder, type); - GenericInstanceType genInst = type as GenericInstanceType; if (type.IsRequiredModifier) { @@ -186,6 +193,12 @@ namespace Mono.Documentation.Updater } } + GenericInstanceType genInst = type as GenericInstanceType; + if (IsSpecialGenericNullableValueType (genInst)) // For special C# nullable value type only. + { + AppendSpecialGenericNullableValueTypeName (buf, genInst, context); + return SetBuffer (buf, interimBuilder, useTypeProjection: useTypeProjection); + } if (type.GenericParameters.Count == 0 && (genInst == null ? true : genInst.GenericArguments.Count == 0)) @@ -197,6 +210,18 @@ namespace Mono.Documentation.Updater return SetBuffer(buf, interimBuilder, useTypeProjection: useTypeProjection); } + protected virtual bool IsSpecialGenericNullableValueType(GenericInstanceType genInst) + { + // For special C# nullable value type only, the CSharpFullMemberFormatter subclass will override the method. + return false; + } + + protected virtual StringBuilder AppendSpecialGenericNullableValueTypeName(StringBuilder buf, GenericInstanceType genInst, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true) + { + // For special C# nullable value type only, the CSharpFullMemberFormatter subclass will override the method. + return buf; + } + private StringBuilder SetBuffer(StringBuilder buf, StringBuilder interimBuilder, bool useTypeProjection) { var interimResult = interimBuilder.ToString(); @@ -232,17 +257,16 @@ namespace Mono.Documentation.Updater return buf; } - protected virtual StringBuilder AppendFullTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context) + protected virtual StringBuilder AppendFullTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context) { if (type.DeclaringType != null) AppendFullTypeName (buf, type.DeclaringType, context).Append (NestedTypeSeparator); return AppendTypeName (buf, type, context); } - protected virtual StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context) + protected virtual StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context) { - if (context != null) - context.TransformIndex++; + context.NextDynamicFlag(); return AppendTypeName (buf, type.Name); } @@ -268,7 +292,7 @@ namespace Mono.Documentation.Updater get { return "@"; } } - protected virtual StringBuilder AppendRefTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context) + protected virtual StringBuilder AppendRefTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context) { TypeSpecification spec = type as TypeSpecification; return _AppendTypeName(buf, spec != null ? spec.ElementType : type.GetElementType(), context); @@ -279,7 +303,7 @@ namespace Mono.Documentation.Updater get { return "*"; } } - protected virtual StringBuilder AppendPointerTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context) + protected virtual StringBuilder AppendPointerTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context) { TypeSpecification spec = type as TypeSpecification; return _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType (), context) @@ -296,36 +320,39 @@ namespace Mono.Documentation.Updater get { return "."; } } - protected virtual StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection = true) + protected virtual StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = true) { - List<TypeReference> decls = DocUtils.GetDeclaringTypes ( - type is GenericInstanceType ? type.GetElementType () : type); - List<TypeReference> genArgs = GetGenericArguments (type); int argIdx = 0; int prev = 0; bool insertNested = false; + var declaringType = type is GenericInstanceType ? type.GetElementType () : type; + List<TypeReference> decls = DocUtils.GetDeclaringTypes (declaringType); + List<TypeReference> genArgs = GetGenericArguments (type); foreach (var decl in decls) { - TypeReference declDef = decl.Resolve () ?? decl; if (insertNested) { buf.Append (NestedTypeSeparator); } + insertNested = true; + TypeReference declDef = decl.Resolve () ?? decl; AppendTypeName (buf, declDef, context); int ac = DocUtils.GetGenericArgumentCount (declDef); int c = ac - prev; prev = ac; - if ( appendGeneric && c > 0) + if (appendGeneric && c > 0) { buf.Append (GenericTypeContainer[0]); var origState = MemberFormatterState; MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters; - _AppendTypeName (buf, genArgs[argIdx++], context, useTypeProjection: useTypeProjection); + AppendGenericTypeParameter (buf, genArgs[argIdx++], context, useTypeProjection); for (int i = 1; i < c; ++i) { - _AppendTypeName (buf.Append (","), genArgs[argIdx++], context, useTypeProjection: useTypeProjection); + buf.Append (","); + AppendGenericTypeParameter (buf, genArgs[argIdx++], context, useTypeProjection); } + MemberFormatterState = origState; buf.Append (GenericTypeContainer[1]); } @@ -333,6 +360,37 @@ namespace Mono.Documentation.Updater return buf; } + private void AppendGenericTypeParameter (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool useTypeProjection = true) + { + var isNullableType = false; + if (type is GenericInstanceType) + { + isNullableType = context.IsNullable(); + buf.Append(GetTypeName(type, context)); + } + else + { + if (!type.IsValueType) + { + isNullableType = context.IsNullable(); + } + + _AppendTypeName(buf, type, context, useTypeProjection: useTypeProjection); + } + + AppendNullableSymbol(buf, type, isNullableType); + } + + private StringBuilder AppendNullableSymbol (StringBuilder buf, TypeReference type, bool? isNullableType) + { + return buf.Append(GetTypeNullableSymbol(type, isNullableType)); + } + + protected virtual string GetTypeNullableSymbol(TypeReference type, bool? isNullableType) + { + return string.Empty; + } + protected List<TypeReference> GetGenericArguments (TypeReference type) { var args = new List<TypeReference> (); @@ -465,8 +523,7 @@ namespace Mono.Documentation.Updater if (buf.Length != 0) buf.Append (" "); - buf.Append (GetTypeName (method.ReturnType, new DynamicParserContext (method.MethodReturnType))).Append (" "); - + AppendReturnTypeName (buf, method); AppendMethodName (buf, method); AppendGenericMethod (buf, method).Append (" "); AppendParameters (buf, method, method.Parameters); @@ -474,6 +531,19 @@ namespace Mono.Documentation.Updater return buf.ToString (); } + + private StringBuilder AppendReturnTypeName (StringBuilder buf, MethodDefinition method) + { + var context = AttributeParserContext.Create (method.MethodReturnType); + var isNullableType = context.IsNullable (); + var returnTypeName = GetTypeName (method.ReturnType, context); + buf.Append (returnTypeName); + buf.Append (GetTypeNullableSymbol (method.ReturnType, isNullableType)); + buf.Append (" "); + + return buf; + } + protected virtual StringBuilder AppendMethodName (StringBuilder buf, MethodDefinition method) { return buf.Append (method.Name); diff --git a/mdoc/Mono.Documentation/Updater/Formatters/MsxdocSlashDocMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/MsxdocSlashDocMemberFormatter.cs index 09760e88..8d0beac3 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/MsxdocSlashDocMemberFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/MsxdocSlashDocMemberFormatter.cs @@ -7,7 +7,7 @@ namespace Mono.Documentation.Updater {
public MsxdocSlashDocMemberFormatter(TypeMap map) : base(map) { }
- protected override StringBuilder AppendRefTypeName(StringBuilder buf, TypeReference type, DynamicParserContext context)
+ protected override StringBuilder AppendRefTypeName(StringBuilder buf, TypeReference type, IAttributeParserContext context)
{
TypeSpecification spec = type as TypeSpecification;
return _AppendTypeName(buf, spec != null ? spec.ElementType : type.GetElementType(), context).Append(RefTypeModifier);
diff --git a/mdoc/Mono.Documentation/Updater/Formatters/SlashDocMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/SlashDocMemberFormatter.cs index 9a4122e4..4bb986fc 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/SlashDocMemberFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/SlashDocMemberFormatter.cs @@ -23,7 +23,7 @@ namespace Mono.Documentation.Updater public SlashDocMemberFormatter(TypeMap map) : base(map) { } - protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context) { if (type is GenericParameter) { @@ -82,7 +82,7 @@ namespace Mono.Documentation.Updater return buf; } - protected override StringBuilder AppendRefTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendRefTypeName (StringBuilder buf, TypeReference type, IAttributeParserContext context) { return base.AppendRefTypeName (buf, type, context).Append (RefTypeModifier); } @@ -102,7 +102,7 @@ namespace Mono.Documentation.Updater return buf.Append (ArrayDelimeters[1]); } - protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection = false) + protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false) { if (!AddTypeCount) base.AppendGenericType (buf, type, context); @@ -111,7 +111,7 @@ namespace Mono.Documentation.Updater return buf; } - private StringBuilder AppendType (StringBuilder buf, TypeReference type, DynamicParserContext context) + private StringBuilder AppendType (StringBuilder buf, TypeReference type, IAttributeParserContext context) { List<TypeReference> decls = DocUtils.GetDeclaringTypes (type); bool insertNested = false; diff --git a/mdoc/Mono.Documentation/Updater/Formatters/VBFullMemberFormatter.cs b/mdoc/Mono.Documentation/Updater/Formatters/VBFullMemberFormatter.cs index 24f1a3fe..92a74cec 100644 --- a/mdoc/Mono.Documentation/Updater/Formatters/VBFullMemberFormatter.cs +++ b/mdoc/Mono.Documentation/Updater/Formatters/VBFullMemberFormatter.cs @@ -67,7 +67,7 @@ namespace Mono.Documentation.Updater return typeToCompare == t ? null : typeToCompare; } - protected override StringBuilder AppendTypeName(StringBuilder buf, TypeReference type, DynamicParserContext context) + protected override StringBuilder AppendTypeName(StringBuilder buf, TypeReference type, IAttributeParserContext context) { if (type is GenericParameter) return AppendGenericParameterConstraints(buf, (GenericParameter)type, context).Append(type.Name); @@ -80,15 +80,14 @@ namespace Mono.Documentation.Updater string s = GetVBType(t); if (s != null) { - if (context != null) - context.TransformIndex++; + context.NextDynamicFlag(); return buf.Append(s); } return base.AppendTypeName(buf, type, context); } - private StringBuilder AppendGenericParameterConstraints(StringBuilder buf, GenericParameter type, DynamicParserContext context) + private StringBuilder AppendGenericParameterConstraints(StringBuilder buf, GenericParameter type, IAttributeParserContext context) { if (MemberFormatterState != MemberFormatterState.WithinGenericTypeParameters) return buf; @@ -128,7 +127,7 @@ namespace Mono.Documentation.Updater if (isFunction) { buf.Append(" As "); - buf.Append(full.GetName(invoke.ReturnType, new DynamicParserContext(invoke.MethodReturnType))).Append(" "); + buf.Append(full.GetName(invoke.ReturnType, AttributeParserContext.Create(invoke.MethodReturnType))).Append(" "); } return buf.ToString(); @@ -210,7 +209,7 @@ namespace Mono.Documentation.Updater } } - protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, DynamicParserContext context, bool appendGeneric = true, bool useTypeProjection = false) + protected override StringBuilder AppendGenericType(StringBuilder buf, TypeReference type, IAttributeParserContext context, bool appendGeneric = true, bool useTypeProjection = false) { List<TypeReference> decls = DocUtils.GetDeclaringTypes( type is GenericInstanceType ? type.GetElementType() : type); @@ -377,7 +376,7 @@ namespace Mono.Documentation.Updater AppendParameters(buf, method, method.Parameters); AppendGenericMethodConstraints(buf, method); if (isFunction) - buf.Append(" As ").Append(GetTypeName(method.ReturnType, new DynamicParserContext(method.MethodReturnType))); + buf.Append(" As ").Append(GetTypeName(method.ReturnType, AttributeParserContext.Create(method.MethodReturnType))); if (DocUtils.IsExplicitlyImplemented(method)) { @@ -581,7 +580,7 @@ namespace Mono.Documentation.Updater } buf.Append(parameter.Name); buf.Append(" As "); - buf.Append(GetTypeName(parameter.ParameterType, new DynamicParserContext(parameter))); + buf.Append(GetTypeName(parameter.ParameterType, AttributeParserContext.Create(parameter))); if (parameter.HasDefault && parameter.IsOptional && parameter.HasConstant) { var parameterValue = new AttributeFormatter().MakeAttributesValueString(parameter.Constant, parameter.ParameterType); @@ -658,7 +657,7 @@ namespace Mono.Documentation.Updater AppendParameters(buf, method, property.Parameters, '(', ')'); } buf.Append(" As "); - buf.Append(GetTypeName(property.PropertyType, new DynamicParserContext(property))); + buf.Append(GetTypeName(property.PropertyType, AttributeParserContext.Create(property))); if (DocUtils.IsExplicitlyImplemented(property.GetMethod)) { TypeReference iface; @@ -694,7 +693,7 @@ namespace Mono.Documentation.Updater buf.Append(" Const"); buf.Append(' ').Append(field.Name); - buf.Append(" As ").Append(GetTypeName(field.FieldType, new DynamicParserContext(field))).Append(' '); + buf.Append(" As ").Append(GetTypeName(field.FieldType, AttributeParserContext.Create(field))).Append(' '); DocUtils.AppendFieldValue(buf, field); return buf.ToString(); @@ -747,7 +746,7 @@ namespace Mono.Documentation.Updater buf.Append(e.Name.Split('.').Last()); else buf.Append(e.Name); - buf.Append(" As ").Append(GetTypeName(e.EventType, new DynamicParserContext(e.AddMethod.Parameters[0]))).Append(' '); + buf.Append(" As ").Append(GetTypeName(e.EventType, AttributeParserContext.Create(e.AddMethod.Parameters[0]))).Append(' '); if (isPublicEII) { var dotIndex = e.Name.LastIndexOf ('.'); dotIndex = dotIndex > -1 ? dotIndex : e.Name.Length; diff --git a/mdoc/Mono.Documentation/Updater/IAttributeParserContext.cs b/mdoc/Mono.Documentation/Updater/IAttributeParserContext.cs new file mode 100644 index 00000000..aca6ba21 --- /dev/null +++ b/mdoc/Mono.Documentation/Updater/IAttributeParserContext.cs @@ -0,0 +1,9 @@ +namespace Mono.Documentation.Updater +{ + public interface IAttributeParserContext + { + void NextDynamicFlag(); + bool IsDynamic(); + bool IsNullable(); + } +} diff --git a/mdoc/Mono.Documentation/Updater/NullableReferenceTypeProvider.cs b/mdoc/Mono.Documentation/Updater/NullableReferenceTypeProvider.cs new file mode 100644 index 00000000..8832a2a0 --- /dev/null +++ b/mdoc/Mono.Documentation/Updater/NullableReferenceTypeProvider.cs @@ -0,0 +1,163 @@ +using Mono.Cecil; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Mono.Documentation.Updater +{ + // About Nullable Reference Types: https://github.com/dotnet/roslyn/blob/master/docs/features/nullable-reference-types.md + // About Nullable Metadata: https://github.com/dotnet/roslyn/blob/master/docs/features/nullable-metadata.md + public class NullableReferenceTypeProvider + { + private const string NullableAttributeFullName = "System.Runtime.CompilerServices.NullableAttribute"; + private const string NullableContextAttributeFullName = "System.Runtime.CompilerServices.NullableContextAttribute"; + private const byte ObliviousNullableAttribute = 0; + private const byte NotAnnotatedNullableAttribute = 1; + private const byte AnnotatedNullableAttribute = 2; + + private ICustomAttributeProvider provider; + + public NullableReferenceTypeProvider(ICustomAttributeProvider provider) + { + this.provider = provider; + } + + public IList<bool?> GetNullableReferenceTypeFlags() + { + var nullableAttribute = FindNullableAttribute(); + + return GetTypeNullability(nullableAttribute); + } + + private CustomAttribute FindNullableAttribute() + { + string findAttributeName = NullableAttributeFullName; + foreach (var item in GetTypeNullableAttributes()) + { + CustomAttribute nullableAttribute = FindCustomAttribute(item, findAttributeName); + if (nullableAttribute != null) + { + return nullableAttribute; + } + + findAttributeName = NullableContextAttributeFullName; + } + + return null; + } + + private CustomAttribute FindCustomAttribute(ICustomAttributeProvider customAttributeProvider, string customAttributeName) + { + if (customAttributeProvider.HasCustomAttributes) + { + return customAttributeProvider.CustomAttributes.SingleOrDefault(a => a.AttributeType.FullName.Equals(customAttributeName)); + } + + return null; + } + + private IList<bool?> GetTypeNullability(CustomAttribute typeCustomAttribute) + { + if (typeCustomAttribute == null) + { + return new List<bool?> + { + null + }; + } + + var nullableAttributeValue = typeCustomAttribute.ConstructorArguments[0].Value; + if (nullableAttributeValue is CustomAttributeArgument[] nullableAttributeArguments) + { + return nullableAttributeArguments.Select(a => IsAnnotated((byte)a.Value)).ToList(); + } + + return new List<bool?> + { + IsAnnotated((byte)nullableAttributeValue) + }; + } + + private bool? IsAnnotated(byte value) + { + switch (value) + { + case AnnotatedNullableAttribute: + return true; + + case NotAnnotatedNullableAttribute: + return false; + + case ObliviousNullableAttribute: + return null; + } + + throw new ArgumentOutOfRangeException(nameof(value), value, $"The nullable attribute value is not a valid type argument."); + } + + private ICollection<ICustomAttributeProvider> GetTypeNullableAttributes() + { + if (provider is ParameterDefinition parameterDefinition) + { + return GetTypeNullableAttributes(parameterDefinition); + } + + if (provider is MethodReturnType methodReturnType) + { + return GetTypeNullableAttributes(methodReturnType); + } + + if (provider is PropertyDefinition propertyDefinition) + { + return GetTypeNullableAttributes(propertyDefinition); + } + + if (provider is FieldDefinition fieldDefinition) + { + return GetTypeNullableAttributes(fieldDefinition); + } + + throw new ArgumentException("We don't support this custom attribute provider type now.", nameof(provider)); + } + + private ICollection<ICustomAttributeProvider> GetTypeNullableAttributes(ParameterDefinition parameterDefinition) + { + return GetTypeNullableAttributes(parameterDefinition, parameterDefinition.Method as MethodDefinition); + } + + private ICollection<ICustomAttributeProvider> GetTypeNullableAttributes(MethodReturnType methodReturnType) + { + return GetTypeNullableAttributes(methodReturnType, methodReturnType.Method as MethodDefinition); + } + + private ICollection<ICustomAttributeProvider> GetTypeNullableAttributes(PropertyDefinition propertyDefinition) + { + return GetTypeNullableAttributes(propertyDefinition, propertyDefinition.GetMethod); + } + + private ICollection<ICustomAttributeProvider> GetTypeNullableAttributes(FieldDefinition fieldDefinition) + { + return new List<ICustomAttributeProvider> + { + fieldDefinition, + fieldDefinition.DeclaringType + }; + } + + private ICollection<ICustomAttributeProvider> GetTypeNullableAttributes(ICustomAttributeProvider customAttributeProvider, MethodDefinition methodDefinition) + { + var resultList = new List<ICustomAttributeProvider> + { + customAttributeProvider + }; + + if (methodDefinition != null) + { + resultList.Add(methodDefinition); + resultList.Add(methodDefinition.DeclaringType); + } + + return resultList; + } + } +} diff --git a/mdoc/Test/en.expected-fsharp-wsl/Delegates+Delegate1.xml b/mdoc/Test/en.expected-fsharp-wsl/Delegates+Delegate1.xml index 35c80296..b9a1134c 100644 --- a/mdoc/Test/en.expected-fsharp-wsl/Delegates+Delegate1.xml +++ b/mdoc/Test/en.expected-fsharp-wsl/Delegates+Delegate1.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate1" FullName="Delegates+Delegate1"> - <TypeSignature Language="C#" Value="public delegate int Delegates.Delegate1((int,int) );" /> + <TypeSignature Language="C#" Value="public delegate int Delegates.Delegate1(Tuple<int,int> );" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate1 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate1 = delegate of (int * int) -> int" /> <AssemblyInfo> diff --git a/mdoc/Test/en.expected-fsharp-wsl/Delegates+Delegate9.xml b/mdoc/Test/en.expected-fsharp-wsl/Delegates+Delegate9.xml index 877a09ed..7da4ac51 100644 --- a/mdoc/Test/en.expected-fsharp-wsl/Delegates+Delegate9.xml +++ b/mdoc/Test/en.expected-fsharp-wsl/Delegates+Delegate9.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate9" FullName="Delegates+Delegate9"> - <TypeSignature Language="C#" Value="public delegate char Delegates.Delegate9((int,int) );" /> + <TypeSignature Language="C#" Value="public delegate char Delegates.Delegate9(Tuple<int,int> );" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate9 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate9 = delegate of (int * int) -> char" /> <AssemblyInfo> diff --git a/mdoc/Test/en.expected-fsharp-wsl/PatternMatching/PatternMatchingExamples.xml b/mdoc/Test/en.expected-fsharp-wsl/PatternMatching/PatternMatchingExamples.xml index 9a9db62e..6894bbba 100644 --- a/mdoc/Test/en.expected-fsharp-wsl/PatternMatching/PatternMatchingExamples.xml +++ b/mdoc/Test/en.expected-fsharp-wsl/PatternMatching/PatternMatchingExamples.xml @@ -588,7 +588,7 @@ </Docs> </Member> <Member MemberName="tuple1"> - <MemberSignature Language="C#" Value="public static (int,int) tuple1 { get; }" /> + <MemberSignature Language="C#" Value="public static Tuple<int,int> tuple1 { get; }" /> <MemberSignature Language="ILAsm" Value=".property class System.Tuple`2<int32, int32> tuple1" /> <MemberSignature Language="F#" Value="PatternMatching.PatternMatchingExamples.tuple1 : int * int" Usage="PatternMatching.PatternMatchingExamples.tuple1" /> <MemberType>Property</MemberType> diff --git a/mdoc/Test/en.expected-fsharp/AbstractClasses+Shape2D.xml b/mdoc/Test/en.expected-fsharp/AbstractClasses+Shape2D.xml index fa5f3eee..fc640bb7 100644 --- a/mdoc/Test/en.expected-fsharp/AbstractClasses+Shape2D.xml +++ b/mdoc/Test/en.expected-fsharp/AbstractClasses+Shape2D.xml @@ -131,9 +131,9 @@ </Docs> </Member> <Member MemberName="Rotate2"> - <MemberSignature Language="C#" Value="public abstract void Rotate2 (double );" /> - <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance void Rotate2(float64 ) cil managed" /> - <MemberSignature Language="F#" Value="abstract member Rotate2 : double -> unit" Usage="shape2D.Rotate2 " /> + <MemberSignature Language="C#" Value="public abstract void Rotate2 (double unnamedParam1);" /> + <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance void Rotate2(float64 unnamedParam1) cil managed" /> + <MemberSignature Language="F#" Value="abstract member Rotate2 : double -> unit" Usage="shape2D.Rotate2 unnamedParam1" /> <MemberType>Method</MemberType> <AssemblyInfo> <AssemblyVersion>1.0.0.0</AssemblyVersion> @@ -142,10 +142,10 @@ <ReturnType>System.Void</ReturnType> </ReturnValue> <Parameters> - <Parameter Name="" Type="System.Double" /> + <Parameter Name="unnamedParam1" Type="System.Double" /> </Parameters> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <remarks>To be added.</remarks> </Docs> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate1.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate1.xml index 35c80296..5024229d 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate1.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate1.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate1" FullName="Delegates+Delegate1"> - <TypeSignature Language="C#" Value="public delegate int Delegates.Delegate1((int,int) );" /> + <TypeSignature Language="C#" Value="public delegate int Delegates.Delegate1(Tuple<int,int> unnamedParam1);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate1 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate1 = delegate of (int * int) -> int" /> <AssemblyInfo> @@ -20,13 +20,13 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="System.Tuple<System.Int32,System.Int32>" /> + <Parameter Name="unnamedParam1" Type="System.Tuple<System.Int32,System.Int32>" /> </Parameters> <ReturnValue> <ReturnType>System.Int32</ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate10.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate10.xml index 588b0bb0..3bfae723 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate10.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate10.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate10" FullName="Delegates+Delegate10"> - <TypeSignature Language="C#" Value="public delegate char Delegates.Delegate10(int , int );" /> + <TypeSignature Language="C#" Value="public delegate char Delegates.Delegate10(int unnamedParam1, int unnamedParam2);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate10 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate10 = delegate of int * int -> char" /> <AssemblyInfo> @@ -20,15 +20,15 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="System.Int32" /> - <Parameter Name="" Type="System.Int32" /> + <Parameter Name="unnamedParam1" Type="System.Int32" /> + <Parameter Name="unnamedParam2" Type="System.Int32" /> </Parameters> <ReturnValue> <ReturnType>System.Char</ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> + <param name="unnamedParam2">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate11.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate11.xml index 634e0384..e7c9088b 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate11.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate11.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate11" FullName="Delegates+Delegate11"> - <TypeSignature Language="C#" Value="public delegate void Delegates.Delegate11(char );" /> + <TypeSignature Language="C#" Value="public delegate void Delegates.Delegate11(char unnamedParam1);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate11 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate11 = delegate of char -> unit" /> <AssemblyInfo> @@ -20,13 +20,13 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="System.Char" /> + <Parameter Name="unnamedParam1" Type="System.Char" /> </Parameters> <ReturnValue> <ReturnType>System.Void</ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <remarks>To be added.</remarks> </Docs> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate13.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate13.xml index 32171f31..840c239c 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate13.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate13.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate13" FullName="Delegates+Delegate13"> - <TypeSignature Language="C#" Value="public delegate double Delegates.Delegate13(FSharpFunc<int,FSharpFunc<char,FSharpFunc<string,decimal>>> );" /> + <TypeSignature Language="C#" Value="public delegate double Delegates.Delegate13(FSharpFunc<int,FSharpFunc<char,FSharpFunc<string,decimal>>> unnamedParam1);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate13 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate13 = delegate of (int -> char -> string -> decimal) -> double" /> <AssemblyInfo> @@ -20,13 +20,13 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="Microsoft.FSharp.Core.FSharpFunc<System.Int32,Microsoft.FSharp.Core.FSharpFunc<System.Char,Microsoft.FSharp.Core.FSharpFunc<System.String,System.Decimal>>>" /> + <Parameter Name="unnamedParam1" Type="Microsoft.FSharp.Core.FSharpFunc<System.Int32,Microsoft.FSharp.Core.FSharpFunc<System.Char,Microsoft.FSharp.Core.FSharpFunc<System.String,System.Decimal>>>" /> </Parameters> <ReturnValue> <ReturnType>System.Double</ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate2.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate2.xml index 294962fe..97bb177b 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate2.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate2.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate2" FullName="Delegates+Delegate2"> - <TypeSignature Language="C#" Value="public delegate int Delegates.Delegate2(int , int );" /> + <TypeSignature Language="C#" Value="public delegate int Delegates.Delegate2(int unnamedParam1, int unnamedParam2);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate2 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate2 = delegate of int * int -> int" /> <AssemblyInfo> @@ -20,15 +20,15 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="System.Int32" /> - <Parameter Name="" Type="System.Int32" /> + <Parameter Name="unnamedParam1" Type="System.Int32" /> + <Parameter Name="unnamedParam2" Type="System.Int32" /> </Parameters> <ReturnValue> <ReturnType>System.Int32</ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> + <param name="unnamedParam2">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate3.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate3.xml index 7277a35d..6ab632ce 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate3.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate3.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate3" FullName="Delegates+Delegate3"> - <TypeSignature Language="C#" Value="public delegate string Delegates.Delegate3(int , char );" /> + <TypeSignature Language="C#" Value="public delegate string Delegates.Delegate3(int unnamedParam1, char unnamedParam2);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate3 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate3 = delegate of int * char -> string" /> <AssemblyInfo> @@ -20,15 +20,15 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="System.Int32" /> - <Parameter Name="" Type="System.Char" /> + <Parameter Name="unnamedParam1" Type="System.Int32" /> + <Parameter Name="unnamedParam2" Type="System.Char" /> </Parameters> <ReturnValue> <ReturnType>System.String</ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> + <param name="unnamedParam2">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate4.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate4.xml index 969f28ba..add42ee2 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate4.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate4.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate4" FullName="Delegates+Delegate4"> - <TypeSignature Language="C#" Value="public delegate Microsoft.FSharp.Core.FSharpFunc<int,char> Delegates.Delegate4(int );" /> + <TypeSignature Language="C#" Value="public delegate Microsoft.FSharp.Core.FSharpFunc<int,char> Delegates.Delegate4(int unnamedParam1);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate4 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate4 = delegate of int -> (int -> char)" /> <AssemblyInfo> @@ -20,13 +20,13 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="System.Int32" /> + <Parameter Name="unnamedParam1" Type="System.Int32" /> </Parameters> <ReturnValue> <ReturnType>Microsoft.FSharp.Core.FSharpFunc<System.Int32,System.Char></ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate5.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate5.xml index b72d9777..29384c34 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate5.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate5.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate5" FullName="Delegates+Delegate5"> - <TypeSignature Language="C#" Value="public delegate Microsoft.FSharp.Core.FSharpFunc<int,Microsoft.FSharp.Core.FSharpFunc<char,string>> Delegates.Delegate5(int );" /> + <TypeSignature Language="C#" Value="public delegate Microsoft.FSharp.Core.FSharpFunc<int,Microsoft.FSharp.Core.FSharpFunc<char,string>> Delegates.Delegate5(int unnamedParam1);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate5 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate5 = delegate of int -> (int -> char -> string)" /> <AssemblyInfo> @@ -20,13 +20,13 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="System.Int32" /> + <Parameter Name="unnamedParam1" Type="System.Int32" /> </Parameters> <ReturnValue> <ReturnType>Microsoft.FSharp.Core.FSharpFunc<System.Int32,Microsoft.FSharp.Core.FSharpFunc<System.Char,System.String>></ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate6.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate6.xml index 241f52d3..33cc504c 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate6.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate6.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate6" FullName="Delegates+Delegate6"> - <TypeSignature Language="C#" Value="public delegate char Delegates.Delegate6(FSharpFunc<int,double> );" /> + <TypeSignature Language="C#" Value="public delegate char Delegates.Delegate6(FSharpFunc<int,double> unnamedParam1);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate6 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate6 = delegate of (int -> double) -> char" /> <AssemblyInfo> @@ -20,13 +20,13 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="Microsoft.FSharp.Core.FSharpFunc<System.Int32,System.Double>" /> + <Parameter Name="unnamedParam1" Type="Microsoft.FSharp.Core.FSharpFunc<System.Int32,System.Double>" /> </Parameters> <ReturnValue> <ReturnType>System.Char</ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate7.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate7.xml index 5f88bcf9..fb40e142 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate7.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate7.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate7" FullName="Delegates+Delegate7"> - <TypeSignature Language="C#" Value="public delegate double Delegates.Delegate7(FSharpFunc<int,FSharpFunc<char,string>> );" /> + <TypeSignature Language="C#" Value="public delegate double Delegates.Delegate7(FSharpFunc<int,FSharpFunc<char,string>> unnamedParam1);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate7 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate7 = delegate of (int -> char -> string) -> double" /> <AssemblyInfo> @@ -20,13 +20,13 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="Microsoft.FSharp.Core.FSharpFunc<System.Int32,Microsoft.FSharp.Core.FSharpFunc<System.Char,System.String>>" /> + <Parameter Name="unnamedParam1" Type="Microsoft.FSharp.Core.FSharpFunc<System.Int32,Microsoft.FSharp.Core.FSharpFunc<System.Char,System.String>>" /> </Parameters> <ReturnValue> <ReturnType>System.Double</ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate8.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate8.xml index 1f3713a9..158bccc6 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate8.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate8.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate8" FullName="Delegates+Delegate8"> - <TypeSignature Language="C#" Value="public delegate char Delegates.Delegate8(int );" /> + <TypeSignature Language="C#" Value="public delegate char Delegates.Delegate8(int unnamedParam1);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate8 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate8 = delegate of int -> char" /> <AssemblyInfo> @@ -20,13 +20,13 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="System.Int32" /> + <Parameter Name="unnamedParam1" Type="System.Int32" /> </Parameters> <ReturnValue> <ReturnType>System.Char</ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Delegates+Delegate9.xml b/mdoc/Test/en.expected-fsharp/Delegates+Delegate9.xml index 877a09ed..48b52f5e 100644 --- a/mdoc/Test/en.expected-fsharp/Delegates+Delegate9.xml +++ b/mdoc/Test/en.expected-fsharp/Delegates+Delegate9.xml @@ -1,5 +1,5 @@ <Type Name="Delegates+Delegate9" FullName="Delegates+Delegate9"> - <TypeSignature Language="C#" Value="public delegate char Delegates.Delegate9((int,int) );" /> + <TypeSignature Language="C#" Value="public delegate char Delegates.Delegate9(Tuple<int,int> unnamedParam1);" /> <TypeSignature Language="ILAsm" Value=".class nested public auto ansi serializable sealed Delegates/Delegate9 extends System.MulticastDelegate" /> <TypeSignature Language="F#" Value="type Delegates.Delegate9 = delegate of (int * int) -> char" /> <AssemblyInfo> @@ -20,13 +20,13 @@ </Attribute> </Attributes> <Parameters> - <Parameter Name="" Type="System.Tuple<System.Int32,System.Int32>" /> + <Parameter Name="unnamedParam1" Type="System.Tuple<System.Int32,System.Int32>" /> </Parameters> <ReturnValue> <ReturnType>System.Char</ReturnType> </ReturnValue> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Interfaces+Interface0.xml b/mdoc/Test/en.expected-fsharp/Interfaces+Interface0.xml index cb47a026..63dcede2 100644 --- a/mdoc/Test/en.expected-fsharp/Interfaces+Interface0.xml +++ b/mdoc/Test/en.expected-fsharp/Interfaces+Interface0.xml @@ -23,9 +23,9 @@ </Docs> <Members> <Member MemberName="Method1"> - <MemberSignature Language="C#" Value="public int Method1 (int );" /> - <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance int32 Method1(int32 ) cil managed" /> - <MemberSignature Language="F#" Value="abstract member Method1 : int -> int" Usage="interface0.Method1 " /> + <MemberSignature Language="C#" Value="public int Method1 (int unnamedParam1);" /> + <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance int32 Method1(int32 unnamedParam1) cil managed" /> + <MemberSignature Language="F#" Value="abstract member Method1 : int -> int" Usage="interface0.Method1 unnamedParam1" /> <MemberType>Method</MemberType> <AssemblyInfo> <AssemblyVersion>1.0.0.0</AssemblyVersion> @@ -34,10 +34,10 @@ <ReturnType>System.Int32</ReturnType> </ReturnValue> <Parameters> - <Parameter Name="" Type="System.Int32" /> + <Parameter Name="unnamedParam1" Type="System.Int32" /> </Parameters> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Interfaces+Interface1.xml b/mdoc/Test/en.expected-fsharp/Interfaces+Interface1.xml index 9ed7d805..4d946f12 100644 --- a/mdoc/Test/en.expected-fsharp/Interfaces+Interface1.xml +++ b/mdoc/Test/en.expected-fsharp/Interfaces+Interface1.xml @@ -23,9 +23,9 @@ </Docs> <Members> <Member MemberName="Method1"> - <MemberSignature Language="C#" Value="public int Method1 (int );" /> - <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance int32 Method1(int32 ) cil managed" /> - <MemberSignature Language="F#" Value="abstract member Method1 : int -> int" Usage="interface1.Method1 " /> + <MemberSignature Language="C#" Value="public int Method1 (int unnamedParam1);" /> + <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance int32 Method1(int32 unnamedParam1) cil managed" /> + <MemberSignature Language="F#" Value="abstract member Method1 : int -> int" Usage="interface1.Method1 unnamedParam1" /> <MemberType>Method</MemberType> <AssemblyInfo> <AssemblyVersion>1.0.0.0</AssemblyVersion> @@ -34,10 +34,10 @@ <ReturnType>System.Int32</ReturnType> </ReturnValue> <Parameters> - <Parameter Name="" Type="System.Int32" /> + <Parameter Name="unnamedParam1" Type="System.Int32" /> </Parameters> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Interfaces+Interface2.xml b/mdoc/Test/en.expected-fsharp/Interfaces+Interface2.xml index 06023a4f..73c7d650 100644 --- a/mdoc/Test/en.expected-fsharp/Interfaces+Interface2.xml +++ b/mdoc/Test/en.expected-fsharp/Interfaces+Interface2.xml @@ -23,9 +23,9 @@ </Docs> <Members> <Member MemberName="Method2"> - <MemberSignature Language="C#" Value="public int Method2 (int );" /> - <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance int32 Method2(int32 ) cil managed" /> - <MemberSignature Language="F#" Value="abstract member Method2 : int -> int" Usage="interface2.Method2 " /> + <MemberSignature Language="C#" Value="public int Method2 (int unnamedParam1);" /> + <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance int32 Method2(int32 unnamedParam1) cil managed" /> + <MemberSignature Language="F#" Value="abstract member Method2 : int -> int" Usage="interface2.Method2 unnamedParam1" /> <MemberType>Method</MemberType> <AssemblyInfo> <AssemblyVersion>1.0.0.0</AssemblyVersion> @@ -34,10 +34,10 @@ <ReturnType>System.Int32</ReturnType> </ReturnValue> <Parameters> - <Parameter Name="" Type="System.Int32" /> + <Parameter Name="unnamedParam1" Type="System.Int32" /> </Parameters> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/Interfaces+Interface3.xml b/mdoc/Test/en.expected-fsharp/Interfaces+Interface3.xml index 405b4458..079c290a 100644 --- a/mdoc/Test/en.expected-fsharp/Interfaces+Interface3.xml +++ b/mdoc/Test/en.expected-fsharp/Interfaces+Interface3.xml @@ -30,9 +30,9 @@ </Docs> <Members> <Member MemberName="Method3"> - <MemberSignature Language="C#" Value="public int Method3 (int );" /> - <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance int32 Method3(int32 ) cil managed" /> - <MemberSignature Language="F#" Value="abstract member Method3 : int -> int" Usage="interface3.Method3 " /> + <MemberSignature Language="C#" Value="public int Method3 (int unnamedParam1);" /> + <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance int32 Method3(int32 unnamedParam1) cil managed" /> + <MemberSignature Language="F#" Value="abstract member Method3 : int -> int" Usage="interface3.Method3 unnamedParam1" /> <MemberType>Method</MemberType> <AssemblyInfo> <AssemblyVersion>1.0.0.0</AssemblyVersion> @@ -41,10 +41,10 @@ <ReturnType>System.Int32</ReturnType> </ReturnValue> <Parameters> - <Parameter Name="" Type="System.Int32" /> + <Parameter Name="unnamedParam1" Type="System.Int32" /> </Parameters> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples.xml b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples.xml index 9a9db62e..6894bbba 100644 --- a/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples.xml +++ b/mdoc/Test/en.expected-fsharp/PatternMatching/PatternMatchingExamples.xml @@ -588,7 +588,7 @@ </Docs> </Member> <Member MemberName="tuple1"> - <MemberSignature Language="C#" Value="public static (int,int) tuple1 { get; }" /> + <MemberSignature Language="C#" Value="public static Tuple<int,int> tuple1 { get; }" /> <MemberSignature Language="ILAsm" Value=".property class System.Tuple`2<int32, int32> tuple1" /> <MemberSignature Language="F#" Value="PatternMatching.PatternMatchingExamples.tuple1 : int * int" Usage="PatternMatching.PatternMatchingExamples.tuple1" /> <MemberType>Property</MemberType> diff --git a/mdoc/Test/en.expected-fsharp/SomeNamespace/SomeModule+IVector.xml b/mdoc/Test/en.expected-fsharp/SomeNamespace/SomeModule+IVector.xml index 24013a92..bac8e490 100644 --- a/mdoc/Test/en.expected-fsharp/SomeNamespace/SomeModule+IVector.xml +++ b/mdoc/Test/en.expected-fsharp/SomeNamespace/SomeModule+IVector.xml @@ -23,9 +23,9 @@ </Docs> <Members> <Member MemberName="Scale"> - <MemberSignature Language="C#" Value="public SomeNamespace.SomeModule.IVector Scale (double );" /> - <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance class SomeNamespace.SomeModule/IVector Scale(float64 ) cil managed" /> - <MemberSignature Language="F#" Value="abstract member Scale : double -> SomeNamespace.SomeModule.IVector" Usage="iVector.Scale " /> + <MemberSignature Language="C#" Value="public SomeNamespace.SomeModule.IVector Scale (double unnamedParam1);" /> + <MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance class SomeNamespace.SomeModule/IVector Scale(float64 unnamedParam1) cil managed" /> + <MemberSignature Language="F#" Value="abstract member Scale : double -> SomeNamespace.SomeModule.IVector" Usage="iVector.Scale unnamedParam1" /> <MemberType>Method</MemberType> <AssemblyInfo> <AssemblyVersion>1.0.0.0</AssemblyVersion> @@ -34,10 +34,10 @@ <ReturnType>SomeNamespace.SomeModule+IVector</ReturnType> </ReturnValue> <Parameters> - <Parameter Name="" Type="System.Double" /> + <Parameter Name="unnamedParam1" Type="System.Double" /> </Parameters> <Docs> - <param name="">To be added.</param> + <param name="unnamedParam1">To be added.</param> <summary>To be added.</summary> <returns>To be added.</returns> <remarks>To be added.</remarks> diff --git a/mdoc/mdoc.Test/BasicTests.cs b/mdoc/mdoc.Test/BasicTests.cs index adf2d639..61f8bbb4 100644 --- a/mdoc/mdoc.Test/BasicTests.cs +++ b/mdoc/mdoc.Test/BasicTests.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Xml.Linq; using Mono.Cecil; -using Mono.Documentation.Framework; using Mono.Documentation.Updater; namespace mdoc.Test @@ -23,7 +22,7 @@ namespace mdoc.Test if (!moduleCash.ContainsKey(filepath)) { var fullpath = Path.Combine (Path.GetDirectoryName (this.GetType ().Module.Assembly.Location), filepath); - var resolver = new DefaultAssemblyResolver (); + var resolver = new DotnetCoreAssemblyResolver (); var testAssemblyPath = Path.GetDirectoryName (this.GetType ().Module.Assembly.Location); resolver.AddSearchDirectory (testAssemblyPath); @@ -46,7 +45,7 @@ namespace mdoc.Test throw new Exception($"Test was unable to find type {classname}"); } - var typeDef = testclass.Resolve(); + var typeDef = DocUtils.FixUnnamedParameters(testclass.Resolve()); typesCash.Add(classname, typeDef); return typeDef; } diff --git a/mdoc/mdoc.Test/DotnetCoreAssemblyResolver.cs b/mdoc/mdoc.Test/DotnetCoreAssemblyResolver.cs new file mode 100644 index 00000000..a0feab52 --- /dev/null +++ b/mdoc/mdoc.Test/DotnetCoreAssemblyResolver.cs @@ -0,0 +1,106 @@ +using Mono.Cecil; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace mdoc.Test +{ + // Fix DefaultAssemblyResolver don't load .NET Core platform assemblies in macOS, WSL, and Ubuntu OS environment. + public class DotnetCoreAssemblyResolver : DefaultAssemblyResolver + { + public DotnetCoreAssemblyResolver() + { + AddDotnetCoreToSearchDirectory(); + } + + private void AddDotnetCoreToSearchDirectory() + { + if (Environment.OSVersion.Platform == PlatformID.Unix || + Environment.OSVersion.Platform == PlatformID.MacOSX) + { + var latestDotnetCorePath = GetLatestPlatformAssembliesPath(); + if (string.IsNullOrEmpty(latestDotnetCorePath)) + { + Console.WriteLine("The platform assemblies of .NET Core was not found, do you have .NET Core installed?"); + } + + AddSearchDirectory(latestDotnetCorePath); + } + } + + private string GetLatestPlatformAssembliesPath() + { + SortedList<Version, string> versionResults = new SortedList<Version, string>(); + foreach (var installedSdkVersion in GetInstalledSdkVersions()) + { + if (File.Exists(Path.Combine(installedSdkVersion, "System.dll"))) + { + Version sdkVersion; + DirectoryInfo sdkDirectoryInfo = new DirectoryInfo(installedSdkVersion); + if (Version.TryParse(sdkDirectoryInfo.Name, out sdkVersion)) + { + versionResults.Add(sdkVersion, installedSdkVersion); + } + } + } + + return versionResults.LastOrDefault().Value; + } + + private string[] GetInstalledSdkVersions() + { + var dotnetCorePackagesPath = GetDotnetCorePath(); + if (Directory.Exists(dotnetCorePackagesPath)) + { + return Directory.GetDirectories(dotnetCorePackagesPath); + } + + return Array.Empty<string>(); + } + + private string GetDotnetCorePath() + { + var dotnetCorePath = GetMacOSDotnetCorePath(); + if (string.IsNullOrEmpty(dotnetCorePath)) + { + dotnetCorePath = GetLinuxDotnetCorePath(); + } + + if (!Directory.Exists(dotnetCorePath)) + { + Console.WriteLine($"The path of .NET Core was not found, do you have .NET Core installed? {dotnetCorePath}"); + } + + return dotnetCorePath; + } + + private string GetMacOSDotnetCorePath() + { + var macOSDotnetCorePath = GetAzureMacOSDotnetCorePath(); + if (string.IsNullOrEmpty(macOSDotnetCorePath)) + { + // Hard code the local path of .NET Core for macOS. + macOSDotnetCorePath = "/usr/local/share/dotnet/shared/Microsoft.NETCore.App"; + } + + return Directory.Exists(macOSDotnetCorePath) ? macOSDotnetCorePath : string.Empty; + } + + private string GetAzureMacOSDotnetCorePath() + { + var azureMacOSDotnetCorePath = Environment.GetEnvironmentVariable("DOTNET_ROOT"); + if (!string.IsNullOrEmpty(azureMacOSDotnetCorePath)) + { + return Path.Combine(azureMacOSDotnetCorePath, "shared/Microsoft.NETCore.App"); + } + + return string.Empty; + } + + private string GetLinuxDotnetCorePath() + { + return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "dotnet/shared/Microsoft.NETCore.App"); + } + } +} diff --git a/mdoc/mdoc.Test/NullableReferenceTypesTests.cs b/mdoc/mdoc.Test/NullableReferenceTypesTests.cs new file mode 100644 index 00000000..fb8af0e4 --- /dev/null +++ b/mdoc/mdoc.Test/NullableReferenceTypesTests.cs @@ -0,0 +1,305 @@ +using Mono.Documentation; +using Mono.Documentation.Updater.Formatters; +using NUnit.Framework; +using System; +using System.Linq; + +namespace mdoc.Test +{ + public class NullableReferenceTypesTests : BasicFormatterTests<CSharpMemberFormatter> + { + private const string NullableReferenceTypesAssemblyPath = "../../../../external/Test/mdoc.Test.NullableReferenceTypes.dll"; + + private CSharpMemberFormatter csharpMemberFormatter = new CSharpMemberFormatter(); + + protected override CSharpMemberFormatter formatter => csharpMemberFormatter; + + [TestCase("dynamic", "DynamicType")] + [TestCase("dynamic?", "NullableDynamicType")] + [TestCase("DayOfWeek", "Enumeration")] + [TestCase("DayOfWeek?", "NullableEnumeration")] + [TestCase("int", "ValueType")] + [TestCase("int?", "NullableValueType")] + [TestCase("int[]", "ArrayOfValueType")] + [TestCase("int?[]", "ArrayOfValueTypeNullable")] + [TestCase("int[]?", "NullableArrayOfValueType")] + [TestCase("int?[]?", "NullableArrayOfNullableValueType")] + [TestCase("int[][]", "DimensionalArrayOfValueType")] + [TestCase("int?[][]", "DimensionalArrayOfNullableValueType")] + [TestCase("int?[]?[]", "DimensionalArrayOfNullableValueTypeOfNullableRow")] + [TestCase("int?[]?[]?", "NullableDimensionalArrayOfNullableValueTypeOfNullableRow")] + [TestCase("int?[][]?", "NullableDimensionalArrayOfNullableValueType")] + [TestCase("int[][]?", "NullableDimensionalArrayOfValueType")] + [TestCase("int[][]?[][]?", "NullableFourDimensionalArrayOfValueTypeOfMiddleNullableArray")] + [TestCase("int?[][]?[][]", "FourDimensionalArrayOfNullableValueTypeOfMiddleNullableArray")] + [TestCase("Tuple<int,int>", "TupleOfValueType")] + [TestCase("Tuple<int,int>?", "NullableTupleOfValueType")] + [TestCase("Tuple<int?,int?>", "TupleOfNullableValueType")] + [TestCase("Tuple<int?,int?>?", "NullableTupleOfNullableValueType")] + [TestCase("(int,int)", "ValueTupleOfValueType")] + [TestCase("(int,int)?", "NullableValueTupleOfValueType")] + [TestCase("(int?,int?)", "ValueTupleOfNullableValueType")] + [TestCase("(int?,int?)?", "NullableValueTupleOfNullableValueType")] + [TestCase("ICollection<int>", "InterfaceOfValueType")] + [TestCase("ICollection<int>?", "NullableInterfaceOfValueType")] + [TestCase("ICollection<int?>?", "NullableInterfaceOfNullableValueType")] + [TestCase("Action<int>", "ActionOfValueType")] + [TestCase("Action<int?>", "ActionOfNullableValueType")] + [TestCase("Action<int>?", "NullableActionOfValueType")] + [TestCase("Action<int?>?", "NullableActionOfNullableValueType")] + [TestCase("Dictionary<int,int>", "DictionaryOfValueType")] + [TestCase("Dictionary<int,int>?", "NullableDictionaryOfValueType")] + [TestCase("Dictionary<int?,int?>", "DictionaryOfNullableValueType")] + [TestCase("Dictionary<int?,int?>?", "NullableDictionaryOfNullableValueType")] + [TestCase("Dictionary<int,int?>", "DictionaryOfNullableValueTypeValue")] + [TestCase("Dictionary<int,int?>?", "NullableDictionaryOfNullableValueTypeValue")] + [TestCase("Dictionary<int?,int>?", "NullableDictionaryOfNullableValueTypeKey")] + [TestCase("Dictionary<int,Dictionary<int,int>>", "DictionaryOfValueTypeKeyAndDictionaryOfValueTypeValue")] + [TestCase("Dictionary<int,Dictionary<int,int>>?", "NullableDictionaryOfValueTypeKeyAndDictionaryOfValueTypeValue")] + [TestCase("Dictionary<int?,Dictionary<int,int>?>?", "NullableDictionaryOfNullableValueTypeKeyAndNullableDictionaryOfValueTypeValue")] + [TestCase("Dictionary<int?,Dictionary<int?,int?>?>?", "NullableDictionaryOfNullableValueTypeKeyAndNullableDictionaryOfNullableValueTypeValue")] + [TestCase("Dictionary<int,Tuple<int,int>>", "DictionaryOfValueTypeKeyAndTupleOfValueTypeValue")] + [TestCase("Dictionary<int,Tuple<int,int>>?", "NullableDictionaryOfValueTypeKeyAndTupleOfValueTypeValue")] + [TestCase("Dictionary<int?,Tuple<int,int>?>?", "NullableDictionaryOfNullableValueTypeKeyAndNullableTupleOfValueTypeValue")] + [TestCase("Dictionary<int?,Tuple<int?,int?>?>?", "NullableDictionaryOfNullableValueTypeKeyAndNullableTupleOfNullableValueTypeValue")] + [TestCase("Dictionary<Dictionary<int,int>,Dictionary<int,int>>", "DictionaryOfDictionaryOfValueType")] + [TestCase("Dictionary<Dictionary<int,int>?,Dictionary<int,int>?>?", "NullableDictionaryOfNullableDictionaryOfValueType")] + [TestCase("Dictionary<Dictionary<int?,int?>?,Dictionary<int?,int?>?>?", "NullableDictionaryOfNullableDictionaryOfNullableValueType")] + [TestCase("string", "ReferenceType")] + [TestCase("string?", "NullableReferenceType")] + [TestCase("string[]", "ArrayOfReferenceType")] + [TestCase("string?[]", "ArrayOfNullableReferenceType")] + [TestCase("string[]?", "NullableArrayOfReferenceType")] + [TestCase("string?[]?", "NullableArrayOfNullableReferenceType")] + [TestCase("string[][]", "DimensionalArrayOfReferenceType")] + [TestCase("string?[][]", "DimensionalArrayOfNullableReferenceType")] + [TestCase("string?[]?[]", "DimensionalArrayOfNullableReferenceTypeOfNullableRow")] + [TestCase("string?[]?[]?", "NullableDimensionalArrayOfNullableReferenceTypeOfNullableRow")] + [TestCase("string?[][]?", "NullableDimensionalArrayOfNullableReferenceType")] + [TestCase("string[][]?", "NullableDimensionalArrayOfReferenceType")] + [TestCase("string[][]?[][]?", "NullableFourDimensionalArrayOfReferenceTypeOfMiddleNullableArray")] + [TestCase("string?[][]?[][]", "FourDimensionalArrayOfNullableReferenceTypeOfMiddleNullableArray")] + [TestCase("Tuple<string,string>", "TupleOfReferenceType")] + [TestCase("Tuple<string,string>?", "NullableTupleOfReferenceType")] + [TestCase("Tuple<string?,string?>", "TupleOfNullableReferenceType")] + [TestCase("Tuple<string?,string?>?", "NullableTupleOfNullableReferenceType")] + [TestCase("(string,string)", "ValueTupleOfReferenceType")] + [TestCase("(string,string)?", "NullableValueTupleOfReferenceType")] + [TestCase("(string?,string?)", "ValueTupleOfNullableReferenceType")] + [TestCase("(string?,string?)?", "NullableValueTupleOfNullableReferenceType")] + [TestCase("ICollection<string>", "InterfaceOfReferenceType")] + [TestCase("ICollection<string>?", "NullableInterfaceOfReferenceType")] + [TestCase("ICollection<string?>?", "NullableInterfaceOfNullableReferenceType")] + [TestCase("ICollection<dynamic>", "InterfaceOfDynamicType")] + [TestCase("ICollection<dynamic>?", "NullableInterfaceOfDynamicType")] + [TestCase("ICollection<dynamic?>?", "NullableInterfaceOfNullableDynamicType")] + [TestCase("Action<string>", "ActionOfReferenceType")] + [TestCase("Action<string?>", "ActionOfNullableReferenceType")] + [TestCase("Action<string>?", "NullableActionOfReferenceType")] + [TestCase("Action<string?>?", "NullableActionOfNullableReferenceType")] + [TestCase("Dictionary<string,string>", "DictionaryOfReferenceType")] + [TestCase("Dictionary<string,string>?", "NullableDictionaryOfReferenceType")] + [TestCase("Dictionary<string?,string?>", "DictionaryOfNullableReferenceType")] + [TestCase("Dictionary<string?,string?>?", "NullableDictionaryOfNullableReferenceType")] + [TestCase("Dictionary<string,string?>", "DictionaryOfNullableReferenceTypeValue")] + [TestCase("Dictionary<string,string?>?", "NullableDictionaryOfNullableReferenceTypeValue")] + [TestCase("Dictionary<string?,string>?", "NullableDictionaryOfNullableReferenceTypeKey")] + [TestCase("Dictionary<Dictionary<string,string>,Dictionary<string,string>>", "DictionaryOfDictionaryOfReferenceType")] + [TestCase("Dictionary<Dictionary<string,string>?,Dictionary<string,string>?>?", "NullableDictionaryOfNullableDictionaryOfReferenceType")] + [TestCase("Dictionary<Dictionary<string?,string?>?,Dictionary<string?,string?>?>?", "NullableDictionaryOfNullableDictionaryOfNullableReferenceType")] + [TestCase("Dictionary<string,Dictionary<string,string>>", "DictionaryOfReferenceTypeKeyAndDictionaryOfReferenceTypeValue")] + [TestCase("Dictionary<string,Dictionary<string,string>>?", "NullableDictionaryOfReferenceTypeKeyAndDictionaryOfReferenceTypeValue")] + [TestCase("Dictionary<string?,Dictionary<string,string>?>?", "NullableDictionaryOfNullableReferenceTypeKeyAndNullableDictionaryOfReferenceTypeValue")] + [TestCase("Dictionary<string?,Dictionary<string?,string?>?>?", "NullableDictionaryOfNullableReferenceTypeKeyAndNullableDictionaryOfNullableReferenceTypeValue")] + [TestCase("Dictionary<string,Tuple<string,string>>", "DictionaryOfReferenceTypeKeyAndTupleOfReferenceTypeValue")] + [TestCase("Dictionary<string,Tuple<string,string>>?", "NullableDictionaryOfReferenceTypeKeyAndTupleOfReferenceTypeValue")] + [TestCase("Dictionary<string?,Tuple<string,string>?>?", "NullableDictionaryOfNullableReferenceTypeKeyAndNullableTupleOfReferenceTypeValue")] + [TestCase("Dictionary<string?,Tuple<string?,string?>?>?", "NullableDictionaryOfNullableReferenceTypeKeyAndNullableTupleOfNullableReferenceTypeValue")] + public void TypeName(string returnType, string methodName) + { + // Test single parameter and return type for method, extension method, property, field, event, delegate. + // They have the same process logic that we just test once the type of them. + TestMethodSignature(NullableReferenceTypesAssemblyPath, "mdoc.Test.NullableReferenceTypes.CommonType", + methodName, $"public {returnType} {methodName} ();"); + } + + [TestCase("ParamsArrayOfNullableValueType", "int i, params int?[] array")] + [TestCase("ParamsArrayOfNullableReferenceType", "string s, params object?[] array")] + [TestCase("NullableAndNonNullableValueType", "int i1, int? i2, int i3")] + [TestCase("NullableAndNonNullableReferenceType", "string s1, string? s2, string s3")] + [TestCase("NullableGenericValueTypeOfValueType", "ReadOnlySpan<int> s1, ReadOnlySpan<int?> s2, ReadOnlySpan<int> s3")] + [TestCase("NullableGenericValueTypeOfReferenceType", "ReadOnlySpan<string> s1, ReadOnlySpan<string?> s2, ReadOnlySpan<string> s3")] + [TestCase("NullableAndNonNullableInterfaceOfValueType", "ICollection<int> collection1, ICollection<int>? collection2, ICollection<int> collection3")] + [TestCase("NullableAndNonNullableInterfaceOfReferenceType", "ICollection<string> collection1, ICollection<string>? collection2, ICollection<string> collection3")] + [TestCase("NonNullableValueTypeWithOutModifier", "string? value, out bool result")] + [TestCase("NonNullableValueTypeWithRefModifier", "string? value, ref bool result")] + public void MethodParameter(string methodName, string methodParameter) + { + TestMethodSignature(NullableReferenceTypesAssemblyPath, "mdoc.Test.NullableReferenceTypes.MethodParameter", + methodName, $"public void {methodName} ({methodParameter});"); + } + + [TestCase("GenericType", "<T> ({0})", "T t")] + [TestCase("GenericReferenceType", "<T> ({0}) where T : class", "T t")] + [TestCase("GenericNullableReferenceType", "<T> ({0}) where T : class", "T? t")] + [TestCase("ActionOfGenericNullableReferenceType", "<T> ({0}) where T : class", "Action<T?> t")] + [TestCase("NullableActionOfGenericNullableReferenceType", "<T> ({0}) where T : class", "Action<T?>? t")] + [TestCase("FuncGenericNullableReferenceType", "<T> ({0}) where T : class", "Func<T?> t")] + [TestCase("NullableFuncGenericNullableReferenceType", "<T> ({0}) where T : class", "Func<T?>? t")] + [TestCase("GenericNonNullableAndNullableReferenceType", "<T1,T2> ({0}) where T2 : class", "T1 t1, T2? t2")] + [TestCase("GenericValueType", "<T> ({0}) where T : struct", "T t")] + [TestCase("GenericNullableValueType", "<T> ({0}) where T : struct", "T? t")] + [TestCase("ActionOfGenericNullableValueType", "<T> ({0}) where T : struct", "Action<T?> action")] + [TestCase("NullableActionOfGenericNullableValueType", "<T> ({0}) where T : struct", "Action<T?>? action")] + [TestCase("FuncGenericNullableValueType", "<T> ({0}) where T : struct", "Func<T?> func")] + [TestCase("NullableFuncGenericNullableValueType", "<T> ({0}) where T : struct", "Func<T?>? func")] + [TestCase("GenericNonNullableAndNullableValueType", "<T1,T2> ({0}) where T2 : struct", "T1 t1, T2? t2")] + public void GenericMethodParameter(string methodName, string otherPartOfMethodSignature, string genericParameter) + { + TestMethodSignature(NullableReferenceTypesAssemblyPath, "mdoc.Test.NullableReferenceTypes.GenericMethodParameter", + methodName, $"public void {methodName}{string.Format(otherPartOfMethodSignature, genericParameter)};"); + } + + [TestCase("T", "GenericType", "<T> ()")] + [TestCase("T", "GenericReferenceType", "<T> () where T : class")] + [TestCase("T?", "GenericNullableReferenceType", "<T> () where T : class")] + [TestCase("T", "GenericValueType", "<T> () where T : struct")] + [TestCase("T?", "GenericNullableValueType", "<T> () where T : struct")] + public void GenericMethodReturnType(string returnType, string methodName, string otherPartOfMethodSignature) + { + TestMethodSignature(NullableReferenceTypesAssemblyPath, "mdoc.Test.NullableReferenceTypes.GenericMethodReturnType", + methodName, $"public {returnType} {methodName}{otherPartOfMethodSignature};"); + } + + [TestCase("T", "GenericType")] + [TestCase("TClass", "GenericReferenceType")] + [TestCase("TClass?", "GenericNullableReferenceType")] + [TestCase("TStruct", "GenericValueType")] + [TestCase("TStruct?", "GenericNullableValueType")] + public void GenericPropertyReturnType(string returnType, string propertyName) + { + TestPropertySignature(NullableReferenceTypesAssemblyPath, $"mdoc.Test.NullableReferenceTypes.{GetGenericTypeILName("GenericPropertyReturnType<T, TClass, TStruct>")}", + propertyName, $"public {returnType} {propertyName} {{ get; }}"); + } + + [TestCase("EventHandler", "EventHandler")] + [TestCase("EventHandler?", "NullableEventHandler")] + [TestCase("EventHandler<EventArgs>", "GenericEventHandler")] + [TestCase("EventHandler<EventArgs?>", "GenericEventHandlerOfNullableEventArgs")] + [TestCase("EventHandler<EventArgs>?", "NullableGenericEventHandler")] + [TestCase("EventHandler<EventArgs?>?", "NullableGenericEventHandlerOfNullableEventArgs")] + public void EventDelegateType(string delegateType, string eventName) + { + TestEventSignature(NullableReferenceTypesAssemblyPath, "mdoc.Test.NullableReferenceTypes.Event", + eventName, $"public event {delegateType} {eventName};"); + } + + [TestCase("Handler", "object sender, EventArgs args")] + [TestCase("NullableSender", "object? sender, EventArgs args")] + [TestCase("NullableSenderAndEventArgs", "object? sender, EventArgs? args")] + public void DelegateTypeParameter(string delegateName, string delegateParameter) + { + TestTypeSignature(NullableReferenceTypesAssemblyPath, $"mdoc.Test.NullableReferenceTypes.Delegate.{delegateName}", + $"public delegate void {delegateName}({delegateParameter});"); + } + + [TestCase("GenericHandler<TEventArgs>", "object sender, TEventArgs args", "{0}")] + [TestCase("NullableSender<TEventArgs>", "object? sender, TEventArgs args", "{0}")] + [TestCase("NullableSenderAndEventArgs<TEventArgs>", "object? sender, TEventArgs? args", "{0} where TEventArgs : class")] + [TestCase("ActionHandler<TClass,TStruct>", "TClass t1, TStruct t2", "{0} where TClass : class where TStruct : struct")] + [TestCase("NullableActionHandler<TClass,TStruct>", "TClass? t1, TStruct? t2", "{0} where TClass : class where TStruct : struct")] + public void GenericDelegateTypeParameter(string delegateName, string delegateParameter, string otherPartOfMethodSignature) + { + TestTypeSignature(NullableReferenceTypesAssemblyPath, $"mdoc.Test.NullableReferenceTypes.Delegate.{GetGenericTypeILName(delegateName)}", + $"public delegate void {delegateName}{string.Format(otherPartOfMethodSignature, $"({delegateParameter})")};"); + } + + [TestCase("TReturn", "FuncHandler<TReturn>", "()")] + [TestCase("TReturn?", "NullableReferenceType<TReturn>", "() where TReturn : class")] + [TestCase("TReturn?", "NullableValueType<TReturn>", "() where TReturn : struct")] + public void GenericDelegateTypeReturnType(string returnType, string delegateName, string otherPartOfMethodSignature) + { + TestTypeSignature(NullableReferenceTypesAssemblyPath, $"mdoc.Test.NullableReferenceTypes.Delegate.{GetGenericTypeILName(delegateName)}", + $"public delegate {returnType} {delegateName}{otherPartOfMethodSignature};"); + } + + [TestCase("NonNullableAndNullableValueType", "int i1, int? i2, int i3")] + [TestCase("NonNullableAndNullableReferenceType", "string s1, string? s2, string s3")] + [TestCase("InterfaceOfValueType", "ICollection<int> collection1, ICollection<int>? collection2, ICollection<int> collection3")] + [TestCase("InterfaceOfReferenceType", "ICollection<string> collection1, ICollection<string>? collection2, ICollection<string> collection3")] + public void ConstructorParameter(string typeName, string constructorParameter) + { + TestMethodSignature(NullableReferenceTypesAssemblyPath, $"mdoc.Test.NullableReferenceTypes.Constructor.{typeName}", + ".ctor", $"public {typeName} ({constructorParameter});"); + } + + [TestCase("GenericFieldType<T>", "T", "GenericType")] + [TestCase("GenericFieldTypeOfValueType<T>", "T", "GenericType")] + [TestCase("GenericFieldTypeOfValueType<T>", "T?", "NullableGenericType")] + [TestCase("GenericFieldTypeOfValueType<T>", "ICollection<T>", "InterfaceOfGenericType")] + [TestCase("GenericFieldTypeOfValueType<T>", "ICollection<T?>", "InterfaceOfNullableGenericType")] + [TestCase("GenericFieldTypeOfValueType<T>", "ICollection<T>?", "NullableInterfaceOfGenericType")] + [TestCase("GenericFieldTypeOfValueType<T>", "ICollection<T?>?", "NullableInterfaceOfNullableGenericType")] + [TestCase("GenericFieldTypeOfValueType<T>", "Dictionary<Dictionary<T,string>,string>", "DictionaryOfDictionary")] + [TestCase("GenericFieldTypeOfValueType<T>", "Dictionary<Dictionary<T?,string>,string>", "DictionaryOfDictionaryOfNullableGenericTypeKey")] + [TestCase("GenericFieldTypeOfValueType<T>", "Dictionary<Dictionary<T?,string>,string>?", "NullableDictionaryOfDictionaryOfNullableGenericTypeKey")] + [TestCase("GenericFieldTypeOfReferenceType<T>", "T", "GenericType")] + [TestCase("GenericFieldTypeOfReferenceType<T>", "T?", "NullableGenericType")] + [TestCase("GenericFieldTypeOfReferenceType<T>", "ICollection<T>", "InterfaceOfGenericType")] + [TestCase("GenericFieldTypeOfReferenceType<T>", "ICollection<T?>", "InterfaceOfNullableGenericType")] + [TestCase("GenericFieldTypeOfReferenceType<T>", "ICollection<T>?", "NullableInterfaceOfGenericType")] + [TestCase("GenericFieldTypeOfReferenceType<T>", "ICollection<T?>?", "NullableInterfaceOfNullableGenericType")] + [TestCase("GenericFieldTypeOfReferenceType<T>", "Dictionary<Dictionary<T,string>,string>", "DictionaryOfDictionary")] + [TestCase("GenericFieldTypeOfReferenceType<T>", "Dictionary<Dictionary<T?,string>,string>", "DictionaryOfDictionaryOfNullableGenericTypeKey")] + [TestCase("GenericFieldTypeOfReferenceType<T>", "Dictionary<Dictionary<T?,string>,string>?", "NullableDictionaryOfDictionaryOfNullableGenericTypeKey")] + public void GenericFieldReturnType(string typeName, string returnType, string fieldName) + { + TestFieldSignature(NullableReferenceTypesAssemblyPath, $"mdoc.Test.NullableReferenceTypes.{GetGenericTypeILName(typeName)}", + fieldName, $"public {returnType} {fieldName};"); + } + + [TestCase("NullableAndNonNullableValueType", "this int? type, int? i1, int i2, int? i3")] + [TestCase("NullableAndNonNullableNullableReferenceType", "this string? type, string? s1, string s2, string? s3")] + [TestCase("NullableAndNonNullableNullableReferenceTypeAndValueType", "this string? type, string? s1, int? i1, int i2, string s2, string? s3")] + public void ExtensionMethodParameter(string methodName, string methodParameter) + { + TestMethodSignature(NullableReferenceTypesAssemblyPath, "mdoc.Test.NullableReferenceTypes.ExtensionMethod", + methodName, $"public static void {methodName} ({methodParameter});"); + } + + [TestCase("Student", "op_Addition", "Student operator +", "Student s1, Student s2")] + [TestCase("Student", "op_Subtraction", "Student? operator -", "Student? s1, Student? s2")] + [TestCase("Student", "op_Multiply", "Student operator *", "Student s1, Student? s2")] + [TestCase("Student", "op_Division", "Student operator /", "Student? s1, Student s2")] + [TestCase("Student", "op_Implicit", "implicit operator ExamScore", "Student? s")] + [TestCase("Student", "op_Explicit", "explicit operator Student?", "ExamScore? s")] + [TestCase("ExamScore", "op_Addition", "ExamScore operator +", "ExamScore s1, ExamScore s2")] + [TestCase("ExamScore", "op_Subtraction", "ExamScore? operator -", "ExamScore? s1, ExamScore? s2")] + [TestCase("ExamScore", "op_Multiply", "ExamScore operator *", "ExamScore s1, ExamScore? s2")] + [TestCase("ExamScore", "op_Division", "ExamScore operator /", "ExamScore? s1, ExamScore s2")] + [TestCase("ExamScore", "op_Implicit", "implicit operator ExamScore", "Student? s")] + [TestCase("ExamScore", "op_Explicit", "explicit operator Student?", "ExamScore? s")] + public void OperatorOverloading(string typeName, string methodName, string operatorName, string methodParameter) + { + TestMethodSignature(NullableReferenceTypesAssemblyPath, $"mdoc.Test.NullableReferenceTypes.OperatorOverloading.{typeName}", + methodName, $"public static {operatorName} ({methodParameter});"); + } + + private string GetGenericTypeILName(string genericTypeName) + { + var startParameterIndex = genericTypeName.IndexOf('<'); + var endParameterIndex = genericTypeName.IndexOf('>'); + + if (startParameterIndex != -1 && endParameterIndex != -1 && endParameterIndex == genericTypeName.Length - 1) + { + var parameterList = genericTypeName.Substring(startParameterIndex + 1, endParameterIndex - startParameterIndex - 1); + var parameterCount = parameterList.Split(',').Count(); + var genericTypeNameWithoutParameter = genericTypeName.Substring(0, startParameterIndex); + + return $"{genericTypeNameWithoutParameter}`{parameterCount}"; + } + + throw new ArgumentException("The generic type name is not a valid value.", nameof(genericTypeName)); + } + } +} diff --git a/mdoc/mdoc.Test/mdoc.Test.Cplusplus/AssemblyInfo.cpp b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/AssemblyInfo.cpp new file mode 100644 index 00000000..7b42acab --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/AssemblyInfo.cpp @@ -0,0 +1,38 @@ +#include "stdafx.h" + +using namespace System; +using namespace System::Reflection; +using namespace System::Runtime::CompilerServices; +using namespace System::Runtime::InteropServices; +using namespace System::Security::Permissions; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly:AssemblyTitleAttribute(L"mdocTestCplusplus")]; +[assembly:AssemblyDescriptionAttribute(L"")]; +[assembly:AssemblyConfigurationAttribute(L"")]; +[assembly:AssemblyCompanyAttribute(L"EPAM Systems")]; +[assembly:AssemblyProductAttribute(L"mdocTestCplusplus")]; +[assembly:AssemblyCopyrightAttribute(L"Copyright (c) EPAM Systems 2017")]; +[assembly:AssemblyTrademarkAttribute(L"")]; +[assembly:AssemblyCultureAttribute(L"")]; + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the value or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly:AssemblyVersionAttribute("1.0.*")]; + +[assembly:ComVisible(false)]; + +[assembly:CLSCompliantAttribute(true)];
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.Cplusplus/ReadMe.txt b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/ReadMe.txt new file mode 100644 index 00000000..9cd874fc --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/ReadMe.txt @@ -0,0 +1,38 @@ +======================================================================== + DYNAMIC LINK LIBRARY : mdoc.Test.Cplusplus Project Overview +======================================================================== + +AppWizard has created this mdoc.Test.Cplusplus DLL for you. + +This file contains a summary of what you will find in each of the files that +make up your mdoc.Test.Cplusplus application. + +mdoc.Test.Cplusplus.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +mdoc.Test.Cplusplus.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +mdoc.Test.Cplusplus.cpp + This is the main DLL source file. + +mdoc.Test.Cplusplus.h + This file contains a class declaration. + +AssemblyInfo.cpp + Contains custom attributes for modifying assembly metadata. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/mdoc/mdoc.Test/mdoc.Test.Cplusplus/Stdafx.cpp b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/Stdafx.cpp new file mode 100644 index 00000000..64dbda38 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/Stdafx.cpp @@ -0,0 +1,5 @@ +// stdafx.cpp : source file that includes just the standard includes +// mdoc.Test.Cplusplus.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/mdoc/mdoc.Test/mdoc.Test.Cplusplus/Stdafx.h b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/Stdafx.h new file mode 100644 index 00000000..3cc4c24e --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/Stdafx.h @@ -0,0 +1,7 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#pragma once + + diff --git a/mdoc/mdoc.Test/mdoc.Test.Cplusplus/TestClass.cpp b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/TestClass.cpp new file mode 100644 index 00000000..81b0fcfa --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/TestClass.cpp @@ -0,0 +1,647 @@ +#include "stdafx.h" +#include "TestClass.h" +#include <string> +#include <vector> + +using namespace std; +using namespace cli; +using namespace System::Collections::ObjectModel; +using namespace System; +using namespace Runtime::InteropServices; +using namespace System::Runtime::InteropServices; +namespace Generic1 = System::Collections::Generic; +using namespace System::Runtime::CompilerServices; + +//using namespace System::att; + + + + +TestClass::TestClass() +{ +} + + +TestClass::~TestClass() +{ +} + +/// <summary>Namespace Test: [<see cref="N:Mono.DocTest" />] <see href="http://www.mono-project.com/">Mono Project</see></summary> +/// <remarks><c>T:NoNamespace</c></remarks> +public ref class NoNamespace {}; + +namespace System { + + /// <remarks><c>T:System.Action`1</c></remarks> + generic<typename T> + [SerializableAttribute] + public delegate void Action(T obj); + + //TODO: Env1 name as not supported + /// <remarks><c>T:System.Environment</c></remarks> + public ref class Environment1 abstract sealed { + //public: Environment1() {}; + public: + /// <remarks><c>T:System.Environment+SpecialFolder</c></remarks> + enum class SpecialFolder {}; + + /// <param name="folder"> + /// A <see cref="T:System.Environment+SpecialFolder" /> instance. + /// </param> + /// <remarks> + /// <c>M:System.Environment.GetFolderPath(System.Environment+SpecialFolder)</c> + /// </remarks> + public: + static SpecialFolder GetFolderPath(SpecialFolder folder) { + //throw std::runtime_error("error"); + return folder; + + }; + + // Testing whether this extension method shows up for System.Array + public: + generic<typename T> + where T : value class + [System::Runtime::CompilerServices::Extension] + static bool IsAligned(cli::array<T>^ vect, int index) + { + return false; + }; + + + }; + + // to test ECMA doc importing... + //todo: array1 instad real name + public ref class Array1 { + // the ECMA docs have a different return type than .NET -- skip. + public: + //todo: cli::array or std::array + generic<typename T> + static ReadOnlyCollection<T> ^ AsReadOnly(cli::array<T>^ array) + { + throw gcnew NotImplementedException(); + } + + // ECMA docs use <T,U> instead of <TInput,TOutput> --> map them. + public: + generic<typename TInput, typename TOutput> + static cli::array<TOutput>^ ConvertAll(cli::array<TInput>^ array, Converter<TInput, TOutput>^ converter) + { + throw gcnew InvalidOperationException(); + }; + + // ECMA docs *incorrectly* document parameter -- skip + public: + generic<typename T> + static void Resize(cli::array<T> ^ % array, int newSize) + { + throw gcnew Exception(); + } + }; + + // to test ECMA doc importing... + //public delegate void AsyncCallback(IAsyncResult^ ar); +} + +//todo: no dot in namespace name +namespace Mono_DocTest { + //todo: no internal modifier + class Internal { + class ShouldNotBeDocumented { + }; + }; + + //todo: no internal modifier + ref class MonoTODOAttribute : public System::Attribute { + }; + + public ref class CustomException : System::Exception { + protected: System::ArgumentNullException ArgumentNullExceptionField; + }; + + public delegate void DelegateWithNetSystemType(System::Exception parameter); + + generic<typename T> + [SerializableAttribute] + public delegate void Action22(T obj); + + /// <remarks> + /// <para> + /// cref=<c>T:Mono.DocTest.DocAttribute</c>. + /// </para> + /// <format type="text/html"> + /// <table width="100%"> + /// <tr> + /// <td style="color:red">red</td> + /// <td style="color:blue">blue</td> + /// <td style="color:green">green</td> + /// </tr> + /// </table> + /// </format> + /// <code lang="C#" src="../DocTest.cs#DocAttribute Example" /> + /// </remarks> + [AttributeUsageAttribute(AttributeTargets::All)] + public ref class DocAttribute : Attribute { + /// <remarks><c>C:Mono.DocTest.DocAttribute(System.String)</c></remarks> + public: DocAttribute(String ^ docs) + { + if (String::IsNullOrEmpty(docs)) + throw gcnew ArgumentNullException(); + }; + + private: + Type^ quantity; + /// <remarks><c>P:Mono.DocTest.DocAttribute.Property</c></remarks> + public: + property Type^ Property { + Type^ get() { return quantity; } + void set(Type^ value) + { + quantity = value; + }}; + + /// <remarks><c>F:Mono.DocTest.DocAttribute.Field</c></remarks> + bool Field; + /// <remarks><c>F:Mono.DocTest.DocAttribute.FlagsEnum</c></remarks> + ConsoleModifiers FlagsEnum; + /// <remarks><c>F:Mono.DocTest.DocAttribute.NonFlagsEnum</c></remarks> + Color NonFlagsEnum; + }; + + /// <summary>Possible colors</summary> + /// <remarks> + /// <see cref="T:Mono.DocTest.Color"/>. + /// Namespace Test: [<see cref="N:Mono.DocTest" />] + /// </remarks> + /*[MonoTODO] + public enum Color { + /// <summary>Insert Red summary here</summary> + ///<remarks><c>F:Mono.DocTest.Color.Red</c>.</remarks> + Red, + ///<summary>Insert Blue summary here</summary> + ///<remarks><c>F:Mono.DocTest.Color.Blue</c>.</remarks> + Blue, + ///<summary>Insert Green summary here</summary> + ///<remarks><c>F:Mono.DocTest.Color.Green</c>.</remarks> + Green, + + AnotherGreen = Green, + };*/ + + /// <summary>Process interface</summary> + /// <remarks><c>T:Mono.DocTest.IProcess</c>.</remarks> + public interface class IProcess + { + + }; + + /// <summary>Process interface</summary> + /// <remarks><c>T:Mono.DocTest.DocValueType</c>.</remarks> + public value class DocValueType : IProcess { + + public: + /// <remarks><c>F:Mono.DocTest.DocValueType.total</c>.</remarks> + int total; + + public: + /// <param name="i">A <see cref="T:System.Int32" />.</param> + /// <remarks><see cref="M:Mono.DocTest.DocValueType.M(System.Int32)"/>.</remarks> + void M(int i) + { + if (((gcnew Random())->Next() % 2) == 0) + throw gcnew SystemException(); + throw gcnew ApplicationException(); + } + }; + + public value class ValueClassSpecificField { + public: DocValueType ExceptionField; + }; + + /// <remarks><c>T:Mono.DocTest.D</c></remarks> + public delegate Object ^ D(Func<String ^ , Object ^ , Object ^ > ^ value ); + + /// <remarks><c>T:Mono.DocTest.Widget</c>.</remarks> + /// <seealso cref="P:Mono.DocTest.Widget.Item(System.Int32)" /> + /// <extra>Some extra tag value</extra> + public ref class Widget : IProcess { + + //public: virtual double getVolume() { return 0; }; + /// <remarks><c>T:Mono.DocTest.Widget.NestedClass</c>.</remarks> + public: ref class NestedClass { + /// <remarks><c>F:Mono.DocTest.Widget.NestedClass.value</c>.</remarks> + public: int value; + /// <param name="i">Some <see cref="T:System.Int32" />.</param> + /// <remarks><c>M:Mono.DocTest.Widget.NestedClass.M(System.Int32)</c>.</remarks> + void M(int i) {}; + /// <remarks><c>T:Mono.DocTest.Widget.NestedClass.Double</c>.</remarks> + ref class Double { + /// <remarks><c>T:Mono.DocTest.Widget.NestedClass.Double.Triple</c>.</remarks> + public: ref class Triple { + /// <remarks><c>T:Mono.DocTest.Widget.NestedClass.Double.Triple.Quadruple</c>.</remarks> + public: ref class Quadruple {};// for good measure + }; + }; + }; + public: enum class NestedEnum { Value1, Value2}; + + /// <remarks><c>T:Mono.DocTest.Widget.NestedClass`1</c>.</remarks> + + public: + //todo: cannot use the same class name here with generic par-r + generic<typename T> + ref class NestedClass1 { + /// <remarks><c>F:Mono.DocTest.Widget.NestedClass`1.value</c>.</remarks> + public: int value; + + /// <param name="i">Another <see cref="T:System.Int32" />.</param> + /// <remarks><c>M:Mono.DocTest.Widget.NestedClass`1.M(System.Int32)</c>.</remarks> + public: void M(int i) {}; + }; + + /// <remarks><c>F:Mono.DocTest.Widget.classCtorError</c>.</remarks> + + public: static initonly cli::array<String^>^ classCtorError = CreateArray(); + + private: static cli::array<String^>^ CreateArray() + { + throw gcnew NotSupportedException(); + }; + + /// <remarks><c>F:Mono.DocTest.Widget.message</c>.</remarks> + public: String^ message; + + /// <remarks><c>F:Mono.DocTest.Widget.defaultColor</c>.</remarks> + protected: static Color defaultColor; + + /// <remarks><c>F:Mono.DocTest.Widget.PI</c>.</remarks> + //TODO: no internal + protected: const double PI = 3.14159; + + /// <remarks><c>F:Mono.DocTest.Widget.monthlyAverage</c>.</remarks> + + protected public: initonly double monthlyAverage; + + /// <remarks><c>F:Mono.DocTest.Widget.array1</c>.</remarks> + public: cli::array<long^>^ array1; + + /// <remarks><c>F:Mono.DocTest.Widget.array2</c>.</remarks> + //todo: check if works correctly + public: cli::array<Widget^, 2> ^ array2; + + //TODO: no possibiiti for unsafe + /// <remarks><c>F:Mono.DocTest.Widget.pCount</c>.</remarks> + public: int *pCount; + + //TODO: no possibiiti for unsafe + /// <remarks><c>F:Mono.DocTest.Widget.ppValues</c>.</remarks> + public: float** ppValues; + + /// <remarks><c>T:Mono.DocTest.Widget.IMenuItem</c>.</remarks> + public: interface class IMenuItem { + /// <remarks><c>M:Mono.DocTest.Widget.IMenuItem.A</c>.</remarks> + void A(); + + /// <remarks><c>P:Mono.DocTest.Widget.IMenuItem.P</c>.</remarks> + property int B { + int get(); + void set(int value); + }; + }; + + /// <remarks><c>T:Mono.DocTest.Widget.Del</c>.</remarks> + public: delegate void Del(int i); + + /// <remarks><c>T:Mono.DocTest.Widget.Direction</c>.</remarks> + //todo: no internal + protected: + [FlagsAttribute] + /*internal*/ enum class Direction { + /// <remarks><c>T:Mono.DocTest.Widget.Direction.North</c>.</remarks> + North, + /// <remarks><c>T:Mono.DocTest.Widget.Direction.South</c>.</remarks> + South, + /// <remarks><c>T:Mono.DocTest.Widget.Direction.East</c>.</remarks> + East, + /// <remarks><c>T:Mono.DocTest.Widget.Direction.West</c>.</remarks> + West, + }; + + /// <remarks> + /// <para><c>C:Mono.DocTest.Widget</c>.</para> + /// <para><c>M:Mono.DocTest.Widget.#ctor</c>.</para> + /// <para><see cref="C:Mono.DocTest.Widget(System.String)" /></para> + /// <para><see cref="C:Mono.DocTest.Widget(System.Converter{System.String,System.String})" /></para> + /// </remarks> + public: Widget() {}; + + /// <param name="s">A <see cref="T:System.String" />.</param> + /// <remarks> + /// <para><c>C:Mono.DocTest.Widget(System.String)</c>.</para> + /// <para><c>M:Mono.DocTest.Widget.#ctor(System.String)</c>.</para> + /// </remarks> + public: Widget(String^ s) {}; + + /// <param name="c">A <see cref="T:System.Converter{System.String,System.String}" />.</param> + /// <remarks> + /// <para><c>C:Mono.DocTest.Widget(System.Converter{System.String,System.String})</c>.</para> + /// </remarks> + public: Widget(Converter<String^, String^>^ c) {}; + + /// <remarks><c>M:Mono.DocTest.Widget.M0</c>.</remarks> + public: static void M0() {}; + + /// <param name="c">A <see cref="T:System.Char" />.</param> + /// <param name="f">A <see cref="T:System.Single" />.</param> + /// <param name="v">A <see cref="T:Mono.DocTest.DocValueType" />.</param> + /// <remarks><c>M:Mono.DocTest.Widget.M1(System.Char,System.Signle@,Mono.DocTest.DocValueType@)</c>.</remarks> + /// //TODO: doc attribute is not working + public: + [DocAttribute("normal DocAttribute", Field = true)] + //[return:Doc("return:DocAttribute", Property = typeof(Widget))] + void M1([Doc("c", FlagsEnum = ConsoleModifiers::Alt | ConsoleModifiers::Control)] long c, + [Doc("f", NonFlagsEnum = Color::Red)][Runtime::InteropServices::Out] float % f, + [DocAttribute("v")] DocValueType % v) { + f = 0; + }; + + /// <param name="x1">A <see cref="T:System.Int16" /> array.</param> + /// <param name="x2">A <see cref="T:System.Int32" /> array.</param> + /// <param name="x3">A <see cref="T:System.Int64" /> array.</param> + /// <remarks><c>M:Mono.DocTest.Widget.M2(System.Int16[],System.Int32[0:,0:],System.Int64[][])</c>.</remarks> + public: void M2(cli::array<short>^ x1, cli::array<int, 2>^ x2, cli::array<cli::array<long >^ >^ x3) {}; + + /// <param name="x3">Another <see cref="T:System.Int64" /> array.</param> + /// <param name="x4">A <see cref="T:Mono.DocTest.Widget" /> array.</param> + /// <remarks><c>M:Mono.DocTest.Widget.M3(System.Int64[][],Mono.DocTest.Widget[0:,0:,0:][])</c>.</remarks> + protected: void M3(cli::array<cli::array<long >^ >^ x3, cli::array<cli::array<Widget^, 3>^>^ x4) {}; + + //TODO: no unsafe + /// <param name="pc">A <see cref="T:System.Char" /> pointer.</param> + /// <param name="ppf">A <see cref="T:Mono.DocTest.Color" /> pointer.</param> + /// <remarks><c>M:Mono.DocTest.Widget.M4(System.Char*,Mono.DocTest.Color**)</c>.</remarks> + protected: void M4(char *pc, Color **ppf) {}; + + //TODO: no unsafe + /// <param name="pv">A <see cref="T:System.Void" /> pointer.</param> + /// <param name="pd">A <see cref="T:System.Double" /> array.</param> + /// <remarks><c>M:Mono.DocTest.Widget.M5(System.Void*,System.Double*[0:,0:][])</c>.</remarks> + protected: void M5(void *pv, cli::array<cli::array<double, 2>^>^*pd) {}; + + protected: void M55(void *pv, System::String ^ *pd) {}; + + /// <param name="i">Yet another <see cref="T:System.Int32" />.</param> + /// <param name="args">An <see cref="T:System.Object" /> array.</param> + /// <remarks><c>M:Mono.DocTest.Widget.M6(System.Int32,System.Object[])</c>.</remarks> + protected: void M6(int i, ... cli::array<Object^>^ args) {}; + + /// <remarks><c>M:Mono.DocTest.Widget.M7(Mono.DocTest.Widget.NestedClass.Double.Triple.Quadruple)</c>.</remarks> + public: void M7(Widget::NestedClass::Double::Triple::Quadruple ^ a) {}; + + + + /// <value>A <see cref="T:System.Int32" /> value...</value> + /// <remarks><c>P:Mono.DocTest.Widget.Width</c>.</remarks> + + public: + [DocAttribute("Width property")] + property int Width { + [Doc("Width get accessor")] + int get() { return 0; }; + + protected: + [Doc("Width set accessor")] + void set(int value) {}; + }; + + /// <value>A <see cref="T:System.Int64" /> value...</value> + /// <remarks><c>P:Mono.DocTest.Widget.Height</c>.</remarks> + protected: + [Doc("Height property")] + property long Height { long get() { return 0; }; }; + + /// <value>A <see cref="T:System.Int16" /> value...</value> + /// <remarks><c>P:Mono.DocTest.Widget.X</c>.</remarks> + //todo: no internal (protected internal) + protected: property short X { void set(short value) {}; }; + + /// <value>A <see cref="T:System.Double" /> value...</value> + /// <remarks><c>P:Mono.DocTest.Widget.Y</c>.</remarks> + //todo: no internal(protected internal) + protected: property double Y { + double get() { return 0; }; + void set(double value) {}; + }; + + + /// <param name="i">TODO</param> + /// <remarks><c>P:Mono.DocTest.Widget.Item(System.Int32)</c>.</remarks> + /// <value>A <see cref="T:System.Int32" /> instance.</value> + + public: + [DocAttribute("Item property")] + property int default[int]{ + int get(int index) { return 0; }; + + [Doc("Item property set accessor")] + void set(int index, int value) {}; + }; + + public: + [DocAttribute("Item property")] + property long indexedProperty[long]{ + long get(long index) { return 0; }; + + [Doc("Item property set accessor")] + void set(long index, long value) {}; + }; + + /// <param name="s">Some <see cref="T:System.String" />.</param> + /// <param name="i">I love <see cref="T:System.Int32" />s.</param> + /// <remarks><c>P:Mono.DocTest.Widget.Item(System.String,System.Int32)</c>.</remarks> + /// <value>A <see cref="T:System.Int32" /> instance.</value> + public: + property int default[System::String ^, int] + { int get(System::String ^ s, int i) { return 0; } + void set(System::String ^ s, int i, int value) {}; + }; + + /// <remarks><c>E:Mono.DocTest.Widget.AnEvent</c>.</remarks> + public: + [Doc("Del event")] + event Del^ AnEvent { + [Doc("Del add accessor")] + void add(Del^ name) {}; + [Doc("Del remove accessor")] + void remove(Del^ name) {}; + void raise(int i) {}; + }; + + /// <remarks><c>E:Mono.DocTest.Widget.AnotherEvent</c>.</remarks> + protected: event Del^ AnotherEvent; + + + /// <param name="x">Another <see cref="T:Mono.DocTest.Widget" />.</param> + /// <remarks><c>M:Mono.DocTest.Widget.op_UnaryPlus(Mono.DocTest.Widget)</c>.</remarks> + /// <returns>A <see cref="T:Mono.DocTest.Widget" /> instance.</returns> + public: static Widget^ operator + (Widget x) { return nullptr; } + + /// <remarks><c>M:Mono.DocTest.Widget.op_Division</c>.</remarks> + /// <returns>A <see cref="T:Mono.DocTest.Widget" /> instance.</returns> + //todo": added 1 to compile + public: static Widget^ op_Division1 = nullptr; + + /// <param name="x1">Yet Another <see cref="T:Mono.DocTest.Widget" />.</param> + /// <param name="x2">Yay, <see cref="T:Mono.DocTest.Widget" />s.</param> + /// <remarks><c>M:Mono.DocTest.Widget.op_Addition(Mono.DocTest.Widget,Mono.DocTest.Widget)</c>.</remarks> + /// <returns>A <see cref="T:Mono.DocTest.Widget" /> instance (2).</returns> + public: static Widget^ operator+ (Widget x1, Widget x2) { return nullptr; } + + /// <param name="x"><see cref="T:Mono.DocTest.Widget" />s are fun!.</param> + /// <remarks><c>M:Mono.DocTest.Widget.op_Explicit(Mono.DocTest.Widget)~System.Int32</c>.</remarks> + /// <returns>A <see cref="T:System.Int32" /> instance.</returns> + public: static explicit operator int(Widget^ x) { return 0; } + + /// <param name="x"><c>foo</c>; <see cref="T:Mono.DocTest.Widget" />.</param> + /// <remarks><c>M:Mono.DocTest.Widget.op_Implicit(Mono.DocTest.Widget)~System.Int64</c>.</remarks> + /// <returns>A <see cref="T:System.Int64" /> instance.</returns> + //todo: no implicit(default behavior) + public: static operator long(Widget x) { return 0; } + + /// <remarks><c>M:Mono.DocTest.Widget.Default(System.Int32,System.Int32)</c></remarks>c + //todo: no default value + public: void Default( + [System::Runtime::InteropServices::Optional] + /*[System::Runtime::InteropServices::DefaultParameterValueAttribute(1)]*/int a, + [System::Runtime::InteropServices::Optional] + /*[System::Runtime::InteropServices::DefaultParameterValueAttribute(2)]*/int b) {}; + + /// <remarks><c>M:Mono.DocTest.Widget.Default(System.String,System.Char)</c></remarks> + //todo: no default value + public: void Default(/*[System::Runtime::InteropServices::DefaultParameterValueAttribute("a")]*/string a, /*[System::Runtime::InteropServices::DefaultParameterValueAttribute('b')]*/char b) {}; + + //TODO: no dynamics - use Object instead/ + no + operator + /// <remarks><c>M:Mono.DocTest.Widget.Dynamic0(System.Object,System.Object)</c></remarks> + public: Object^ Dynamic0(Object^ a, Object^ b) { return gcnew Object(); } + + + + //TODO: no dynamics - use Object instead + /// <remarks><c>M:Mono.DocTest.Widget.Dynamic1(System.Collections.Generic.Dictionary{System.Object,System.Object})</c></remarks> + public: Generic1::Dictionary<Object^, System::String^> ^ Dynamic1(Generic1::Dictionary<Object^, System::String^>^ value) { return value; }; + + //TODO: no dynamics - use Object instead + /// <remarks><c>M:Mono.DocTest.Widget.Dynamic2(System.Func{System.String,System.Object})</c></remarks> + public: Func<String^, Object^>^ Dynamic2(Func<String^, Object^>^ value) { return value; }; + + //TODO: no dynamics - use Object instead + /// <remarks><c>M:Mono.DocTest.Widget.Dynamic3(System.Func{System.Func{System.String,System.Object},System.Func{System.Object,System.String}})</c></remarks> + public: Func<Func<String^, Object^>^, Func< Object^, String^>^>^ Dynamic3( + Func<Func<String^, Object^>^, Func< Object^, String^>^>^ value) { + return value; + }; + + //TODO: no dynamics - use Object instead + /// <remarks><c>P:Mono.DocTest.Widget.DynamicP</c></remarks> + /*public: property Func<Func<String^, Object^, String^>^, Func<Object^, Func<Object^>, String^>^> ^DynamicP{ + Func<Func<String^, Object^, String^>^, Func<Object^, Func<Object^>, String^>^> get(){ return nullptr; }; + };*/ + + //TODO: no dynamics - use Object instead + /// <remarks><c>F:Mono.DocTest.Widget.DynamicF</c></remarks> + public: Func<Func<String^, Object^, String^>^, Func<Object^, Func<Object^>^, String^>^> ^DynamicF; + + //TODO: no dynamics - use Object instead + use delegate as pure Func cannot be used + /// <remarks><c>E:Mono.DocTest.Widget.DynamicE1</c></remarks> + + public: [Obsolete("why not")] event Func<Object^>^ DynamicE1; + + //TODO: no dynamics - use Object instead + /// <remarks><c>E:Mono.DocTest.Widget.DynamicE2</c></remarks> + public: event Func<Object^>^ DynamicE2 { + [Doc("Del add accessor")] + void add(Func<Object^>^ name) {}; + [Doc("Del remove accessor")] + void remove(Func<Object^>^ name) {}; + Object^ raise() { return gcnew Object(); }; + }; + + + }; + + /// <remarks><c>T:Mono.DocTest.UseLists</c>.</remarks> + public ref class UseLists + { + /// <param name="list">A <see cref="T:Mono.DocTest.Generic.MyList{System.Int32}" />.</param> + /// <remarks><c>M:Mono.DocTest.UseLists.Process(Mono.DocTest.MyList{System.Int32})</c>.</remarks> + + public: void Process(Mono_DocTest_Generic::MyList<int> ^ list) {}; + + /// <param name="value">A <c>T</c>.</param> + /// <typeparam name="T">Something</typeparam> + /// <remarks><c>M:Mono.DocTest.UseLists.GetValues``1(``0)</c>.</remarks> + /// <returns>A <see cref="T:Mono.DocTest.Generic.MyList`1" /> instance.</returns> + + public: + generic<typename T> + where T : value class + Mono_DocTest_Generic::MyList<T>^ GetValues(T value) { return nullptr; }; + + /// <param name="list">Another <see cref="T:Mono.DocTest.Generic.MyList{System.Int32}" />.</param> + /// <remarks> + /// <para><c>M:Mono.DocTest.UseLists.Process(System.Collections.Generic.List{System.Int32})</c>.</para> + /// <para><see cref="M:System.Collections.Generic.List{System.Int32}.Remove(`0)" /></para> + /// </remarks> + /// <exception name="Whatever">text!</exception> + /// <exception invalid="foo">text!</exception> + public: void Process(Generic1::List<int> list) + { + // Bug: only creation is looked for, so this generates an <exception/> + // node: + gcnew Exception(); + + // Bug? We only look at "static" types, so we can't follow + // delegates/interface calls: + + //todo:uncomment + /*Func<int, int>^ a = x = > {throw gcnew InvalidOperationException(); }; + a(1);*/ + + // Multi-dimensional arrays have "phantom" methods that Cecil can't + // resolve, as they're provided by the runtime. These should be + // ignored. + cli::array<int, 2>^ array = gcnew cli::array<int, 2>(1, 1); + array[0, 0] = 42; + }; + + /// <param name="list">A <see cref="T:Mono.DocTest.Generic.MyList{System.Predicate{System.Int32}}" />.</param> + /// <remarks><c>M:Mono.DocTest.UseLists.Process(System.Collections.Generic.List{System.Predicate{System.Int32}})</c>.</remarks> + public: void Process(Generic1::List<Predicate<int>^>^ list) + { + if (list == nullptr) + throw gcnew ArgumentNullException("list"); + Process<int>(list); + }; + + /// <param name="list">A <see cref="T:Mono.DocTest.Generic.MyList{System.Predicate{``0}}" />.</param> + /// <typeparam name="T">Something Else</typeparam> + /// <remarks><c>M:Mono.DocTest.UseLists.Process``1(System.Collections.Generic.List{System.Predicate{``0}})</c>.</remarks> + public: + generic<typename T> + void Process(Generic1::List<Predicate<T>^>^ list) + { + if (list->Contains(nullptr)) + throw gcnew ArgumentException("predicate null"); + }; + + /// <param name="helper">A <see cref="T:Mono.DocTest.Generic.MyList{``0}.Helper{``1,``2}" />.</param> + /// <typeparam name="T"><c>T</c></typeparam> + /// <typeparam name="U"><c>U</c></typeparam> + /// <typeparam name="V"><c>V</c></typeparam> + /// <remarks><c>M:Mono.DocTest.UseLists.UseHelper``3(Mono.DocTest.Generic.MyList{``0}.Helper{``1,``2})</c>.</remarks> + public: + generic<typename T, typename U, typename V> + void UseHelper(Mono_DocTest_Generic::MyList<T>::Helper<U, V>^ helper) {}; + }; +}; diff --git a/mdoc/mdoc.Test/mdoc.Test.Cplusplus/TestClass.h b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/TestClass.h new file mode 100644 index 00000000..36382d6f --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/TestClass.h @@ -0,0 +1,400 @@ +#pragma once +#pragma once + +namespace Generic1 = System::Collections::Generic; + + +class TestClass +{ +public: + TestClass(); + ~TestClass(); +}; + +public enum class Color { + /// <summary>Insert Red summary here</summary> + /// <remarks><c>F:Mono.DocTest.Color.Red</c>.</remarks> + Red, + /// <summary>Insert Blue summary here</summary> + /// <remarks><c>F:Mono.DocTest.Color.Blue</c>.</remarks> + Blue, + /// <summary>Insert Green summary here</summary> + /// <remarks><c>F:Mono.DocTest.Color.Green</c>.</remarks> + Green, + + AnotherGreen = Green, +}; + +/// <typeparam name="T">T generic param</typeparam> +/// <remarks><c>T:Mono.DocTest.IFoo`1</c>.</remarks> +generic<typename T> + public interface class IFoo { + /// <typeparam name="U">U generic param</typeparam> + /// <remarks><c>T:Mono.DocTest.IFoo`1.Method``1(`0,``0)</c>.</remarks> + generic<typename U> + T Method(T t, U u); + }; + + namespace Mono_DocTest_Generic { + using namespace System; + using namespace System::Collections; + + generic<typename T> + where T: value class + public interface class IFooNew { + /// <typeparam name="U">U generic param</typeparam> + /// <remarks><c>T:Mono.DocTest.IFoo`1.Method``1(`0,``0)</c>.</remarks> + generic<typename U> + T Method(T t, U u); + }; + + + /// <summary>extension methods!</summary> + /// <remarks><c>T:Mono.DocTest.Generic.Extensions</c></remarks> + //todo: do need attribute on class?? + [System::Runtime::CompilerServices::Extension] + public ref class Extensions abstract sealed { + /// <summary><c>System.Object</c> extension method</summary> + /// <remarks><c>M:Mono.DocTest.Generic.Extensions.ToEnumerable``1</c></remarks> + public: + generic <typename T> + [System::Runtime::CompilerServices::Extension] + static Generic1::IEnumerable<T> ^ ToEnumerable(T self) + { + //todo: no yield + //yield return self; + return gcnew Generic1::List<T>(); + }; + + /// <summary><see cref="T:System.Collections.Generic.IEnumerable`1" /> extension method</summary> + /// <remarks><c>M:Mono.DocTest.Generic.Extensions.ForEach``1</c></remarks> + public: + generic <typename T> + [System::Runtime::CompilerServices::Extension] + static void ForEach(Generic1::IEnumerable<T> ^ self, Action<T> ^ a) + { + }; + + /// <summary><see cref="T:Mono.DocTest.Generic.IFoo`1" /> extension method</summary> + /// <remarks><c>M:Mono.DocTest.Generic.Extensions.Bar``1</c></remarks> + + public: + generic <typename T> + [System::Runtime::CompilerServices::Extension] + static void Bar(IFoo<T>^ self, String ^ s) + { + }; + + /// <summary> + /// <see cref="T:System.Collections.Generic.IEnumerable{System.Int32}" /> + /// extension method. + /// </summary> + /// <remarks><c>M:Mono.DocTest.Generic.Extensions.ToDouble</c></remarks> + public: + [System::Runtime::CompilerServices::Extension] + static Generic1::IEnumerable<double>^ ToDouble(Generic1::IEnumerable<int>^ list) + { + return nullptr; + }; + + /// <summary> + /// <see cref="T:Mono.DocTest.Generic.IFoo`1" /> extension method. + /// </summary> + /// <remarks><c>M:Mono.DocTest.Generic.Extensions.ToDouble</c></remarks> + public: + generic <typename T> + where T : IFoo<T> + [System::Runtime::CompilerServices::Extension] + static double ToDouble(T val) + { + // the target type is T:...IFoo<T>, NOT T:System.Object. + return 0.0; + }; + }; + + /// <typeparam name="U">Insert <c>text</c> here.</typeparam> + /// <remarks><c>T:Mono.DocTest.Generic.GenericBase`1</c>.</remarks> + generic <typename U> + public ref class GenericBase { + /// <param name="genericParameter">Something</param> + /// <typeparam name="S">Insert more <c>text</c> here.</typeparam> + /// <remarks><c>M:Mono.DocTest.GenericBase`1.BaseMethod``1(``0)</c>.</remarks> + /// <returns>The default value.</returns> + + //todo: done for default keyword + private: U member; + //todo: done for default keyword + public: GenericBase() : member() + { + }; + //todo: done for default keyword + GenericBase(GenericBase^ c) + { + member = c->member; + }; + + public: + generic <typename S> + U BaseMethod(/*[Doc("S")]*/S genericParameter) { + return member; + }; + + U BaseMethod2(GenericBase<U> genericParameter) { + return member; + }; + + /// <remarks><c>F:Mono.DocTest.GenericBase`1.StaticField1</c></remarks> + public: + static initonly GenericBase<U> ^ StaticField1 = gcnew GenericBase<U>(); + + /// <remarks><c>F:Mono.DocTest.GenericBase`1.ConstField1</c></remarks> + public: const int ConstInt = 1; + + public: const long ConstLong = 2; + + public: const Decimal ConstDecimal; + + public: const short ConstShort = 4; + + public: const UInt16 ConstUint16 = 2 ; + + public: const UInt32 ConstUint32 = 3; + + public: const UInt64 ConstUint64 = 4; + + public: const float ConstFloat = 2.4; + + public: const bool ConstBool = true; + + public: const char ConstChar = 't'; + + public: const Object^ ConstObject; + + public: const String^ ConstString; + + + + + /// <param name="list">Insert description here</param> + /// <remarks><c>M:Mono.DocTest.GenericBase`1.op_Explicit(Mono.DocTest.GenericBase{`0})~`0</c></remarks> + /// <returns>The default value for <typeparamref name="U"/>.</returns> + //public: static explicit operator U(GenericBase<U> list) { /*return 0;*/ return nullptr; }; + + /// <remarks>T:Mono.DocTest.Generic.GenericBase`1.FooEventArgs</remarks> + public: ref class FooEventArgs : EventArgs { + }; + + /// <remarks>E:Mono.DocTest.Generic.GenericBase`1.MyEvent</remarks> + public: event EventHandler<FooEventArgs ^ > ^ MyEvent; + + /// <remarks>E:Mono.DocTest.Generic.GenericBase`1.ItemChanged</remarks> + //todo: uncomment + //public: event Action<Mono_DocTest_Generic::MyList<U>^, Mono_DocTest_Generic::MyList<U>::Helper<U, U>^> ItemChanged; + + /// <remarks>T:Mono.DocTest.Generic.GenericBase`1.NestedCollection</remarks> + public: ref class NestedCollection { + //todo: no internal + /// <remarks>T:Mono.DocTest.Generic.GenericBase`1.NestedCollection.Enumerator</remarks> + protected: value struct Enumerator { + }; + }; + }; + + /// <typeparam name="T">I'm Dying Here!</typeparam> + /// <remarks><c>T:Mono.DocTest.Generic.MyList`1</c>.</remarks> + //todo: on generic par-r [Mono.DocTest.Doc("Type Parameter!")] + generic <typename T> + public ref class MyList : GenericBase<T>, Generic1::IEnumerable<cli::array <int> ^ > + { + /// <typeparam name="U">Seriously!</typeparam> + /// <typeparam name="V">Too <c>many</c> docs!</typeparam> + /// <remarks><c>T:Mono.DocTest.MyList`1.Helper`2</c>.</remarks> + + public: + generic<typename U, typename V> + ref class Helper { + /// <param name="a">Ako</param> + /// <param name="b">bko</param> + /// <param name="c">cko</param> + /// <remarks><c>M:Mono.DocTest.MyList`1.Helper`2.UseT(`0,`1,`2)</c>.</remarks> + public: void UseT(T a, U b, V c) { }; + }; + + /// <param name="t">tko</param> + /// <remarks><c>M:Mono.DocTest.MyList`1.Test(`0)</c>.</remarks> + public: void Test(T t) { auto a = gcnew MyList::Helper<int, String^>(); }; + + /// <param name="t">Class generic type</param> + /// <param name="u">Method generic type</param> + /// <typeparam name="U">Method generic parameter</typeparam> + /// <remarks><c>M:Mono.DocTest.MyList`1.Method``1(`0,``0)</c>.</remarks> + + public: + generic<typename U> + void Method(T t, U u) {}; + + // mcs "crashes" (CS1569) on this method; exclude it for now. + // <remarks><c>M:Mono.DocTest.MyList`1.RefMethod``1(`0@,``0@)</c>.</remarks> + public: + generic<typename U> + void RefMethod(T% t, U% u) {}; + + /// <param name="helper">A <see cref="T:Mono.DocTest.Generic.MyList`1.Helper`2" />.</param> + /// <typeparam name="U">Argh!</typeparam> + /// <typeparam name="V">Foo Argh!</typeparam> + /// <remarks><c>M:Mono.DocTest.Generic.MyList`1.UseHelper``2(Mono.DocTest.Generic.MyList{``0}.Helper{``1,``2})</c>.</remarks> + public: + generic<typename U, typename V> + void UseHelper(Helper helper) {}; + + /// <remarks><c>M:Mono.DocTest.Generic.MyList`1.GetHelper``2</c>.</remarks> + /// <returns><see langword="null" />.</returns> + public: + generic<typename U, typename V> + Helper^ GetHelper() { return nullptr; }; + + /// <remarks><c>M:Mono.DocTest.MyList`1.System#Collections#GetEnumerator</c>.</remarks> + public: virtual IEnumerator^ GetEnumerator1() = IEnumerable::GetEnumerator{ + return nullptr; + }; + + + /// <remarks><c>M:Mono.DocTest.MyList`1.GetEnumerator</c>.</remarks> + public: virtual Generic1::IEnumerator<cli::array<int>^>^ GetEnumerator() = Generic1::IEnumerable<cli::array<int>^>::GetEnumerator{ + return nullptr; + }; + }; + + /// <typeparam name="T">T generic param</typeparam> + /// <remarks><c>T:Mono.DocTest.IFoo`1</c>.</remarks> + generic <typename T> + public interface class IFoo { + /// <typeparam name="U">U generic param</typeparam> + /// <remarks><c>T:Mono.DocTest.IFoo`1.Method``1(`0,``0)</c>.</remarks> + generic<typename U> + T Method(T t, U u); + }; + + generic <typename T> + where T: gcnew() + public ref class GenericConstraintClass { + }; + + + + /// <typeparam name="A">Ako generic param</typeparam> + /// <typeparam name="B">Bko generic param</typeparam> + /// <remarks><c>T:Mono.DocTest.MyList`2</c>.</remarks> + generic <typename A, typename B> + //where A : class, IList<B>, gcnew() + //where B : class, A + public ref class MyList1 : Generic1::ICollection<A>, + Generic1::IEnumerable<A>, Generic1::IEnumerator<A>, + IFoo<A> + , GenericBase<Generic1::Dictionary<A,B>^ >/*<>*/ + { + + ~MyList1() {}; + // IEnumerator + + // shown? + //todo: uncomment + //property Object^ IEnumerator::Current { Object^ get() { return nullptr; } } + + /// <remarks><c>M:Mono.DocTest.MyList`2.MoveNext</c>.</remarks> + /// <returns><see cref="T:System.Boolean" /></returns> + public: + virtual bool MoveNext() { return false; }; + + /// <remarks><c>M:Mono.DocTest.MyList`2.Reset</c>.</remarks> + public: + virtual void Reset() {}; + + virtual property Object^ Current3 { + Object^ get() = IEnumerator::Current::get{ return nullptr; } + }; + + // IEnumerator<T> + /// <remarks><c>P:Mono.DocTest.MyList`2.Current</c>.</remarks> + /// <value>The current value.</value> + public: + property A Current1 { + A get() { return Current2; /*default(A);*/ } + }; + /// <remarks><c>P:Mono.DocTest.MyList`2.Current</c>.</remarks> + /// <value>The current value.</value> + virtual property A Current2 { + A get() sealed = Generic1::IEnumerator<A>::Current::get{ return Current1; /*default(A);*/ };// { return default(A); } + }; + + /// <remarks><c>M:Mono.DocTest.MyList`2.System#Collections#GetEnumerator</c>.</remarks> + public: virtual System::Collections::IEnumerator^ GetEnumerator1() = System::Collections::IEnumerable::GetEnumerator{ + return nullptr; + }; + + + // IEnumerable<T> + /// <remarks><c>M:Mono.DocTest.MyList`2.System#Collections#Generic#IEnumerable{A}#GetEnumerator</c>.</remarks> + /// <returns>A <see cref="T:System.Collections.Generic.IEnumerator{`0}" />.</returns> + virtual Generic1::IEnumerator<A>^ GetEnumerator() = Generic1::IEnumerable<A>::GetEnumerator{ return nullptr; }; + + + public: Generic1::List<A>::Enumerator^ GetEnumerator3() { return gcnew Generic1::List<A>::Enumerator(); }; + + // ICollection<T> + /// <remarks><c>P:Mono.DocTest.MyList`2.Count</c>.</remarks> + /// <value>A <see cref="T:System.Int32" />.</value> + public: + virtual property int Count { + int get() { return 0; } + }; + + /// <remarks><c>P:Mono.DocTest.MyList`2.System#Collections#Generic#ICollection{A}#IsReadOnly</c>.</remarks> + /// <value>A <see cref="T:System.Boolean" />.</value> + public: + virtual property bool IsReadOnly { + bool get() { return false; } + }; + /// <param name="item">The item to add.</param> + /// <remarks><c>M:Mono.DocTest.MyList`2.System#Collections#Generic#ICollection{A}#Add(`0)</c>.</remarks> + virtual void Add(A item) = Generic1::ICollection<A>::Add{}; + /// <remarks><c>M:Mono.DocTest.MyList`2.System#Collections#Generic#ICollection{A}#Clear</c>.</remarks> + virtual void Clear() = Generic1::ICollection<A>::Clear{}; + /// <param name="item">The item to check for</param> + /// <remarks><c>M:Mono.DocTest.MyList`2.System#Collections#Generic#ICollection{A}.Contains(`0)</c>.</remarks> + /// <returns>A <see cref="T:System.Boolean" /> instance (<see langword="false" />).</returns> + virtual bool Contains(A item) = Generic1::ICollection<A>::Contains{ return false; }; + /// <param name="array">Where to copy elements to</param> + /// <param name="arrayIndex">Where to start copyingto</param> + /// <remarks><c>M:Mono.DocTest.MyList`2.CopyTo(`0[],System.Int32)</c>.</remarks> + public: virtual void CopyTo(cli::array<A>^ arrayPar, int arrayIndex) = Generic1::ICollection<A>::CopyTo{}; + /// <param name="item">the item to remove</param> + /// <remarks><c>M:Mono.DocTest.MyList`2.System#Collections#Generic#ICollection{A}#Remove(`0)</c>.</remarks> + /// <returns>Whether the item was removed.</returns> + virtual bool Remove(A item) = Generic1::ICollection<A>::Remove{ return false; }; + + /// <remarks>M:Mono.DocTest.Generic.MyList`2.Foo</remarks> + public: + generic<typename AA, typename BB> + where AA : Generic1::IEnumerable<A> + where BB : Generic1::IEnumerable<B> + Generic1::KeyValuePair<AA, BB>^ Foo() + { + return gcnew Generic1::KeyValuePair<AA, BB>(); + }; + + // IFoo members + /// <typeparam name="U">U generic param on MyList`2</typeparam> + /// <remarks><c>M:Mono.DocTest.Generic.MyList`2.Mono#DocTest#Generic#IFoo{A}#Method``1(`0,``0)</c>.</remarks> + generic<typename U> + virtual A Method(A a, U u) = IFoo<A>::Method + { + return Current2; /*default(A);*/ + }; + + }; + + + + + } diff --git a/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.cpp b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.cpp new file mode 100644 index 00000000..cecc25ff --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.cpp @@ -0,0 +1,6 @@ +// This is the main DLL file. + +#include "stdafx.h" + +#include "mdoc.Test.Cplusplus.h" + diff --git a/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.h b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.h new file mode 100644 index 00000000..d609e8b2 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.h @@ -0,0 +1,15 @@ +// mdoc.Test.Cplusplus.h + +#pragma once + +using namespace System; + +namespace mdocTestCplusplus { + + public ref class Class1 + { + // TODO: Add your methods for this class here. + public: + int t; + }; +} diff --git a/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.vcxproj b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.vcxproj new file mode 100644 index 00000000..24b5bc22 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{9398D4E3-1779-44FD-AF8C-BB46562DCD88}</ProjectGuid> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <Keyword>ManagedCProj</Keyword> + <RootNamespace>mdocTestCplusplus</RootNamespace> + <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <CLRSupport>true</CLRSupport> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <CLRSupport>true</CLRSupport> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <CLRSupport>true</CLRSupport> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <CLRSupport>true</CLRSupport> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>Use</PrecompiledHeader> + </ClCompile> + <Link> + <AdditionalDependencies /> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>Use</PrecompiledHeader> + </ClCompile> + <Link> + <AdditionalDependencies /> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>Use</PrecompiledHeader> + </ClCompile> + <Link> + <AdditionalDependencies /> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PrecompiledHeader>Use</PrecompiledHeader> + </ClCompile> + <Link> + <AdditionalDependencies /> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="mdoc.Test.Cplusplus.h" /> + <ClInclude Include="resource.h" /> + <ClInclude Include="Stdafx.h" /> + <ClInclude Include="TestClass.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="AssemblyInfo.cpp" /> + <ClCompile Include="mdoc.Test.Cplusplus.cpp" /> + <ClCompile Include="Stdafx.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> + </ClCompile> + <ClCompile Include="TestClass.cpp" /> + </ItemGroup> + <ItemGroup> + <Text Include="ReadMe.txt" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.vcxproj.filters b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.vcxproj.filters new file mode 100644 index 00000000..2b57d18e --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/mdoc.Test.Cplusplus.vcxproj.filters @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="mdoc.Test.Cplusplus.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Stdafx.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="resource.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="TestClass.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="mdoc.Test.Cplusplus.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="AssemblyInfo.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Stdafx.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="TestClass.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <Text Include="ReadMe.txt" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.Cplusplus/resource.h b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/resource.h new file mode 100644 index 00000000..d5ac7c42 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.Cplusplus/resource.h @@ -0,0 +1,3 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by app.rc diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes.sln b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes.sln new file mode 100644 index 00000000..8e71976e --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mdoc.Test.NullableReferenceTypes", "mdoc.Test.NullableReferenceTypes\mdoc.Test.NullableReferenceTypes.csproj", "{3B5783A4-56B2-459D-9373-2B1DB96E6F39}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3B5783A4-56B2-459D-9373-2B1DB96E6F39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3B5783A4-56B2-459D-9373-2B1DB96E6F39}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3B5783A4-56B2-459D-9373-2B1DB96E6F39}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3B5783A4-56B2-459D-9373-2B1DB96E6F39}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B66A9CE2-DDBF-46C0-A8E5-0C47FEBE5C7E} + EndGlobalSection +EndGlobal diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/CommonType.cs b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/CommonType.cs new file mode 100644 index 00000000..1c6ea790 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/CommonType.cs @@ -0,0 +1,508 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace mdoc.Test.NullableReferenceTypes +{ + public class CommonType + { + public dynamic DynamicType() + { + return default; + } + + public dynamic? NullableDynamicType() + { + return default; + } + + public DayOfWeek Enumeration() + { + return 0; + } + + public DayOfWeek? NullableEnumeration() + { + return 0; + } + + public int ValueType() + { + return 0; + } + + public int? NullableValueType() + { + return default; + } + + public int[] ArrayOfValueType() + { + return default; + } + + public int?[] ArrayOfValueTypeNullable() + { + return default; + } + + public int[]? NullableArrayOfValueType() + { + return default; + } + + public int?[]? NullableArrayOfNullableValueType() + { + return default; + } + + public int[][] DimensionalArrayOfValueType() + { + return default; + } + + public int?[][] DimensionalArrayOfNullableValueType() + { + return default; + } + + public int?[]?[] DimensionalArrayOfNullableValueTypeOfNullableRow() + { + return default; + } + + public int?[]?[]? NullableDimensionalArrayOfNullableValueTypeOfNullableRow() + { + return default; + } + + public int?[][]? NullableDimensionalArrayOfNullableValueType() + { + return default; + } + + public int[][]? NullableDimensionalArrayOfValueType() + { + return default; + } + + public int[][]?[][]? NullableFourDimensionalArrayOfValueTypeOfMiddleNullableArray() + { + return default; + } + + public int?[][]?[][] FourDimensionalArrayOfNullableValueTypeOfMiddleNullableArray() + { + return default; + } + + public Tuple<int, int> TupleOfValueType() + { + return default; + } + + public Tuple<int, int>? NullableTupleOfValueType() + { + return default; + } + + public Tuple<int?, int?> TupleOfNullableValueType() + { + return default; + } + + public Tuple<int?, int?>? NullableTupleOfNullableValueType() + { + return default; + } + + public ValueTuple<int, int> ValueTupleOfValueType() + { + return default; + } + + public ValueTuple<int, int>? NullableValueTupleOfValueType() + { + return default; + } + public ValueTuple<int?, int?> ValueTupleOfNullableValueType() + { + return default; + } + public ValueTuple<int?, int?>? NullableValueTupleOfNullableValueType() + { + return default; + } + + public ICollection<int> InterfaceOfValueType() + { + return default; + } + + public ICollection<int>? NullableInterfaceOfValueType() + { + return default; + } + + public ICollection<int?>? NullableInterfaceOfNullableValueType() + { + return default; + } + + public Action<int> ActionOfValueType() + { + return default; + } + + public Action<int?> ActionOfNullableValueType() + { + return default; + } + + public Action<int>? NullableActionOfValueType() + { + return default; + } + + public Action<int?>? NullableActionOfNullableValueType() + { + return default; + } + + public Dictionary<int, int> DictionaryOfValueType() + { + return default; + } + + public Dictionary<int, int>? NullableDictionaryOfValueType() + { + return default; + } + + public Dictionary<int?, int?> DictionaryOfNullableValueType() + { + return default; + } + + public Dictionary<int?, int?>? NullableDictionaryOfNullableValueType() + { + return default; + } + + public Dictionary<int, int?> DictionaryOfNullableValueTypeValue() + { + return default; + } + + public Dictionary<int, int?>? NullableDictionaryOfNullableValueTypeValue() + { + return default; + } + + public Dictionary<int?, int>? NullableDictionaryOfNullableValueTypeKey() + { + return default; + } + + public Dictionary<int, Dictionary<int, int>> DictionaryOfValueTypeKeyAndDictionaryOfValueTypeValue() + { + return default; + } + + public Dictionary<int, Dictionary<int, int>>? NullableDictionaryOfValueTypeKeyAndDictionaryOfValueTypeValue() + { + return default; + } + + public Dictionary<int?, Dictionary<int, int>?>? NullableDictionaryOfNullableValueTypeKeyAndNullableDictionaryOfValueTypeValue() + { + return default; + } + public Dictionary<int?, Dictionary<int?, int?>?>? NullableDictionaryOfNullableValueTypeKeyAndNullableDictionaryOfNullableValueTypeValue() + { + return default; + } + + public Dictionary<int, Tuple<int, int>> DictionaryOfValueTypeKeyAndTupleOfValueTypeValue() + { + return default; + } + + public Dictionary<int, Tuple<int, int>>? NullableDictionaryOfValueTypeKeyAndTupleOfValueTypeValue() + { + return default; + } + + public Dictionary<int?, Tuple<int, int>?>? NullableDictionaryOfNullableValueTypeKeyAndNullableTupleOfValueTypeValue() + { + return default; + } + public Dictionary<int?, Tuple<int?, int?>?>? NullableDictionaryOfNullableValueTypeKeyAndNullableTupleOfNullableValueTypeValue() + { + return default; + } + + public Dictionary<Dictionary<int, int>, Dictionary<int, int>> DictionaryOfDictionaryOfValueType() + { + return default; + } + + public Dictionary<Dictionary<int, int>?, Dictionary<int, int>?>? NullableDictionaryOfNullableDictionaryOfValueType() + { + return default; + } + + public Dictionary<Dictionary<int?, int?>?, Dictionary<int?, int?>?>? NullableDictionaryOfNullableDictionaryOfNullableValueType() + { + return default; + } + + public string ReferenceType() + { + return default; + } + + public string? NullableReferenceType() + { + return default; + } + + public string[] ArrayOfReferenceType() + { + return default; + } + + public string?[] ArrayOfNullableReferenceType() + { + return default; + } + + public string[]? NullableArrayOfReferenceType() + { + return default; + } + + public string?[]? NullableArrayOfNullableReferenceType() + { + return default; + } + + public string[][] DimensionalArrayOfReferenceType() + { + return default; + } + + public string?[][] DimensionalArrayOfNullableReferenceType() + { + return default; + } + + public string?[]?[] DimensionalArrayOfNullableReferenceTypeOfNullableRow() + { + return default; + } + + public string?[]?[]? NullableDimensionalArrayOfNullableReferenceTypeOfNullableRow() + { + return default; + } + + public string?[][]? NullableDimensionalArrayOfNullableReferenceType() + { + return default; + } + + public string[][]? NullableDimensionalArrayOfReferenceType() + { + return default; + } + + public string[][]?[][]? NullableFourDimensionalArrayOfReferenceTypeOfMiddleNullableArray() + { + return default; + } + + public string?[][]?[][] FourDimensionalArrayOfNullableReferenceTypeOfMiddleNullableArray() + { + return default; + } + + public Tuple<string, string> TupleOfReferenceType() + { + return default; + } + + public Tuple<string, string>? NullableTupleOfReferenceType() + { + return default; + } + public Tuple<string?, string?> TupleOfNullableReferenceType() + { + return default; + } + + public Tuple<string?, string?>? NullableTupleOfNullableReferenceType() + { + return default; + } + + public ValueTuple<string, string> ValueTupleOfReferenceType() + { + return default; + } + + public ValueTuple<string, string>? NullableValueTupleOfReferenceType() + { + return default; + } + + public ValueTuple<string?, string?> ValueTupleOfNullableReferenceType() + { + return default; + } + + public ValueTuple<string?, string?>? NullableValueTupleOfNullableReferenceType() + { + return default; + } + + public ICollection<string> InterfaceOfReferenceType() + { + return default; + } + + public ICollection<string>? NullableInterfaceOfReferenceType() + { + return default; + } + + public ICollection<string?>? NullableInterfaceOfNullableReferenceType() + { + return default; + } + + public ICollection<dynamic> InterfaceOfDynamicType() + { + return default; + } + + public ICollection<dynamic>? NullableInterfaceOfDynamicType() + { + return default; + } + + public ICollection<dynamic?>? NullableInterfaceOfNullableDynamicType() + { + return default; + } + + public Action<string> ActionOfReferenceType() + { + return default; + } + + public Action<string?> ActionOfNullableReferenceType() + { + return default; + } + + public Action<string>? NullableActionOfReferenceType() + { + return default; + } + + public Action<string?>? NullableActionOfNullableReferenceType() + { + return default; + } + + public Dictionary<string, string> DictionaryOfReferenceType() + { + return default; + } + + public Dictionary<string, string>? NullableDictionaryOfReferenceType() + { + return default; + } + + public Dictionary<string?, string?> DictionaryOfNullableReferenceType() + { + return default; + } + + public Dictionary<string?, string?>? NullableDictionaryOfNullableReferenceType() + { + return default; + } + + public Dictionary<string, string?> DictionaryOfNullableReferenceTypeValue() + { + return default; + } + + public Dictionary<string, string?>? NullableDictionaryOfNullableReferenceTypeValue() + { + return default; + } + + public Dictionary<string?, string>? NullableDictionaryOfNullableReferenceTypeKey() + { + return default; + } + + public Dictionary<Dictionary<string, string>, Dictionary<string, string>> DictionaryOfDictionaryOfReferenceType() + { + return default; + } + + public Dictionary<Dictionary<string, string>?, Dictionary<string, string>?>? NullableDictionaryOfNullableDictionaryOfReferenceType() + { + return default; + } + + public Dictionary<Dictionary<string?, string?>?, Dictionary<string?, string?>?>? NullableDictionaryOfNullableDictionaryOfNullableReferenceType() + { + return default; + } + + public Dictionary<string, Dictionary<string, string>> DictionaryOfReferenceTypeKeyAndDictionaryOfReferenceTypeValue() + { + return default; + } + + public Dictionary<string, Dictionary<string, string>>? NullableDictionaryOfReferenceTypeKeyAndDictionaryOfReferenceTypeValue() + { + return default; + } + + public Dictionary<string?, Dictionary<string, string>?>? NullableDictionaryOfNullableReferenceTypeKeyAndNullableDictionaryOfReferenceTypeValue() + { + return default; + } + + public Dictionary<string?, Dictionary<string?, string?>?>? NullableDictionaryOfNullableReferenceTypeKeyAndNullableDictionaryOfNullableReferenceTypeValue() + { + return default; + } + + public Dictionary<string, Tuple<string, string>> DictionaryOfReferenceTypeKeyAndTupleOfReferenceTypeValue() + { + return default; + } + + public Dictionary<string, Tuple<string, string>>? NullableDictionaryOfReferenceTypeKeyAndTupleOfReferenceTypeValue() + { + return default; + } + + public Dictionary<string?, Tuple<string, string>?>? NullableDictionaryOfNullableReferenceTypeKeyAndNullableTupleOfReferenceTypeValue() + { + return default; + } + public Dictionary<string?, Tuple<string?, string?>?>? NullableDictionaryOfNullableReferenceTypeKeyAndNullableTupleOfNullableReferenceTypeValue() + { + return default; + } + } +} diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/Constructor.cs b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/Constructor.cs new file mode 100644 index 00000000..5a93dce0 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/Constructor.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; + +namespace mdoc.Test.NullableReferenceTypes.Constructor +{ + public class NonNullableAndNullableValueType + { + public NonNullableAndNullableValueType(int i1, int? i2, int i3) + { + } + } + + public class NonNullableAndNullableReferenceType + { + public NonNullableAndNullableReferenceType(string s1, string? s2, string s3) + { + } + } + + public class InterfaceOfValueType + { + public InterfaceOfValueType(ICollection<int> collection1, ICollection<int>? collection2, ICollection<int> collection3) + { + } + } + + public class InterfaceOfReferenceType + { + public InterfaceOfReferenceType(ICollection<string> collection1, ICollection<string>? collection2, ICollection<string> collection3) + { + } + } +} diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/Delegate.cs b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/Delegate.cs new file mode 100644 index 00000000..57fe6261 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/Delegate.cs @@ -0,0 +1,18 @@ +using System; + +namespace mdoc.Test.NullableReferenceTypes.Delegate +{ + public delegate void Handler(object sender, EventArgs args); + public delegate void NullableSender(object? sender, EventArgs args); + public delegate void NullableSenderAndEventArgs(object? sender, EventArgs? args); + + public delegate void GenericHandler<TEventArgs>(object sender, TEventArgs args); + public delegate void NullableSender<TEventArgs>(object? sender, TEventArgs args); + public delegate void NullableSenderAndEventArgs<TEventArgs>(object? sender, TEventArgs? args) where TEventArgs : class; + public delegate void ActionHandler<TClass, TStruct>(TClass t1, TStruct t2) where TClass : class where TStruct : struct; + public delegate void NullableActionHandler<TClass, TStruct>(TClass? t1, TStruct? t2) where TClass : class where TStruct : struct; + + public delegate TReturn FuncHandler<TReturn>(); + public delegate TReturn? NullableReferenceType<TReturn>() where TReturn : class; + public delegate TReturn? NullableValueType<TReturn>() where TReturn : struct; +} diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/Event.cs b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/Event.cs new file mode 100644 index 00000000..30fbde1c --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/Event.cs @@ -0,0 +1,19 @@ +using System; + +namespace mdoc.Test.NullableReferenceTypes +{ + public class Event + { + public event EventHandler EventHandler; + + public event EventHandler? NullableEventHandler; + + public event EventHandler<EventArgs> GenericEventHandler; + + public event EventHandler<EventArgs?> GenericEventHandlerOfNullableEventArgs; + + public event EventHandler<EventArgs>? NullableGenericEventHandler; + + public event EventHandler<EventArgs?>? NullableGenericEventHandlerOfNullableEventArgs; + } +} diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/ExtensionMethod.cs b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/ExtensionMethod.cs new file mode 100644 index 00000000..100770ec --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/ExtensionMethod.cs @@ -0,0 +1,17 @@ +namespace mdoc.Test.NullableReferenceTypes +{ + public static class ExtensionMethod + { + public static void NullableAndNonNullableValueType(this int? type, int? i1, int i2, int? i3) + { + } + + public static void NullableAndNonNullableNullableReferenceType(this string? type, string? s1, string s2, string? s3) + { + } + + public static void NullableAndNonNullableNullableReferenceTypeAndValueType(this string? type, string? s1, int? i1, int i2, string s2, string? s3) + { + } + } +} diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericFieldReturnType.cs b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericFieldReturnType.cs new file mode 100644 index 00000000..3e4df0a8 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericFieldReturnType.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; + +namespace mdoc.Test.NullableReferenceTypes +{ + public class GenericFieldType<T> + { + public T GenericType; + } + + public class GenericFieldTypeOfValueType<T> where T : struct + { + public T GenericType; + public T? NullableGenericType; + public ICollection<T> InterfaceOfGenericType; + public ICollection<T?> InterfaceOfNullableGenericType; + public ICollection<T>? NullableInterfaceOfGenericType; + public ICollection<T?>? NullableInterfaceOfNullableGenericType; + public Dictionary<Dictionary<T, string>, string> DictionaryOfDictionary; + public Dictionary<Dictionary<T?, string>, string> DictionaryOfDictionaryOfNullableGenericTypeKey; + public Dictionary<Dictionary<T?, string>, string>? NullableDictionaryOfDictionaryOfNullableGenericTypeKey; + } + + public class GenericFieldTypeOfReferenceType<T> where T : class + { + public T GenericType; + public T? NullableGenericType; + public ICollection<T> InterfaceOfGenericType; + public ICollection<T?> InterfaceOfNullableGenericType; + public ICollection<T>? NullableInterfaceOfGenericType; + public ICollection<T?>? NullableInterfaceOfNullableGenericType; + public Dictionary<Dictionary<T, string>, string> DictionaryOfDictionary; + public Dictionary<Dictionary<T?, string>, string> DictionaryOfDictionaryOfNullableGenericTypeKey; + public Dictionary<Dictionary<T?, string>, string>? NullableDictionaryOfDictionaryOfNullableGenericTypeKey; + } +} diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericMethodParameter.cs b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericMethodParameter.cs new file mode 100644 index 00000000..021404a8 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericMethodParameter.cs @@ -0,0 +1,67 @@ +using System; + +namespace mdoc.Test.NullableReferenceTypes +{ + public class GenericMethodParameter + { + public void GenericType<T>(T t) + { + } + + public void GenericReferenceType<T>(T t) where T : class + { + } + + public void GenericNullableReferenceType<T>(T? t) where T : class + { + } + + public void ActionOfGenericNullableReferenceType<T>(Action<T?> t) where T : class + { + } + + public void NullableActionOfGenericNullableReferenceType<T>(Action<T?>? t) where T : class + { + } + + public void FuncGenericNullableReferenceType<T>(Func<T?> t) where T : class + { + } + + public void NullableFuncGenericNullableReferenceType<T>(Func<T?>? t) where T : class + { + } + + public void GenericNonNullableAndNullableReferenceType<T1, T2>(T1 t1, T2? t2) where T2 : class + { + } + + public void GenericValueType<T>(T t) where T : struct + { + } + + public void GenericNullableValueType<T>(T? t) where T : struct + { + } + + public void ActionOfGenericNullableValueType<T>(Action<T?> action) where T : struct + { + } + + public void NullableActionOfGenericNullableValueType<T>(Action<T?>? action) where T : struct + { + } + + public void FuncGenericNullableValueType<T>(Func<T?> func) where T : struct + { + } + + public void NullableFuncGenericNullableValueType<T>(Func<T?>? func) where T : struct + { + } + + public void GenericNonNullableAndNullableValueType<T1, T2>(T1 t1, T2? t2) where T2 : struct + { + } + } +} diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericMethodReturnType.cs b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericMethodReturnType.cs new file mode 100644 index 00000000..0794c8c6 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericMethodReturnType.cs @@ -0,0 +1,30 @@ +namespace mdoc.Test.NullableReferenceTypes +{ + public class GenericMethodReturnType + { + public T GenericType<T>() + { + return default; + } + + public T GenericReferenceType<T>() where T : class + { + return default; + } + + public T? GenericNullableReferenceType<T>() where T : class + { + return default; + } + + public T GenericValueType<T>() where T : struct + { + return default; + } + + public T? GenericNullableValueType<T>() where T : struct + { + return default; + } + } +} diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericPropertyReturnType.cs b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericPropertyReturnType.cs new file mode 100644 index 00000000..dfc2acb1 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/GenericPropertyReturnType.cs @@ -0,0 +1,15 @@ +namespace mdoc.Test.NullableReferenceTypes +{ + public class GenericPropertyReturnType<T, TClass, TStruct> where TClass : class where TStruct : struct + { + public T GenericType { get; } + + public TClass GenericReferenceType { get; } + + public TClass? GenericNullableReferenceType { get; } + + public TStruct GenericValueType { get; } + + public TStruct? GenericNullableValueType { get; } + } +} diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/MethodParameter.cs b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/MethodParameter.cs new file mode 100644 index 00000000..0baf924a --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/MethodParameter.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; + +namespace mdoc.Test.NullableReferenceTypes +{ + public class MethodParameter + { + public void ParamsArrayOfNullableValueType(int i, params int?[] array) + { + } + + public void ParamsArrayOfNullableReferenceType(string s, params object?[] array) + { + } + + public void NullableAndNonNullableValueType(int i1, int? i2, int i3) + { + } + + public void NullableAndNonNullableReferenceType(string s1, string? s2, string s3) + { + } + + public void NullableGenericValueTypeOfValueType(ReadOnlySpan<int> s1, ReadOnlySpan<int?> s2, ReadOnlySpan<int> s3) + { + } + + public void NullableGenericValueTypeOfReferenceType(ReadOnlySpan<string> s1, ReadOnlySpan<string?> s2, ReadOnlySpan<string> s3) + { + } + + public void NullableAndNonNullableInterfaceOfValueType(ICollection<int> collection1, ICollection<int>? collection2, ICollection<int> collection3) + { + } + + public void NullableAndNonNullableInterfaceOfReferenceType(ICollection<string> collection1, ICollection<string>? collection2, ICollection<string> collection3) + { + } + + public void NonNullableValueTypeWithOutModifier(string? value, out bool result) + { + result = false; + } + + public void NonNullableValueTypeWithRefModifier(string? value, ref bool result) + { + } + } +}
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/OperatorOverloading.cs b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/OperatorOverloading.cs new file mode 100644 index 00000000..a000e85e --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/OperatorOverloading.cs @@ -0,0 +1,75 @@ +namespace mdoc.Test.NullableReferenceTypes.OperatorOverloading +{ + public class Student + { + public string Name { get; set; } + + public int Age { get; set; } + + public static Student operator +(Student s1, Student s2) + { + return default; + } + + public static Student? operator -(Student? s1, Student? s2) + { + return default; + } + + public static Student operator *(Student s1, Student? s2) + { + return default; + } + public static Student operator /(Student? s1, Student s2) + { + return default; + } + + public static implicit operator ExamScore(Student? s) + { + return default; + } + + public static explicit operator Student?(ExamScore? s) + { + return default; + } + } + + public struct ExamScore + { + public int ClassId { get; set; } + + public int Score { get; set; } + + public static ExamScore operator +(ExamScore s1, ExamScore s2) + { + return default; + } + + public static ExamScore? operator -(ExamScore? s1, ExamScore? s2) + { + return default; + } + + public static ExamScore operator *(ExamScore s1, ExamScore? s2) + { + return default; + } + + public static ExamScore operator /(ExamScore? s1, ExamScore s2) + { + return default; + } + + public static implicit operator ExamScore(Student? s) + { + return default; + } + + public static explicit operator Student?(ExamScore? s) + { + return default; + } + } +} diff --git a/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes.csproj b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes.csproj new file mode 100644 index 00000000..04a8e6fb --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes/mdoc.Test.NullableReferenceTypes.csproj @@ -0,0 +1,11 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>netcoreapp3.1</TargetFramework> + <Nullable>enable</Nullable> + <RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild> + <AnalysisLevel>latest</AnalysisLevel> + <EnableNETAnalyzers>false</EnableNETAnalyzers> + </PropertyGroup> + +</Project> diff --git a/mdoc/mdoc.Test/mdoc.Test.csproj b/mdoc/mdoc.Test/mdoc.Test.csproj index 0b163d96..5daf4464 100644 --- a/mdoc/mdoc.Test/mdoc.Test.csproj +++ b/mdoc/mdoc.Test/mdoc.Test.csproj @@ -77,6 +77,7 @@ <Compile Include="CppWinRtMembersTests.cs" />
<Compile Include="CppWinRtFormatterTests.cs" />
<Compile Include="Enumeration\AttachedEntityTests.cs" />
+ <Compile Include="DotnetCoreAssemblyResolver.cs" />
<Compile Include="FrameworkIndexHelperTests.cs" />
<Compile Include="DocUtilsFSharpTests.cs" />
<Compile Include="DocUtilsTests.cs" />
@@ -92,6 +93,7 @@ <Compile Include="JsUsageFormatterTests.cs" />
<Compile Include="MDocFileSourceTests.cs" />
<Compile Include="MDocUpdaterTests.cs" />
+ <Compile Include="NullableReferenceTypesTests.cs" />
<Compile Include="SampleClasses\EiiImplementclass.cs" />
<Compile Include="SampleClasses\Interface_A.cs" />
<Compile Include="SampleClasses\Interface_B.cs" />
diff --git a/mdoc/mdoc.csproj b/mdoc/mdoc.csproj index 29314adb..f9b0d745 100644 --- a/mdoc/mdoc.csproj +++ b/mdoc/mdoc.csproj @@ -53,15 +53,19 @@ </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
+ <Compile Include="Mono.Documentation\Updater\DynamicTypeProvider.cs" />
+ <Compile Include="Mono.Documentation\Updater\EmptyAttributeParserContext.cs" />
<Compile Include="Mono.Documentation\Framework\FrameworkIndexHelper.cs" />
<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" />
<Compile Include="Mono.Documentation\Updater\Formatters\AttributeFormatters\CSharpAttributeFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\CppFormatters\CppWinRtMemberFormatter.cs" />
+ <Compile Include="Mono.Documentation\Updater\NullableReferenceTypeProvider.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\FormatterManager.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\FSharpFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\JsFormatter.cs" />
@@ -96,7 +100,7 @@ <Compile Include="Mono.Documentation\Updater\Formatters\DocIdFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\Formatters\MemberFormatter.cs" />
<Compile Include="Mono.Documentation\Updater\MemberFormatterState.cs" />
- <Compile Include="Mono.Documentation\Updater\DynamicParserContext.cs" />
+ <Compile Include="Mono.Documentation\Updater\AttributeParserContext.cs" />
<Compile Include="Mono.Documentation\Updater\DocumentationMember.cs" />
<Compile Include="Mono.Documentation\Updater\EcmaDocumentationImporter.cs" />
<Compile Include="Mono.Documentation\Updater\MsxdocDocumentationImporter.cs" />
diff --git a/mdoc/mdoc.nuspec b/mdoc/mdoc.nuspec index c4a8a9fb..6adf740b 100644 --- a/mdoc/mdoc.nuspec +++ b/mdoc/mdoc.nuspec @@ -2,7 +2,7 @@ <package > <metadata> <id>mdoc</id> - <version>5.8</version> + <version>5.8.2</version> <title>mdoc</title> <authors>Microsoft</authors> <owners>Microsoft</owners> |