louthy / language-ext

C# functional language extensions - a base class library for functional programming
MIT License
6.46k stars 417 forks source link

Error updating project that uses codegen to .NET8 #1378

Open MrYossu opened 4 days ago

MrYossu commented 4 days ago

I have a project that is currently targeting .NET7, and uses the [Union] attribute.

I tried changing the .NET version to 8 (and updating all Nuget packages to the latest), but when I try to build, it fails with the following error...

Error MSB3073: The command "dotnet codegen "@obj\Debug\net8.0\MyProject.csproj.dotnet-codegen.rsp"" exited with code 3. (85, 6)

My project file includes the following section...

  <ItemGroup>
    <PackageReference Include="LanguageExt.Core" Version="4.4.9" />
    <PackageReference Include="LanguageExt.CodeGen" Version="4.4.8" PrivateAssets="all" />
    <PackageReference Include="CodeGeneration.Roslyn.BuildTime" Version="0.6.1" PrivateAssets="all" />
    <DotNetCliToolReference Include="dotnet-codegen" Version="0.6.1" />
    <PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.10" />
  </ItemGroup>

Anyone any idea how I fix this?

Please let me know if there is any more info you need. Thanks

aloslider commented 4 days ago

Using a test project I don't have such error:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="LanguageExt.CodeGen" Version="4.4.8" PrivateAssets="all" />
    <PackageReference Include="LanguageExt.Core" Version="4.4.9" />
    <PackageReference Include="CodeGeneration.Roslyn.BuildTime" Version="0.6.1" PrivateAssets="all" />
    <DotNetCliToolReference Include="dotnet-codegen" Version="0.6.1" />
  </ItemGroup>

</Project>
using LanguageExt;
using LanguageExt.ClassInstances;
using LanguageExt.TypeClasses;

Shape<TInt, int> s = Shape.Circle<TInt, int>(5);
Console.WriteLine(s.ToString());

[Union]
public abstract partial class Shape<NumA, A> where NumA : struct, Num<A>
{
    public abstract Shape<NumA, A> Rectangle(A width, A length);
    public abstract Shape<NumA, A> Circle(A radius);
    public abstract Shape<NumA, A> Prism(A width, A height);
}

I've added PrivateAssets="all" to LanguageExt.CodeGen line, but it also builds without it.

I remember I had some error with codegen as well long time ago, and the answer was in some issue thread. The solutions was something with dotnet-codegen properties

MrYossu commented 3 days ago

Using a test project I don't have such error:

Hmm, your settings are the same as mine. I wonder why I get the error then. Causing me great problems as I have some code that urgently needs this upgrade.

Any ideas what else might be the cause?

I remember I had some error with codegen as well long time ago, and the answer was in some issue thread. The solutions was something with dotnet-codegen properties

I vaguely remember having some issues with it when I first set up this project, but no idea what they were. I followed someone's advice to add the references to CodeGeneration.Roslyn.BuildTime and dotnet-codegen exactly as-is, and it worked.

Thanks for the reply. Any further help you can give would be appreciated, as I'm stumped.

louthy commented 3 days ago

I've stopped supporting the CodeGen library because the CodeGeneration.Roslyn.BuildTime library is so finicky and seems especially problematic depending on the .NET SDKs you have installed.

If you want to do unions, I advise using records:

public abstract record Maybe<A>
{
    private Maybe() { }
    public sealed record Just(A value) : Maybe<A>;
    public sealed record Nothing : Maybe<A>;
}

public static class Maybe
{
    public static Maybe<A> Just<A>(A value) => new Maybe<A>.Just(value);
    public static Maybe<A> Nothing<A>() => new Maybe<A>.Nothing();
}

It doesn't quite have all of the features of the lang-ext unions, but it gets you 90% of the way without too much typing.

MrYossu commented 3 days ago

@louthy Oh, that's worth knowing. I'll have a go with records and see if anything breaks. I'm not doing anything particularly clever, so I doubt I'll hit any of the missing 90% 😎

Thanks for a fantastic library.

louthy commented 3 days ago

If you're already using [Union] then you may want to create your record based unions like this:

public abstract record Maybe<A>;
public sealed record Just(A value) : Maybe<A>;
public sealed record Nothing : Maybe<A>;

public static class Maybe
{
    public static Maybe<A> Just<A>(A value) => new Just<A>(value);
    public static Maybe<A> Nothing<A>() => new Nothing<A>();
}

Because the case-types are all top-level with [Union].

MrYossu commented 3 days ago

In case it helps anyone, I found this old issue in which it was pointed out that you need version 2.1.818 exactly of the SDK. Not sure if I've installed that version since I got my latest PC, but repairing the installation (which is what the downloader claimed it was doing) fixed the issue.

SDK can be downloaded here

@louthy Thanks again, when I have more time I'll look at dropping the code gen altogether and using records as you suggested.