Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix member ordering #138

Merged
merged 5 commits into from Nov 15, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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)
danielmarbach marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
124 changes: 124 additions & 0 deletions src/PublicApiGenerator/CodeTypeDeclarationExtensions.cs
@@ -0,0 +1,124 @@
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.GetType().Name, StringComparer.Ordinal)
adamralph marked this conversation as resolved.
Show resolved Hide resolved
.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;
}
}
}
}
15 changes: 15 additions & 0 deletions src/PublicApiGeneratorTests/Method_order.cs
Expand Up @@ -15,8 +15,11 @@ 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() { }
}
}");
Expand All @@ -33,10 +36,22 @@ 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 Down
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