Skip to content

Commit

Permalink
WIP(apireference): Add support for nested types
Browse files Browse the repository at this point in the history
Rewrite code that requires C# 8.0
  • Loading branch information
ap0llo committed Dec 28, 2019
1 parent a740766 commit f5099ca
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 60 deletions.
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>

<PropertyGroup>
<LangVersion>8.0</LangVersion>
<LangVersion>7.3</LangVersion>
</PropertyGroup>

<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,12 @@ public void GetDefinition_returns_the_expected_definition_for_types(string typeN
)]
[InlineData(
nameof(TestClass_CSharpDefinition_NestedTypes),
"NestedClass7`1",
"NestedClass7`1",
"public class TestClass_CSharpDefinition_NestedTypes.NestedClass6<T1, T2>.NestedClass7<T3>"
)]
public void GetDefinition_returns_the_expected_definition_for_nested_types(string declaringTypeName, string typeName, string expected)
{
static IEnumerable<TypeDefinition> GetNestedTypes(TypeDefinition type)
IEnumerable<TypeDefinition> GetNestedTypes(TypeDefinition type)
{
return type.NestedTypes.Union(type.NestedTypes.SelectMany(GetNestedTypes));
}
Expand Down
113 changes: 56 additions & 57 deletions src/MdDocs.ApiReference.Model/_Helpers/CSharpDefinitionFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,61 +281,7 @@ public static string GetDefinition(EventDefinition @event)
/// Gets the C# code defining the specified type.
/// </summary>
public static string GetDefinition(TypeDefinition type)
{
static void AppendTypeName(StringBuilder definitionBuilder, TypeDefinition type)
{
if (type.IsNested)
{
AppendTypeName(definitionBuilder, type.DeclaringType);
definitionBuilder.Append(".");
}

// class name and type parameters
if (type.HasGenericParameters)
{
// remove number of type parameters from type name
var index = type.Name.LastIndexOf('`');

// for nested types, the type's name might not include the arity
// because all type parameters are type parameters of the declaring type, e.g.
//
// public class MyClass<T>
// {
// public class NestedType
// { }
// }
//
if (index > 0)
{
var name = type.Name.Substring(0, index);
definitionBuilder.Append(name);

IEnumerable<GenericParameter> genericParameters = type.GenericParameters;
if (type.IsNested)
{
// determine generic parameter for nested types:
// type.GenericParameters for a nested class contains both the
// generic parameters of the nested type *and* the generic parameters
// of the surrounding types.
// To avoid appending too many generic parameters,
// remove the declaring type's parameter from the list.
genericParameters = genericParameters
.Where(p1 => !type.DeclaringType.GenericParameters.Any(p2 => p2.Name == p1.Name));
}

AppendTypeParameters(definitionBuilder, genericParameters);
}
else
{
definitionBuilder.Append(type.Name);
}
}
else
{
definitionBuilder.Append(type.Name);
}
}

{
var definitionBuilder = new StringBuilder();
var typeKind = type.Kind();

Expand All @@ -347,7 +293,7 @@ static void AppendTypeName(StringBuilder definitionBuilder, TypeDefinition type)
definitionBuilder.Append(" ");

// type name
AppendTypeName(definitionBuilder, type);
AppendTypeDefinitionTypeName(definitionBuilder, type);

// base type and interface implementations
AppendBaseTypes(type, typeKind, definitionBuilder);
Expand All @@ -358,7 +304,60 @@ static void AppendTypeName(StringBuilder definitionBuilder, TypeDefinition type)
}



private static void AppendTypeDefinitionTypeName(StringBuilder definitionBuilder, TypeDefinition type)
{
if (type.IsNested)
{
AppendTypeDefinitionTypeName(definitionBuilder, type.DeclaringType);
definitionBuilder.Append(".");
}

// class name and type parameters
if (type.HasGenericParameters)
{
// remove number of type parameters from type name
var index = type.Name.LastIndexOf('`');

// for nested types, the type's name might not include the arity
// because all type parameters are type parameters of the declaring type, e.g.
//
// public class MyClass<T>
// {
// public class NestedType
// { }
// }
//
if (index > 0)
{
var name = type.Name.Substring(0, index);
definitionBuilder.Append(name);

IEnumerable<GenericParameter> genericParameters = type.GenericParameters;
if (type.IsNested)
{
// determine generic parameter for nested types:
// type.GenericParameters for a nested class contains both the
// generic parameters of the nested type *and* the generic parameters
// of the surrounding types.
// To avoid appending too many generic parameters,
// remove the declaring type's parameter from the list.
genericParameters = genericParameters
.Where(p1 => !type.DeclaringType.GenericParameters.Any(p2 => p2.Name == p1.Name));
}

AppendTypeParameters(definitionBuilder, genericParameters);
}
else
{
definitionBuilder.Append(type.Name);
}
}
else
{
definitionBuilder.Append(type.Name);
}
}

private static void AppendCustomAttributes(StringBuilder definitionBuilder, IEnumerable<CustomAttribute> customAttributes, bool singleLine = false)
{
foreach (var attribute in customAttributes)
Expand Down

0 comments on commit f5099ca

Please sign in to comment.