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
29 changes: 14 additions & 15 deletions .github/workflows/build-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,23 @@ name: .NET

on:
push:
branches: [ "main" ]
branches: ["main"]
pull_request:
branches: [ "main" ]
branches: ["main"]

jobs:
build:
runs-on: windows-2025
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
9.0.x
5.0.x
- name: Build
run: dotnet build -c Release
- name: Test
run: dotnet test -c Release
- name: Checkout
uses: actions/checkout@v2
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
10.0.x
- name: Build
run: dotnet build -c Release
- name: Test
run: dotnet test -c Release
46 changes: 24 additions & 22 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,31 @@ name: Release to NuGet
on:
release:
types: [published]


env:
VERSION: ${{ github.event.release.draft && format('{0}-beta', github.event.release.tag_name) || github.event.release.tag_name }}

jobs:
build:
runs-on: windows-2025
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
9.0.x
5.0.x
- name: Build
run: dotnet build -c Release /p:Version=${{github.event.release.tag_name}}
- name: Test
run: dotnet test -c Release --no-build
- name: Pack Funzo
run: dotnet pack Funzo -c Release --no-build --output . /p:PackageVersion=${{github.event.release.tag_name}}
- name: Pack Serialization
run: dotnet pack Funzo.Serialization -c Release --no-build --output . /p:PackageVersion=${{github.event.release.tag_name}}
- name: Pack Source Generators
run: dotnet pack Funzo.SourceGenerators -c Release --no-build --output . /p:PackageVersion=${{github.event.release.tag_name}}
- name: Push to NuGet
run: dotnet nuget push "*.nupkg" --api-key ${{secrets.nuget_api_key}} --source https://api.nuget.org/v3/index.json
- name: Checkout
uses: actions/checkout@v2
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
10.0.x
- name: Build
run: dotnet build -c Release /p:Version=$VERSION
- name: Test
run: dotnet test -c Release --no-build
- name: Pack Funzo
run: dotnet pack Funzo -c Release --no-build --output . /p:PackageVersion=$VERSION
- name: Pack Serialization
run: dotnet pack Funzo.Serialization -c Release --no-build --output . /p:PackageVersion=$VERSION
- name: Pack Source Generators
run: dotnet pack Funzo.SourceGenerators -c Release --no-build --output . /p:PackageVersion=$VERSION
- name: Push to NuGet
run: dotnet nuget push "*.nupkg" --api-key ${{secrets.nuget_api_key}} --source https://api.nuget.org/v3/index.json
3 changes: 2 additions & 1 deletion Funzo.Example/Funzo.Example.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

Expand Down
2 changes: 1 addition & 1 deletion Funzo.Generator/Funzo.Generator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IncludeBuildOutput>false</IncludeBuildOutput>
Expand Down
4 changes: 2 additions & 2 deletions Funzo.Serialization/Funzo.Serialization.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net9.0;netstandard2.1;netstandard2.0</TargetFrameworks>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
Expand Down Expand Up @@ -31,7 +31,7 @@
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1' or '$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="System.Text.Json" Version="9.0.6" />
<PackageReference Include="System.Text.Json" Version="10.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net9.0;net481;net5.0</TargetFrameworks>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
Expand All @@ -10,10 +10,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,4 @@ public partial class MyError ;

public class ArgumentError;
public class InvalidError;
public class UnknownError;
public class UnknownError;
19 changes: 17 additions & 2 deletions Funzo.SourceGenerators.Test/ResultGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ static TwoUnionResult process(int value)

Assert.True(isOk);
}

[Fact]
public void Generates_Nested_Results()
{
InnerClass.InnerResult result = "test";

Assert.True(result.IsErr(out _));
}
}

[Result<int, string>]
Expand All @@ -70,7 +78,7 @@ public partial class TestResult;
public partial class TestUnitResult;

[Union<int, string>]
public partial class MyOk ;
public partial class MyOk;

[Result<MyOk, MyError>]
public partial class TwoUnionResult;
Expand All @@ -82,4 +90,11 @@ public partial class ClonedErr;
public partial class ClonedOk;

[Result<ClonedOk, ClonedErr>]
public partial class CheapClone;
public partial class CheapClone;


public static partial class InnerClass
{
[Result<int, string>]
public partial class InnerResult;
}
19 changes: 19 additions & 0 deletions Funzo.SourceGenerators.Test/UnionGeneratorTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;

namespace Funzo.SourceGenerators.Test;

public class UnionGeneratorTests
{
[Fact]
Expand Down Expand Up @@ -42,6 +43,14 @@ public void Generates_Shared_Property()
Assert.Equal("b", u2.Text);
Assert.Equal("c", u3.Text);
}

[Fact]
public void Generates_Inner_Union()
{
TestUnionInPartialClass.InnerUnion u = new TestUnionInPartialClass.A();

u.Switch(a => { }, b => throw new InvalidOperationException());
}
}


Expand All @@ -67,4 +76,14 @@ public class C(string text)
{
public string Text { get; set; } = text;
public DateTime Date { get; set; }
}


public static partial class TestUnionInPartialClass
{
public record A;
public record B;

[Union<A, B>]
public partial class InnerUnion;
}
4 changes: 2 additions & 2 deletions Funzo.SourceGenerators/Funzo.SourceGenerators.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.1">
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
Expand Down
37 changes: 31 additions & 6 deletions Funzo.SourceGenerators/Generators/ResultSourceGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using Funzo.SourceGenerators.Generators.Results;
using Funzo.SourceGenerators.Helpers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Linq;
using System.Text;

namespace Funzo.SourceGenerators.Generators;

Expand All @@ -20,11 +24,21 @@ internal class ResultSourceGenerator : SourceGeneratorBase
? new Result1AritySourceGenerator(symbolWithAttribute)
: new Result2AritySourceGenerator(symbolWithAttribute);

var source = $@"// <auto-generated />
var containingType = symbolWithAttribute.Symbol.ContainingType?.Name;

var sb = new StringBuilder($@"// <auto-generated />

namespace {symbolWithAttribute.Symbol.ContainingNamespace.ToDisplayString()}
{{
{generator.ClassDefinition}
{{");

if (containingType is not null)
{
var isStatic = symbolWithAttribute.Symbol.ContainingType!.IsStatic ? "static " : "";
sb.AppendLine($"{isStatic}partial class {containingType} {{");
}

sb.AppendLine($@"
{generator.ClassDefinition}
{{
{generator.OkConstructor}
{generator.OkStaticHelper}
Expand All @@ -33,15 +47,26 @@ namespace {symbolWithAttribute.Symbol.ContainingNamespace.ToDisplayString()}
{generator.ErrStaticHelper}
{generator.ErrImplicitConverter}
}}
}}";
}}");

return source;
if (containingType is not null)
{
sb.AppendLine("}");
}

var src = sb.ToString();

return src;
}

private bool HasErrors(SourceProductionContext context, SymbolWithAttribute symbolWithAttribute)
{
var (ClassSymbol, _) = symbolWithAttribute;
if (!ClassSymbol.ContainingSymbol.Equals(ClassSymbol.ContainingNamespace, SymbolEqualityComparer.Default))

if (!ClassSymbol.ContainingSymbol.Equals(ClassSymbol.ContainingNamespace, SymbolEqualityComparer.Default) && ClassSymbol.ContainingType is { } containerType
&& containerType.DeclaringSyntaxReferences.Any(syntax =>
syntax.GetSyntax() is BaseTypeDeclarationSyntax declaration
&& !declaration.Modifiers.Any(mod => mod.IsKind(SyntaxKind.PartialKeyword))))
{
CreateDiagnosticError(context, FunzoDiagnosticDescriptors.Result.TopLevelError, ClassSymbol);
return true;
Expand Down
27 changes: 23 additions & 4 deletions Funzo.SourceGenerators/Generators/Unions/UnionSourceGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Funzo.SourceGenerators.Helpers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Collections.Immutable;
using System.Linq;
Expand All @@ -22,11 +24,20 @@ internal class UnionSourceGenerator : SourceGeneratorBase
var className = $"{classSymbol.Name}";
var typeArguments = symbolWithAttribute.TypeArguments;

var containingType = classSymbol.ContainingType?.Name;

StringBuilder source = new($@"// <auto-generated />

namespace {classSymbol.ContainingNamespace.ToDisplayString()}
{{
partial class {className} : global::Funzo.Union{typeArguments.OpenGenericPart()}
{{");

if (containingType is not null)
{
var isStatic = classSymbol.IsStatic ? "static " : "";
source.AppendLine($"{isStatic}partial class {containingType} {{");
}

source.AppendLine($@" partial class {className} : global::Funzo.Union{typeArguments.OpenGenericPart()}
{{");

foreach (var type in typeArguments)
Expand All @@ -37,7 +48,7 @@ partial class {className} : global::Funzo.Union{typeArguments.OpenGenericPart()}
");
}

foreach(var prop in commonProperties)
foreach (var prop in commonProperties)
{
source.Append($@"
public {prop.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)} {prop.Name} => Match({string.Join(",", Enumerable.Range(0, typeArguments.Length).Select(_ => $"x => x.{prop.Name}"))});
Expand All @@ -46,6 +57,10 @@ partial class {className} : global::Funzo.Union{typeArguments.OpenGenericPart()}

source.Append(@" }
}");
if (containingType is not null)
{
source.AppendLine("}");
}

var src = source.ToString();
return src;
Expand All @@ -56,8 +71,12 @@ private bool HasErrors(SourceProductionContext context, SymbolWithAttribute symb
var (classSymbol, attributeData) = symbol;
var attributeLocation = classSymbol.Locations.FirstOrDefault() ?? Location.None;

if (!classSymbol.ContainingSymbol.Equals(classSymbol.ContainingNamespace, SymbolEqualityComparer.Default))
if (!classSymbol.ContainingSymbol.Equals(classSymbol.ContainingNamespace, SymbolEqualityComparer.Default) && classSymbol.ContainingType is { } containerType
&& containerType.DeclaringSyntaxReferences.Any(syntax =>
syntax.GetSyntax() is BaseTypeDeclarationSyntax declaration
&& !declaration.Modifiers.Any(mod => mod.IsKind(SyntaxKind.PartialKeyword))))
{
System.Diagnostics.Debugger.Launch();
CreateDiagnosticError(context, FunzoDiagnosticDescriptors.Union.TopLevelError, classSymbol);
return true;
}
Expand Down
Loading
Loading