Skip to content

Commit

Permalink
Merge pull request #138 from adamralph/fix-member-ordering
Browse files Browse the repository at this point in the history
Fix member ordering
  • Loading branch information
danielmarbach committed Nov 15, 2019
2 parents 5c03e73 + 25ed5ab commit e11d012
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/PublicApiGenerator/ApiGenerator.cs
Expand Up @@ -312,7 +312,7 @@ static CodeTypeDeclaration CreateTypeDeclaration(TypeDefinition publicType, stri
}
}

return declaration;
return declaration.Sort();
}

static CodeTypeDeclaration CreateDelegateDeclaration(TypeDefinition publicType, AttributeFilter attributeFilter)
Expand Down
125 changes: 125 additions & 0 deletions src/PublicApiGenerator/CodeTypeDeclarationExtensions.cs
@@ -0,0 +1,125 @@
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;

namespace PublicApiGenerator
{
internal static class CodeTypeDeclarationExtensions
{
public static CodeTypeDeclaration Sort(this CodeTypeDeclaration original)
{
if (original.IsEnum)
{
return original;
}

var sorted = new CodeTypeDeclaration(original.Name)
{
Attributes = original.Attributes,
CustomAttributes = original.CustomAttributes,
IsClass = original.IsClass,
IsEnum = original.IsEnum,
IsInterface = original.IsInterface,
IsPartial = original.IsPartial,
IsStruct = original.IsStruct,
LinePragma = original.LinePragma,
Name = original.Name,
TypeAttributes = original.TypeAttributes,
};

sorted.BaseTypes.AddRange(original.BaseTypes);
sorted.Comments.AddRange(original.Comments);
sorted.EndDirectives.AddRange(original.EndDirectives);
sorted.StartDirectives.AddRange(original.StartDirectives);
sorted.TypeParameters.AddRange(original.TypeParameters);

foreach (var key in original.UserData.Keys)
{
sorted.UserData[key] = original.UserData[key];
}

var emptyParamList = new List<CodeParameterDeclarationExpression>();

var sortedMembers = original.Members.OfType<CodeTypeMember>()
.OrderBy(m => m.Attributes.HasFlag(MemberAttributes.Static))
.ThenBy(m => m.GetType().Name, StringComparer.Ordinal)
.ThenBy(m => m.Name, StringComparer.Ordinal)
.ThenBy(m => m is CodeMemberMethod method
? method.TypeParameters.Count
: 0)
.ThenBy(m => m is CodeMemberMethod method
? method.Parameters.OfType<CodeParameterDeclarationExpression>().ToList()
: emptyParamList,
new ParamListComparer());

foreach (var member in sortedMembers)
{
sorted.Members.Add(member);
}

return sorted;
}

private class ParamListComparer : IComparer<List<CodeParameterDeclarationExpression>>
{
public int Compare(List<CodeParameterDeclarationExpression> x, List<CodeParameterDeclarationExpression> y)
{
var paramIndex = 0;
for (; paramIndex < x.Count; ++paramIndex)
{
if (paramIndex == y.Count)
{
return 1;
}

var paramX = x[paramIndex];
var paramY = y[paramIndex];

var type = Compare(paramX.Type, paramY.Type);
if (type != 0)
{
return type;
}

var name = string.CompareOrdinal(paramX.Name, paramY.Name);
if (name != 0)
{
return name;
}
}

return paramIndex < y.Count ? -1 : 0;
}

private int Compare(CodeTypeReference x, CodeTypeReference y)
{
var baseType = string.CompareOrdinal(x.BaseType, y.BaseType);
if (baseType != 0)
{
return baseType;
}

var typeArgsX = x.TypeArguments.OfType<CodeTypeReference>().ToList();
var typeArgsY = y.TypeArguments.OfType<CodeTypeReference>().ToList();

var typeArgIndex = 0;
for (; typeArgIndex < typeArgsX.Count; ++typeArgIndex)
{
if (typeArgIndex == typeArgsY.Count)
{
return 1;
}

var typeArg = Compare(typeArgsX[typeArgIndex], typeArgsY[typeArgIndex]);
if (typeArg != 0)
{
return typeArg;
}
}

return typeArgIndex < typeArgsY.Count ? -1 : 0;
}
}
}
}
24 changes: 22 additions & 2 deletions src/PublicApiGeneratorTests/Method_order.cs
@@ -1,4 +1,4 @@
using PublicApiGeneratorTests.Examples;
using PublicApiGeneratorTests.Examples;
using Xunit;

