Repository: swig/swig (language: cpp)

Issue:
Possible bug in attribute.swg/attribute2ref
Hi

I'm using the function "attribute2ref" contained inside the file Libs/typemaps/attribute.swg, and I'm calling it providing only the first three arguments (namely, Class, AttributeType and AttributeName).

I got a build error  'no member named ‘AccessorName’

Looking at the code 

```
%define %attribute2ref(Class, AttributeType, AttributeName, AccessorMethod...)
  #if #AccessorMethod != ""
    %attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AccessorMethod, AccessorMethod, &self_->AccessorMethod(), self_->AccessorMethod() = *val_)
  #else
    %attribute_custom(%arg(Class), %arg(AttributeType), AccessorName, AccessorName, AccessorName, &self_->AccessorName(), self_->AccessorName() = *val_)
  #endif
%enddef

```

It seems that in the call  %attribute_custom after the #else statement "AccessorName" should be indeed replaced with AttributeName.

Is this the case?

Thank you very much


Discussion / hints:
Yes I think so. It looks like a typo when 71dddaa2de7298d002a37538e84f5be00cca080c was committed. Do you want to put together a Github pull request for this? Could you enhance the li_attribute.i testcase and test it with one of these runtime tests:
```
william@bobcat:~/swig/github/swig (master=)$ find Examples/test-suite/ -name "li_attribute_runme.*"
Examples/test-suite/d/li_attribute_runme.1.d
Examples/test-suite/d/li_attribute_runme.2.d
Examples/test-suite/csharp/li_attribute_runme.cs
Examples/test-suite/csharp/li_attribute_runme.exe.mdb
Examples/test-suite/csharp/li_attribute_runme.exe
Examples/test-suite/python/li_attribute_runme.py
Examples/test-suite/go/li_attribute_runme.go
Examples/test-suite/octave/li_attribute_runme.m
```
Ok thanks I'll do that :)
For what it's worth, I took a look at this issue a few days ago and came up with this patch:

```diff
diff --git a/Examples/test-suite/li_attribute.i b/Examples/test-suite/li_attribute.i
index 4f9497afb..95389b2b6 100644
--- a/Examples/test-suite/li_attribute.i
+++ b/Examples/test-suite/li_attribute.i
@@ -95,6 +95,7 @@ struct MyFoo; // %attribute2 does not work with templates
 
 // class/struct attribute with get/set methods using return/pass by reference
 %attribute2(MyClass, MyFoo, Foo, GetFoo, SetFoo);
+%attribute2ref(MyClass, MyFoo, Foo2);
 %inline %{
   struct MyFoo { 
     MyFoo() : x(-1) {}
@@ -102,9 +103,11 @@ struct MyFoo; // %attribute2 does not work with templates
   };
   class MyClass {
     MyFoo foo;
+    MyFoo foo2;
   public:
     MyFoo& GetFoo() { return foo; }
     void SetFoo(const MyFoo& other) { foo = other; }
+    MyFoo& Foo2() { return foo2; }
   };
 %} 
 
diff --git a/Examples/test-suite/python/li_attribute_runme.py b/Examples/test-suite/python/li_attribute_runme.py
index a5a6914cd..d26bf0b68 100644
--- a/Examples/test-suite/python/li_attribute_runme.py
+++ b/Examples/test-suite/python/li_attribute_runme.py
@@ -45,6 +45,9 @@ myClass = li_attribute.MyClass()
 myClass.Foo = myFoo
 if myClass.Foo.x != 8:
     raise RuntimeError
+myClass.Foo2 = myFoo
+if myClass.Foo2.x != 8:
+    raise RuntimeError
 
 # class/struct attribute with get/set methods using return/pass by value
 myClassVal = li_attribute.MyClassVal()
diff --git a/Lib/typemaps/attribute.swg b/Lib/typemaps/attribute.swg
index 988113991..37c3340cf 100644
--- a/Lib/typemaps/attribute.swg
+++ b/Lib/typemaps/attribute.swg
@@ -224,7 +224,7 @@
   #if #AccessorMethod != ""
     %attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AccessorMethod, AccessorMethod, &self_->AccessorMethod(), self_->AccessorMethod() = *val_)
   #else
-    %attribute_custom(%arg(Class), %arg(AttributeType), AccessorName, AccessorName, AccessorName, &self_->AccessorName(), self_->AccessorName() = *val_)
+    %attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AttributeName, AttributeName, &self_->AttributeName(), self_->AttributeName() = *val_)
   #endif
 %enddef
 

```

Fix patch:
diff --git a/Lib/typemaps/attribute.swg b/Lib/typemaps/attribute.swg
index 98811399193..37c3340cf3c 100644
--- a/Lib/typemaps/attribute.swg
+++ b/Lib/typemaps/attribute.swg
@@ -224,7 +224,7 @@
   #if #AccessorMethod != ""
     %attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AccessorMethod, AccessorMethod, &self_->AccessorMethod(), self_->AccessorMethod() = *val_)
   #else
-    %attribute_custom(%arg(Class), %arg(AttributeType), AccessorName, AccessorName, AccessorName, &self_->AccessorName(), self_->AccessorName() = *val_)
+    %attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AttributeName, AttributeName, &self_->AttributeName(), self_->AttributeName() = *val_)
   #endif
 %enddef
 


Test patch:
diff --git a/Examples/test-suite/li_attribute.i b/Examples/test-suite/li_attribute.i
index 4f9497afb30..95389b2b6ab 100644
--- a/Examples/test-suite/li_attribute.i
+++ b/Examples/test-suite/li_attribute.i
@@ -95,6 +95,7 @@ struct MyFoo; // %attribute2 does not work with templates
 
 // class/struct attribute with get/set methods using return/pass by reference
 %attribute2(MyClass, MyFoo, Foo, GetFoo, SetFoo);
+%attribute2ref(MyClass, MyFoo, Foo2);
 %inline %{
   struct MyFoo { 
     MyFoo() : x(-1) {}
@@ -102,9 +103,11 @@ struct MyFoo; // %attribute2 does not work with templates
   };
   class MyClass {
     MyFoo foo;
+    MyFoo foo2;
   public:
     MyFoo& GetFoo() { return foo; }
     void SetFoo(const MyFoo& other) { foo = other; }
+    MyFoo& Foo2() { return foo2; }
   };
 %} 
 
diff --git a/Examples/test-suite/python/li_attribute_runme.py b/Examples/test-suite/python/li_attribute_runme.py
index a5a6914cd3d..d26bf0b68e4 100644
--- a/Examples/test-suite/python/li_attribute_runme.py
+++ b/Examples/test-suite/python/li_attribute_runme.py
@@ -45,6 +45,9 @@
 myClass.Foo = myFoo
 if myClass.Foo.x != 8:
     raise RuntimeError
+myClass.Foo2 = myFoo
+if myClass.Foo2.x != 8:
+    raise RuntimeError
 
 # class/struct attribute with get/set methods using return/pass by value
 myClassVal = li_attribute.MyClassVal()