diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index 5222c70d45..42233c80ce 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -1,4 +1,4 @@ -// +// // CSharpCompletionEngine.cs // // Author: @@ -2570,7 +2570,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion foreach (var m in meths) { if (!lookup.IsAccessible(m, isProtectedAllowed)) continue; - result.AddMember(new InvocatedExtensionMethod (m)); + result.AddMember(new ReducedExtensionMethod (m)); } } } diff --git a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj index 99711e8435..ca27cbff2f 100644 --- a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj +++ b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj @@ -512,7 +512,7 @@ - + diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs b/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs index e96f534af3..59e6974130 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -951,7 +951,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver throw new InvalidOperationException(); if (this.IsExtensionMethodInvocation && member is IMethod) - member =new InvocatedExtensionMethod ((IMethod)member); + member =new ReducedExtensionMethod ((IMethod)member); return new CSharpInvocationResolveResult( this.IsExtensionMethodInvocation ? new TypeResolveResult(member.DeclaringType) : targetResolveResult, member, diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/InvocatedExtensionMethod.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ReducedExtensionMethod.cs similarity index 83% rename from ICSharpCode.NRefactory.CSharp/Resolver/InvocatedExtensionMethod.cs rename to ICSharpCode.NRefactory.CSharp/Resolver/ReducedExtensionMethod.cs index dfd298110b..8561e6030a 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/InvocatedExtensionMethod.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/ReducedExtensionMethod.cs @@ -1,5 +1,5 @@ // -// InvocatedExtensionMethod.cs +// ReducedExtensionMethod.cs // // Author: // Mike Krüger @@ -35,26 +35,64 @@ namespace ICSharpCode.NRefactory.CSharp /// It's used to hide the internals of extension method invocation in certain situation to simulate the /// syntactic way of writing extension methods on semantic level. /// - public class InvocatedExtensionMethod : IMethod + public class ReducedExtensionMethod : IMethod { readonly IMethod baseMethod; - public IMethod InvocatedMethod { - get { - return baseMethod; + public ReducedExtensionMethod(IMethod baseMethod) + { + this.baseMethod = baseMethod; + } + + public override bool Equals(object obj) + { + var other = obj as ReducedExtensionMethod; + if (other == null) + return false; + return baseMethod.Equals(other.baseMethod); + } + + public override int GetHashCode() + { + unchecked { + return baseMethod.GetHashCode() + 1; } } - public InvocatedExtensionMethod(IMethod baseMethod) + public override string ToString() { - this.baseMethod = baseMethod; + return string.Format("[ReducedExtensionMethod: ReducedFrom={0}]", ReducedFrom); } #region IMember implementation + [Serializable] + public sealed class ReducedExtensionMethodMemberReference : IMemberReference + { + readonly IMethod baseMethod; + + public ReducedExtensionMethodMemberReference (IMethod baseMethod) + { + this.baseMethod = baseMethod; + } + + #region IMemberReference implementation + public IMember Resolve(ITypeResolveContext context) + { + return new ReducedExtensionMethod ((IMethod)baseMethod.ToMemberReference ().Resolve (context)); + } + + public ITypeReference DeclaringTypeReference { + get { + return baseMethod.ToMemberReference ().DeclaringTypeReference; + } + } + #endregion + } + public IMemberReference ToMemberReference() { - return baseMethod.ToMemberReference (); + return new ReducedExtensionMethodMemberReference (baseMethod); } public IMember MemberDefinition { @@ -129,7 +167,7 @@ namespace ICSharpCode.NRefactory.CSharp public bool IsExtensionMethod { get { - return baseMethod.IsExtensionMethod; + return false; } } @@ -181,6 +219,10 @@ namespace ICSharpCode.NRefactory.CSharp } } + public IMethod ReducedFrom { + get { return baseMethod; } + } + #endregion #region IParameterizedMember implementation diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs index 8e46e12c9c..047e3da60c 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -54,12 +54,12 @@ namespace XN { InvocationResolveResult mrr; mrr = Resolve(program.Replace("$", "$a.F(1)$")); - var member = ((InvocatedExtensionMethod)mrr.Member).InvocatedMethod; + var member = ((IMethod)mrr.Member).ReducedFrom; Assert.AreEqual("XN.XC.F", member.FullName); Assert.AreEqual("System.Int32", member.Parameters [1].Type.FullName); mrr = Resolve(program.Replace("$", "$a.F(\"text\")$")); - member = ((InvocatedExtensionMethod)mrr.Member).InvocatedMethod; + member = ((IMethod)mrr.Member).ReducedFrom; Assert.AreEqual("XN.XC.F", member.FullName); Assert.AreEqual("System.String", member.Parameters[1].Type.FullName); @@ -67,7 +67,7 @@ namespace XN { Assert.AreEqual("B.F", mrr.Member.FullName); mrr = Resolve(program.Replace("$", "$b.F(\"text\")$")); - member = ((InvocatedExtensionMethod)mrr.Member).InvocatedMethod; + member = ((IMethod)mrr.Member).ReducedFrom; Assert.AreEqual("XN.XC.F", member.FullName); Assert.AreEqual("System.String", member.Parameters[1].Type.FullName); @@ -146,7 +146,7 @@ public static class XC { "; var rr = Resolve(program); Assert.AreEqual("A[]", rr.Type.ReflectionName); - var member = ((InvocatedExtensionMethod)rr.Member).InvocatedMethod; + var member = ((IMethod)rr.Member).ReducedFrom; Assert.AreEqual("System.Linq.Enumerable.ToArray", member.FullName); Assert.AreEqual("A", ((SpecializedMethod)member).TypeArguments.Single().ReflectionName); } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs index e8d161adaa..beffba026b 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -349,7 +349,7 @@ class TestClass }"; var rr = Resolve(program); Assert.IsFalse(rr.IsError); - var member = ((InvocatedExtensionMethod)rr.Member).InvocatedMethod; + var member = ((IMethod)rr.Member).ReducedFrom; Assert.AreEqual("SelectMany", member.Name); Assert.AreEqual(3, member.Parameters.Count); var typeArguments = ((SpecializedMethod)member).TypeArguments; @@ -372,7 +372,7 @@ class TestClass }"; var rr = Resolve(program); Assert.IsFalse(rr.IsError); - var member = ((InvocatedExtensionMethod)rr.Member).InvocatedMethod; + var member = ((IMethod)rr.Member).ReducedFrom; Assert.AreEqual("SelectMany", member.Name); Assert.AreEqual(3, member.Parameters.Count); var typeArguments = ((SpecializedMethod)member).TypeArguments; diff --git a/ICSharpCode.NRefactory/TypeSystem/IMethod.cs b/ICSharpCode.NRefactory/TypeSystem/IMethod.cs index 310d09d3fb..201acfb94f 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IMethod.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IMethod.cs @@ -132,5 +132,10 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Otherwise, returns null. /// IMember AccessorOwner { get; } + + /// + /// If this method is reduced from an extension method return the original method, null otherwhise. + /// + IMethod ReducedFrom { get; } } } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedMethod.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedMethod.cs index 480007c94d..30493ed15a 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedMethod.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedMethod.cs @@ -208,7 +208,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation public bool IsAccessor { get { return ((IUnresolvedMethod)unresolved).AccessorOwner != null; } } - + + public IMethod ReducedFrom { + get { return null; } + } + public IMember AccessorOwner { get { var reference = ((IUnresolvedMethod)unresolved).AccessorOwner; diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs index 87b50fc9c6..415043e78d 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs @@ -136,7 +136,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation public bool IsAccessor { get { return methodDefinition.IsAccessor; } } - + + public IMethod ReducedFrom { + get { return null; } + } + IMember accessorOwner; public IMember AccessorOwner {