diff --git a/src/Generator/AST/Utils.cs b/src/Generator/AST/Utils.cs index 986b5585..47836867 100644 --- a/src/Generator/AST/Utils.cs +++ b/src/Generator/AST/Utils.cs @@ -36,9 +36,6 @@ namespace CppSharp.AST if (method.IsDestructor) return true; - if (method.OperatorKind == CXXOperatorKind.Equal) - return true; - if (method.Access == AccessSpecifier.Private && !method.IsOverride && !method.IsExplicitlyGenerated) return true; diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 8cedbf44..e0764de8 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -1009,8 +1009,34 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat private void GenerateFieldSetter(Field field, Class @class, QualifiedType fieldType) { + if (field.Type.IsClass() && !field.Type.IsPointer()) + { + if (field.Type.TryGetClass(out Class fieldClass)) + { + var caop = fieldClass.Methods.FirstOrDefault(m => m.OperatorKind == CXXOperatorKind.Equal); + if (caop != null) + { + var fieldName = ((Class)field.Namespace).Layout.Fields.First( + f => f.FieldPtr == field.OriginalPtr).Name; + WriteLine($"var dest = new __IntPtr(&((__Internal*)__Instance)->{fieldName});"); + WriteLine($"var src = value.{Helpers.InstanceIdentifier};"); + + var typeName = TypePrinter.PrintNative(fieldClass); + if (IsInternalClassNested(fieldClass)) + typeName.RemoveNamespace(); + + WriteLine($"{fieldClass}.__Internal.OperatorEqual(dest, src);"); + //UnindentAndWriteCloseBrace(); + + return; + } + } + } + + string returnVar; Type type = field.Type.Desugar(); + var arrayType = type as ArrayType; if (arrayType != null && @class.IsValueType) { @@ -1481,6 +1507,11 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat continue; } + // We only use the copy assignment operator internally, + // so do not generate a public method wrapper for it + if (method.OperatorKind == CXXOperatorKind.Equal) + continue; + GenerateMethod(method, @class); } diff --git a/src/Generator/Passes/ValidateOperatorsPass.cs b/src/Generator/Passes/ValidateOperatorsPass.cs index b1f86db1..bf1dbd92 100644 --- a/src/Generator/Passes/ValidateOperatorsPass.cs +++ b/src/Generator/Passes/ValidateOperatorsPass.cs @@ -55,6 +55,9 @@ namespace CppSharp.Passes // The conversion operators can be overloaded case CXXOperatorKind.Conversion: case CXXOperatorKind.ExplicitConversion: + + // Copy assignment operator is used internally + case CXXOperatorKind.Equal: return true; // The comparison operators can be overloaded if their return type is bool @@ -127,7 +130,6 @@ namespace CppSharp.Passes case CXXOperatorKind.PipePipe: // These operators cannot be overloaded. - case CXXOperatorKind.Equal: case CXXOperatorKind.Comma: case CXXOperatorKind.ArrowStar: case CXXOperatorKind.Arrow: