diff --git a/src/AST/Property.cs b/src/AST/Property.cs index 4c52b5d7..a5524f3a 100644 --- a/src/AST/Property.cs +++ b/src/AST/Property.cs @@ -72,7 +72,10 @@ namespace CppSharp.AST { get { - return (GetMethod != null) || (Field != null); + return (GetMethod != null && + GetMethod.GenerationKind != GenerationKind.None) || + (Field != null && + Field.GenerationKind != GenerationKind.None); } } @@ -80,8 +83,11 @@ namespace CppSharp.AST { get { - return (SetMethod != null) || - (Field != null && !Field.QualifiedType.Qualifiers.IsConst); + return (SetMethod != null && + SetMethod.GenerationKind != GenerationKind.None) || + (Field != null && + !Field.QualifiedType.Qualifiers.IsConst && + Field.GenerationKind != GenerationKind.None); } } diff --git a/src/Generator.Tests/Passes/TestPasses.cs b/src/Generator.Tests/Passes/TestPasses.cs index c2656f73..58d8edec 100644 --- a/src/Generator.Tests/Passes/TestPasses.cs +++ b/src/Generator.Tests/Passes/TestPasses.cs @@ -108,5 +108,20 @@ namespace CppSharp.Generator.Tests.Passes Assert.IsFalse(AstContext.FindClass("Foo").First().Methods.Find( m => m.Name == "toIgnore").IsGenerated); } + + [Test] + public void TestSetPropertyAsReadOnly() + { + const string className = "TestReadOnlyProperties"; + passBuilder.AddPass(new FieldToPropertyPass()); + passBuilder.AddPass(new GetterSetterToPropertyPass()); + passBuilder.RunPasses(pass => pass.VisitLibrary(AstContext)); + AstContext.SetPropertyAsReadOnly(className, "readOnlyProperty"); + Assert.IsFalse(AstContext.FindClass(className).First().Properties.Find( + m => m.Name == "readOnlyProperty").HasSetter); + AstContext.SetPropertyAsReadOnly(className, "ReadOnlyPropertyMethod"); + Assert.IsFalse(AstContext.FindClass(className).First().Properties.Find( + m => m.Name == "ReadOnlyPropertyMethod").HasSetter); + } } } diff --git a/src/Generator/Library.cs b/src/Generator/Library.cs index 5a8aba08..0b52bc31 100644 --- a/src/Generator/Library.cs +++ b/src/Generator/Library.cs @@ -204,6 +204,26 @@ namespace CppSharp } } + public static void SetPropertyAsReadOnly(this ASTContext context, string className, string propertyName) + { + var properties = context.FindClass(className) + .SelectMany(c => c.Properties.Where(p => p.Name == propertyName && p.HasSetter)); + foreach (var property in properties) + if (property.SetMethod != null) + property.SetMethod.GenerationKind = GenerationKind.None; + else + { + var field = property.Field; + var quals = field.QualifiedType.Qualifiers; + quals.IsConst = true; + + var qualType = field.QualifiedType; + qualType.Qualifiers = quals; + + field.QualifiedType = qualType; + } + } + /// /// Sets the parameter usage for a function parameter. /// diff --git a/tests/Native/Passes.h b/tests/Native/Passes.h index 2435b21d..09cd1e5a 100644 --- a/tests/Native/Passes.h +++ b/tests/Native/Passes.h @@ -26,6 +26,13 @@ struct TestRename int lowerCaseField; }; +struct TestReadOnlyProperties +{ + int readOnlyProperty; + int getReadOnlyPropertyMethod() { return 0; } + void setReadOnlyPropertyMethod(int value) { } +}; + #define TEST_ENUM_ITEM_NAME_0 0 #define TEST_ENUM_ITEM_NAME_1 1 #define TEST_ENUM_ITEM_NAME_2 2