Skip to content

Conversation

@Exanite
Copy link
Collaborator

@Exanite Exanite commented Jan 13, 2026

Summary of the PR

This fixes the interaction between Khronos vendor suffixes and the Singularize method, which led to cases like the following:

image

In order to fix this, this also exposes the NameAffix API, allowing mods to read NameAffix attributes and process the name without the affixes attached.

Related issues, Discord discussions, or proposals

Original Discord discussion: https://discord.com/channels/521092042781229087/1376331581198827520/1456785841753035005

Further Comments

Todo list:

  • Prevent OES and similar from being singularizing into O in ArrayParameterTransformer.TransformArrayParameterRewriter.
    • Eg: glFeedbackBufferxOES
    • Discussed solution is to expose the name affix API so that TransformArrayParameterRewriter can singularize the base name instead of the full name.
    • OES (incorrect version is OOES)
    • SGIS (incorrect version is SgiSGIS)
  • Allow mods to read NameAffix data.
  • Allow mods to strip a name of its affixes
  • Allow mods to re-apply a list of affixes to the name, but without allowing mods to deeply configure the process
    • Reasoning is that more involved transformations should be restricted to PrettifyNames.
    • This is because PrettifyNames can be configured by the generator user, while other mods must expose their own (possible duplicate) configuration.
  • Consider updating AddNameAffix API to use the new NameAffixType enum for consistency and simplicity

@Exanite Exanite changed the title [3.0] Fix OES/SGIS singularize issue and expose NameAffix API [3.0] Improve handling of affixed names when singularizing (OES/SGIS issue) and expose NameAffix API Jan 13, 2026
@Exanite Exanite force-pushed the fix/vendor-suffix-singularize-interaction branch from 6b7c293 to 589792e Compare January 13, 2026 08:14
… the AddNameAffix method instead of AddNameSuffix/Prefix separately
Copy link
Collaborator Author

@Exanite Exanite left a comment

Choose a reason for hiding this comment

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

Self review completed

/// Use false if not (outside or appended to end).
/// True means that the attribute is added to the start of the attribute list, meaning that the affix is re-appended earlier.
/// </param>
public static SyntaxList<AttributeListSyntax> AddNamePrefix(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I moved these to the new NameAffixer static class to keep everything related to name affixes together.

I also changed the API to use the new NameAffixType enum and changed it so that we only have the AddNameAffix method instead of AddNamePrefix/Suffix separately.

affixes
);

return node.WithIdentifier(Identifier(singularizedIdentifier))
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the core fix for the OES/SGIS singularize issue.

Comment on lines -873 to -877
private record struct NameAffix(
bool IsPrefix,
string Category,
string Affix,
int DeclarationOrder
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This been moved to a separate file as a public type.

|| _enumInProgress is not null
|| node.Ancestors().OfType<BaseTypeDeclarationSyntax>().Any();

private bool TryGetAffixData(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Replaced by NameAffixer.GetNameAffixes(), which returns an array directly instead of the TryGet pattern. The array is empty in the "false" case and does not allocate.

/// <param name="affixTypes">The affix data retrieved by the <see cref="Visitor"/>.</param>
/// <param name="config">The configuration from <see cref="Configuration.Affixes"/>.</param>
private class NameAffixer(
private class PrettifyNamesAffixer(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This class is the NameAffixer, but specialized for the needs of PrettifyNames.

Comment on lines +45 to +53
[
.. affixes,
new NameAffix(
type == "Prefix" ? NameAffixType.Prefix : NameAffixType.Suffix,
category,
affix,
declarationOrder
),
];
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure what is more performant here. Most names right now have 0 affixes so this method won't allocate at all.

Later, if we change NameTrimmer to be a mod that adds name affixes, most names will have 1 affix (the shared prefix), which would allocate, but would be the minimal amount.

Also not sure if this gets stack allocated or not by .NET 10. I need to look up the escape analysis rules.

/// <summary>
/// The type of name affix.
/// </summary>
public enum NameAffixType
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I decided to add this enum since the name affix API is now fully exposed.

@Exanite Exanite marked this pull request as ready for review January 15, 2026 01:10
@Exanite Exanite requested a review from a team as a code owner January 15, 2026 01:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant