diff options
author | Mikhail Melnikov <mikhail_melnikov@epam.com> | 2017-12-11 19:56:06 +0300 |
---|---|---|
committer | Joel Martinez <joelmartinez@gmail.com> | 2017-12-11 22:48:35 +0300 |
commit | 555de5c794e508ab36154ec57da6c5fd819cbf1f (patch) | |
tree | 0f9e56a5d1677ffb02e3bed0b7a5c53663a0fc6b /mdoc/Mono.Documentation/Updater/DocUtils.cs | |
parent | 43f31b8e6ec4ed6e2a70121ef4ea3f2f01c08360 (diff) |
[mdoc] Fixed StackOverflow in F# and exception in members implementations generation
StackOverflow in F# was caused by generic types constrained recursively by themselves (`'T :> seq<'T>`)
Added `TestConstraints_2_2` unit test
For members implementations generation, we shouldn't count on order of type generic arguments because they can be passed to interface reordered. Slightly remade generation of fingerprints.
Extended `check-monodocer-members-implementation` integration test with `IScrollable` and `ScrollableBase` classes
Diffstat (limited to 'mdoc/Mono.Documentation/Updater/DocUtils.cs')
-rw-r--r-- | mdoc/Mono.Documentation/Updater/DocUtils.cs | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/mdoc/Mono.Documentation/Updater/DocUtils.cs b/mdoc/Mono.Documentation/Updater/DocUtils.cs index 863f9c3a..663722d1 100644 --- a/mdoc/Mono.Documentation/Updater/DocUtils.cs +++ b/mdoc/Mono.Documentation/Updater/DocUtils.cs @@ -410,8 +410,8 @@ namespace Mono.Documentation.Updater StringBuilder buf = new StringBuilder();
var unifiedTypeNames = new Dictionary<string, string>();
- FillUnifiedTypeNames(unifiedTypeNames, memberReference as IGenericParameterProvider, "M", genericInterface);// Fill the member generic parameters unified names as M0, M1....
- FillUnifiedTypeNames(unifiedTypeNames, memberReference.DeclaringType, "T", genericInterface);// Fill the type generic parameters unified names as T0, T1....
+ FillUnifiedMemberTypeNames(unifiedTypeNames, memberReference as IGenericParameterProvider);// Fill the member generic parameters unified names as M0, M1....
+ FillUnifiedTypeNames(unifiedTypeNames, memberReference.DeclaringType, genericInterface);// Fill the type generic parameters unified names as T0, T1....
switch (memberReference)
{
@@ -436,7 +436,7 @@ namespace Mono.Documentation.Updater }
var memberUnifiedTypeNames = new Dictionary<string, string>();
- FillUnifiedTypeNames(memberUnifiedTypeNames, memberReference as IGenericParameterProvider, "M", genericInterface);
+ FillUnifiedMemberTypeNames(memberUnifiedTypeNames, memberReference as IGenericParameterProvider);
if (memberUnifiedTypeNames.Any())// Add generic arguments to the fingerprint. SomeMethod<T>() != SomeMethod()
{
buf.Append(" ").Append(string.Join(" ", memberUnifiedTypeNames.Values));
@@ -457,35 +457,56 @@ namespace Mono.Documentation.Updater return memberName;
}
+ /// <summary>
+ /// Resolve generic type names of the type type based on interface implementation details
+ /// </summary>
private static void FillUnifiedTypeNames(Dictionary<string, string> unifiedTypeNames,
- IGenericParameterProvider genericParameterProvider,
- string newName,
+ IGenericParameterProvider type,
GenericInstanceType genericInterface)
{
- if (genericParameterProvider == null)
+ if (type == null)
return;
int i = 0;
- foreach (var genericParameter in genericParameterProvider.GenericParameters)
+ foreach (var genericParameter in type.GenericParameters)
{
if (unifiedTypeNames.ContainsKey(genericParameter.Name))
continue;
-
+
// if generic type can be resolved with interface implementation parameters
- if (genericInterface != null
- && i < genericInterface.GenericArguments.Count
- && ! genericInterface.GenericArguments[i].IsGenericParameter)
+ if (genericInterface != null
+ && i < genericInterface.GenericArguments.Count)
{
unifiedTypeNames[genericParameter.Name] = genericInterface.GenericArguments[i].FullName;
}
else
{
- unifiedTypeNames[genericParameter.Name] = newName + i;
+ unifiedTypeNames[genericParameter.Name] = genericParameter.Name;
}
++i;
}
}
+ /// <summary>
+ /// Resolve generic type names of the member based on the order of generic arguments
+ /// </summary>
+ private static void FillUnifiedMemberTypeNames(Dictionary<string, string> unifiedTypeNames,
+ IGenericParameterProvider member)
+ {
+ if (member == null)
+ return;
+
+ int i = 0;
+ foreach (var genericParameter in member.GenericParameters)
+ {
+ if (unifiedTypeNames.ContainsKey(genericParameter.Name))
+ continue;
+ unifiedTypeNames[genericParameter.Name] = "MemberGenericType" + i;
+
+ ++i;
+ }
+ }
+
private static void AppendParameters(StringBuilder buf, Collection<ParameterDefinition> parameters, Dictionary<string, string> genericTypes)
{
buf.Append("(");
@@ -502,7 +523,7 @@ namespace Mono.Documentation.Updater if (genericInstance != null && genericInstance.HasGenericArguments)
{
return
- $"{type.Name}<{string.Join(", ", genericInstance.GenericArguments.Select(i => GetUnifiedTypeName(i, genericTypes)))}>";
+ $"{type.Namespace}.{type.Name}<{string.Join(",", genericInstance.GenericArguments.Select(i => GetUnifiedTypeName(i, genericTypes)))}>";
}
return genericTypes.ContainsKey(type.Name)
|