Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-conventional C# multi-dimensional arrays generated #346

Open
Anatoly03 opened this issue Sep 16, 2024 · 3 comments
Open

Non-conventional C# multi-dimensional arrays generated #346

Anatoly03 opened this issue Sep 16, 2024 · 3 comments

Comments

@Anatoly03
Copy link

Anatoly03 commented Sep 16, 2024

Describe the bug

In C#, a multi-dimensional array is declared with commas in-between the square brackets ([,]), and not conventionally with square brackets stacked ([][]).

ArrayType at =>
$"{(at.MemberType is ArrayType ? $"{TypeName(at.MemberType, arraySizeVar)}[]" : $"{TypeName(at.MemberType)}[{arraySizeVar}]")}",

This line should not append the type recursively to be (recursive call)[], but instead read out the dimension of the array, and write commas by formula by pseudo-code"[" + ",".repeat(dimension - 1) + "]".
A clear and concise description of what the bug is.

To Reproduce

struct FooBar {
    uint8[][] foo;
    string[][][] bar;
}

Expected behavior

The generated C# code should have multi-dimensional arrays with the respective commas [,] and [,,]

Screenshots / Snippets

// struct WorldInit {
//     uint16 width;
//     uint16 height;
//     BlockData[][] background;
//     BlockData[][] foreground;
// }
public partial class WorldInit : global::Bebop.Runtime.BaseBebopRecord, global::Bebop.Runtime.IDecodable<WorldInit>, global::System.IEquatable<WorldInit> {
    ...
    public global::PixelWalker.MessageLibrary.BlockData[][] Background { get; init; }
    [global::System.Diagnostics.CodeAnalysis.NotNull, global::System.Diagnostics.CodeAnalysis.DisallowNull]
    public global::PixelWalker.MessageLibrary.BlockData[][] Foreground { get; init; }
    ...
}

Bebop info:

  • Version: 3.0.14
  • Runtime: .NET
    <ItemGroup>
      <PackageReference Include="bebop" Version="3.0.14" />
      <PackageReference Include="bebop-tools" Version="3.0.14">
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        <PrivateAssets>all</PrivateAssets>
      </PackageReference>
      <Bebop Include="**/*.bop" OutputDir="./Models/" OutputFile="Models.g.cs" Namespace="PixelWalker.MessageLibrary" />
    </ItemGroup>

Desktop (please complete the following information):

  • OS: macOS-Intel
  • Version Ventura
@andrewmd5
Copy link
Contributor

Thanks for opening this issue. Bebop only supports jagged arrays and has no concept for multi-dimensional arrays.

While C# does support multi-dimensional arrays, languages Bebop also supports such as Rust and Dart do not. So we only generate data structures that every language can support.

@Anatoly03
Copy link
Author

Thanks for replying. If I understand right, the bebop generators are language specific, so this can be customized? A simple recursive function that stops on a non array can yield the array dimensions. Could this be implemented in the lines mentioned above?

/// <summary>
/// Generate a C# type name for the given <see cref="TypeBase"/>.
/// </summary>
/// <param name="type">The field type to generate code for.</param>
/// <param name="arraySizeVar">A variable name that will be formatted into the array initializer</param>
/// <returns>The C# type name.</returns>
private string TypeName(in TypeBase type, string arraySizeVar = "")
{
return type switch
{
ScalarType st => st.BaseType switch
{
BaseType.Bool => "bool",
BaseType.Byte => "byte",
BaseType.UInt32 => "uint",
BaseType.Int32 => "int",
BaseType.Float32 => "float",
BaseType.Float64 => "double",
BaseType.String => "string",
BaseType.Guid => "global::System.Guid",
BaseType.UInt16 => "ushort",
BaseType.Int16 => "short",
BaseType.UInt64 => "ulong",
BaseType.Int64 => "long",
BaseType.Date => "global::System.DateTime",
_ => throw new ArgumentOutOfRangeException(st.BaseType.ToString())
},
ArrayType { MemberType: ScalarType { BaseType: BaseType.Byte } } at =>
$"{ImmutableArrayType}<{TypeName(at.MemberType)}>",
ArrayType at =>
$"{(at.MemberType is ArrayType ? $"{TypeName(at.MemberType, arraySizeVar)}[]" : $"{TypeName(at.MemberType)}[{arraySizeVar}]")}",
MapType mt =>
$"global::System.Collections.Generic.Dictionary<{TypeName(mt.KeyType)}, {TypeName(mt.ValueType)}>",
DefinedType dt => PrefixNamespace($"{dt.Name.ToPascalCase()}"),
_ => throw new InvalidOperationException($"GetTypeName: {type}")
};
}

Here's an example of how this function could look like:

private int ArrayDimension(in TypeBase type)
{
    return type switch
    {
        ArrayType at => 1 + ArrayDimension(at.MemberType),
        _ => 0
    };
}

@Emalton
Copy link

Emalton commented Sep 18, 2024

@andrewmd5 We really could use this. Crippling bebop wouldn't be ideal, as both languages that we're using support multi-dimensional arrays. Perhaps a warning that this is only supported on some languages in the readme or something would be best.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants