You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=59472
Assume you have the following Java method:
```java
class Example {
public static CharSequence identity(CharSequence value) {
return value;
}
}
```
When binding `Example.identity()`, we will *rename* it to have a
`Formatted` suffix, and "overload" it with a `string` overload:
```csharp
partial class Example {
public static ICharSequence IdentityFormatted (ICharSequence value)
{
// ...
}
public static string Identity (string value)
{
// ...
}
}
```
The purpose of this overloading is to make it easier to call the
method from C# code. It's not currently possible for interfaces to
contain static methods, which in turn means it's not possible for
interfaces to contain conversion operators. Thus, if a C# developer
wants to do:
Example.Identity ("value");
there would be no way to have this Just Work™ while having only
`ICharSequence` running around.
(Additionally, we rename the method so that we don't need to worry
about return types. In the above example, the return type is
converted, so if we didn't rename to `IdentityFormatted()`, we
couldn't overload for many interesting use cases.)
This feature has existed for quite some time, but there's a bug:
`Example.Identity()` would do:
```csharp
partial class Example {
public static string Identity (string value)
{
var jls_value = value == null ? null : new Java.Lang.String (value)
var __result = IdentityFormatted (jls_value);
jls_value?.Dispose ();
return __result?.ToString ();
}
}
```
This seems acceptable, but this will break when
`Example.IdentityFormatted()` -- `Example.identity()` -- returns the
parameter. When that happens, `jls_value` and `__result` are
*the same instance*, and thus the `jls_value?.Dispose()` *also*
disposes of `__result`. In this case, `__result.ToString()` will be
`null`, which is *not* what is desired.
The fix is to grab `__result.ToString()` *before* disposing of the
temporary parameters:
```csharp
partial class Example {
public static string Identity (string value)
{
var jls_value = value == null ? null : new Java.Lang.String (value)
var __result = IdentityFormatted (jls_value);
var __rsval = __result?.ToString ();
jls_value?.Dispose ();
return __rsval;
}
}
```
This way we ensure that we get a copy before the source is disposed.
// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='TestInterface']/method[@name='append' and count(parameter)=1 and parameter[1][@type='java.lang.CharSequence']]"
// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='TestInterface']/method[@name='identity' and count(parameter)=1 and parameter[1][@type='java.lang.CharSequence']]"
// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='TestInterface']/method[@name='append' and count(parameter)=1 and parameter[1][@type='java.lang.CharSequence']]"
// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='TestInterface']/method[@name='identity' and count(parameter)=1 and parameter[1][@type='java.lang.CharSequence']]"
@@ -123,6 +182,46 @@ public override unsafe int GetSpanFlags (global::Java.Lang.Object tag)
123
182
}
124
183
}
125
184
185
+
// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='TestInterface']/method[@name='append' and count(parameter)=1 and parameter[1][@type='java.lang.CharSequence']]"
// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='TestInterface']/method[@name='identity' and count(parameter)=1 and parameter[1][@type='java.lang.CharSequence']]"
0 commit comments