Skip to content

Commit 84dd96f

Browse files
authored
[3.0] Improve handling of affixed names when singularizing (OES/SGIS issue) and expose NameAffix API (#2535)
* Add NameAffixer class and begin moving name affix code out of PrettifyNames * Add NameAffixType instead of using bool to indicate if the affix is a prefix; Rewrite StripAffixes to not allocate; Update PrettifyNames to use new GetAffixes method * Add NameAffixer.ApplyAffixes() * Strip affixes before singularizing names in ArrayParameterTransformer * Add test: NameAffixerTests.GetAffixes * Generate on Windows * Import static SyntaxFactory * Attempt to write tests for ArrayParameterTransformer * Actually return true; tests still don't work as expected * Finally get the ArrayParameterTransformer tests working * Change AddNameAffix API to use the NameAffixType enum and only expose the AddNameAffix method instead of AddNameSuffix/Prefix separately
1 parent 9ded1ed commit 84dd96f

23 files changed

+5992
-5596
lines changed

.silktouch/sdl-clangsharp.stout

0 Bytes
Binary file not shown.

sources/OpenAL/OpenAL/al/AL.gen.cs

Lines changed: 471 additions & 471 deletions
Large diffs are not rendered by default.

sources/OpenAL/OpenAL/al/IAL.gen.cs

Lines changed: 131 additions & 131 deletions
Large diffs are not rendered by default.

sources/OpenGL/OpenGL/gl/GL.gen.cs

Lines changed: 3606 additions & 3656 deletions
Large diffs are not rendered by default.

sources/OpenGL/OpenGL/gl/IGL.gen.cs

Lines changed: 770 additions & 782 deletions
Large diffs are not rendered by default.

sources/SilkTouch/SilkTouch/Mods/Common/AttributeUtils.cs

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -203,69 +203,6 @@ out _
203203
return meth;
204204
}
205205

206-
/// <summary>
207-
/// Adds a name prefix attribute to the given attribute list.
208-
/// </summary>
209-
/// <param name="attributeLists">The attribute lists to add the attribute to.</param>
210-
/// <param name="category">The affix category.</param>
211-
/// <param name="prefix">The value of the affix.</param>
212-
/// <param name="addToInner">
213-
/// Use true if the affix comes from the inside of the name.
214-
/// Use false if not (outside or appended to end).
215-
/// True means that the attribute is added to the start of the attribute list, meaning that the affix is re-appended earlier.
216-
/// </param>
217-
public static SyntaxList<AttributeListSyntax> AddNamePrefix(
218-
this IEnumerable<AttributeListSyntax> attributeLists,
219-
string category,
220-
string prefix,
221-
bool addToInner = false
222-
) => attributeLists.AddNamePrefixOrSuffix("Prefix", category, prefix, addToInner);
223-
224-
/// <summary>
225-
/// Adds a name suffix attribute to the given attribute list.
226-
/// </summary>
227-
/// <param name="attributeLists">The attribute lists to add the attribute to.</param>
228-
/// <param name="category">The affix category.</param>
229-
/// <param name="suffix">The value of the affix.</param>
230-
/// <param name="addToInner">
231-
/// Use true if the affix comes from the inside of the name.
232-
/// Use false if not (outside or appended to end).
233-
/// True means that the attribute is added to the start of the attribute list, meaning that the affix is re-appended earlier.
234-
/// </param>
235-
public static SyntaxList<AttributeListSyntax> AddNameSuffix(
236-
this IEnumerable<AttributeListSyntax> attributeLists,
237-
string category,
238-
string suffix,
239-
bool addToInner = false
240-
) => attributeLists.AddNamePrefixOrSuffix("Suffix", category, suffix, addToInner);
241-
242-
private static SyntaxList<AttributeListSyntax> AddNamePrefixOrSuffix(
243-
this IEnumerable<AttributeListSyntax> attributeLists,
244-
string type,
245-
string category,
246-
string affix,
247-
bool addToInner = false
248-
)
249-
{
250-
var typeArgument = AttributeArgument(
251-
LiteralExpression(SyntaxKind.StringLiteralExpression, Literal($"\"{type}\"", type))
252-
);
253-
var categoryArgument = AttributeArgument(
254-
LiteralExpression(
255-
SyntaxKind.StringLiteralExpression,
256-
Literal($"\"{category}\"", category)
257-
)
258-
);
259-
var affixArgument = AttributeArgument(
260-
LiteralExpression(SyntaxKind.StringLiteralExpression, Literal($"\"{affix}\"", affix))
261-
);
262-
var argumentList = AttributeArgumentList([typeArgument, categoryArgument, affixArgument]);
263-
264-
var attribute = AttributeList([Attribute(IdentifierName("NameAffix"), argumentList)]);
265-
266-
return addToInner ? [attribute, .. attributeLists] : [.. attributeLists, attribute];
267-
}
268-
269206
/// <summary>
270207
/// Gets the native name or returns the specified default.
271208
/// </summary>