namespace PublicApiGeneratorTests
Expand All @@ -15,9 +15,13 @@ public class MethodOrdering
{
public MethodOrdering() { }
public void Method_AA() { }
public void Method_AA<T>() { }
public void Method_AA<T, U>() { }
public void Method_BB() { }
public void Method_I() { }
public void Method_I(string arg) { }
public void Method_i() { }
public static void Method_CC() { }
}
}");
}
Expand All @@ -29,14 +33,30 @@ namespace Examples
{
public class MethodOrdering
{
public static void Method_CC()
{
}

public void Method_BB()
{
}

public void Method_AA<T, U>()
{
}

public void Method_AA<T>()
{
}

public void Method_AA()
{
}

public void Method_I(string arg)
{
}

public void Method_I()
{
}
Expand All @@ -48,4 +68,4 @@ public void Method_i()
}
// ReSharper restore ClassNeverInstantiated.Global
// ReSharper restore UnusedMember.Global
}
}
28 changes: 14 additions & 14 deletions src/PublicApiGeneratorTests/Operator_order.cs
Expand Up @@ -14,14 +14,14 @@ public void Should_sort_unary_operators()
public class ClassWithUnaryOperators
{
public ClassWithUnaryOperators() { }
public static PublicApiGeneratorTests.Examples.ClassWithUnaryOperators !(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static PublicApiGeneratorTests.Examples.ClassWithUnaryOperators +(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static PublicApiGeneratorTests.Examples.ClassWithUnaryOperators ++(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static PublicApiGeneratorTests.Examples.ClassWithUnaryOperators -(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static PublicApiGeneratorTests.Examples.ClassWithUnaryOperators --(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static bool op_False(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static PublicApiGeneratorTests.Examples.ClassWithUnaryOperators ++(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static PublicApiGeneratorTests.Examples.ClassWithUnaryOperators !(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static PublicApiGeneratorTests.Examples.ClassWithUnaryOperators ~(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static bool op_True(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static PublicApiGeneratorTests.Examples.ClassWithUnaryOperators -(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static PublicApiGeneratorTests.Examples.ClassWithUnaryOperators +(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
public static PublicApiGeneratorTests.Examples.ClassWithUnaryOperators ~(PublicApiGeneratorTests.Examples.ClassWithUnaryOperators first) { }
}
}");
}
Expand All @@ -35,16 +35,16 @@ public void Should_sort_binary_operators()
public class ClassWithBinaryOperators
{
public ClassWithBinaryOperators() { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators +(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators %(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators &(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators |(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators *(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators +(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators -(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators /(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators ^(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators <<(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, int second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators %(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators *(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators >>(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, int second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators -(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators ^(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
public static PublicApiGeneratorTests.Examples.ClassWithBinaryOperators |(PublicApiGeneratorTests.Examples.ClassWithBinaryOperators first, PublicApiGeneratorTests.Examples.ClassWithBinaryOperators second) { }
}
}");
}
Expand All @@ -58,12 +58,12 @@ public void Should_sort_comparison_operators()
public class ClassWithComparisonOperators
{
public ClassWithComparisonOperators() { }
public static bool ==(PublicApiGeneratorTests.Examples.ClassWithComparisonOperators first, PublicApiGeneratorTests.Examples.ClassWithComparisonOperators second) { }
public static bool >(PublicApiGeneratorTests.Examples.ClassWithComparisonOperators first, PublicApiGeneratorTests.Examples.ClassWithComparisonOperators second) { }
public static bool >=(PublicApiGeneratorTests.Examples.ClassWithComparisonOperators first, PublicApiGeneratorTests.Examples.ClassWithComparisonOperators second) { }
public static bool !=(PublicApiGeneratorTests.Examples.ClassWithComparisonOperators first, PublicApiGeneratorTests.Examples.ClassWithComparisonOperators second) { }
public static bool <(PublicApiGeneratorTests.Examples.ClassWithComparisonOperators first, PublicApiGeneratorTests.Examples.ClassWithComparisonOperators second) { }
public static bool <=(PublicApiGeneratorTests.Examples.ClassWithComparisonOperators first, PublicApiGeneratorTests.Examples.ClassWithComparisonOperators second) { }
public static bool ==(PublicApiGeneratorTests.Examples.ClassWithComparisonOperators first, PublicApiGeneratorTests.Examples.ClassWithComparisonOperators second) { }
public static bool >(PublicApiGeneratorTests.Examples.ClassWithComparisonOperators first, PublicApiGeneratorTests.Examples.ClassWithComparisonOperators second) { }
public static bool >=(PublicApiGeneratorTests.Examples.ClassWithComparisonOperators first, PublicApiGeneratorTests.Examples.ClassWithComparisonOperators second) { }
}
}");
}
Expand Down

0 comments on commit e11d012

Please sign in to comment.