diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/BinaryOperatorTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/BinaryOperatorTests.cs index 1b141ecb01..250c2619e4 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/BinaryOperatorTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/BinaryOperatorTests.cs @@ -388,5 +388,62 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver AssertType(typeof(dynamic), resolver.ResolveBinaryOperator( BinaryOperatorType.NullCoalescing, MakeResult(typeof(string)), MakeResult(typeof(dynamic)))); } + + [Test, Ignore("user-defined operators not yet implemented")] + public void LiftedUserDefined() + { + AssertType(typeof(TimeSpan), resolver.ResolveBinaryOperator( + BinaryOperatorType.Subtract, MakeResult(typeof(DateTime)), MakeResult(typeof(DateTime)))); + AssertType(typeof(TimeSpan?), resolver.ResolveBinaryOperator( + BinaryOperatorType.Subtract, MakeResult(typeof(DateTime?)), MakeResult(typeof(DateTime)))); + AssertType(typeof(TimeSpan?), resolver.ResolveBinaryOperator( + BinaryOperatorType.Subtract, MakeResult(typeof(DateTime)), MakeResult(typeof(DateTime?)))); + AssertType(typeof(TimeSpan?), resolver.ResolveBinaryOperator( + BinaryOperatorType.Subtract, MakeResult(typeof(DateTime?)), MakeResult(typeof(DateTime?)))); + } + + [Test, Ignore("user-defined operators not yet implemented")] + public void UserDefinedNeedsLiftingDueToImplicitConversion() + { + string program = @"struct S {} +struct A { + public static implicit operator S?(A a) { return null; } + + public static S operator +(A a, S s) { return s; } +} +class Test { + void M(A a) { + var s = $a + a$; + } +} +"; + MemberResolveResult trr = Resolve(program); + Assert.IsFalse(trr.IsError); + Assert.AreEqual("A.op_Addition", trr.Member.FullName); + // even though we're calling the lifted operator, trr.Member should be the original operator method + Assert.AreEqual("S", trr.Member.ReturnType.Resolve(context).ReflectionName); + Assert.AreEqual("System.Nullable`1[[S]]", trr.Type.ReflectionName); + } + + [Test, Ignore("user-defined operators not yet implemented")] + public void ThereIsNoLiftedOperatorsForClasses() + { + string program = @"struct S {} +class A { + public static implicit operator S?(A a) { return null; } + + public static S operator +(A a, S s) { return s; } +} +class Test { + void M(A a) { + var s = $a + a$; + } +} +"; + MemberResolveResult trr = Resolve(program); + Assert.IsTrue(trr.IsError); // cannot convert from A to S + Assert.AreEqual("A.op_Addition", trr.Member.FullName); + Assert.AreEqual("S", trr.Type.ReflectionName); + } } } diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/MemberLookup.cs b/ICSharpCode.NRefactory/CSharp/Resolver/MemberLookup.cs index d2f349f74f..7d857b6111 100644 --- a/ICSharpCode.NRefactory/CSharp/Resolver/MemberLookup.cs +++ b/ICSharpCode.NRefactory/CSharp/Resolver/MemberLookup.cs @@ -25,9 +25,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver // C# 4.0 spec, §7.4 member lookup if (member is IEvent || member is IMethod) return true; - if (member.ReturnType == SharedTypes.Dynamic) + IType returnType = member.ReturnType.Resolve(context); + if (returnType == SharedTypes.Dynamic) return true; - return member.ReturnType.Resolve(context).IsDelegate(); + return returnType.IsDelegate(); } #endregion diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index 8877f27f5d..1213653727 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -1,4 +1,4 @@ - + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleProjectContent.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleProjectContent.cs index e66ec65289..6cb78cbfaa 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleProjectContent.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleProjectContent.cs @@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation get { return readOnlyAssemblyAttributes; } } - void AddRemoveAssemblyAttributes(ICollection addedAttributes, ICollection removedAttributes) + void AddRemoveAssemblyAttributes(ICollection removedAttributes, ICollection addedAttributes) { // API uses ICollection instead of IEnumerable to discourage users from evaluating // the list inside the lock (this method is called inside the write lock)