mirror of https://github.com/mono/CppSharp.git
Browse Source
This improves our generated API as we no longer need "_0"-like names and also prevents conflicts between an anonymous type and a property of this type. Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>pull/1159/merge
6 changed files with 121 additions and 5 deletions
@ -0,0 +1,81 @@
@@ -0,0 +1,81 @@
|
||||
using CppSharp.AST; |
||||
using CppSharp.AST.Extensions; |
||||
|
||||
namespace CppSharp.Passes |
||||
{ |
||||
/// <summary>
|
||||
/// Replaces anonymous types with their contained fields
|
||||
/// in class layouts and properties in order to avoid generating
|
||||
/// these very same anonymous types which is useless and
|
||||
/// also forces unappealing names.
|
||||
/// </summary>
|
||||
public class FlattenAnonymousTypesToFields : TranslationUnitPass |
||||
{ |
||||
public FlattenAnonymousTypesToFields() |
||||
{ |
||||
VisitOptions.VisitClassBases = false; |
||||
VisitOptions.VisitClassFields = false; |
||||
VisitOptions.VisitClassMethods = false; |
||||
VisitOptions.VisitClassProperties = false; |
||||
VisitOptions.VisitEventParameters = false; |
||||
VisitOptions.VisitFunctionParameters = false; |
||||
VisitOptions.VisitFunctionReturnType = false; |
||||
VisitOptions.VisitNamespaceEnums = false; |
||||
VisitOptions.VisitNamespaceTemplates = false; |
||||
VisitOptions.VisitNamespaceTypedefs = false; |
||||
VisitOptions.VisitNamespaceVariables = false; |
||||
VisitOptions.VisitPropertyAccessors = false; |
||||
VisitOptions.VisitTemplateArguments = false; |
||||
} |
||||
|
||||
public override bool VisitClassDecl(Class @class) |
||||
{ |
||||
if (!base.VisitClassDecl(@class) || @class.Ignore || @class.IsDependent) |
||||
return false; |
||||
|
||||
for (int i = @class.Fields.Count - 1; i >= 0; i--) |
||||
{ |
||||
Field field = @class.Fields[i]; |
||||
Class fieldType; |
||||
if (!string.IsNullOrEmpty(field.OriginalName) || |
||||
!field.Type.Desugar().TryGetClass(out fieldType) || |
||||
!string.IsNullOrEmpty(fieldType.OriginalName)) |
||||
continue; |
||||
|
||||
ReplaceField(@class, i, fieldType); |
||||
ReplaceLayoutField(@class, field, fieldType); |
||||
fieldType.Fields.Clear(); |
||||
fieldType.ExplicitlyIgnore(); |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static void ReplaceField(Class @class, int i, Class fieldType) |
||||
{ |
||||
@class.Fields.RemoveAt(i); |
||||
|
||||
for (int j = 0; j < fieldType.Fields.Count; j++) |
||||
{ |
||||
Field nestedField = fieldType.Fields[j]; |
||||
nestedField.Namespace = @class; |
||||
@class.Fields.Insert(i + j, nestedField); |
||||
} |
||||
} |
||||
|
||||
private static void ReplaceLayoutField(Class @class, Field field, Class fieldType) |
||||
{ |
||||
LayoutField layoutField = @class.Layout.Fields.Find( |
||||
f => f.FieldPtr == field.OriginalPtr); |
||||
int layoutIndex = @class.Layout.Fields.IndexOf(layoutField); |
||||
@class.Layout.Fields.RemoveAt(layoutIndex); |
||||
|
||||
for (int j = 0; j < fieldType.Layout.Fields.Count; j++) |
||||
{ |
||||
LayoutField nestedlayoutField = fieldType.Layout.Fields[j]; |
||||
nestedlayoutField.Offset += layoutField.Offset; |
||||
@class.Layout.Fields.Insert(layoutIndex + j, nestedlayoutField); |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue