diff --git a/src/AST/ClassExtensions.cs b/src/AST/ClassExtensions.cs index f51f9979..2b3fe9e2 100644 --- a/src/AST/ClassExtensions.cs +++ b/src/AST/ClassExtensions.cs @@ -89,10 +89,10 @@ namespace CppSharp.AST return null; } - public static bool HasNonAbstractBaseMethodInPrimaryBase(this Class @class, Method method) + public static bool HasCallableBaseMethodInPrimaryBase(this Class @class, Method method) { var baseMethod = @class.GetBaseMethod(method, true, true); - return baseMethod != null && !baseMethod.IsPure && + return baseMethod != null && !baseMethod.IsPure && baseMethod.IsGenerated && !((Class) baseMethod.OriginalNamespace).IsInterface; } diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index 1b2660ab..fc348a46 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -2209,7 +2209,7 @@ namespace CppSharp.Generators.CSharp Method rootBaseMethod; var isOverride = method.IsOverride && (rootBaseMethod = @class.GetBaseMethod(method, true)) != null && - (rootBaseMethod.IsVirtual || rootBaseMethod.IsPure); + rootBaseMethod.IsGenerated && rootBaseMethod.IsVirtual; if (method.IsVirtual && !isOverride && !method.IsOperator && !method.IsPure) Write("virtual "); @@ -2443,18 +2443,21 @@ namespace CppSharp.Generators.CSharp private static AccessSpecifier GetValidMethodAccess(Method method) { - return method.IsOverride - ? ((Class) method.Namespace).GetBaseMethod(method).Access - : method.Access; + if (!method.IsOverride) + return method.Access; + var baseMethod = ((Class) method.Namespace).GetBaseMethod(method); + return baseMethod.IsGenerated ? baseMethod.Access : method.Access; } private static AccessSpecifier GetValidPropertyAccess(Property property) { if (property.Access == AccessSpecifier.Public) return AccessSpecifier.Public; - return property.IsOverride - ? ((Class) property.Namespace).GetBaseProperty(property).Access - : property.Access; + if (!property.IsOverride) + return property.Access; + var baseProperty = ((Class) property.Namespace).GetBaseProperty(property); + // access can be changed from private to other while overriding in C++ + return baseProperty != null ? baseProperty.Access : property.Access; } private void GenerateVirtualPropertyCall(Method method, Class @class, @@ -2480,7 +2483,7 @@ namespace CppSharp.Generators.CSharp { if (!forceVirtualCall && method.IsOverride && !method.IsPure && method.SynthKind != FunctionSynthKind.AbstractImplCall && - @class.HasNonAbstractBaseMethodInPrimaryBase(method)) + @class.HasCallableBaseMethodInPrimaryBase(method)) { GenerateManagedCall(method, true); } diff --git a/src/Generator/Passes/CheckIgnoredDecls.cs b/src/Generator/Passes/CheckIgnoredDecls.cs index 50439032..4cd1572d 100644 --- a/src/Generator/Passes/CheckIgnoredDecls.cs +++ b/src/Generator/Passes/CheckIgnoredDecls.cs @@ -12,17 +12,22 @@ namespace CppSharp.Passes switch (decl.Access) { - case AccessSpecifier.Public: - return true; - case AccessSpecifier.Protected: - var @class = decl.Namespace as Class; - if (@class != null && @class.IsValueType) - return false; - return generateNonPublicDecls; - case AccessSpecifier.Private: - var method = decl as Method; - var isOverride = method != null && method.IsOverride; - return generateNonPublicDecls && (isOverride || decl.IsExplicitlyGenerated); + case AccessSpecifier.Public: + return true; + case AccessSpecifier.Protected: + var @class = decl.Namespace as Class; + if (@class != null && @class.IsValueType) + return false; + return generateNonPublicDecls; + case AccessSpecifier.Private: + var method = decl as Method; + var isOverride = false; + if (method != null && method.IsOverride) + { + var baseMethod = ((Class) method.Namespace).GetBaseMethod(method); + isOverride = baseMethod.IsGenerated; + } + return generateNonPublicDecls && (isOverride || decl.IsExplicitlyGenerated); } return true; @@ -178,20 +183,6 @@ namespace CppSharp.Passes method.ExplicitlyIgnore(); return false; } - - if (method.IsOverride) - { - var baseOverride = @class.GetBaseMethod(method); - if (baseOverride != null && !baseOverride.IsDeclared) - { - Log.Debug( - "Virtual method '{0}' was ignored due to ignored override '{1}'", - method.QualifiedOriginalName, baseOverride.Name); - - method.ExplicitlyIgnore(); - return false; - } - } } return true; diff --git a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs index 8fac269b..e46499e8 100644 --- a/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs +++ b/src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs @@ -113,7 +113,7 @@ namespace CppSharp.Passes private static string GetReadWritePropertyName(INamedDecl getter, string afterSet) { string name = GetPropertyName(getter.Name); - if (name != afterSet && name.StartsWith("is")) + if (name != afterSet && name.StartsWith("is", StringComparison.Ordinal)) { name = char.ToLowerInvariant(name[2]) + name.Substring(3); } @@ -152,7 +152,11 @@ namespace CppSharp.Passes if (getter.IsOverride || (setter != null && setter.IsOverride)) { var baseVirtualProperty = type.GetBaseProperty(property, getTopmost: true); - if (baseVirtualProperty.SetMethod == null) + if (baseVirtualProperty == null && type.GetBaseMethod(getter, getTopmost: true).IsGenerated) + throw new Exception(string.Format( + "Property {0} has a base property null but its getter has a generated base method.", + getter.QualifiedOriginalName)); + if (baseVirtualProperty != null && baseVirtualProperty.SetMethod == null) setter = null; } property.GetMethod = getter; diff --git a/src/Generator/Passes/verbs.txt b/src/Generator/Passes/verbs.txt index 83794b42..1f2a9b34 100644 --- a/src/Generator/Passes/verbs.txt +++ b/src/Generator/Passes/verbs.txt @@ -1924,6 +1924,7 @@ divulse divvies dizen dizzy +do doat does doest diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index 3ae489a3..9d5d7a11 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -894,3 +894,22 @@ namespace NamespaceB void Function(CS_OUT NamespaceA::A &a); }; } + +class HasPrivateVirtualProperty +{ +private: + virtual int property(); + virtual void protectedAbstractMethod() = 0; + virtual void protectedMethod(); + virtual int protectedProperty() = 0; +}; + +class HasPrivateOverriddenProperty : public HasPrivateVirtualProperty +{ +protected: + virtual void protectedAbstractMethod(); + virtual void protectedMethod(); + virtual int protectedProperty(); +private: + virtual int property(); +};