Skip to content

Commit

Permalink
Merge pull request #49 from ryanwersal/include-operators
Browse files Browse the repository at this point in the history
Include operators in api generation
  • Loading branch information
danielmarbach committed Jul 24, 2018
2 parents c9f4e83 + 2d11a48 commit c564f28
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 3 deletions.
40 changes: 37 additions & 3 deletions src/PublicApiGenerator/ApiGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -510,16 +510,50 @@ static void AddCtorToTypeDeclaration(CodeTypeDeclaration typeDeclaration, Method
typeDeclaration.Members.Add(method);
}

static readonly IDictionary<string, string> OperatorNameMap = new Dictionary<string, string>
{
{ "op_Addition", "+" },
{ "op_UnaryPlus", "+" },
{ "op_Subtraction", "-" },
{ "op_UnaryNegation", "-" },
{ "op_Multiply", "*" },
{ "op_Division", "/" },
{ "op_Modulus", "%" },
{ "op_Increment", "++" },
{ "op_Decrement", "--" },
{ "op_OnesComplement", "~" },
{ "op_LogicalNot", "!" },
{ "op_BitwiseAnd", "&" },
{ "op_BitwiseOr", "|" },
{ "op_ExclusiveOr", "^" },
{ "op_LeftShift", "<<" },
{ "op_RightShift", ">>" },
{ "op_Equality", "==" },
{ "op_Inequality", "!=" },
{ "op_GreaterThan", ">" },
{ "op_GreaterThanOrEqual", ">=" },
{ "op_LessThan", "<" },
{ "op_LessThanOrEqual", "<=" }
};

static void AddMethodToTypeDeclaration(CodeTypeDeclaration typeDeclaration, MethodDefinition member, HashSet<string> excludeAttributes)
{
if (member.IsAssembly || member.IsPrivate || member.IsSpecialName)
return;
if (member.IsAssembly || member.IsPrivate) return;

var isOperator = member.Name.StartsWith("op_");
if (member.IsSpecialName && !isOperator) return;

var memberName = member.Name;
if (isOperator && OperatorNameMap.ContainsKey(memberName))
{
memberName = OperatorNameMap[memberName];
}

var returnType = CreateCodeTypeReference(member.ReturnType);

var method = new CodeMemberMethod
{
Name = member.Name,
Name = memberName,
Attributes = GetMethodAttributes(member),
CustomAttributes = CreateCustomAttributes(member, excludeAttributes),
ReturnType = returnType,
Expand Down
110 changes: 110 additions & 0 deletions src/PublicApiGeneratorTests/Operator_order.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using PublicApiGeneratorTests.Examples;
using Xunit;

namespace PublicApiGeneratorTests
{
public class Operator_order : ApiGeneratorTestsBase
{
[Fact]
public void Should_sort_unary_operators()
{
AssertPublicApi<ClassWithUnaryOperators>(
@"namespace PublicApiGeneratorTests.Examples
{
public class ClassWithUnaryOperators
{
public ClassWithUnaryOperators() { }
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) { }
}
}");
}

[Fact]
public void Should_sort_binary_operators()
{
AssertPublicApi<ClassWithBinaryOperators>(
@"namespace PublicApiGeneratorTests.Examples
{
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, 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) { }
}
}");
}

[Fact]
public void Should_sort_comparison_operators()
{
AssertPublicApi<ClassWithComparisonOperators>(
@"namespace PublicApiGeneratorTests.Examples
{
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) { }
}
}");
}
}

namespace Examples
{
public class ClassWithUnaryOperators
{
public static ClassWithUnaryOperators operator +(ClassWithUnaryOperators first) => first;
public static ClassWithUnaryOperators operator -(ClassWithUnaryOperators first) => first;
public static ClassWithUnaryOperators operator !(ClassWithUnaryOperators first) => first;
public static ClassWithUnaryOperators operator ~(ClassWithUnaryOperators first) => first;
public static ClassWithUnaryOperators operator ++(ClassWithUnaryOperators first) => first;
public static ClassWithUnaryOperators operator --(ClassWithUnaryOperators first) => first;
public static bool operator true(ClassWithUnaryOperators first) => true;
public static bool operator false(ClassWithUnaryOperators first) => false;
}

public class ClassWithBinaryOperators
{
public static ClassWithBinaryOperators operator +(ClassWithBinaryOperators first, ClassWithBinaryOperators second) => first;
public static ClassWithBinaryOperators operator -(ClassWithBinaryOperators first, ClassWithBinaryOperators second) => first;
public static ClassWithBinaryOperators operator /(ClassWithBinaryOperators first, ClassWithBinaryOperators second) => first;
public static ClassWithBinaryOperators operator *(ClassWithBinaryOperators first, ClassWithBinaryOperators second) => first;
public static ClassWithBinaryOperators operator %(ClassWithBinaryOperators first, ClassWithBinaryOperators second) => first;
public static ClassWithBinaryOperators operator &(ClassWithBinaryOperators first, ClassWithBinaryOperators second) => first;
public static ClassWithBinaryOperators operator |(ClassWithBinaryOperators first, ClassWithBinaryOperators second) => first;
public static ClassWithBinaryOperators operator ^(ClassWithBinaryOperators first, ClassWithBinaryOperators second) => first;
public static ClassWithBinaryOperators operator <<(ClassWithBinaryOperators first, int second) => first;
public static ClassWithBinaryOperators operator >>(ClassWithBinaryOperators first, int second) => first;
}

public class ClassWithComparisonOperators
{
public static bool operator ==(ClassWithComparisonOperators first, ClassWithComparisonOperators second) => true;
public static bool operator !=(ClassWithComparisonOperators first, ClassWithComparisonOperators second) => true;
public static bool operator <(ClassWithComparisonOperators first, ClassWithComparisonOperators second) => true;
public static bool operator >(ClassWithComparisonOperators first, ClassWithComparisonOperators second) => true;
public static bool operator <=(ClassWithComparisonOperators first, ClassWithComparisonOperators second) => true;
public static bool operator >=(ClassWithComparisonOperators first, ClassWithComparisonOperators second) => true;
}
}
}
30 changes: 30 additions & 0 deletions src/PublicApiGeneratorTests/Operator_visibility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using PublicApiGeneratorTests.Examples;
using Xunit;

namespace PublicApiGeneratorTests
{
public class Operator_visibility : ApiGeneratorTestsBase
{
[Fact]
public void Should_show_custom_operators()
{
AssertPublicApi<ClassWithOperator>(
@"namespace PublicApiGeneratorTests.Examples
{
public class ClassWithOperator
{
public ClassWithOperator() { }
public static PublicApiGeneratorTests.Examples.ClassWithOperator +(PublicApiGeneratorTests.Examples.ClassWithOperator first, PublicApiGeneratorTests.Examples.ClassWithOperator second) { }
}
}");
}
}

namespace Examples
{
public class ClassWithOperator
{
public static ClassWithOperator operator +(ClassWithOperator first, ClassWithOperator second) => second;
}
}
}

0 comments on commit c564f28

Please sign in to comment.