xoofx / GitLib.NET

GitLib.NET is a bare metal P/Invoke wrapper around libgit2 for .NET
BSD 2-Clause "Simplified" License
30 stars 2 forks source link

Add mapping rules to fix automatic generated API #1

Open xoofx opened 5 years ago

xoofx commented 5 years ago

The generated API requires mapping fixes (e.g change int to bool, use enums instead of integers...etc.)

Here is the list of API that needs to be verified and fix with mapping rules if necessary:

HELP much welcome (you can see how API can be fixed by looking at one of the commit below)

StephenHodgson commented 5 years ago

This is quite a manual task. Wondering if the CppAst.CodeGen lib can provide some basic mappings?

xoofx commented 1 year ago

This is quite a manual task. Wondering if the CppAst.CodeGen lib can provide some basic mappings?

Sorry to respond so late (and this is mostly in case someone else is wondering about your good question 😃). If you look at commit 6da77e5427257294e9b09ac185a001c9be26f1da CppAst.CodeGen is actually helping to change parameter types. The problem with libgit2 C API is that it does not describe what an int is (it can be an enum or a bool) and you can only infer this information from the comments.

                    e => e.MapMacroToConst("GIT_REPOSITORY_INIT_OPTIONS_VERSION", "unsigned int"),
                    e => e.Map<CppParameter>("git_repository_open_ext::flags").Type("git_repository_open_flag_t"),
                    e => e.Map<CppParameter>("git_repository_init::is_bare").Type("bool").MarshalAs(CSharpUnmanagedKind.I4),
                    e => e.Map<CppParameter>("git_repository_discover::across_fs").Type("bool").MarshalAs(CSharpUnmanagedKind.I4),
                    e => e.Map<CppParameter>("git_repository_init_init_options::version").InitValue("GIT_REPOSITORY_INIT_OPTIONS_VERSION"),
                    e => e.Map<CppParameter>("git_repository_set_workdir::update_gitlink").Type("bool").MarshalAs(CSharpUnmanagedKind.I4),
                    e => e.Map<CppField>("git_repository_init_options::flags").Type("git_repository_init_flag_t"),
                    e => e.Map<CppField>("git_repository_init_options::mode").Type("git_repository_init_mode_t"),
                    e => e.Map<CppFunction>("git_repository_state").Type("git_repository_state_t"),
                    e => e.Map<CppFunction>("git_repository_is_shallow").Type("bool").MarshalAs(CSharpUnmanagedKind.I4),
                    e => e.Map<CppFunction>("git_repository_ident").Type("git_result"),
                    e => e.Map<CppFunction>("git_repository_set_ident").Type("git_result"),

You see that I have to manually do this mapping and CppAst.CodeGen is helping (to change the mapping easily), but cannot be of any help to decide that this specific int is going to be a flag or a boolean or a git_result.

For example, I proposed years ago to libgit2 https://github.com/libgit2/libgit2/issues/3385 (even before I made this project 😅 ) to correctly type method with a proper git_error_code or git_result but they refused, meaning that you have to infer this manually, which is super laborious.

I tried to overcome that by parsing the comment in the codegen, and If I see a pattern that says that it looks like the int returned is actually a git_result then I turn the type into a git_result:

https://github.com/xoofx/GitLib.NET/blob/65b05d8a62685ceedd61c4292d2410b0ee9d4837/src/GitLib.CodeGen/Program.cs#L281-L309

But there are many APIs that don't consistently have these comments, and so you have also to map these API types manually.

That's why basically I stopped this project. That was too much work! 😅