Skip to content

Commit 7e48890

Browse files
Merge pull request #527 from fredrikhr/strip-enum-member-type-name
Config option: strip-enum-member-type-name
2 parents 305eff5 + c246b41 commit 7e48890

File tree

7 files changed

+74
-31
lines changed

7 files changed

+74
-31
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ Options:
256256
generate-unmanaged-constants Unmanaged constants should be generated using static ref readonly properties. This is currently experimental.
257257
generate-vtbl-index-attribute [VtblIndex(#)] attribute should be generated to document the underlying VTBL index for a helper method.
258258
259+
# Stripping Options
260+
261+
strip-enum-member-type-name Strips the enum type name from the beginning of its member names.
262+
259263
# Logging Options
260264
261265
log-exclusions A list of excluded declaration types should be generated. This will also log if the exclusion was due to an exact or partial match.

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Linq;
88
using System.Runtime.InteropServices;
99
using System.Text;
10+
using System.Text.RegularExpressions;
1011
using ClangSharp.Abstractions;
1112
using ClangSharp.CSharp;
1213
using static ClangSharp.Interop.CX_CastKind;
@@ -294,6 +295,11 @@ private void VisitEnumConstantDecl(EnumConstantDecl enumConstantDecl)
294295
parentName = _outputBuilder.Name;
295296
}
296297

298+
if (Config.StripEnumMemberTypeName)
299+
{
300+
escapedName = PrefixAndStrip(escapedName, parentName, trimChar: '_');
301+
}
302+
297303
var kind = isAnonymousEnum ? ValueKind.Primitive : ValueKind.Enumerator;
298304
var flags = ValueFlags.Constant;
299305

@@ -535,12 +541,12 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
535541
if ((cxxMethodDecl is not null) && cxxMethodDecl.IsVirtual)
536542
{
537543
isVirtual = true;
538-
escapedName = PrefixAndStripName(name, GetOverloadIndex(cxxMethodDecl));
544+
escapedName = PrefixAndStripMethodName(name, GetOverloadIndex(cxxMethodDecl));
539545
}
540546
else
541547
{
542548
isVirtual = false;
543-
escapedName = EscapeAndStripName(name);
549+
escapedName = EscapeAndStripMethodName(name);
544550
}
545551

546552
var returnType = functionDecl.ReturnType;
@@ -2024,7 +2030,7 @@ void OutputMarkerInterface(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethodD
20242030

20252031
var desc = new FunctionOrDelegateDesc {
20262032
AccessSpecifier = AccessSpecifier.Public,
2027-
EscapedName = EscapeAndStripName(name),
2033+
EscapedName = EscapeAndStripMethodName(name),
20282034
IsMemberFunction = true,
20292035
NativeTypeName = nativeTypeName,
20302036
HasFnPtrCodeGen = !_config.ExcludeFnptrCodegen,
@@ -2112,7 +2118,7 @@ void OutputVtblEntry(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethodDecl)
21122118
}
21132119

21142120
var remappedName = FixupNameForMultipleHits(cxxMethodDecl);
2115-
var escapedName = EscapeAndStripName(remappedName);
2121+
var escapedName = EscapeAndStripMethodName(remappedName);
21162122

21172123
var desc = new FieldDesc
21182124
{
@@ -2181,7 +2187,7 @@ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethod
21812187
var desc = new FunctionOrDelegateDesc {
21822188
AccessSpecifier = AccessSpecifier.Public,
21832189
IsAggressivelyInlined = _config.GenerateAggressiveInlining,
2184-
EscapedName = EscapeAndStripName(name),
2190+
EscapedName = EscapeAndStripMethodName(name),
21852191
ParentName = parentName,
21862192
IsMemberFunction = true,
21872193
IsInherited = isInherited,
@@ -2261,7 +2267,7 @@ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethod
22612267
{
22622268
body.Write("Marshal.GetDelegateForFunctionPointer<");
22632269
body.BeginMarker("delegate");
2264-
body.Write(PrefixAndStripName(name, GetOverloadIndex(cxxMethodDecl)));
2270+
body.Write(PrefixAndStripMethodName(name, GetOverloadIndex(cxxMethodDecl)));
22652271
body.EndMarker("delegate");
22662272
body.Write(">(");
22672273
}
@@ -2270,7 +2276,7 @@ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethod
22702276
{
22712277
body.Write("lpVtbl->");
22722278
body.BeginMarker("vtbl", new KeyValuePair<string, object>("explicit", true));
2273-
body.Write(EscapeAndStripName(remappedName));
2279+
body.Write(EscapeAndStripMethodName(remappedName));
22742280
body.EndMarker("vtbl");
22752281
}
22762282
else

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ private void VisitDeclRefExpr(DeclRefExpr declRefExpr)
970970

971971
if (declRefExpr.Decl is FunctionDecl)
972972
{
973-
escapedName = EscapeAndStripName(name);
973+
escapedName = EscapeAndStripMethodName(name);
974974
}
975975
}
976976

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,18 +1454,18 @@ static void GenerateTransparentStructs(PInvokeGenerator generator, Stream? strea
14541454
return type.Contains('*', StringComparison.Ordinal)
14551455
? (8, 4, +1)
14561456
: type switch {
1457-
"sbyte" => (1, 1, -1),
1458-
"byte" => (1, 1, +1),
1459-
"short" => (2, 2, -1),
1460-
"ushort" => (2, 2, +1),
1461-
"int" => (4, 4, -1),
1462-
"uint" => (4, 4, +1),
1463-
"nint" => (8, 4, -1),
1464-
"nuint" => (8, 4, +1),
1465-
"long" => (8, 8, -1),
1466-
"ulong" => (8, 8, +1),
1467-
_ => (0, 0, 0),
1468-
};
1457+
"sbyte" => (1, 1, -1),
1458+
"byte" => (1, 1, +1),
1459+
"short" => (2, 2, -1),
1460+
"ushort" => (2, 2, +1),
1461+
"int" => (4, 4, -1),
1462+
"uint" => (4, 4, +1),
1463+
"nint" => (8, 4, -1),
1464+
"nuint" => (8, 4, +1),
1465+
"long" => (8, 8, -1),
1466+
"ulong" => (8, 8, +1),
1467+
_ => (0, 0, 0),
1468+
};
14691469
}
14701470

14711471
static void OutputConversions(StreamWriter sw, string indentString, string name, string type, PInvokeGeneratorTransparentStructKind kind, string target)
@@ -2326,13 +2326,9 @@ private static string EscapeName(string name)
23262326
}
23272327
}
23282328

2329-
private string EscapeAndStripName(string name)
2329+
private string EscapeAndStripMethodName(string name)
23302330
{
2331-
if (name.StartsWith(_config.MethodPrefixToStrip, StringComparison.Ordinal))
2332-
{
2333-
name = name[_config.MethodPrefixToStrip.Length..];
2334-
}
2335-
2331+
name = PrefixAndStrip(name, _config.MethodPrefixToStrip);
23362332
return EscapeName(name);
23372333
}
23382334

@@ -5407,7 +5403,7 @@ private static bool IsTransparentStructBoolean(PInvokeGeneratorTransparentStruct
54075403
=> kind is PInvokeGeneratorTransparentStructKind.Boolean;
54085404

54095405
private static bool IsTransparentStructHandle(PInvokeGeneratorTransparentStructKind kind)
5410-
=> kind is PInvokeGeneratorTransparentStructKind.Handle
5406+
=> kind is PInvokeGeneratorTransparentStructKind.Handle
54115407
or PInvokeGeneratorTransparentStructKind.HandleWin32;
54125408

54135409
private static bool IsTransparentStructHexBased(PInvokeGeneratorTransparentStructKind kind)
@@ -6153,7 +6149,7 @@ private bool NeedsReturnFixup(CXXMethodDecl cxxMethodDecl)
61536149

61546150
private static bool NeedsNewKeyword(string name)
61556151
{
6156-
return name.Equals("Equals",StringComparison.Ordinal)
6152+
return name.Equals("Equals", StringComparison.Ordinal)
61576153
|| name.Equals("GetHashCode", StringComparison.Ordinal)
61586154
|| name.Equals("GetType", StringComparison.Ordinal)
61596155
|| name.Equals("MemberwiseClone", StringComparison.Ordinal)
@@ -6198,13 +6194,32 @@ private void ParenthesizeStmt(Stmt stmt)
61986194
}
61996195
}
62006196

6201-
private string PrefixAndStripName(string name, uint overloadIndex)
6197+
/// <summary>
6198+
/// Checks whether the specified name starts with a prefix, optionally trims a separator character following the prefix and returns the remainder.
6199+
/// </summary>
6200+
/// <param name="name">The name to strip.</param>
6201+
/// <param name="prefix">The prefix to strip from <paramref name="name"/>.</param>
6202+
/// <param name="trimChar">Additional separator that may follow <paramref name="prefix"/> which should also be trimmed away.</param>
6203+
/// <returns>
6204+
/// <paramref name="name"/> if it does not start with <paramref name="prefix"/>;
6205+
/// otherwise,
6206+
/// the remainder of <paramref name="name"/> after stripping <paramref name="prefix"/> and all immediate following occurences of <paramref name="trimChar"/> from it beginning.
6207+
/// </returns>
6208+
private static string PrefixAndStrip(string name, string prefix, char trimChar = '\0')
62026209
{
6203-
if (name.StartsWith(_config.MethodPrefixToStrip, StringComparison.Ordinal))
6210+
var nameSpan = name.AsSpan();
6211+
if (nameSpan.StartsWith(prefix, StringComparison.Ordinal))
62046212
{
6205-
name = name[_config.MethodPrefixToStrip.Length..];
6213+
nameSpan = nameSpan[prefix.Length..];
6214+
nameSpan = nameSpan.TrimStart(trimChar);
6215+
return nameSpan.ToString();
62066216
}
6217+
return name;
6218+
}
62076219

6220+
private string PrefixAndStripMethodName(string name, uint overloadIndex)
6221+
{
6222+
name = PrefixAndStrip(name, _config.MethodPrefixToStrip);
62086223
return $"_{name}{((overloadIndex != 0) ? overloadIndex.ToString(CultureInfo.InvariantCulture) : "")}";
62096224
}
62106225

sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,8 @@ public IReadOnlyCollection<string> ExcludedNames
265265

266266
public bool GenerateVtblIndexAttribute => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateVtblIndexAttribute);
267267

268+
public bool StripEnumMemberTypeName => _options.HasFlag(PInvokeGeneratorConfigurationOptions.StripEnumMemberTypeName);
269+
268270
public string HeaderText => _headerText;
269271

270272
[AllowNull]

sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,6 @@ public enum PInvokeGeneratorConfigurationOptions : long
8686
GenerateCallConvMemberFunction = 1L << 37,
8787

8888
GenerateGenericPointerWrapper = 1L << 38,
89+
90+
StripEnumMemberTypeName = 1L << 39,
8991
}

sources/ClangSharpPInvokeGenerator/Program.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ public static class Program
177177
new TwoColumnHelpRow("generate-unmanaged-constants", "Unmanaged constants should be generated using static ref readonly properties. This is currently experimental."),
178178
new TwoColumnHelpRow("generate-vtbl-index-attribute", "[VtblIndex(#)] attribute should be generated to document the underlying VTBL index for a helper method."),
179179

180+
new TwoColumnHelpRow("", ""),
181+
new TwoColumnHelpRow("# Stripping Options", ""),
182+
new TwoColumnHelpRow("", ""),
183+
184+
new TwoColumnHelpRow("strip-enum-member-type-name", "Strips the enum type name from the beginning of its member names."),
185+
180186
new TwoColumnHelpRow("", ""),
181187
new TwoColumnHelpRow("# Logging Options", ""),
182188
new TwoColumnHelpRow("", ""),
@@ -617,6 +623,14 @@ public static void Run(InvocationContext context)
617623
break;
618624
}
619625

626+
// Strip Options
627+
628+
case "strip-enum-member-type-name":
629+
{
630+
configOptions |= PInvokeGeneratorConfigurationOptions.StripEnumMemberTypeName;
631+
break;
632+
}
633+
620634
// Legacy Options
621635

622636
case "default-remappings":

0 commit comments

Comments
 (0)