Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>

<ItemGroup>
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="5.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="5.3.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.3.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="5.3.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.6.0" />
<PackageVersion Include="Verify.SourceGenerators" Version="2.5.0" />
<PackageVersion Include="Verify.Xunit" Version="31.9.3" />
<PackageVersion Include="Verify.Xunit" Version="31.12.5" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="Microsoft.XmlSerializer.Generator" Version="10.0.1" />
<PackageVersion Include="coverlet.collector" Version="10.0.1" />
<PackageVersion Include="Microsoft.XmlSerializer.Generator" Version="10.0.8" />
</ItemGroup>
</Project>
</Project>
26 changes: 22 additions & 4 deletions clean.bat
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
FOR /F "tokens=*" %%G IN ('DIR /B /AD /S bin') DO RMDIR /S /Q "%%G"
FOR /F "tokens=*" %%G IN ('DIR /B /AD /S obj') DO RMDIR /S /Q "%%G"
FOR /F "tokens=*" %%G IN ('DIR /B /AD /S log') DO RMDIR /S /Q "%%G"
@echo off

rem nuget locals all -clear
:: Delete all bin directories and their contents recursively
FOR /F "tokens=*" %%G IN ('DIR /B /AD /S bin') DO (
ECHO Deleting directory and contents: "%%G"
RMDIR /S /Q "%%G"
)

:: Delete all obj directories and their contents recursively
FOR /F "tokens=*" %%G IN ('DIR /B /AD /S obj') DO (
ECHO Deleting directory and contents: "%%G"
RMDIR /S /Q "%%G"
)

:: Delete all log directories and their contents recursively
FOR /F "tokens=*" %%G IN ('DIR /B /AD /S log') DO (
ECHO Deleting directory and contents: "%%G"
RMDIR /S /Q "%%G"
)

@echo on

:: rem nuget locals all -clear

