From 2f93bc6c6448172f0815543facf9f7769883d80f Mon Sep 17 00:00:00 2001 From: Sebastien Pouliot Date: Fri, 20 Jan 2017 08:16:46 -0500 Subject: [PATCH] [generator] Fix a potential compile time error in generated *Async methods (#1536) This can happen when a parameter of the method being [Async]-ified has the same name as one of the delegate parameter. E.g. * Binding code ``` delegate void MTKTextureLoaderCallback ([NullAllowed] IMTLTexture texture, [NullAllowed] NSError error); [Async] void FromTexture (MDLTexture texture, [NullAllowed] MTKTextureLoaderOptions options, MTKTextureLoaderCallback completionHandler); ``` * Generated code ``` public unsafe virtual Task FromTextureAsync (global::ModelIO.MDLTexture texture, NSDictionary options) { var tcs = new TaskCompletionSource (); > FromTexture(texture, options, (texture, error) => { if (error != null) tcs.SetException (new NSErrorException(error)); else tcs.SetResult (texture); }); return tcs.Task; } ``` * Errpr ``` MTKTextureLoader.g.cs(397,35): error CS0136: A local variable named `texture' cannot be declared in this scope because it would give a different meaning to `texture', which is already used in a `parent or current' scope to denote something else ``` Note: we are appending, not prepending, a '_' character Because: * we don't want to pick up a fight with GetUniqueParamName that already prepend a '_' in some cases; * Pre-fixing '_' does not work for parameters names starting with a `@` --- src/generator.cs | 17 ++++++++++------- src/metalkit.cs | 2 ++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/generator.cs b/src/generator.cs index bae304da40..9cc3a420ec 100644 --- a/src/generator.cs +++ b/src/generator.cs @@ -4287,15 +4287,18 @@ public partial class Generator : IMemberGatherer { throw new BindingException (1023, true, "Async method {0} with more than one result parameter in the callback by neither ResultTypeName or ResultType", minfo.mi); } - string GetInvokeParamList (ParameterInfo[] parameters) + string GetInvokeParamList (ParameterInfo [] parameters, bool suffix = true) { StringBuilder sb = new StringBuilder (); bool comma = false; foreach (var pi in parameters) { - if (comma) + if (comma) { sb.Append (", "); + } comma = true; sb.Append (pi.Name.GetSafeParamName ()); + if (suffix) + sb.Append ('_'); } return sb.ToString (); } @@ -4360,7 +4363,7 @@ public partial class Generator : IMemberGatherer { print ("var tcs = new TaskCompletionSource<{0}> ();", ttype); print ("{6}{5}{4}{0}({1}{2}({3}) => {{", mi.Name, - GetInvokeParamList (minfo.async_initial_params), + GetInvokeParamList (minfo.async_initial_params, false), minfo.async_initial_params.Length > 0 ? ", " : "", GetInvokeParamList (minfo.async_completion_params), minfo.is_extension_method ? "This." : string.Empty, @@ -4372,8 +4375,8 @@ public partial class Generator : IMemberGatherer { int nesting_level = 1; if (minfo.has_nserror && !tuple) { var var_name = minfo.async_completion_params.Last ().Name.GetSafeParamName ();; - print ("if ({0} != null)", var_name); - print ("\ttcs.SetException (new NSErrorException({0}));", var_name); + print ("if ({0}_ != null)", var_name); + print ("\ttcs.SetException (new NSErrorException({0}_));", var_name); print ("else"); ++nesting_level; ++indent; } @@ -4383,9 +4386,9 @@ public partial class Generator : IMemberGatherer { else if (tuple) { var cond_name = minfo.async_completion_params [0].Name; var var_name = minfo.async_completion_params.Last ().Name; - print ("tcs.SetResult (new Tuple ({0}, {1}));", cond_name, var_name); + print ("tcs.SetResult (new Tuple ({0}_, {1}_));", cond_name, var_name); } else if (minfo.is_single_arg_async) - print ("tcs.SetResult ({0});", minfo.async_completion_params [0].Name); + print ("tcs.SetResult ({0}_);", minfo.async_completion_params [0].Name); else print ("tcs.SetResult (new {0} ({1}));", GetAsyncTaskType (minfo), diff --git a/src/metalkit.cs b/src/metalkit.cs index 6125990809..7db0b0eade 100644 --- a/src/metalkit.cs +++ b/src/metalkit.cs @@ -291,10 +291,12 @@ namespace XamCore.MetalKit { [iOS (10,0)][Mac (10,12, onlyOn64 : true)] [Export ("newTextureWithMDLTexture:options:completionHandler:")] + [Async] void FromTexture (MDLTexture texture, [NullAllowed] NSDictionary options, MTKTextureLoaderCallback completionHandler); [iOS (10,0)][Mac (10,12, onlyOn64 : true)] [Wrap ("FromTexture (texture, options == null ? null : options.Dictionary, completionHandler)")] + [Async] void FromTexture (MDLTexture texture, [NullAllowed] MTKTextureLoaderOptions options, MTKTextureLoaderCallback completionHandler); [iOS (10,0)][Mac (10,12, onlyOn64 : true)]