Skip to content

Conversation

@just-ero
Copy link
Contributor

Closes #1265.

@just-ero just-ero force-pushed the cs-fully-qualified-typenames branch from 3c9f118 to 8b7231f Compare April 16, 2025 19:26
@just-ero just-ero changed the title Use fully qualified type names C#: Use fully qualified type names Apr 16, 2025
@just-ero just-ero force-pushed the cs-fully-qualified-typenames branch 2 times, most recently from 87c3fb2 to e8daded Compare April 17, 2025 11:25
@just-ero just-ero force-pushed the cs-fully-qualified-typenames branch from e8daded to d0be31c Compare April 17, 2025 11:48
self.src,
"
var {array} = new List<{ty}>({length});
var {array} = new global::System.Collections.Generic.List<{ty}>({length});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does type_name_with_qualifier give ty the global name too ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not believe so. Please lead me in the right direction to make this happen. It should be unnecessary as long as ty is either a primitive or a type already contained within the same namespace as this emitted code.

Copy link
Collaborator

@pavelsavara pavelsavara Apr 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know much about the generator codebase, @jsturtevant please advise.

I just noticed that different flavors ty is sprinkled thru the code.

I'm thinking that we could have built-in hash table (or switch) translating known system types from short name to long name. All of them for consistency sake.

For int -> global::System.Int32

I guess later we will also generate marshaling for global::System.Threading.Tasks.Task which is not in System namespace. Also global::System.Threading.Tasks.Task<global::System.Int32>

And I think WIT can do list of list ?
global::System.Collections.Generic.List<global::System.Collections.Generic.List<global::System.Int32>>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't personally believe that primitives (int) should be fully specified, but that's up to you.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not big deal for me, I mentioned it for consistency. This generated code should not be something that people need to read often and compiler sees that as equivalent.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does type_name_with_qualifier give ty the global name too ?

No type_name_with_qualifier will not add global:: in-front of the type name.

And I think WIT can do list of list ?

Yes it can.

I like that this makes the code generation part a lot easier. On a personal opinion thought I don't particularly like the fact that we will be generating code that you would normally never write yourself (I know this isn't true for everything already, but I would prefer if we can take it in that direction). Would adjusting the current code to address the scenario of usage of types that haven't been imported (by adding the using statement in the generated code, for those missing places) be sufficient or do you think there is a broader problem with that approach @just-ero ?

Copy link
Contributor Author

@just-ero just-ero Apr 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since wit-bindgen is a standalone tool (as in, not directly connected to componentize-dotnet), it seems reasonable to me to generate code that a human might write.

However, a couple things to dissuade;

  • Since the generated header explicitly discourages editing of the generated code, users would interact with it very rarely. The appearance of the generated code would not matter in most cases, as it is rarely even observed.
  • Fully qualified type names are safer, as they leave no ambiguity. Please read string vs. String is not a style debate by Jared Parsons.
    To be clear: in our case, the fully qualified type name would be closer to the string variant, including namespaces and using just the type name is closer to the String variant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, one requirement of generated code (at least for .NET) is to fulfill the lowest common denominator. In C# that might mean not using interpolated strings, file-scoped namespaces, or other more modern features, as the user may target a language version which does not support those features.

componentize-dotnet is basically hard locked to projects which target .NET 10 and up, so this would only be a problem if the user explicitly downgraded using the LangVersion MSBuild property. It's not a scenario I would worry too much about, but I thought I'd mention it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not worry about below Net10

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fully qualified type names are safer, as they leave no ambiguity.

This is compelling to me for generated code. So I am +1 to this change.

@pavelsavara pavelsavara added the gen-c# Related to the C# code generator label Apr 22, 2025
@just-ero
Copy link
Contributor Author

just-ero commented Apr 25, 2025

It may make sense to introduce constants for some namespace or type names; const SPAN: &str = "global::System.Span";. What are your opinions on this? How is this done conventionally in Rust?

@just-ero
Copy link
Contributor Author

Hello, any news on this?

@jsturtevant jsturtevant added this pull request to the merge queue May 13, 2025
@just-ero
Copy link
Contributor Author

I don't believe this PR was ready for merge yet.

Does type_name_with_qualifier give ty the global name too ?
No type_name_with_qualifier will not add global:: in-front of the type name.
And I think WIT can do list of list ?
Yes it can.

I was hoping for some input to address these problems. I was also waiting for input on the const question I asked above.

Merged via the queue into bytecodealliance:main with commit 54eac63 May 13, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gen-c# Related to the C# code generator

Projects

None yet

Development

Successfully merging this pull request may close these issues.

C#: Generated code contains compilation errors (+ lots of other opinionated problems)

4 participants