From b495c9ac44440cda289f09eb40e276c8d8e27ee9 Mon Sep 17 00:00:00 2001 From: mattwar Date: Tue, 6 Jan 2015 14:33:44 -0800 Subject: [PATCH] Fix for bug 612002 Undos previous fix that changed the compiler to always emitted a generated property name of __result for EndInvoke. The new change only adds the underscores if there is a name conflict. In this way, we stay metadata compatible with the prior native compiler. Also added same fix to generated parameters for BeginInvoke, callback and object. Added test cases. (changeset 1393061) --- .../Source/SourceDelegateMethodSymbol.cs | 29 +++- .../Attributes/AttributeTests_MarshalAs.cs | 2 +- .../AttributeTests_WellKnownAttributes.cs | 6 +- .../CSharp/Test/Emit/Emit/NoPiaEmbedTypes.cs | 2 +- .../Semantic/Semantics/LookupPositionTests.cs | 8 +- .../Symbol/Symbols/Source/DelegateTests.cs | 130 +++++++++++++++++- 6 files changed, 164 insertions(+), 13 deletions(-) diff --git a/Src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs b/Src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs index 9e047f2cc16..274d3f3e7f0 100644 --- a/Src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs +++ b/Src/Compilers/CSharp/Portable/Symbols/Source/SourceDelegateMethodSymbol.cs @@ -281,8 +281,8 @@ private sealed class BeginInvokeMethod : SourceDelegateMethodSymbol } int paramCount = invoke.ParameterCount; - parameters.Add(new SynthesizedParameterSymbol(this, asyncCallbackType, paramCount, RefKind.None, "callback")); - parameters.Add(new SynthesizedParameterSymbol(this, objectType, paramCount + 1, RefKind.None, "object")); + parameters.Add(new SynthesizedParameterSymbol(this, asyncCallbackType, paramCount, RefKind.None, GetUniqueParameterName(parameters, "callback"))); + parameters.Add(new SynthesizedParameterSymbol(this, objectType, paramCount + 1, RefKind.None, GetUniqueParameterName(parameters, "object"))); InitializeParameters(parameters.ToImmutableAndFree()); } @@ -311,6 +311,7 @@ private sealed class EndInvokeMethod : SourceDelegateMethodSymbol { var parameters = ArrayBuilder.GetInstance(); int ordinal = 0; + foreach (SourceParameterSymbol p in invoke.Parameters) { if (p.RefKind != RefKind.None) @@ -320,7 +321,7 @@ private sealed class EndInvokeMethod : SourceDelegateMethodSymbol } } - parameters.Add(new SynthesizedParameterSymbol(this, iAsyncResultType, ordinal++, RefKind.None, "__result")); + parameters.Add(new SynthesizedParameterSymbol(this, iAsyncResultType, ordinal++, RefKind.None, GetUniqueParameterName(parameters, "result"))); InitializeParameters(parameters.ToImmutableAndFree()); } @@ -339,5 +340,27 @@ public override string Name } } + private static string GetUniqueParameterName(ArrayBuilder currentParameters, string name) + { + while (!IsUnique(currentParameters, name)) + { + name = "__" + name; + } + + return name; + } + + private static bool IsUnique(ArrayBuilder currentParameters, string name) + { + foreach (var p in currentParameters) + { + if (string.CompareOrdinal(p.Name, name) == 0) + { + return false; + } + } + + return true; + } } } diff --git a/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_MarshalAs.cs b/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_MarshalAs.cs index 79e173fd42f..35255eea6a1 100644 --- a/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_MarshalAs.cs +++ b/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_MarshalAs.cs @@ -1244,7 +1244,7 @@ class C { "EndInvoke:p1", marshalAsBstr }, { "EndInvoke:p2", marshalAsBstr }, { "EndInvoke:p3", marshalAsBstr }, - { "EndInvoke:__result", null }, + { "EndInvoke:result", null }, }, isField: false); } diff --git a/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs b/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs index e700a09b71a..4c07156f3b9 100644 --- a/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs +++ b/Src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs @@ -837,7 +837,7 @@ public void DPV_Optional_Delegates() case "BeginInvoke.b": case "BeginInvoke.callback": case "BeginInvoke.object": - case "EndInvoke.__result": + case "EndInvoke.result": expectedFlags = 0; break; @@ -1673,7 +1673,7 @@ public void DecimalConstant_Delegates() Signature("D", "EndInvoke", ".method public hidebysig newslot virtual instance System.Void EndInvoke(" + "[System.Runtime.CompilerServices.DecimalConstantAttribute(1, 2, 3, 4, 5)] [opt] System.Decimal& a = -5534023223830852403.7, " + - "System.IAsyncResult __result) " + + "System.IAsyncResult result) " + "runtime managed"), Signature("D", "Invoke", @@ -1812,7 +1812,7 @@ public void InOutAttributes_Delegates() case "callback": case "object": case "method": - case "__result": + case "result": expectedFlags = 0; break; diff --git a/Src/Compilers/CSharp/Test/Emit/Emit/NoPiaEmbedTypes.cs b/Src/Compilers/CSharp/Test/Emit/Emit/NoPiaEmbedTypes.cs index a81d80c85ca..a649401d275 100644 --- a/Src/Compilers/CSharp/Test/Emit/Emit/NoPiaEmbedTypes.cs +++ b/Src/Compilers/CSharp/Test/Emit/Emit/NoPiaEmbedTypes.cs @@ -1386,7 +1386,7 @@ public void M6(ITest26 x) Assert.Equal(MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot, end.Flags); Assert.Equal(MethodImplAttributes.Runtime, (MethodImplAttributes)end.ImplementationAttributes); Assert.Equal(CallingConvention.Default | CallingConvention.HasThis, end.CallingConvention); - Assert.Equal("void Test11.EndInvoke(System.IAsyncResult __result)", end.ToTestDisplayString()); + Assert.Equal("void Test11.EndInvoke(System.IAsyncResult result)", end.ToTestDisplayString()); var invoke = (PEMethodSymbol)test11.GetMembers("Invoke").Single(); diff --git a/Src/Compilers/CSharp/Test/Semantic/Semantics/LookupPositionTests.cs b/Src/Compilers/CSharp/Test/Semantic/Semantics/LookupPositionTests.cs index e99caf611bf..079e432ad54 100644 --- a/Src/Compilers/CSharp/Test/Semantic/Semantics/LookupPositionTests.cs +++ b/Src/Compilers/CSharp/Test/Semantic/Semantics/LookupPositionTests.cs @@ -401,25 +401,25 @@ static C() string[] delegate_d1_members = new string[]{ "System.IAsyncResult C.D1.BeginInvoke(System.AsyncCallback callback, System.Object @object)", - "void C.D1.EndInvoke(System.IAsyncResult __result)", + "void C.D1.EndInvoke(System.IAsyncResult result)", "void C.D1.Invoke()" }.Concat(CommonDelegateTypeMembers).ToArray(); string[] delegate_d2_members = new string[]{ "System.IAsyncResult C.D2.BeginInvoke(System.Int32 t, System.AsyncCallback callback, System.Object @object)", - "void C.D2.EndInvoke(System.IAsyncResult __result)", + "void C.D2.EndInvoke(System.IAsyncResult result)", "void C.D2.Invoke(System.Int32 t)" }.Concat(CommonDelegateTypeMembers).ToArray(); string[] delegate_d3_members = new string[]{ "System.IAsyncResult C.D3.BeginInvoke(System.AsyncCallback callback, System.Object @object)", - "void C.D3.EndInvoke(System.IAsyncResult __result)", + "void C.D3.EndInvoke(System.IAsyncResult result)", "void C.D3.Invoke()" }.Concat(CommonDelegateTypeMembers).ToArray(); string[] delegate_d4_members = new string[]{ "System.IAsyncResult C.D4.BeginInvoke(V t, System.AsyncCallback callback, System.Object @object)", - "void C.D4.EndInvoke(System.IAsyncResult __result)", + "void C.D4.EndInvoke(System.IAsyncResult result)", "void C.D4.Invoke(V t)" }.Concat(CommonDelegateTypeMembers).ToArray(); diff --git a/Src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs b/Src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs index cd80c5f4cfd..cc7a086ad39 100644 --- a/Src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs +++ b/Src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs @@ -350,7 +350,7 @@ public void DelegateMethodParameterNames() Assert.Equal(3, endInvokeParameters.Length); Assert.Equal("y", endInvokeParameters[0].Name); Assert.Equal("z", endInvokeParameters[1].Name); - Assert.Equal("__result", endInvokeParameters[2].Name); + Assert.Equal("result", endInvokeParameters[2].Name); } [WorkItem(541179, "DevDiv")] @@ -371,6 +371,134 @@ void M(int i) CreateCompilationWithMscorlib(text).VerifyDiagnostics(); } + [WorkItem(612002, "DevDiv")] + [Fact] + public void DelegateWithOutParameterNamedResult() + { + var text = @" +delegate void D(out int result); +"; + var comp = CreateCompilationWithMscorlib(text); + comp.VerifyDiagnostics(); + + NamedTypeSymbol d = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("D").Single(); + + MethodSymbol invoke = d.DelegateInvokeMethod; + ImmutableArray invokeParameters = invoke.Parameters; + Assert.Equal(1, invokeParameters.Length); + Assert.Equal("result", invokeParameters[0].Name); + + MethodSymbol beginInvoke = (MethodSymbol)d.GetMembers("BeginInvoke").Single(); + ImmutableArray beginInvokeParameters = beginInvoke.Parameters; + Assert.Equal(3, beginInvokeParameters.Length); + Assert.Equal("result", beginInvokeParameters[0].Name); + Assert.Equal("callback", beginInvokeParameters[1].Name); + Assert.Equal("object", beginInvokeParameters[2].Name); + + MethodSymbol endInvoke = (MethodSymbol)d.GetMembers("EndInvoke").Single(); + ImmutableArray endInvokeParameters = endInvoke.Parameters; + Assert.Equal(2, endInvokeParameters.Length); + Assert.Equal("result", endInvokeParameters[0].Name); + Assert.Equal("__result", endInvokeParameters[1].Name); + } + + [WorkItem(612002, "DevDiv")] + [Fact] + public void DelegateWithOutParameterNamedResult2() + { + var text = @" +delegate void D(out int @__result); +"; + var comp = CreateCompilationWithMscorlib(text); + comp.VerifyDiagnostics(); + + NamedTypeSymbol d = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("D").Single(); + + MethodSymbol invoke = d.DelegateInvokeMethod; + ImmutableArray invokeParameters = invoke.Parameters; + Assert.Equal(1, invokeParameters.Length); + Assert.Equal("__result", invokeParameters[0].Name); + + MethodSymbol beginInvoke = (MethodSymbol)d.GetMembers("BeginInvoke").Single(); + ImmutableArray beginInvokeParameters = beginInvoke.Parameters; + Assert.Equal(3, beginInvokeParameters.Length); + Assert.Equal("__result", beginInvokeParameters[0].Name); + Assert.Equal("callback", beginInvokeParameters[1].Name); + Assert.Equal("object", beginInvokeParameters[2].Name); + + MethodSymbol endInvoke = (MethodSymbol)d.GetMembers("EndInvoke").Single(); + ImmutableArray endInvokeParameters = endInvoke.Parameters; + Assert.Equal(2, endInvokeParameters.Length); + Assert.Equal("__result", endInvokeParameters[0].Name); + Assert.Equal("result", endInvokeParameters[1].Name); + } + + [WorkItem(612002, "DevDiv")] + [Fact] + public void DelegateWithOutParameterNamedResult3() + { + var text = @" +delegate void D(out int result, out int @__result); +"; + var comp = CreateCompilationWithMscorlib(text); + comp.VerifyDiagnostics(); + + NamedTypeSymbol d = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("D").Single(); + + MethodSymbol invoke = d.DelegateInvokeMethod; + ImmutableArray invokeParameters = invoke.Parameters; + Assert.Equal(2, invokeParameters.Length); + Assert.Equal("result", invokeParameters[0].Name); + Assert.Equal("__result", invokeParameters[1].Name); + + MethodSymbol beginInvoke = (MethodSymbol)d.GetMembers("BeginInvoke").Single(); + ImmutableArray beginInvokeParameters = beginInvoke.Parameters; + Assert.Equal(4, beginInvokeParameters.Length); + Assert.Equal("result", invokeParameters[0].Name); + Assert.Equal("__result", invokeParameters[1].Name); + Assert.Equal("callback", beginInvokeParameters[2].Name); + Assert.Equal("object", beginInvokeParameters[3].Name); + + MethodSymbol endInvoke = (MethodSymbol)d.GetMembers("EndInvoke").Single(); + ImmutableArray endInvokeParameters = endInvoke.Parameters; + Assert.Equal(3, endInvokeParameters.Length); + Assert.Equal("result", endInvokeParameters[0].Name); + Assert.Equal("__result", endInvokeParameters[1].Name); + Assert.Equal("____result", endInvokeParameters[2].Name); + } + + [WorkItem(612002, "DevDiv")] + [Fact] + public void DelegateWithParametersNamedCallbackAndObject() + { + var text = @" +delegate void D(int callback, int @object); +"; + var comp = CreateCompilationWithMscorlib(text); + comp.VerifyDiagnostics(); + + NamedTypeSymbol d = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("D").Single(); + + MethodSymbol invoke = d.DelegateInvokeMethod; + ImmutableArray invokeParameters = invoke.Parameters; + Assert.Equal(2, invokeParameters.Length); + Assert.Equal("callback", invokeParameters[0].Name); + Assert.Equal("object", invokeParameters[1].Name); + + MethodSymbol beginInvoke = (MethodSymbol)d.GetMembers("BeginInvoke").Single(); + ImmutableArray beginInvokeParameters = beginInvoke.Parameters; + Assert.Equal(4, beginInvokeParameters.Length); + Assert.Equal("callback", beginInvokeParameters[0].Name); + Assert.Equal("object", beginInvokeParameters[1].Name); + Assert.Equal("__callback", beginInvokeParameters[2].Name); + Assert.Equal("__object", beginInvokeParameters[3].Name); + + MethodSymbol endInvoke = (MethodSymbol)d.GetMembers("EndInvoke").Single(); + ImmutableArray endInvokeParameters = endInvoke.Parameters; + Assert.Equal(1, endInvokeParameters.Length); + Assert.Equal("result", endInvokeParameters[0].Name); + } + [Fact] public void DelegateConversion() { -- GitLab