Browse Source
Add unit tests for overload resolution; fixed an overload resolution bug. Added some new helper methods. Various documentation updates.newNRvisualizers
19 changed files with 481 additions and 75 deletions
@ -0,0 +1,2 @@
@@ -0,0 +1,2 @@
|
||||
/lib/*.dll |
||||
/ICSharpCode.NRefactory.Tests/PartCover/* |
||||
@ -0,0 +1,106 @@
@@ -0,0 +1,106 @@
|
||||
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Linq; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.NRefactory.TypeSystem.Implementation; |
||||
using NUnit.Framework; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Resolver |
||||
{ |
||||
[TestFixture] |
||||
public class OverloadResolutionTests |
||||
{ |
||||
readonly ITypeResolveContext context = CecilLoaderTests.Mscorlib; |
||||
readonly DefaultTypeDefinition dummyClass = new DefaultTypeDefinition(CecilLoaderTests.Mscorlib, string.Empty, "DummyClass"); |
||||
|
||||
ResolveResult[] MakeArgumentList(params Type[] argumentTypes) |
||||
{ |
||||
return argumentTypes.Select(t => new ResolveResult(t.ToTypeReference().Resolve(context))).ToArray(); |
||||
} |
||||
|
||||
DefaultMethod MakeMethod(params Type[] parameterTypes) |
||||
{ |
||||
DefaultMethod m = new DefaultMethod(dummyClass, "Method"); |
||||
foreach (var type in parameterTypes) { |
||||
m.Parameters.Add(new DefaultParameter(type.ToTypeReference(), string.Empty)); |
||||
} |
||||
return m; |
||||
} |
||||
|
||||
DefaultMethod MakeParamsMethod(params Type[] parameterTypes) |
||||
{ |
||||
DefaultMethod m = MakeMethod(parameterTypes); |
||||
((DefaultParameter)m.Parameters.Last()).IsParams = true; |
||||
return m; |
||||
} |
||||
|
||||
[Test] |
||||
public void PreferIntOverUInt() |
||||
{ |
||||
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(ushort))); |
||||
var c1 = MakeMethod(typeof(int)); |
||||
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(c1)); |
||||
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(uint)))); |
||||
Assert.IsFalse(r.IsAmbiguous); |
||||
Assert.AreSame(c1, r.BestCandidate); |
||||
} |
||||
|
||||
[Test] |
||||
public void NullableIntAndNullableUIntIsAmbiguous() |
||||
{ |
||||
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(ushort?))); |
||||
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(int?)))); |
||||
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(uint?)))); |
||||
Assert.AreEqual(OverloadResolutionErrors.AmbiguousMatch, r.BestCandidateErrors); |
||||
|
||||
// then adding a matching overload solves the ambiguity:
|
||||
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeMethod(typeof(ushort?)))); |
||||
Assert.AreEqual(OverloadResolutionErrors.None, r.BestCandidateErrors); |
||||
Assert.IsNull(r.BestCandidateAmbiguousWith); |
||||
} |
||||
|
||||
[Test] |
||||
public void ParamsMethodMatchesEmptyArgumentList() |
||||
{ |
||||
OverloadResolution r = new OverloadResolution(context, MakeArgumentList()); |
||||
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[])))); |
||||
Assert.IsTrue(r.BestCandidateIsExpandedForm); |
||||
} |
||||
|
||||
[Test] |
||||
public void ParamsMethodMatchesOneArgumentInExpandedForm() |
||||
{ |
||||
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(int))); |
||||
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[])))); |
||||
Assert.IsTrue(r.BestCandidateIsExpandedForm); |
||||
} |
||||
|
||||
[Test] |
||||
public void ParamsMethodMatchesInUnexpandedForm() |
||||
{ |
||||
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(int[]))); |
||||
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[])))); |
||||
Assert.IsFalse(r.BestCandidateIsExpandedForm); |
||||
} |
||||
|
||||
[Test] |
||||
public void LessArgumentsPassedToParamsIsBetter() |
||||
{ |
||||
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(int), typeof(int), typeof(int))); |
||||
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int[])))); |
||||
Assert.AreEqual(OverloadResolutionErrors.None, r.AddCandidate(MakeParamsMethod(typeof(int), typeof(int[])))); |
||||
Assert.IsFalse(r.IsAmbiguous); |
||||
Assert.AreEqual(2, r.BestCandidate.Parameters.Count); |
||||
} |
||||
|
||||
[Test] |
||||
public void CallInvalidParamsDeclaration() |
||||
{ |
||||
OverloadResolution r = new OverloadResolution(context, MakeArgumentList(typeof(int[,]))); |
||||
Assert.AreEqual(OverloadResolutionErrors.ArgumentTypeMismatch, r.AddCandidate(MakeParamsMethod(typeof(int)))); |
||||
Assert.IsFalse(r.BestCandidateIsExpandedForm); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using NUnit.Framework; |
||||
|
||||
namespace ICSharpCode.NRefactory.Util |
||||
{ |
||||
[TestFixture] |
||||
public class CSharpPrimitiveCastTests |
||||
{ |
||||
// I know, these tests aren't really clever, more of a way to fake code coverage...
|
||||
// Well, at least they should ensure the 'tables' in CSharpPrimitiveCast don't contain any typos.
|
||||
|
||||
[Test] |
||||
public void FloatToInteger() |
||||
{ |
||||
for (int checkedMode = 0; checkedMode < 2; checkedMode++) { |
||||
for (TypeCode to = TypeCode.Char; to <= TypeCode.UInt64; to++) { |
||||
object val = CSharpPrimitiveCast.Cast(to, 3.9f, checkedMode == 1); |
||||
Assert.AreEqual(to, Type.GetTypeCode(val.GetType())); |
||||
Assert.AreEqual(3, Convert.ToInt64(val)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void DoubleToInteger() |
||||
{ |
||||
for (int checkedMode = 0; checkedMode < 2; checkedMode++) { |
||||
for (TypeCode to = TypeCode.Char; to <= TypeCode.UInt64; to++) { |
||||
object val = CSharpPrimitiveCast.Cast(to, 3.9, checkedMode == 1); |
||||
Assert.AreEqual(to, Type.GetTypeCode(val.GetType())); |
||||
Assert.AreEqual(3, Convert.ToInt64(val)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void DecimalToInteger() |
||||
{ |
||||
for (int checkedMode = 0; checkedMode < 2; checkedMode++) { |
||||
for (TypeCode to = TypeCode.Char; to <= TypeCode.UInt64; to++) { |
||||
object val = CSharpPrimitiveCast.Cast(to, 3.9m, checkedMode == 1); |
||||
Assert.AreEqual(to, Type.GetTypeCode(val.GetType())); |
||||
Assert.AreEqual(3, Convert.ToInt64(val)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void IntegerToInteger() |
||||
{ |
||||
for (int checkedMode = 0; checkedMode < 2; checkedMode++) { |
||||
for (TypeCode to = TypeCode.Char; to <= TypeCode.UInt64; to++) { |
||||
for (TypeCode to2 = TypeCode.Char; to2 <= TypeCode.Decimal; to2++) { |
||||
object val = CSharpPrimitiveCast.Cast(to, 3, checkedMode == 1); |
||||
Assert.AreEqual(to, Type.GetTypeCode(val.GetType())); |
||||
Assert.AreEqual(3, Convert.ToInt64(val)); |
||||
object val2 = CSharpPrimitiveCast.Cast(to2, val, checkedMode == 1); |
||||
Assert.AreEqual(to2, Type.GetTypeCode(val2.GetType())); |
||||
Assert.AreEqual(3, Convert.ToInt64(val2)); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.NRefactory.CSharp.Resolver |
||||
{ |
||||
/// <summary>
|
||||
/// Implementation of member lookup (C# 4.0 spec, §7.4).
|
||||
/// </summary>
|
||||
public class MemberLookup |
||||
{ |
||||
ITypeResolveContext context; |
||||
|
||||
public MemberLookup(ITypeResolveContext context) |
||||
{ |
||||
if (context == null) |
||||
throw new ArgumentNullException("context"); |
||||
this.context = context; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets whether the member is considered to be invocable.
|
||||
/// </summary>
|
||||
public bool IsInvocable(IMember member) |
||||
{ |
||||
if (member is IEvent || member is IMethod) |
||||
return true; |
||||
if (member.ReturnType == SharedTypes.Dynamic) |
||||
return true; |
||||
return member.ReturnType.Resolve(context).IsDelegate(); |
||||
} |
||||
|
||||
} |
||||
} |
||||
Loading…
Reference in new issue