Skip to content

Commit

Permalink
Access modifier of union ctors are configurable + implicit conversion…
Browse files Browse the repository at this point in the history
…s can be omitted.
  • Loading branch information
PawelGerr committed Sep 9, 2024
1 parent 1d25cfa commit 5e62d7c
Show file tree
Hide file tree
Showing 11 changed files with 738 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Thinktecture.DiscriminatedUnions;

[Union<string, int>(T1Name = "Text",
T2Name = "Number",
SkipImplicitConversionFromValue = true,
ConstructorAccessModifier = UnionConstructorAccessModifier.Private)]
public sealed partial class TextOrNumberExtended
{
public required string AdditionalProperty { get; init; }

public TextOrNumberExtended(string text, string additionalProperty)
: this(text)
{
AdditionalProperty = additionalProperty;
}

public TextOrNumberExtended(int number, string additionalProperty)
: this(number)
{
AdditionalProperty = additionalProperty;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ public sealed class AllUnionSettings : IEquatable<AllUnionSettings>
public SwitchMapMethodsGeneration MapMethods { get; }
public IReadOnlyList<MemberTypeSetting> MemberTypeSettings { get; }
public StringComparison DefaultStringComparison { get; }
public UnionConstructorAccessModifier ConstructorAccessModifier { get; }
public bool SkipImplicitConversionFromValue { get; }

public AllUnionSettings(AttributeData attribute, int numberOfMemberTypes)
{
SkipToString = attribute.FindSkipToString() ?? false;
SwitchMethods = attribute.FindSwitchMethods();
MapMethods = attribute.FindMapMethods();
DefaultStringComparison = attribute.FindDefaultStringComparison();
ConstructorAccessModifier = attribute.FindUnionConstructorAccessModifier();
SkipImplicitConversionFromValue = attribute.FindSkipImplicitConversionFromValue();

var memberTypeSettings = new MemberTypeSetting[numberOfMemberTypes];
MemberTypeSettings = memberTypeSettings;
Expand Down Expand Up @@ -41,6 +45,8 @@ public bool Equals(AllUnionSettings? other)
&& SwitchMethods == other.SwitchMethods
&& MapMethods == other.MapMethods
&& DefaultStringComparison == other.DefaultStringComparison
&& ConstructorAccessModifier == other.ConstructorAccessModifier
&& SkipImplicitConversionFromValue == other.SkipImplicitConversionFromValue
&& MemberTypeSettings.SequenceEqual(other.MemberTypeSettings);
}

Expand All @@ -52,6 +58,8 @@ public override int GetHashCode()
hashCode = (hashCode * 397) ^ SwitchMethods.GetHashCode();
hashCode = (hashCode * 397) ^ MapMethods.GetHashCode();
hashCode = (hashCode * 397) ^ (int)DefaultStringComparison;
hashCode = (hashCode * 397) ^ (int)ConstructorAccessModifier;
hashCode = (hashCode * 397) ^ SkipImplicitConversionFromValue.GetHashCode();
hashCode = (hashCode * 397) ^ MemberTypeSettings.ComputeHashCode();

return hashCode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ private void GenerateUnion(CancellationToken cancellationToken)
GenerateMap(true);
}

GenerateImplicitConversions();
if (!_state.Settings.SkipImplicitConversionFromValue)
GenerateImplicitConversions();

GenerateExplicitConversions();
GenerateEqualityOperators();
GenerateEquals();
Expand Down Expand Up @@ -702,7 +704,7 @@ private void GenerateConstructors()
/// Initializes new instance with <paramref name=""").Append(memberType.ArgumentName.Raw).Append(@"""/>.
/// </summary>
/// <param name=""").Append(memberType.ArgumentName.Raw).Append(@""">Value to create a new instance for.</param>
public ").Append(_state.Name).Append("(").AppendTypeFullyQualified(memberType).Append(" ").Append(memberType.ArgumentName.Escaped).Append(@")
").AppendAccessModifier(_state.Settings.ConstructorAccessModifier).Append(" ").Append(_state.Name).Append("(").AppendTypeFullyQualified(memberType).Append(" ").Append(memberType.ArgumentName.Escaped).Append(@")
{
this._").Append(memberType.ArgumentName.Raw).Append(" = ").Append(memberType.ArgumentName.Escaped).Append(@";
this._valueIndex = ").Append(i + 1).Append(@";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace Thinktecture.CodeAnalysis.DiscriminatedUnions;
public SwitchMapMethodsGeneration SwitchMethods => _settings.SwitchMethods;
public SwitchMapMethodsGeneration MapMethods => _settings.MapMethods;
public StringComparison DefaultStringComparison => _settings.DefaultStringComparison;
public UnionConstructorAccessModifier ConstructorAccessModifier => _settings.ConstructorAccessModifier;
public bool SkipImplicitConversionFromValue => _settings.SkipImplicitConversionFromValue;
public bool HasStructLayoutAttribute => _attributeInfo.HasStructLayoutAttribute;

public UnionSettings(AllUnionSettings settings, AttributeInfo attributeInfo)
Expand All @@ -28,6 +30,8 @@ public bool Equals(UnionSettings other)
&& SwitchMethods == other.SwitchMethods
&& MapMethods == other.MapMethods
&& DefaultStringComparison == other.DefaultStringComparison
&& ConstructorAccessModifier == other.ConstructorAccessModifier
&& SkipImplicitConversionFromValue == other.SkipImplicitConversionFromValue
&& HasStructLayoutAttribute == other.HasStructLayoutAttribute;
}

Expand All @@ -39,6 +43,8 @@ public override int GetHashCode()
hashCode = (hashCode * 397) ^ SwitchMethods.GetHashCode();
hashCode = (hashCode * 397) ^ MapMethods.GetHashCode();
hashCode = (hashCode * 397) ^ (int)DefaultStringComparison;
hashCode = (hashCode * 397) ^ (int)ConstructorAccessModifier;
hashCode = (hashCode * 397) ^ SkipImplicitConversionFromValue.GetHashCode();
hashCode = (hashCode * 397) ^ HasStructLayoutAttribute.GetHashCode();

return hashCode;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Thinktecture.CodeAnalysis;

public enum UnionConstructorAccessModifier
{
Private = 1 << 0,
Internal = 1 << 2,
Public = 1 << 3
}
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,17 @@ public static bool FindTxIsNullableReferenceType(this AttributeData attributeDat
return GetStringParameterValue(attributeData, $"T{index}Name");
}

public static UnionConstructorAccessModifier FindUnionConstructorAccessModifier(this AttributeData attributeData)
{
return (UnionConstructorAccessModifier?)GetIntegerParameterValue(attributeData, "ConstructorAccessModifier")
?? UnionConstructorAccessModifier.Public;
}

public static bool FindSkipImplicitConversionFromValue(this AttributeData attributeData)
{
return GetBooleanParameterValue(attributeData, "SkipImplicitConversionFromValue") ?? false;
}

public static (ITypeSymbol ComparerType, ITypeSymbol ItemType)? GetComparerTypes(this AttributeData attributeData)
{
if (attributeData.AttributeClass is not { } attributeClass || attributeClass.TypeKind == TypeKind.Error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ public static StringBuilder RenderAccessModifier(
return sb;
}

public static StringBuilder AppendAccessModifier(
this StringBuilder sb,
UnionConstructorAccessModifier accessModifier)
{
switch (accessModifier)
{
case UnionConstructorAccessModifier.Private:
sb.Append("private");
break;
case UnionConstructorAccessModifier.Internal:
sb.Append("internal");
break;
case UnionConstructorAccessModifier.Public:
sb.Append("public");
break;
}

return sb;
}

public static StringBuilder RenderArguments(
this StringBuilder sb,
IReadOnlyList<InstanceMemberInfo> members,
Expand Down
14 changes: 14 additions & 0 deletions src/Thinktecture.Runtime.Extensions/UnionAttributeBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ public abstract class UnionAttributeBase : Attribute
/// </summary>
public bool SkipToString { get; set; }

/// <summary>
/// Defines the access modifier of the constructors.
/// Default is <see cref="UnionConstructorAccessModifier.Public"/>.
/// </summary>
/// <remarks>
/// Access modifier of the constructors will have effect on the access modifier of implicit casts.
/// </remarks>
public UnionConstructorAccessModifier ConstructorAccessModifier { get; set; } = UnionConstructorAccessModifier.Public;

/// <summary>
/// Indication whether the generator should skip the implementation of implicit conversions from value to union type.
/// </summary>
public bool SkipImplicitConversionFromValue { get; set; }

/// <summary>
/// Indication whether and how the generator should generate the methods <c>Switch</c>.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Thinktecture;

/// <summary>
/// Access modifer.
/// </summary>
public enum UnionConstructorAccessModifier
{
/// <summary>
/// Access modifer "private".
/// </summary>
Private = 1 << 0,

/// <summary>
/// Access modifer "internal".
/// </summary>
Internal = 1 << 2,

/// <summary>
/// Access modifer "public".
/// </summary>
Public = 1 << 3
}
Loading

0 comments on commit 5e62d7c

Please sign in to comment.