Browse Source

Move the fix for #94 into CSharpConversions.IsConstraintConvertible.

Also added a couple of additional unit tests for constraint validation.
newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
c403f389b7
  1. 11
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs
  2. 2
      ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs
  3. 52
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs

11
ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs

@ -186,8 +186,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -186,8 +186,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return true;
if (ImplicitReferenceConversion(fromType, toType, 0))
return true;
if (IsBoxingConversion(fromType, toType) && !NullableType.IsNullable(fromType))
return true;
if (NullableType.IsNullable(fromType)) {
// An 'object' constraint still allows nullable value types
// (object constraints don't exist in C#, but are inserted by DefaultResolvedTypeParameter.DirectBaseTypes)
if (toType.IsKnownType(KnownTypeCode.Object))
return true;
} else {
if (IsBoxingConversion(fromType, toType))
return true;
}
if (ImplicitTypeParameterConversion(fromType, toType))
return true;
return false;

2
ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs

@ -507,7 +507,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -507,7 +507,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (!ctors.Any())
return false;
}
foreach (IType constraintType in typeParameter.DirectBaseTypes.Where(tp => !tp.IsKnownType(KnownTypeCode.Object))) {
foreach (IType constraintType in typeParameter.DirectBaseTypes) {
IType c = constraintType;
if (substitution != null)
c = c.AcceptVisitor(substitution);

52
ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs

@ -670,6 +670,58 @@ public class C { @@ -670,6 +670,58 @@ public class C {
Assert.IsFalse(rr.IsError);
}
[Test]
public void MethodCanBeInvokedWithNullableTypeArgument3() {
string program = @"
public class C {
static T F<T, U>() where T : U {
return default(T);
}
void M() {
$F<int?, object>()$;
}
}";
var rr = Resolve<CSharpInvocationResolveResult>(program);
Assert.IsFalse(rr.IsError);
}
[Test]
public void MethodWithStructContraintCanBeInvokedWithValueType() {
string program = @"
public class C {
static T F<T>() where T : struct {
return default(T);
}
void M() {
$F<int>()$;
}
}";
var rr = Resolve<CSharpInvocationResolveResult>(program);
Assert.IsFalse(rr.IsError);
}
[Test]
public void MethodWithStructContraintCannotBeInvokedWithNullableValueType() {
string program = @"
public class C {
static T F<T>() where T : struct {
return default(T);
}
void M() {
$F<int?>()$;
}
}";
var rr = Resolve<CSharpInvocationResolveResult>(program);
Assert.IsTrue(rr.IsError);
Assert.AreEqual(OverloadResolutionErrors.MethodConstraintsNotSatisfied, rr.OverloadResolutionErrors);
}
[Test]
public void CanConstructGenericTypeWithNullableTypeArgument() {
string program = @"

Loading…
Cancel
Save