Skip to content

Commit

Permalink
Merge pull request #34 from sveinungf/dev/srcgen-column-order
Browse files Browse the repository at this point in the history
Source generator - Column ordering
  • Loading branch information
sveinungf authored Jan 7, 2024
2 parents 9b165ab + 1ad069a commit 2fe06e2
Show file tree
Hide file tree
Showing 93 changed files with 1,256 additions and 217 deletions.
8 changes: 7 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ dotnet_diagnostic.CA1815.severity = warning
# CA2201: Do not raise reserved exception types
dotnet_diagnostic.CA2201.severity = warning

[{ColumnOrderAttribute.cs,WorksheetRowAttribute.cs}]
# CA1019: Define accessors for attribute arguments
dotnet_diagnostic.CA1019.severity = none
# CS9113: Parameter is unread
dotnet_diagnostic.CS9113.severity = none

[{*Test,*.Benchmark,*.Cmd}/**.cs]
# CA1305: Specify IFormatProvider
dotnet_diagnostic.CA1305.severity = none
Expand Down Expand Up @@ -199,7 +205,7 @@ dotnet_diagnostic.MA0076.severity = warning
[{AutoFilterOptions.cs,ColumnOptions.cs,RowOptions.cs,SpreadCheetahOptions.cs,WorksheetOptions.cs,WorksheetRowGenerator.cs}]
dotnet_diagnostic.MA0053.severity = none

[{*Test,*.Benchmark}/**.cs]
[{*Test,*TestHelpers,*.Benchmark}/**.cs]
# MA0004: Use .ConfigureAwait(false)
dotnet_diagnostic.MA0004.severity = none
# MA0011: IFormatProvider is missing
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,6 @@ MigrationBackup/

# Ionide (cross platform F# VS Code tools) working folder
.ionide/

# Snapshot tests with Verify
*.received.*
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.7.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="Polyfill" Version="1.29.0" />
<PackageVersion Include="PolySharp" Version="1.14.1" />
<PackageVersion Include="System.Collections.Immutable" Version="8.0.0" />
<PackageVersion Include="System.IO.Compression" Version="4.3.0" />
<PackageVersion Include="System.Memory" Version="4.5.5" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal static class TestHelper
MetadataReference.CreateFromFile(typeof(TestHelper).Assembly.Location)
};

var compilation = CSharpCompilation.Create("Tests", new[] { syntaxTree }, references);
var compilation = CSharpCompilation.Create("Tests", [syntaxTree], references);

var generator = new T();
#pragma warning disable S3220 // Method calls should not resolve ambiguously to overloads with "params"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace SpreadCheetah.SourceGenerator.SnapshotTest.Models;

public class ClassWithInheritance : ClassWithSingleProperty
{
public string Address { get; set; } = "";
public string Country { get; set; } = "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using SpreadCheetah.SourceGeneration;

namespace SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering;

public class ClassWithColumnOrderForAllProperties
{
[ColumnOrder(2)]
public string FirstName { get; set; } = "";

[ColumnOrder(3)]
public string? MiddleName { get; set; }

[ColumnOrder(1)]
public string LastName { get; set; } = "";

[ColumnOrder(5)]
public int Age { get; set; }

[ColumnOrder(4)]
public bool Employed { get; set; }

[ColumnOrder(6)]
public double Score { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using SpreadCheetah.SourceGeneration;

namespace SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering;

public class ClassWithColumnOrderForSomeProperties
{
public string FirstName { get; set; } = "";

[ColumnOrder(-1000)]
public string? MiddleName { get; set; }

public string LastName { get; set; } = "";

[ColumnOrder(500)]
public int Age { get; set; }

public bool Employed { get; set; }

[ColumnOrder(2)]
public double Score { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace SpreadCheetah.SourceGenerator.SnapshotTest.Models;

public record RecordClassWithInheritance(string Name, bool Value, int Age)
: RecordClassWithSingleProperty(Value);
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//HintName: MyNamespace.MyGenRowContext.g.cs
// <auto-generated />
#nullable enable
using SpreadCheetah;
using SpreadCheetah.SourceGeneration;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace MyNamespace
{
public partial class MyGenRowContext
{
private static MyGenRowContext? _default;
public static MyGenRowContext Default => _default ??= new MyGenRowContext();

public MyGenRowContext()
{
}

private WorksheetRowTypeInfo<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties>? _ClassWithColumnOrderForAllProperties;
public WorksheetRowTypeInfo<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties> ClassWithColumnOrderForAllProperties => _ClassWithColumnOrderForAllProperties ??= WorksheetRowMetadataServices.CreateObjectInfo<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties>(AddAsRowAsync, AddRangeAsRowsAsync);

private static ValueTask AddAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties? obj, CancellationToken token)
{
if (spreadsheet is null)
throw new ArgumentNullException(nameof(spreadsheet));
if (obj is null)
return spreadsheet.AddRowAsync(ReadOnlyMemory<DataCell>.Empty, token);
return AddAsRowInternalAsync(spreadsheet, obj, token);
}

private static ValueTask AddRangeAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties?> objs, CancellationToken token)
{
if (spreadsheet is null)
throw new ArgumentNullException(nameof(spreadsheet));
if (objs is null)
throw new ArgumentNullException(nameof(objs));
return AddRangeAsRowsInternalAsync(spreadsheet, objs, token);
}

private static async ValueTask AddAsRowInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties obj, CancellationToken token)
{
var cells = ArrayPool<DataCell>.Shared.Rent(6);
try
{
await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false);
}
finally
{
ArrayPool<DataCell>.Shared.Return(cells, true);
}
}

private static async ValueTask AddRangeAsRowsInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties?> objs, CancellationToken token)
{
var cells = ArrayPool<DataCell>.Shared.Rent(6);
try
{
await AddEnumerableAsRowsAsync(spreadsheet, objs, cells, token).ConfigureAwait(false);
}
finally
{
ArrayPool<DataCell>.Shared.Return(cells, true);
}
}

private static async ValueTask AddEnumerableAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties?> objs, DataCell[] cells, CancellationToken token)
{
foreach (var obj in objs)
{
await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false);
}
}

private static ValueTask AddCellsAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties? obj, DataCell[] cells, CancellationToken token)
{
if (obj is null)
return spreadsheet.AddRowAsync(ReadOnlyMemory<DataCell>.Empty, token);

cells[0] = new DataCell(obj.LastName);
cells[1] = new DataCell(obj.FirstName);
cells[2] = new DataCell(obj.MiddleName);
cells[3] = new DataCell(obj.Employed);
cells[4] = new DataCell(obj.Age);
cells[5] = new DataCell(obj.Score);
return spreadsheet.AddRowAsync(cells.AsMemory(0, 6), token);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//HintName: MyNamespace.MyGenRowContext.g.cs
// <auto-generated />
#nullable enable
using SpreadCheetah;
using SpreadCheetah.SourceGeneration;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace MyNamespace
{
public partial class MyGenRowContext
{
private static MyGenRowContext? _default;
public static MyGenRowContext Default => _default ??= new MyGenRowContext();

public MyGenRowContext()
{
}

private WorksheetRowTypeInfo<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties>? _ClassWithColumnOrderForSomeProperties;
public WorksheetRowTypeInfo<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties> ClassWithColumnOrderForSomeProperties => _ClassWithColumnOrderForSomeProperties ??= WorksheetRowMetadataServices.CreateObjectInfo<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties>(AddAsRowAsync, AddRangeAsRowsAsync);

private static ValueTask AddAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties? obj, CancellationToken token)
{
if (spreadsheet is null)
throw new ArgumentNullException(nameof(spreadsheet));
if (obj is null)
return spreadsheet.AddRowAsync(ReadOnlyMemory<DataCell>.Empty, token);
return AddAsRowInternalAsync(spreadsheet, obj, token);
}

private static ValueTask AddRangeAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties?> objs, CancellationToken token)
{
if (spreadsheet is null)
throw new ArgumentNullException(nameof(spreadsheet));
if (objs is null)
throw new ArgumentNullException(nameof(objs));
return AddRangeAsRowsInternalAsync(spreadsheet, objs, token);
}

private static async ValueTask AddAsRowInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties obj, CancellationToken token)
{
var cells = ArrayPool<DataCell>.Shared.Rent(6);
try
{
await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false);
}
finally
{
ArrayPool<DataCell>.Shared.Return(cells, true);
}
}

private static async ValueTask AddRangeAsRowsInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties?> objs, CancellationToken token)
{
var cells = ArrayPool<DataCell>.Shared.Rent(6);
try
{
await AddEnumerableAsRowsAsync(spreadsheet, objs, cells, token).ConfigureAwait(false);
}
finally
{
ArrayPool<DataCell>.Shared.Return(cells, true);
}
}

private static async ValueTask AddEnumerableAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable<SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties?> objs, DataCell[] cells, CancellationToken token)
{
foreach (var obj in objs)
{
await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false);
}
}

private static ValueTask AddCellsAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties? obj, DataCell[] cells, CancellationToken token)
{
if (obj is null)
return spreadsheet.AddRowAsync(ReadOnlyMemory<DataCell>.Empty, token);

cells[0] = new DataCell(obj.MiddleName);
cells[1] = new DataCell(obj.FirstName);
cells[2] = new DataCell(obj.Score);
cells[3] = new DataCell(obj.LastName);
cells[4] = new DataCell(obj.Employed);
cells[5] = new DataCell(obj.Age);
return spreadsheet.AddRowAsync(cells.AsMemory(0, 6), token);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//HintName: MyNamespace.MyGenRowContext.g.cs
// <auto-generated />
#nullable enable
using SpreadCheetah;
using SpreadCheetah.SourceGeneration;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace MyNamespace
{
public partial class MyGenRowContext
{
private static MyGenRowContext? _default;
public static MyGenRowContext Default => _default ??= new MyGenRowContext();

public MyGenRowContext()
{
}

private WorksheetRowTypeInfo<MyNamespace.ClassWithDuplicateColumnOrdering>? _ClassWithDuplicateColumnOrdering;
public WorksheetRowTypeInfo<MyNamespace.ClassWithDuplicateColumnOrdering> ClassWithDuplicateColumnOrdering => _ClassWithDuplicateColumnOrdering ??= WorksheetRowMetadataServices.CreateObjectInfo<MyNamespace.ClassWithDuplicateColumnOrdering>(AddAsRowAsync, AddRangeAsRowsAsync);

private static ValueTask AddAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, MyNamespace.ClassWithDuplicateColumnOrdering? obj, CancellationToken token)
{
if (spreadsheet is null)
throw new ArgumentNullException(nameof(spreadsheet));
if (obj is null)
return spreadsheet.AddRowAsync(ReadOnlyMemory<DataCell>.Empty, token);
return AddAsRowInternalAsync(spreadsheet, obj, token);
}

private static ValueTask AddRangeAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable<MyNamespace.ClassWithDuplicateColumnOrdering?> objs, CancellationToken token)
{
if (spreadsheet is null)
throw new ArgumentNullException(nameof(spreadsheet));
if (objs is null)
throw new ArgumentNullException(nameof(objs));
return AddRangeAsRowsInternalAsync(spreadsheet, objs, token);
}

private static async ValueTask AddAsRowInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, MyNamespace.ClassWithDuplicateColumnOrdering obj, CancellationToken token)
{
var cells = ArrayPool<DataCell>.Shared.Rent(1);
try
{
await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false);
}
finally
{
ArrayPool<DataCell>.Shared.Return(cells, true);
}
}

private static async ValueTask AddRangeAsRowsInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable<MyNamespace.ClassWithDuplicateColumnOrdering?> objs, CancellationToken token)
{
var cells = ArrayPool<DataCell>.Shared.Rent(1);
try
{
await AddEnumerableAsRowsAsync(spreadsheet, objs, cells, token).ConfigureAwait(false);
}
finally
{
ArrayPool<DataCell>.Shared.Return(cells, true);
}
}

private static async ValueTask AddEnumerableAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable<MyNamespace.ClassWithDuplicateColumnOrdering?> objs, DataCell[] cells, CancellationToken token)
{
foreach (var obj in objs)
{
await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false);
}
}

private static ValueTask AddCellsAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, MyNamespace.ClassWithDuplicateColumnOrdering? obj, DataCell[] cells, CancellationToken token)
{
if (obj is null)
return spreadsheet.AddRowAsync(ReadOnlyMemory<DataCell>.Empty, token);

cells[0] = new DataCell(obj.PropertyA);
return spreadsheet.AddRowAsync(cells.AsMemory(0, 1), token);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
Diagnostics: [
{
Id: SPCH1003,
Title: Duplicate column ordering,
Severity: Error,
WarningLevel: 0,
Location: : (8,5)-(8,19),
MessageFormat: The type '{0}' has two or more properties with the same column order,
Message: The type 'ClassWithDuplicateColumnOrdering' has two or more properties with the same column order,
Category: SpreadCheetah.SourceGenerator
}
]
}
Loading

0 comments on commit 2fe06e2

Please sign in to comment.