diff --git a/Directory.Packages.props b/Directory.Packages.props
index 8ce6066..77eab94 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -2,17 +2,16 @@
true
-
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
+
\ No newline at end of file
diff --git a/clean.bat b/clean.bat
index 97b2bab..95285a9 100644
--- a/clean.bat
+++ b/clean.bat
@@ -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
diff --git a/src/AltaSoft.Choice.Generator/Executor.cs b/src/AltaSoft.Choice.Generator/Executor.cs
index 354c734..bd38259 100644
--- a/src/AltaSoft.Choice.Generator/Executor.cs
+++ b/src/AltaSoft.Choice.Generator/Executor.cs
@@ -94,9 +94,10 @@ private static SourceCodeBuilder Process(INamedTypeSymbol typeSymbol, List ")
- .Append(fieldName).AppendLine(";");
+ .Append(fieldName).AppendLine(";");
sb.AppendIfNotEmpty(p.SetterAccessibility.GetPropertyAccessibilityString()).AppendLine("set")
.OpenBracket()
@@ -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,
diff --git a/src/AltaSoft.Choice.Generator/Extensions/CompilationExt.cs b/src/AltaSoft.Choice.Generator/Extensions/CompilationExt.cs
index e263bbd..416f50d 100644
--- a/src/AltaSoft.Choice.Generator/Extensions/CompilationExt.cs
+++ b/src/AltaSoft.Choice.Generator/Extensions/CompilationExt.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -92,57 +91,45 @@ public static IEnumerable GetMembersOfType(this ITypeSymbol? s
///
/// Gets the modifiers for the named type symbol.
///
- /// The named type symbol to retrieve modifiers from.
- /// The modifiers as a string, or null if the type is null or has no modifiers.
- 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
///
- /// Gets the class name including generic arguments as a string.
+ /// Gets the modifiers for the property type symbol.
///
- /// The named type symbol to get the class name from.
- /// The class name including generic arguments as a string.
- 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)
{
@@ -183,6 +170,7 @@ public static string GetFullName(this ITypeSymbol type)
return ns + '.' + friendlyName;
}
#pragma warning restore S1643
+
///
/// Determines whether the specified type symbol is a Nullable<T> value type and, if so, provides the underlying value type symbol.
///
diff --git a/src/AltaSoft.Choice.Generator/Extensions/RoslynExt.cs b/src/AltaSoft.Choice.Generator/Extensions/RoslynExt.cs
deleted file mode 100644
index ad2dc85..0000000
--- a/src/AltaSoft.Choice.Generator/Extensions/RoslynExt.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-
-// https://www.meziantou.net/working-with-types-in-a-roslyn-analyzer.htm
-
-namespace AltaSoft.Choice.Generator.Extensions;
-
-///
-/// A collection of extension methods for working with Roslyn syntax and symbols.
-///
-internal static class RoslynExt
-{
- ///
- /// Gets the namespace of the specified type declaration syntax.
- ///
- /// The type declaration syntax to retrieve the namespace from.
- /// The namespace of the type declaration or null if not found.
- public static string? GetNamespace(this TypeDeclarationSyntax self)
- {
- return self.Parent is not BaseNamespaceDeclarationSyntax ns ? null : ns.GetNamespace();
- }
-
- ///
- /// Gets the namespace from the specified base namespace declaration syntax.
- ///
- /// The base namespace declaration syntax to retrieve the namespace from.
- /// The namespace from the base namespace declaration.
- public static string GetNamespace(this BaseNamespaceDeclarationSyntax self) => self.Name.ToString();
-
- ///
- /// Gets the fully qualified name of the specified type declaration syntax, including its namespace.
- ///
- /// The type declaration syntax to retrieve the fully qualified name from.
- /// The fully qualified name of the type declaration.
- public static string GetClassFullName(this TypeDeclarationSyntax self)
- {
- return self.GetNamespace() + "." + self.GetClassName();
- }
-
- ///
- /// Gets the name of the class specified in the type declaration syntax.
- ///
- /// The type declaration syntax to retrieve the class name from.
- /// The name of the class.
- public static string GetClassName(this TypeDeclarationSyntax proxy)
- {
- return proxy.Identifier.Text + proxy.TypeParameterList?.ToFullString();
- }
-}
diff --git a/src/AltaSoft.Choice.Generator/Models/PropertyDetails.cs b/src/AltaSoft.Choice.Generator/Models/PropertyDetails.cs
index 1f42306..ee696a3 100644
--- a/src/AltaSoft.Choice.Generator/Models/PropertyDetails.cs
+++ b/src/AltaSoft.Choice.Generator/Models/PropertyDetails.cs
@@ -25,6 +25,11 @@ internal sealed class PropertyDetails
///
internal string XmlNameValue { get; private set; }
+ ///
+ /// The access modifiers for the property, such as "public", "private", etc.
+ ///
+ public string Modifiers { get; set; }
+
///
/// The summary documentation for the property.
///
@@ -52,22 +57,16 @@ internal bool IsDateOnly()
{
return TypeSymbol.IsValueType && TypeSymbol.GetFullName().Replace("?", "") == "System.DateOnly";
}
+
///
/// Initializes a new instance of the class.
///
- /// The name of the property.
- /// The type name of the property.
- /// The namespace of the property.
- /// The XML name value of the property.
- /// The summary documentation for the property.
- /// The access modifiers for the property's getter.
- /// The access modifiers for the property's setter.
- /// The type symbol of the property.
public PropertyDetails(
string name,
string typeName,
string @namespace,
string xmlNameValue,
+ string modifiers,
string? summary,
Accessibility getterAccessibility,
Accessibility setterAccessibility,
@@ -77,10 +76,10 @@ public PropertyDetails(
TypeName = typeName;
Namespace = @namespace;
XmlNameValue = xmlNameValue;
+ Modifiers = modifiers;
Summary = summary;
GetterAccessibility = getterAccessibility;
SetterAccessibility = setterAccessibility;
TypeSymbol = typeSymbol;
}
-
}
diff --git a/tests/AltaSoft.ChoiceGenerator.Tests/ChoiceGeneratorTests.cs b/tests/AltaSoft.ChoiceGenerator.Tests/ChoiceGeneratorTests.cs
index aa09a64..892b41d 100644
--- a/tests/AltaSoft.ChoiceGenerator.Tests/ChoiceGeneratorTests.cs
+++ b/tests/AltaSoft.ChoiceGenerator.Tests/ChoiceGeneratorTests.cs
@@ -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);
+ }
}
diff --git a/tests/AltaSoft.ChoiceGenerator.Tests/DateTypeChoice.cs b/tests/AltaSoft.ChoiceGenerator.Tests/DateTypeChoice.cs
index d3009b0..8ef77d8 100644
--- a/tests/AltaSoft.ChoiceGenerator.Tests/DateTypeChoice.cs
+++ b/tests/AltaSoft.ChoiceGenerator.Tests/DateTypeChoice.cs
@@ -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
- {
- ///
- /// Specifies the authorisation, in a coded form.
- ///
- public partial DateOnly? OnlyDate { get; set; }
+ ///
+ /// Specifies the authorisation, in a coded form.
+ ///
+ public partial DateOnly? OnlyDate { get; set; }
- ///
- /// Specifies the authorisation, in a free text form.
- ///
- public partial DateTime? DateTimeChoice { get; set; }
- }
+ ///
+ /// Specifies the authorisation, in a free text form.
+ ///
+ public partial DateTime? DateTimeChoice { get; set; }
}
diff --git a/tests/AltaSoft.ChoiceGenerator.Tests/SinglePropertyChoice.cs b/tests/AltaSoft.ChoiceGenerator.Tests/SinglePropertyChoice.cs
new file mode 100644
index 0000000..c96725c
--- /dev/null
+++ b/tests/AltaSoft.ChoiceGenerator.Tests/SinglePropertyChoice.cs
@@ -0,0 +1,9 @@
+using AltaSoft.Choice;
+
+namespace AltaSoft.ChoiceGenerator.Tests;
+
+[Choice]
+public sealed partial class SinglePropertyChoice
+{
+ public required partial string Value { get; set; }
+}
diff --git a/tests/AltaSoft.ChoiceGenerator.Tests/TwoSameTypeChoice.cs b/tests/AltaSoft.ChoiceGenerator.Tests/TwoSameTypeChoice.cs
index 689dea1..b2f2a11 100644
--- a/tests/AltaSoft.ChoiceGenerator.Tests/TwoSameTypeChoice.cs
+++ b/tests/AltaSoft.ChoiceGenerator.Tests/TwoSameTypeChoice.cs
@@ -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; }
-
}
diff --git a/tests/AltaSoft.ChoiceGenerator.Tests/TwoValueTypeChoice.cs b/tests/AltaSoft.ChoiceGenerator.Tests/TwoValueTypeChoice.cs
index de39feb..00d734f 100644
--- a/tests/AltaSoft.ChoiceGenerator.Tests/TwoValueTypeChoice.cs
+++ b/tests/AltaSoft.ChoiceGenerator.Tests/TwoValueTypeChoice.cs
@@ -1,20 +1,18 @@
using AltaSoft.Choice;
using AltaSoft.ChoiceGenerator.Tests.OtherNamespace;
-namespace AltaSoft.ChoiceGenerator.Tests
-{
- [Choice]
- public sealed partial record TwoValueTypeChoice
- {
- ///
- /// Specifies the authorisation, in a coded form.
- ///
- public partial Authorisation1Code? Code { get; set; }
+namespace AltaSoft.ChoiceGenerator.Tests;
- ///
- /// Specifies the authorisation, in a free text form.
- ///
- public partial int? Integer { get; set; }
+[Choice]
+public sealed partial record TwoValueTypeChoice
+{
+ ///
+ /// Specifies the authorisation, in a coded form.
+ ///
+ public partial Authorisation1Code? Code { get; set; }
- }
+ ///
+ /// Specifies the authorisation, in a free text form.
+ ///
+ public partial int? Integer { get; set; }
}