-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
136 additions
and
29 deletions.
There are no files selected for viewing
25 changes: 25 additions & 0 deletions
25
Tuxedo.SourceGenerators/RefinementSourceGenerator.RefinementAttributeParts.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using System.Linq; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
|
||
namespace Tuxedo.SourceGenerators; | ||
|
||
public sealed partial class RefinementSourceGenerator | ||
{ | ||
private readonly ref struct RefinementAttributeParts | ||
{ | ||
public string FailureMessage { get; } | ||
private bool IsInternal { get; } | ||
public string AccessModifier => IsInternal ? "internal" : "public"; | ||
|
||
public RefinementAttributeParts(MethodDeclarationSyntax methodDeclaration) | ||
{ | ||
var arguments = methodDeclaration | ||
.AttributeLists.SelectMany(list => list.Attributes) | ||
.Single(attribute => attribute.Name.ToString() == "Refinement") | ||
.ArgumentList!.Arguments; | ||
|
||
FailureMessage = arguments[0].Expression.ToString(); | ||
IsInternal = arguments.Count > 1 && arguments[1].Expression.ToString() == "false"; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using FluentAssertions; | ||
using Xunit; | ||
|
||
namespace Tuxedo.Tests; | ||
|
||
public static class CustomAccessModifier | ||
{ | ||
[Refinement("`{value}` is not a whitespace character", isPublic: false)] | ||
public static bool IsWhiteSpace(char value) => char.IsWhiteSpace(value); | ||
} | ||
|
||
public sealed class CustomAccessModifierTests | ||
{ | ||
private static string AppendWhiteSpace(char value, Refined<char, IsWhiteSpace> ws) => | ||
$"{value} {ws.Value}"; | ||
|
||
[Fact(DisplayName = "Internal refinements can be used in the same assembly")] | ||
public void Case1() | ||
{ | ||
const char value = ' '; | ||
Refined<char, IsWhiteSpace> ws = value; | ||
AppendWhiteSpace(value, ws).Should().Be(" "); | ||
typeof(IsWhiteSpace).IsPublic.Should().BeFalse(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using FluentAssertions; | ||
using Xunit; | ||
|
||
namespace Tuxedo.Tests; | ||
|
||
public static class GenericRefinements | ||
{ | ||
[Refinement("The value must be '{default(TOther).Value}', instead found '{value}'")] | ||
internal static bool Equal<T, TOther>(T value) | ||
where TOther : struct, IConstant<TOther, T> => Equals(value, default(TOther).Value); | ||
} | ||
|
||
public readonly record struct FortyTwo : IConstant<FortyTwo, int> | ||
{ | ||
public int Value => 42; | ||
} | ||
|
||
public sealed class GenericRefinementTests | ||
{ | ||
[Fact(DisplayName = "A value can be refined to a constant value")] | ||
public void Case1() | ||
{ | ||
const int value = 42; | ||
Refined<int, Equal<int, FortyTwo>> refined = value; | ||
refined.Value.Should().Be(42); | ||
} | ||
|
||
[Fact( | ||
DisplayName = "A value that is not equal to the constant value should fail the refinement" | ||
)] | ||
public void Case2() | ||
{ | ||
const int value = 43; | ||
Assert | ||
.Throws<RefinementFailureException>(() => (Refined<int, Equal<int, FortyTwo>>)value) | ||
.Message.Should() | ||
.Be("The value must be '42', instead found '43'"); | ||
Refined.TryRefine(value, out Refined<int, Equal<int, FortyTwo>> _).Should().BeFalse(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters