From 2331f1175b287533858b7843d9f108b4270a167f Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sat, 2 Nov 2024 22:03:28 +0100 Subject: [PATCH 1/6] ColumnIgnore attribute --- .../Helpers/AttributeDataComparer.cs | 1 + SpreadCheetah.SourceGenerator/Helpers/Attributes.cs | 1 + .../Helpers/PropertyAnalyzer.cs | 13 +++++++++++++ .../Models/ColumnIgnore.cs | 3 +++ .../Models/PropertyAttributeData.cs | 1 + .../WorksheetRowGenerator.cs | 3 ++- .../SourceGeneration/ColumnIgnoreAttribute.cs | 7 +++++++ 7 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 SpreadCheetah.SourceGenerator/Models/ColumnIgnore.cs create mode 100644 SpreadCheetah/SourceGeneration/ColumnIgnoreAttribute.cs diff --git a/SpreadCheetah.SourceGenerator/Helpers/AttributeDataComparer.cs b/SpreadCheetah.SourceGenerator/Helpers/AttributeDataComparer.cs index c828b1f..8768a54 100644 --- a/SpreadCheetah.SourceGenerator/Helpers/AttributeDataComparer.cs +++ b/SpreadCheetah.SourceGenerator/Helpers/AttributeDataComparer.cs @@ -18,6 +18,7 @@ private static int GetOrder(string? metadataName) { return metadataName switch { + Attributes.ColumnIgnore => -2, Attributes.CellValueConverter => -1, Attributes.CellStyle => 1, _ => 0 diff --git a/SpreadCheetah.SourceGenerator/Helpers/Attributes.cs b/SpreadCheetah.SourceGenerator/Helpers/Attributes.cs index c05b360..2ca34a9 100644 --- a/SpreadCheetah.SourceGenerator/Helpers/Attributes.cs +++ b/SpreadCheetah.SourceGenerator/Helpers/Attributes.cs @@ -7,6 +7,7 @@ internal static class Attributes public const string CellValueConverter = "CellValueConverterAttribute"; public const string CellValueTruncate = "CellValueTruncateAttribute"; public const string ColumnHeader = "ColumnHeaderAttribute"; + public const string ColumnIgnore = "ColumnIgnoreAttribute"; public const string ColumnOrder = "ColumnOrderAttribute"; public const string ColumnWidth = "ColumnWidthAttribute"; public const string GenerationOptions = "WorksheetRowGenerationOptionsAttribute"; diff --git a/SpreadCheetah.SourceGenerator/Helpers/PropertyAnalyzer.cs b/SpreadCheetah.SourceGenerator/Helpers/PropertyAnalyzer.cs index 5cb8cda..54c86ee 100644 --- a/SpreadCheetah.SourceGenerator/Helpers/PropertyAnalyzer.cs +++ b/SpreadCheetah.SourceGenerator/Helpers/PropertyAnalyzer.cs @@ -24,6 +24,12 @@ public PropertyAttributeData Analyze(IPropertySymbol property, CancellationToken foreach (var attribute in attributes) { + if (_result.ColumnIgnore is not null) + { + diagnostics.ReportAttributeCombinationNotSupported(attribute, Attributes.ColumnIgnore, token); + continue; + } + _ = attribute.AttributeClass?.MetadataName switch { Attributes.CellFormat => TryGetCellFormatAttribute(attribute, token), @@ -31,6 +37,7 @@ public PropertyAttributeData Analyze(IPropertySymbol property, CancellationToken Attributes.CellValueConverter => TryGetCellValueConverterAttribute(attribute, property.Type, token), Attributes.CellValueTruncate => TryGetCellValueTruncateAttribute(attribute, property.Type, token), Attributes.ColumnHeader => TryGetColumnHeaderAttribute(attribute, token), + Attributes.ColumnIgnore => TryGetColumnIgnoreAttribute(), Attributes.ColumnOrder => TryGetColumnOrderAttribute(attribute), Attributes.ColumnWidth => TryGetColumnWidthAttribute(attribute, token), _ => false @@ -204,6 +211,12 @@ private bool TryGetColumnHeaderAttribute( return null; } + private bool TryGetColumnIgnoreAttribute() + { + _result.ColumnIgnore = new ColumnIgnore(); + return true; + } + private bool TryGetColumnOrderAttribute(AttributeData attribute) { var args = attribute.ConstructorArguments; diff --git a/SpreadCheetah.SourceGenerator/Models/ColumnIgnore.cs b/SpreadCheetah.SourceGenerator/Models/ColumnIgnore.cs new file mode 100644 index 0000000..7b92499 --- /dev/null +++ b/SpreadCheetah.SourceGenerator/Models/ColumnIgnore.cs @@ -0,0 +1,3 @@ +namespace SpreadCheetah.SourceGenerator.Models; + +internal readonly record struct ColumnIgnore; diff --git a/SpreadCheetah.SourceGenerator/Models/PropertyAttributeData.cs b/SpreadCheetah.SourceGenerator/Models/PropertyAttributeData.cs index 33f95ab..5f0308c 100644 --- a/SpreadCheetah.SourceGenerator/Models/PropertyAttributeData.cs +++ b/SpreadCheetah.SourceGenerator/Models/PropertyAttributeData.cs @@ -10,6 +10,7 @@ internal record struct PropertyAttributeData public CellValueConverter? CellValueConverter { get; set; } public CellValueTruncate? CellValueTruncate { get; set; } public ColumnHeader? ColumnHeader { get; set; } + public ColumnIgnore? ColumnIgnore { get; set; } public ColumnOrder? ColumnOrder { get; set; } public ColumnWidth? ColumnWidth { get; set; } } \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs index d7cb12c..471292c 100644 --- a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs +++ b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs @@ -81,7 +81,8 @@ private static RowType AnalyzeTypeProperties(ITypeSymbol rowType, CancellationTo foreach (var property in properties) { var data = analyzer.Analyze(property, token); - + if (data.ColumnIgnore is not null) + continue; if (data.CellValueConverter is null && !property.Type.IsSupportedType()) continue; diff --git a/SpreadCheetah/SourceGeneration/ColumnIgnoreAttribute.cs b/SpreadCheetah/SourceGeneration/ColumnIgnoreAttribute.cs new file mode 100644 index 0000000..b9575c6 --- /dev/null +++ b/SpreadCheetah/SourceGeneration/ColumnIgnoreAttribute.cs @@ -0,0 +1,7 @@ +namespace SpreadCheetah.SourceGeneration; + +/// +/// Instructs the SpreadCheetah source generator to ignore a property. +/// +[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] +public sealed class ColumnIgnoreAttribute : Attribute; From 00846ea8a6ae6254ded0c1663e22a0f04d8cdde8 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sat, 2 Nov 2024 22:18:25 +0100 Subject: [PATCH 2/6] Test for ColumnIgnore --- .../ClassWithMultipleProperties.cs | 14 ++++++++ .../ColumnIgnore/ColumnIgnoreContext.cs | 6 ++++ .../Tests/ColumnIgnoreTests.cs | 32 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/ColumnIgnore/ClassWithMultipleProperties.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/ColumnIgnore/ColumnIgnoreContext.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Tests/ColumnIgnoreTests.cs diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ColumnIgnore/ClassWithMultipleProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/ColumnIgnore/ClassWithMultipleProperties.cs new file mode 100644 index 0000000..5a1b97d --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/ColumnIgnore/ClassWithMultipleProperties.cs @@ -0,0 +1,14 @@ +using SpreadCheetah.SourceGeneration; + +namespace SpreadCheetah.SourceGenerator.Test.Models.ColumnIgnore; + +public class ClassWithMultipleProperties +{ + [ColumnIgnore] + public int Id { get; set; } + + public string? Name { get; set; } + + [ColumnIgnore] + public decimal Price { get; set; } +} diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ColumnIgnore/ColumnIgnoreContext.cs b/SpreadCheetah.SourceGenerator.Test/Models/ColumnIgnore/ColumnIgnoreContext.cs new file mode 100644 index 0000000..aee6e7b --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/ColumnIgnore/ColumnIgnoreContext.cs @@ -0,0 +1,6 @@ +using SpreadCheetah.SourceGeneration; + +namespace SpreadCheetah.SourceGenerator.Test.Models.ColumnIgnore; + +[WorksheetRow(typeof(ClassWithMultipleProperties))] +public partial class ColumnIgnoreContext : WorksheetRowContext; \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator.Test/Tests/ColumnIgnoreTests.cs b/SpreadCheetah.SourceGenerator.Test/Tests/ColumnIgnoreTests.cs new file mode 100644 index 0000000..bd8c1f5 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Tests/ColumnIgnoreTests.cs @@ -0,0 +1,32 @@ +using SpreadCheetah.SourceGenerator.Test.Models.ColumnIgnore; +using SpreadCheetah.TestHelpers.Assertions; +using Xunit; + +namespace SpreadCheetah.SourceGenerator.Test.Tests; + +public class ColumnIgnoreTests +{ + [Fact] + public async Task ColumnIgnore_ClassWithMultipleProperties() + { + // Arrange + using var stream = new MemoryStream(); + await using var spreadsheet = await Spreadsheet.CreateNewAsync(stream); + await spreadsheet.StartWorksheetAsync("Sheet"); + var obj = new ClassWithMultipleProperties + { + Id = 1, + Name = "Foo", + Price = 199.90m + }; + + // Act + await spreadsheet.AddAsRowAsync(obj, ColumnIgnoreContext.Default.ClassWithMultipleProperties); + await spreadsheet.FinishAsync(); + + // Assert + using var sheet = SpreadsheetAssert.SingleSheet(stream); + Assert.Equal(obj.Name, sheet["A1"].StringValue); + Assert.Single(sheet.Columns); + } +} From bef76f6c377fe172a1d788e52de11b5df053bad4 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sun, 3 Nov 2024 00:17:19 +0100 Subject: [PATCH 3/6] Tests for ColumnIgnore diagnostics --- .../Tests/ColumnIgnoreTests.cs | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Tests/ColumnIgnoreTests.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/ColumnIgnoreTests.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/ColumnIgnoreTests.cs new file mode 100644 index 0000000..2332304 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/ColumnIgnoreTests.cs @@ -0,0 +1,57 @@ +using SpreadCheetah.SourceGenerator.SnapshotTest.Helpers; + +namespace SpreadCheetah.SourceGenerator.SnapshotTest.Tests; + +public class ColumnIgnoreTests +{ + [Fact] + public Task ColumnIgnore_ClassPropertyWithAnotherSpreadCheetahAttribute() + { + // Arrange + var context = AnalyzerTest.CreateContext(); + context.TestCode = """ + using SpreadCheetah.SourceGeneration; + + namespace MyNamespace; + + public class ClassWithColumnIgnore + { + [{|SPCH1008:CellFormat("#.0#")|}] + [ColumnIgnore] + public decimal Value { get; set; } + } + + [WorksheetRow(typeof(ClassWithColumnIgnore))] + public partial class MyGenRowContext : WorksheetRowContext; + """; + + // Act & Assert + return context.RunAsync(); + } + + [Fact] + public Task ColumnIgnore_ClassPropertyWithAnotherUnrelatedAttribute() + { + // Arrange + var context = AnalyzerTest.CreateContext(); + context.TestCode = """ + using SpreadCheetah.SourceGeneration; + using System.ComponentModel.DataAnnotations; + + namespace MyNamespace; + + public class ClassWithColumnIgnore + { + [Required] + [ColumnIgnore] + public decimal Value { get; set; } + } + + [WorksheetRow(typeof(ClassWithColumnIgnore))] + public partial class MyGenRowContext : WorksheetRowContext; + """; + + // Act & Assert + return context.RunAsync(); + } +} From db3196ce2a7d0896d9256a40b1073b5ec2f6cb1d Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sun, 3 Nov 2024 00:19:17 +0100 Subject: [PATCH 4/6] Update packages --- Directory.Packages.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 877f1a6..a00a2e3 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,7 +5,7 @@ - + @@ -35,7 +35,7 @@ - + From 9ed055611cb6c9e2fb8e79837b019cd95be09981 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sun, 3 Nov 2024 00:21:11 +0100 Subject: [PATCH 5/6] Add ColumnIgnoreAttribute to public API snapshots --- .../PublicApiTests.PublicApi_Generate.DotNet6_0.verified.txt | 5 +++++ .../PublicApiTests.PublicApi_Generate.DotNet7_0.verified.txt | 5 +++++ .../PublicApiTests.PublicApi_Generate.DotNet8_0.verified.txt | 5 +++++ .../PublicApiTests.PublicApi_Generate.Net4_7.verified.txt | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet6_0.verified.txt b/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet6_0.verified.txt index 793aaf9..7b3341c 100644 --- a/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet6_0.verified.txt +++ b/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet6_0.verified.txt @@ -218,6 +218,11 @@ namespace SpreadCheetah.SourceGeneration public ColumnHeaderAttribute(System.Type type, string propertyName) { } } [System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple=false)] + public sealed class ColumnIgnoreAttribute : System.Attribute + { + public ColumnIgnoreAttribute() { } + } + [System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple=false)] public sealed class ColumnOrderAttribute : System.Attribute { public ColumnOrderAttribute(int order) { } diff --git a/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet7_0.verified.txt b/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet7_0.verified.txt index e0df903..f65314f 100644 --- a/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet7_0.verified.txt +++ b/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet7_0.verified.txt @@ -218,6 +218,11 @@ namespace SpreadCheetah.SourceGeneration public ColumnHeaderAttribute(System.Type type, string propertyName) { } } [System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple=false)] + public sealed class ColumnIgnoreAttribute : System.Attribute + { + public ColumnIgnoreAttribute() { } + } + [System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple=false)] public sealed class ColumnOrderAttribute : System.Attribute { public ColumnOrderAttribute(int order) { } diff --git a/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet8_0.verified.txt b/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet8_0.verified.txt index 1290abc..07fad89 100644 --- a/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet8_0.verified.txt +++ b/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.DotNet8_0.verified.txt @@ -218,6 +218,11 @@ namespace SpreadCheetah.SourceGeneration public ColumnHeaderAttribute(System.Type type, string propertyName) { } } [System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple=false)] + public sealed class ColumnIgnoreAttribute : System.Attribute + { + public ColumnIgnoreAttribute() { } + } + [System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple=false)] public sealed class ColumnOrderAttribute : System.Attribute { public ColumnOrderAttribute(int order) { } diff --git a/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.Net4_7.verified.txt b/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.Net4_7.verified.txt index 0669b36..c7221bd 100644 --- a/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.Net4_7.verified.txt +++ b/SpreadCheetah.Test/Tests/PublicApiTests.PublicApi_Generate.Net4_7.verified.txt @@ -217,6 +217,11 @@ namespace SpreadCheetah.SourceGeneration public ColumnHeaderAttribute(System.Type type, string propertyName) { } } [System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple=false)] + public sealed class ColumnIgnoreAttribute : System.Attribute + { + public ColumnIgnoreAttribute() { } + } + [System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple=false)] public sealed class ColumnOrderAttribute : System.Attribute { public ColumnOrderAttribute(int order) { } From 4d00924dbdc1286bc5c1d74c6d58e287b0fa197d Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sun, 3 Nov 2024 00:34:37 +0100 Subject: [PATCH 6/6] Increase coverage of test --- .../Tests/ColumnIgnoreTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/ColumnIgnoreTests.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/ColumnIgnoreTests.cs index 2332304..93427cb 100644 --- a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/ColumnIgnoreTests.cs +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/ColumnIgnoreTests.cs @@ -18,6 +18,7 @@ public class ClassWithColumnIgnore { [{|SPCH1008:CellFormat("#.0#")|}] [ColumnIgnore] + [{|SPCH1008:ColumnWidth(10)|}] public decimal Value { get; set; } }