14 changes: 9 additions & 5 deletions src/AltaSoft.Choice.Generator/Executor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,10 @@ private static SourceCodeBuilder Process(INamedTypeSymbol typeSymbol, List<IProp
sb.AppendLine("public ChoiceOf ChoiceType { get; private set; }");
sb.NewLine();

var isOnly1Property = processedProperties.Count == 1;

foreach (var p in processedProperties)
{

var fieldName = p.Name.ToFieldName();

sb.Append("private ").Append(p.TypeName).Append("? ").Append(fieldName).AppendLine(";").NewLine();
Expand All @@ -116,12 +117,13 @@ private static SourceCodeBuilder Process(INamedTypeSymbol typeSymbol, List<IProp
}

sb.AppendLine("[ChoiceProperty]");

sb.Append("public partial ").Append(p.TypeName).Append("? ").Append(p.Name)
.OpenBracket();
sb.Append(p.Modifiers).Append(" ");
sb.Append(p.TypeName);
sb.Append(isOnly1Property ? " " : "? ");
sb.Append(p.Name).OpenBracket();

sb.AppendIfNotEmpty(p.GetterAccessibility.GetPropertyAccessibilityString()).Append("get => ")
.Append(fieldName).AppendLine(";");
.Append(fieldName).AppendLine(";");

sb.AppendIfNotEmpty(p.SetterAccessibility.GetPropertyAccessibilityString()).AppendLine("set")
.OpenBracket()
Expand Down Expand Up @@ -210,12 +212,14 @@ private static PropertyDetails ProcessProperty(IPropertySymbol propertySymbol)

var typeFullName = propertySymbol.Type.GetFullName();
var propertyName = propertySymbol.Name;
var modifiers = propertySymbol.GetModifiers();

return new PropertyDetails(
name: propertyName,
typeName: typeFullName.Replace("?", ""),
@namespace: propertySymbol.ContainingNamespace.ToDisplayString(),
xmlNameValue: xmlElementName,
modifiers: modifiers,
summary: propertySymbol.GetSummaryText(),
getterAccessibility: propertySymbol.GetMethod?.DeclaredAccessibility ?? Accessibility.NotApplicable,
setterAccessibility: propertySymbol.SetMethod?.DeclaredAccessibility ?? Accessibility.NotApplicable,
Expand Down
48 changes: 18 additions & 30 deletions src/AltaSoft.Choice.Generator/Extensions/CompilationExt.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;

Expand Down Expand Up @@ -92,57 +91,45 @@ public static IEnumerable<TMember> GetMembersOfType<TMember>(this ITypeSymbol? s
/// <summary>
/// Gets the modifiers for the named type symbol.
/// </summary>
/// <param name="self">The named type symbol to retrieve modifiers from.</param>
/// <returns>The modifiers as a string, or null if the type is null or has no modifiers.</returns>
public static string? GetModifiers(this INamedTypeSymbol? self)
public static string? GetModifiers(this INamedTypeSymbol self)
{
var declaringSyntax = self?.DeclaringSyntaxReferences;
if (self is null || declaringSyntax is null or { Length: 0 })
var declaringSyntax = self.DeclaringSyntaxReferences;
if (declaringSyntax is { Length: 0 })
return null;

foreach (var syntax in declaringSyntax)
{
if (syntax.GetSyntax() is TypeDeclarationSyntax typeDeclaration && string.Equals(typeDeclaration.GetClassName(), self.GetClassNameWithArguments(), StringComparison.Ordinal))
if (syntax.GetSyntax() is TypeDeclarationSyntax typeDeclaration)
{
var modifiers = typeDeclaration.Modifiers.ToString();

return modifiers;
}
}

return null;
}

#endregion Accessibility
/// <summary>
/// Gets the class name including generic arguments as a string.
/// Gets the modifiers for the property type symbol.
/// </summary>
/// <param name="type">The named type symbol to get the class name from.</param>
/// <returns>The class name including generic arguments as a string.</returns>
public static string GetClassNameWithArguments(this INamedTypeSymbol? type)
public static string GetModifiers(this IPropertySymbol self)
{
if (type is null)
return string.Empty;

var builder = new StringBuilder(type.Name);
var declaringSyntax = self.DeclaringSyntaxReferences;
if (declaringSyntax is { Length: 0 })
return "public";

if (type.TypeArguments.Length == 0)
return builder.ToString();

builder.Append('<');
for (var index = 0; index < type.TypeArguments.Length; index++)
foreach (var syntax in declaringSyntax)
{
var arg = type.TypeArguments[index];
builder.Append(arg.Name);

if (index != type.TypeArguments.Length - 1)
builder.Append(", ");
if (syntax.GetSyntax() is PropertyDeclarationSyntax propertyDeclarationSyntax)
{
return propertyDeclarationSyntax.Modifiers.ToString();
}
}
return "public";
}

builder.Append('>');
#endregion Accessibility

return builder.ToString();
}
#pragma warning disable S1643
public static string GetFullName(this ITypeSymbol type)
{
Expand Down Expand Up @@ -183,6 +170,7 @@ public static string GetFullName(this ITypeSymbol type)
return ns + '.' + friendlyName;
}
#pragma warning restore S1643

/// <summary>
/// Determines whether the specified type symbol is a Nullable&lt;T&gt; value type and, if so, provides the underlying value type symbol.
/// </summary>
Expand Down
48 changes: 0 additions & 48 deletions src/AltaSoft.Choice.Generator/Extensions/RoslynExt.cs

This file was deleted.

17 changes: 8 additions & 9 deletions src/AltaSoft.Choice.Generator/Models/PropertyDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ internal sealed class PropertyDetails
/// </summary>
internal string XmlNameValue { get; private set; }

/// <summary>
/// The access modifiers for the property, such as "public", "private", etc.
/// </summary>
public string Modifiers { get; set; }

/// <summary>
/// The summary documentation for the property.
/// </summary>
Expand Down Expand Up @@ -52,22 +57,16 @@ internal bool IsDateOnly()
{
return TypeSymbol.IsValueType && TypeSymbol.GetFullName().Replace("?", "") == "System.DateOnly";
}

/// <summary>
/// Initializes a new instance of the <see cref="PropertyDetails"/> class.
/// </summary>
/// <param name="name">The name of the property.</param>
/// <param name="typeName">The type name of the property.</param>
/// <param name="namespace">The namespace of the property.</param>
/// <param name="xmlNameValue">The XML name value of the property.</param>
/// <param name="summary">The summary documentation for the property.</param>
/// <param name="getterAccessibility">The access modifiers for the property's getter.</param>
/// <param name="setterAccessibility">The access modifiers for the property's setter.</param>
/// <param name="typeSymbol">The type symbol of the property.</param>
public PropertyDetails(
string name,
string typeName,
string @namespace,
string xmlNameValue,
string modifiers,
string? summary,
Accessibility getterAccessibility,
Accessibility setterAccessibility,
Expand All @@ -77,10 +76,10 @@ public PropertyDetails(
TypeName = typeName;
Namespace = @namespace;
XmlNameValue = xmlNameValue;
Modifiers = modifiers;
Summary = summary;
GetterAccessibility = getterAccessibility;
SetterAccessibility = setterAccessibility;
TypeSymbol = typeSymbol;
}

}
15 changes: 15 additions & 0 deletions tests/AltaSoft.ChoiceGenerator.Tests/ChoiceGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -299,5 +299,20 @@ public void ImplicitConversions_ShouldConvertCorrectly()
Assert.Equal("1234", choice.Proprietary?.Other);

}

[Fact]
public void GenerateSinglePropertyChoice()
{
var choice = SinglePropertyChoice.CreateAsValue("value");

Assert.Equal(SinglePropertyChoice.ChoiceOf.Value, choice.ChoiceType);
Assert.Equal("value", choice.Value);

var matched = choice.Match(_ => "ok");
Assert.Equal("ok", matched);

var switched = choice.Match(x => "matched");
Assert.Equal("matched", switched);
}
}

25 changes: 12 additions & 13 deletions tests/AltaSoft.ChoiceGenerator.Tests/DateTypeChoice.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
using System;
using AltaSoft.Choice;

namespace AltaSoft.ChoiceGenerator.Tests
namespace AltaSoft.ChoiceGenerator.Tests;

[Choice]
public sealed partial record DateTypeChoice
{
[Choice]
public sealed partial record DateTypeChoice
{
/// <summary>
/// <para>Specifies the authorisation, in a coded form.</para>
/// </summary>
public partial DateOnly? OnlyDate { get; set; }
/// <summary>
/// <para>Specifies the authorisation, in a coded form.</para>
/// </summary>
public partial DateOnly? OnlyDate { get; set; }

/// <summary>
/// <para>Specifies the authorisation, in a free text form.</para>
/// </summary>
public partial DateTime? DateTimeChoice { get; set; }
}
/// <summary>
/// <para>Specifies the authorisation, in a free text form.</para>
/// </summary>
public partial DateTime? DateTimeChoice { get; set; }
}
9 changes: 9 additions & 0 deletions tests/AltaSoft.ChoiceGenerator.Tests/SinglePropertyChoice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using AltaSoft.Choice;

namespace AltaSoft.ChoiceGenerator.Tests;

[Choice]
public sealed partial class SinglePropertyChoice
{
public required partial string Value { get; set; }
}
2 changes: 0 additions & 2 deletions tests/AltaSoft.ChoiceGenerator.Tests/TwoSameTypeChoice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
namespace AltaSoft.ChoiceGenerator.Tests;

[Choice]

public sealed partial class TwoSameTypeChoice
{
public partial string? StringChoiceOne { get; set; }

public partial string? StringChoiceTwo { get; set; }

}
26 changes: 12 additions & 14 deletions tests/AltaSoft.ChoiceGenerator.Tests/TwoValueTypeChoice.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
using AltaSoft.Choice;
using AltaSoft.ChoiceGenerator.Tests.OtherNamespace;

namespace AltaSoft.ChoiceGenerator.Tests
{
[Choice]
public sealed partial record TwoValueTypeChoice
{
/// <summary>
/// <para>Specifies the authorisation, in a coded form.</para>
/// </summary>
public partial Authorisation1Code? Code { get; set; }
namespace AltaSoft.ChoiceGenerator.Tests;

/// <summary>
/// <para>Specifies the authorisation, in a free text form.</para>
/// </summary>
public partial int? Integer { get; set; }
[Choice]
public sealed partial record TwoValueTypeChoice
{
/// <summary>
/// <para>Specifies the authorisation, in a coded form.</para>
/// </summary>
public partial Authorisation1Code? Code { get; set; }

}
/// <summary>
/// <para>Specifies the authorisation, in a free text form.</para>
/// </summary>
public partial int? Integer { get; set; }
}
Loading