sources/SilkTouch/SilkTouch/Mods/ExtractNestedTyping.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,11 @@ _fallbackFromOuterFunctionPointer is not null
529529
: default
530530
)
531531
.WithNativeName(currentNativeTypeName)
532-
.AddNameSuffix("FunctionPointerDelegateType", "Delegate"),
532+
.AddNameAffix(
533+
NameAffixType.Suffix,
534+
"FunctionPointerDelegateType",
535+
"Delegate"
536+
),
533537
node
534538
);
535539
FunctionPointerTypes[currentNativeTypeName] = pfnInfo = (pfn, @delegate, [], []);

sources/SilkTouch/SilkTouch/Mods/InterceptNativeFunctions.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Microsoft.CodeAnalysis.CSharp;
66
using Microsoft.CodeAnalysis.CSharp.Syntax;
77
using Microsoft.Extensions.Options;
8+
using Silk.NET.SilkTouch.Naming;
89
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
910

1011
namespace Silk.NET.SilkTouch.Mods;
@@ -131,7 +132,11 @@ or SyntaxKind.ProtectedKeyword
131132
);
132133

133134
return node.WithAttributeLists(
134-
node.AttributeLists.AddNameSuffix("InterceptedFunction", "Internal")
135+
node.AttributeLists.AddNameAffix(
136+
NameAffixType.Suffix,
137+
"InterceptedFunction",
138+
"Internal"
139+
)
135140
);
136141
}
137142
}

sources/SilkTouch/SilkTouch/Mods/MixKhronosData.cs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Silk.NET.SilkTouch.Clang;
1212
using Silk.NET.SilkTouch.Mods.Metadata;
1313
using Silk.NET.SilkTouch.Mods.Transformation;
14+
using Silk.NET.SilkTouch.Naming;
1415
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
1516

