Browse Source

Fix extension method calls on `this in`.

pull/2301/head
Daniel Grunwald 4 years ago
parent
commit
c95da67cbe
  1. 7
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs
  2. 1
      ICSharpCode.Decompiler/CSharp/Resolver/MethodGroupResolveResult.cs
  3. 7
      ICSharpCode.Decompiler/CSharp/Resolver/OverloadResolution.cs
  4. 7
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs

7
ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs

@ -2158,12 +2158,17 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -2158,12 +2158,17 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
if (method.Parameters.Count == 0)
return false;
IType thisParameterType = method.Parameters[0].Type;
if (thisParameterType.Kind == TypeKind.ByReference)
{
// extension method with `this in` or `this ref`
thisParameterType = ((ByReferenceType)thisParameterType).ElementType;
}
if (useTypeInference && method.TypeParameters.Count > 0)
{
// We need to infer type arguments from targetType:
TypeInference ti = new TypeInference(compilation, conversions);
ResolveResult[] arguments = { new ResolveResult(targetType) };
IType[] parameterTypes = { method.Parameters[0].Type };
IType[] parameterTypes = { thisParameterType };
var inferredTypes = ti.InferTypeArguments(method.TypeParameters, arguments, parameterTypes, out _);
var substitution = new TypeParameterSubstitution(null, inferredTypes);
// Validate that the types that could be inferred (aren't unknown) satisfy the constraints:

1
ICSharpCode.Decompiler/CSharp/Resolver/MethodGroupResolveResult.cs

@ -271,6 +271,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -271,6 +271,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
extOr.AllowOptionalParameters = allowOptionalParameters;
extOr.IsExtensionMethodInvocation = true;
extOr.CheckForOverflow = checkForOverflow;
extOr.AllowImplicitIn = allowImplicitIn;
foreach (var g in extensionMethods)
{

7
ICSharpCode.Decompiler/CSharp/Resolver/OverloadResolution.cs

@ -669,8 +669,11 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -669,8 +669,11 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
}
else
{
if (paramRefKind == ReferenceKind.In && AllowImplicitIn
&& candidate.ParameterTypes[parameterIndex].SkipModifiers() is ByReferenceType brt)
// AllowImplicitIn: `in` parameters can be filled implicitly without `in` DirectionExpression
// IsExtensionMethodInvocation: `this ref` and `this in` parameters can be filled implicitly
if (((paramRefKind == ReferenceKind.In && AllowImplicitIn)
|| (IsExtensionMethodInvocation && parameterIndex == 0 && (paramRefKind == ReferenceKind.In || paramRefKind == ReferenceKind.Ref))
) && candidate.ParameterTypes[parameterIndex].SkipModifiers() is ByReferenceType brt)
{
// Treat the parameter as if it was not declared "in" for the following steps
// (applicability + better function member)

7
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs

@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@ -181,6 +180,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -181,6 +180,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
target = new ConversionResolveResult(method.Parameters[0].Type, crr, Conversion.NullLiteralConversion);
}
else if (target is ByReferenceResolveResult brrr)
{
target = brrr.ElementResult;
}
ResolveResult[] args = new ResolveResult[invocationExpression.Arguments.Count - 1];
string[] argNames = null;
int pos = 0;
@ -238,4 +241,4 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -238,4 +241,4 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return CanTransformToExtensionMethodCall(resolver, method, typeArgs, targetType, paramTypes, argumentNames: paramNames);
}
}
}
}

Loading…
Cancel
Save