1617
namespace Silk.NET.SilkTouch.Mods;
@@ -1891,7 +1892,7 @@ private SyntaxList<AttributeListSyntax> ProcessAndGetNewAttributes(
18911892
{
18921893
trimmedName = trimmedName[..^handleSuffix.Length];
18931894
attributeLists = attributeLists
1894-
.AddNameSuffix("KhronosHandleType", handleSuffix, true)
1895+
.AddNameAffix(NameAffixType.Suffix, "KhronosHandleType", handleSuffix, true)
18951896
.WithNativeName(trimmedName);
18961897
}
18971898
}
@@ -1903,7 +1904,11 @@ private SyntaxList<AttributeListSyntax> ProcessAndGetNewAttributes(
19031904
{
19041905
if (trimmedName.EndsWith(vendor))
19051906
{
1906-
attributeLists = attributeLists.AddNameSuffix("KhronosVendor", vendor);
1907+
attributeLists = attributeLists.AddNameAffix(
1908+
NameAffixType.Suffix,
1909+
"KhronosVendor",
1910+
vendor
1911+
);
19071912
trimmedName = trimmedName[..^vendor.Length];
19081913

19091914
break;
@@ -1921,7 +1926,8 @@ private SyntaxList<AttributeListSyntax> ProcessAndGetNewAttributes(
19211926
{
19221927
if (trimmedName.EndsWith(suffix))
19231928
{
1924-
attributeLists = attributeLists.AddNameSuffix(
1929+
attributeLists = attributeLists.AddNameAffix(
1930+
NameAffixType.Suffix,
19251931
"KhronosNonVendor",
19261932
suffix,
19271933
true
@@ -1943,7 +1949,8 @@ private SyntaxList<AttributeListSyntax> ProcessAndGetNewAttributes(
19431949
var dataTypeSuffix = trimmedName[match.Index..];
19441950
trimmedName = trimmedName[..match.Index];
19451951

1946-
attributeLists = attributeLists.AddNameSuffix(
1952+
attributeLists = attributeLists.AddNameAffix(
1953+
NameAffixType.Suffix,
19471954
"KhronosFunctionDataType",
19481955
dataTypeSuffix,
19491956
true
@@ -1998,7 +2005,11 @@ public override SyntaxNode VisitEnumDeclaration(EnumDeclarationSyntax node)
19982005
if (groupInfo?.Namespace != null && typeName == $"{groupInfo.Namespace}Enum")
19992006
{
20002007
node = node.WithAttributeLists(
2001-
node.AttributeLists.AddNamePrefix("KhronosNamespaceEnum", groupInfo.Namespace)
2008+
node.AttributeLists.AddNameAffix(
2009+
NameAffixType.Prefix,
2010+
"KhronosNamespaceEnum",
2011+
groupInfo.Namespace
2012+
)
20022013
);
20032014
}
20042015

@@ -2042,7 +2053,12 @@ public override SyntaxNode VisitEnumDeclaration(EnumDeclarationSyntax node)
20422053
{
20432054
// Mark the type vendor suffix as identified
20442055
node = node.WithAttributeLists(
2045-
node.AttributeLists.AddNameSuffix(vendorAffixType, typeVendor, true)
2056+
node.AttributeLists.AddNameAffix(
2057+
NameAffixType.Suffix,
2058+
vendorAffixType,
2059+
typeVendor,
2060+
true
2061+
)
20462062
);
20472063
}
20482064

@@ -2089,7 +2105,8 @@ .. node.Members.Select(member =>
20892105
{
20902106
// Identify for trimming
20912107
return member.WithAttributeLists(
2092-
member.AttributeLists.AddNameSuffix(
2108+
member.AttributeLists.AddNameAffix(
2109+
NameAffixType.Suffix,
20932110
"KhronosImpliedVendor",
20942111
typeVendor,
20952112
true

sources/SilkTouch/SilkTouch/Mods/PrettifyNames.cs

Lines changed: 15 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public async Task ExecuteAsync(IModContext ctx, CancellationToken ct = default)
128128
// The dictionary containing mappings from the original type names to the new names of the type and its members
129129
var newNames = new Dictionary<string, RenamedType>();
130130

131-
var nameAffixer = new NameAffixer(visitor.AffixTypes, cfg.Affixes);
131+
var nameAffixer = new PrettifyNamesAffixer(visitor.AffixTypes, cfg.Affixes);
132132
var namePrettifier = new NamePrettifier(cfg.LongAcronymThreshold);
133133

134134
// Trim the trimmable names if the trimmer baseline is set
@@ -463,7 +463,7 @@ private string ApplyPrettifyOnlyPipeline(
463463
string? container,
464464
string name,
465465
Dictionary<string, string> nameOverrides,
466-
NameAffixer nameAffixer,
466+
PrettifyNamesAffixer nameAffixer,
467467
NamePrettifier namePrettifier
468468
)
469469
{
@@ -870,13 +870,6 @@ private record struct RenamedType(
870870
Dictionary<string, string> Functions
871871
);
872872

873-
private record struct NameAffix(
874-
bool IsPrefix,
875-
string Category,
876-
string Affix,
877-
int DeclarationOrder
878-
);
879-
880873
private record struct TypeData(List<string> NonFunctions, List<FunctionData> Functions);
881874

882875
private record struct FunctionData(string Name, MethodDeclarationSyntax Syntax);
@@ -958,52 +951,13 @@ _typeInProgress is not null
958951
|| _enumInProgress is not null
959952
|| node.Ancestors().OfType<BaseTypeDeclarationSyntax>().Any();
960953

961-
private bool TryGetAffixData(
962-
SyntaxList<AttributeListSyntax> attributeLists,
963-
out NameAffix[] affixes
964-
)
965-
{
966-
affixes = [];
967-
var declarationOrder = 0;
968-
foreach (var list in attributeLists)
969-
{
970-
foreach (var attribute in list.Attributes)
971-
{
972-
if (!attribute.IsAttribute("Silk.NET.Core.NameAffix"))
973-
{
974-
continue;
975-
}
976-
977-
var argumentList = attribute.ArgumentList;
978-
if (
979-
argumentList != null
980-
&& argumentList.Arguments[0].Expression
981-
is LiteralExpressionSyntax { Token.Value: string type }
982-
&& argumentList.Arguments[1].Expression
983-
is LiteralExpressionSyntax { Token.Value: string category }
984-
&& argumentList.Arguments[2].Expression
985-
is LiteralExpressionSyntax { Token.Value: string affix }
986-
)
987-
{
988-
affixes =
989-
[
990-
.. affixes,
991-
new NameAffix(type == "Prefix", category, affix, declarationOrder),
992-
];
993-
declarationOrder++;
994-
}
995-
}
996-
}
997-
998-
return affixes.Length != 0;
999-
}
1000-
1001954
private void ReportTypeAffixData(
1002955
string typeIdentifier,
1003956
SyntaxList<AttributeListSyntax> attributeLists
1004957
)
1005958
{
1006-
if (!TryGetAffixData(attributeLists, out var affixes))
959+
var affixes = attributeLists.GetNameAffixes();
960+
if (affixes.Length == 0)
1007961
{
1008962
return;
1009963
}
@@ -1025,7 +979,8 @@ private void ReportMemberAffixData(
1025979
SyntaxList<AttributeListSyntax> attributeLists
1026980
)
1027981
{
1028-
if (!TryGetAffixData(attributeLists, out var affixData))
982+
var affixes = attributeLists.GetNameAffixes();
983+
if (affixes.Length == 0)
1029984
{
1030985
return;
1031986
}
@@ -1037,7 +992,7 @@ SyntaxList<AttributeListSyntax> attributeLists
1037992

1038993
// Note that TryAdd will lead to affixes for later members being silently dropped.
1039994
// This is to handle methods which have the same name and affixes. It is fine to drop the affixes in this case.
1040-
(typeAffixData.MemberAffixes ??= []).TryAdd(memberIdentifier, affixData);
995+
(typeAffixData.MemberAffixes ??= []).TryAdd(memberIdentifier, affixes);
1041996
AffixTypes[typeIdentifier] = typeAffixData;
1042997
}
1043998

@@ -1286,7 +1241,7 @@ public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node)
12861241

12871242
/// <param name="affixTypes">The affix data retrieved by the <see cref="Visitor"/>.</param>
12881243
/// <param name="config">The configuration from <see cref="Configuration.Affixes"/>.</param>
1289-
private class NameAffixer(
1244+
private class PrettifyNamesAffixer(
12901245
Dictionary<string, TypeAffixData> affixTypes,
12911246
Dictionary<string, NameAffixConfiguration> config
12921247
)
@@ -1317,61 +1272,13 @@ public string RemoveAffixes(
13171272
return primary;
13181273
}
13191274

1320-
var originalPrimary = primary;
1321-
1322-
// Sort affixes so that the outer affixes are first
1323-
affixes.Sort(
1324-
static (a, b) =>
1325-
{
1326-
// Sort by descending declaration order
1327-
// Lower declaration order means the affix is closer to the inside of the name
1328-
return -a.DeclarationOrder.CompareTo(b.DeclarationOrder);
1329-
}
1330-
);
1331-
1332-
var prefixes = affixes.Where(x => x.IsPrefix).ToList();
1333-
var suffixes = affixes.Where(x => !x.IsPrefix).ToList();
1334-
1335-
RemoveSide(true, prefixes);
1336-
RemoveSide(false, suffixes);
1337-
1338-
if (originalPrimary != primary)
1275+
var stripped = NameAffixer.StripAffixes(primary, affixes);
1276+
if (stripped != primary)
13391277
{
1340-
secondary?.Add(originalPrimary);
1278+
secondary?.Add(primary);
13411279
}
13421280

1343-
return primary;
1344-
1345-
void RemoveSide(bool isPrefix, List<NameAffix> nameAffixes)
1346-
{
1347-
while (nameAffixes.Count > 0)
1348-
{
1349-
var removedAffix = false;
1350-
for (var i = 0; i < nameAffixes.Count; i++)
1351-
{
1352-
var affix = nameAffixes[i];
1353-
if (
1354-
isPrefix
1355-
? primary.StartsWith(affix.Affix)
1356-
: primary.EndsWith(affix.Affix)
1357-
)
1358-
{
1359-
primary = isPrefix
1360-
? primary[affix.Affix.Length..]
1361-
: primary[..^affix.Affix.Length];
1362-
1363-
nameAffixes.RemoveAt(i);
1364-
removedAffix = true;
1365-
break;
1366-
}
1367-
}
1368-
1369-
if (!removedAffix)
1370-
{
1371-
break;
1372-
}
1373-
}
1374-
}
1281+
return stripped;
13751282
}
13761283

13771284
/// <summary>
@@ -1479,7 +1386,7 @@ void CreateName(string name, Span<NameAffix> currentAffixes)
14791386
{
14801387
if (!GetConfiguration(affix).Remove)
14811388
{
1482-
if (affix.IsPrefix)
1389+
if (affix.Type == NameAffixType.Prefix)
14831390
{
14841391
name = affix.Affix + name;
14851392
}
@@ -1544,7 +1451,7 @@ private NameAffixConfiguration GetConfiguration(string category) =>
15441451
/// Removes identified affixes so that other trimmers can process the base name separately.
15451452
/// These affixes should be reapplied by <see cref="NameAffixerLateTrimmer"/>.
15461453
/// </summary>
1547-
private class NameAffixerEarlyTrimmer(NameAffixer affixer) : INameTrimmer
1454+
private class NameAffixerEarlyTrimmer(PrettifyNamesAffixer affixer) : INameTrimmer
15481455
{
15491456
/// <inheritdoc/>
15501457
public Version Version => new(0, 0, 0);
@@ -1583,7 +1490,7 @@ public void Trim(NameTrimmerContext context)
15831490
/// <summary>
15841491
/// Reapplies and transforms identified affixes based on <see cref="NameAffixConfiguration"/>.
15851492
/// </summary>
1586-
private class NameAffixerLateTrimmer(NameAffixer affixer) : INameTrimmer
1493+
private class NameAffixerLateTrimmer(PrettifyNamesAffixer affixer) : INameTrimmer
15871494
{
15881495
/// <inheritdoc/>
15891496
public Version Version => new(0, 0, 0);

0 commit comments

Comments
 (0)