diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index d013ebdc9a..5222c70d45 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -2570,7 +2570,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion foreach (var m in meths) { if (!lookup.IsAccessible(m, isProtectedAllowed)) continue; - result.AddMember(m); + result.AddMember(new InvocatedExtensionMethod (m)); } } } diff --git a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj index fd81292fb1..99711e8435 100644 --- a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj +++ b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj @@ -512,6 +512,7 @@ + diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantWhereWithPredicateIssue.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantWhereWithPredicateIssue.cs index 3b255c029d..1515d3a886 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantWhereWithPredicateIssue.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantWhereWithPredicateIssue.cs @@ -47,9 +47,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring var whereResolve = ctx.Resolve (whereInvoke) as InvocationResolveResult; if (whereResolve == null || whereResolve.Member.Name != "Where" || !IsQueryExtensionClass(whereResolve.Member.DeclaringTypeDefinition)) return; - if (whereResolve.Member.Parameters.Count != 2) + if (whereResolve.Member.Parameters.Count != 1) return; - var predResolve = whereResolve.Member.Parameters [1]; + var predResolve = whereResolve.Member.Parameters [0]; if (predResolve.Type.TypeParameterCount != 2) return; diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/InvocatedExtensionMethod.cs b/ICSharpCode.NRefactory.CSharp/Resolver/InvocatedExtensionMethod.cs new file mode 100644 index 0000000000..dfd298110b --- /dev/null +++ b/ICSharpCode.NRefactory.CSharp/Resolver/InvocatedExtensionMethod.cs @@ -0,0 +1,365 @@ +// +// InvocatedExtensionMethod.cs +// +// Author: +// Mike Krüger +// +// Copyright (c) 2013 Xamarin Inc. (http://xamarin.com) +// +// 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 without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using ICSharpCode.NRefactory.TypeSystem; +using System.Collections.Generic; +using System.Linq; + +namespace ICSharpCode.NRefactory.CSharp +{ + /// + /// An invocated extension method hides the extension parameter in its parameter list. + /// 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 + { + readonly IMethod baseMethod; + + public IMethod InvocatedMethod { + get { + return baseMethod; + } + } + + public InvocatedExtensionMethod(IMethod baseMethod) + { + this.baseMethod = baseMethod; + } + + #region IMember implementation + + public IMemberReference ToMemberReference() + { + return baseMethod.ToMemberReference (); + } + + public IMember MemberDefinition { + get { + return baseMethod.MemberDefinition; + } + } + + public IUnresolvedMember UnresolvedMember { + get { + return baseMethod.UnresolvedMember; + } + } + + public IType ReturnType { + get { + return baseMethod.ReturnType; + } + } + + public System.Collections.Generic.IList ImplementedInterfaceMembers { + get { + return baseMethod.ImplementedInterfaceMembers; + } + } + + public bool IsExplicitInterfaceImplementation { + get { + return baseMethod.IsExplicitInterfaceImplementation; + } + } + + public bool IsVirtual { + get { + return baseMethod.IsVirtual; + } + } + + public bool IsOverride { + get { + return baseMethod.IsOverride; + } + } + + public bool IsOverridable { + get { + return baseMethod.IsOverridable; + } + } + + #endregion + + #region IMethod implementation + + public System.Collections.Generic.IList Parts { + get { + return baseMethod.Parts; + } + } + + public System.Collections.Generic.IList ReturnTypeAttributes { + get { + return baseMethod.ReturnTypeAttributes; + } + } + + public System.Collections.Generic.IList TypeParameters { + get { + return baseMethod.TypeParameters; + } + } + + public bool IsExtensionMethod { + get { + return baseMethod.IsExtensionMethod; + } + } + + public bool IsConstructor { + get { + return baseMethod.IsConstructor; + } + } + + public bool IsDestructor { + get { + return baseMethod.IsDestructor; + } + } + + public bool IsOperator { + get { + return baseMethod.IsOperator; + } + } + + public bool IsPartial { + get { + return baseMethod.IsPartial; + } + } + + public bool IsAsync { + get { + return baseMethod.IsAsync; + } + } + + public bool HasBody { + get { + return baseMethod.HasBody; + } + } + + public bool IsAccessor { + get { + return baseMethod.IsAccessor; + } + } + + public IMember AccessorOwner { + get { + return baseMethod.AccessorOwner; + } + } + + #endregion + + #region IParameterizedMember implementation + List parameters; + public System.Collections.Generic.IList Parameters { + get { + if (parameters == null) + parameters = new List (baseMethod.Parameters.Skip (1)); + return parameters; + } + } + + #endregion + + #region IEntity implementation + + public EntityType EntityType { + get { + return baseMethod.EntityType; + } + } + + public DomRegion Region { + get { + return baseMethod.Region; + } + } + + public DomRegion BodyRegion { + get { + return baseMethod.BodyRegion; + } + } + + public ITypeDefinition DeclaringTypeDefinition { + get { + return baseMethod.DeclaringTypeDefinition; + } + } + + public IType DeclaringType { + get { + return baseMethod.DeclaringType; + } + } + + public IAssembly ParentAssembly { + get { + return baseMethod.ParentAssembly; + } + } + + public System.Collections.Generic.IList Attributes { + get { + return baseMethod.Attributes; + } + } + + public ICSharpCode.NRefactory.Documentation.DocumentationComment Documentation { + get { + return baseMethod.Documentation; + } + } + + public bool IsStatic { + get { + return baseMethod.IsStatic; + } + } + + public bool IsAbstract { + get { + return baseMethod.IsAbstract; + } + } + + public bool IsSealed { + get { + return baseMethod.IsSealed; + } + } + + public bool IsShadowing { + get { + return baseMethod.IsShadowing; + } + } + + public bool IsSynthetic { + get { + return baseMethod.IsSynthetic; + } + } + + #endregion + + #region IHasAccessibility implementation + + public Accessibility Accessibility { + get { + return baseMethod.Accessibility; + } + } + + public bool IsPrivate { + get { + return baseMethod.IsPrivate; + } + } + + public bool IsPublic { + get { + return baseMethod.IsPublic; + } + } + + public bool IsProtected { + get { + return baseMethod.IsProtected; + } + } + + public bool IsInternal { + get { + return baseMethod.IsInternal; + } + } + + public bool IsProtectedOrInternal { + get { + return baseMethod.IsProtectedOrInternal; + } + } + + public bool IsProtectedAndInternal { + get { + return baseMethod.IsProtectedAndInternal; + } + } + + #endregion + + #region INamedElement implementation + + public string FullName { + get { + return baseMethod.FullName; + } + } + + public string Name { + get { + return baseMethod.Name; + } + } + + public string ReflectionName { + get { + return baseMethod.ReflectionName; + } + } + + public string Namespace { + get { + return baseMethod.Namespace; + } + } + + #endregion + + #region ICompilationProvider implementation + + public ICompilation Compilation { + get { + return baseMethod.Compilation; + } + } + + #endregion + } +} + diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs b/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs index 13aecd79d8..e96f534af3 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs @@ -950,8 +950,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver if (member == null) throw new InvalidOperationException(); - if (this.IsExtensionMethodInvocation && member is SpecializedMethod) - ((SpecializedMethod)member).IsExtendedExtensionMethod = true; + if (this.IsExtensionMethodInvocation && member is IMethod) + member =new InvocatedExtensionMethod ((IMethod)member); return new CSharpInvocationResolveResult( this.IsExtensionMethodInvocation ? new TypeResolveResult(member.DeclaringType) : targetResolveResult, member, diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs index cb759789c7..8e46e12c9c 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs @@ -54,19 +54,22 @@ namespace XN { InvocationResolveResult mrr; mrr = Resolve(program.Replace("$", "$a.F(1)$")); - Assert.AreEqual("XN.XC.F", mrr.Member.FullName); - Assert.AreEqual("System.Int32", mrr.Member.Parameters[1].Type.FullName); + var member = ((InvocatedExtensionMethod)mrr.Member).InvocatedMethod; + Assert.AreEqual("XN.XC.F", member.FullName); + Assert.AreEqual("System.Int32", member.Parameters [1].Type.FullName); mrr = Resolve(program.Replace("$", "$a.F(\"text\")$")); - Assert.AreEqual("XN.XC.F", mrr.Member.FullName); - Assert.AreEqual("System.String", mrr.Member.Parameters[1].Type.FullName); + member = ((InvocatedExtensionMethod)mrr.Member).InvocatedMethod; + Assert.AreEqual("XN.XC.F", member.FullName); + Assert.AreEqual("System.String", member.Parameters[1].Type.FullName); mrr = Resolve(program.Replace("$", "$b.F(1)$")); Assert.AreEqual("B.F", mrr.Member.FullName); mrr = Resolve(program.Replace("$", "$b.F(\"text\")$")); - Assert.AreEqual("XN.XC.F", mrr.Member.FullName); - Assert.AreEqual("System.String", mrr.Member.Parameters[1].Type.FullName); + member = ((InvocatedExtensionMethod)mrr.Member).InvocatedMethod; + Assert.AreEqual("XN.XC.F", member.FullName); + Assert.AreEqual("System.String", member.Parameters[1].Type.FullName); mrr = Resolve(program.Replace("$", "$c.F(1)$")); Assert.AreEqual("C.F", mrr.Member.FullName); @@ -143,8 +146,9 @@ public static class XC { "; var rr = Resolve(program); Assert.AreEqual("A[]", rr.Type.ReflectionName); - Assert.AreEqual("System.Linq.Enumerable.ToArray", rr.Member.FullName); - Assert.AreEqual("A", ((SpecializedMethod)rr.Member).TypeArguments.Single().ReflectionName); + var member = ((InvocatedExtensionMethod)rr.Member).InvocatedMethod; + Assert.AreEqual("System.Linq.Enumerable.ToArray", member.FullName); + Assert.AreEqual("A", ((SpecializedMethod)member).TypeArguments.Single().ReflectionName); } [Test] diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs index 379b803f43..e8d161adaa 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LinqTests.cs @@ -349,9 +349,10 @@ class TestClass }"; var rr = Resolve(program); Assert.IsFalse(rr.IsError); - Assert.AreEqual("SelectMany", rr.Member.Name); - Assert.AreEqual(3, rr.Member.Parameters.Count); - var typeArguments = ((SpecializedMethod)rr.Member).TypeArguments; + var member = ((InvocatedExtensionMethod)rr.Member).InvocatedMethod; + Assert.AreEqual("SelectMany", member.Name); + Assert.AreEqual(3, member.Parameters.Count); + var typeArguments = ((SpecializedMethod)member).TypeArguments; Assert.AreEqual(3, typeArguments.Count); Assert.AreEqual("System.String", typeArguments[0].ReflectionName, "TSource"); Assert.AreEqual("System.Char", typeArguments[1].ReflectionName, "TCollection"); @@ -371,9 +372,10 @@ class TestClass }"; var rr = Resolve(program); Assert.IsFalse(rr.IsError); - Assert.AreEqual("SelectMany", rr.Member.Name); - Assert.AreEqual(3, rr.Member.Parameters.Count); - var typeArguments = ((SpecializedMethod)rr.Member).TypeArguments; + var member = ((InvocatedExtensionMethod)rr.Member).InvocatedMethod; + Assert.AreEqual("SelectMany", member.Name); + Assert.AreEqual(3, member.Parameters.Count); + var typeArguments = ((SpecializedMethod)member).TypeArguments; Assert.AreEqual(3, typeArguments.Count); Assert.AreEqual("System.String", typeArguments[0].ReflectionName, "TSource"); Assert.AreEqual("System.Char", typeArguments[1].ReflectionName, "TCollection"); diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index e415dbff55..8bd281f103 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -47,7 +47,7 @@ True - PdbOnly + none False @@ -57,8 +57,9 @@ v4.5 - Full - true + full + True + v4.5 True @@ -67,8 +68,8 @@ v4.5 - PdbOnly - false + none + v4.5 diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs index 5636a5b457..87b50fc9c6 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs @@ -154,14 +154,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation } } - /// - /// Gets/Sets whether the method is an extension method that are being called using extension method syntax. - /// - public bool IsExtendedExtensionMethod { - get; - set; - } - public override IMemberReference ToMemberReference() { // Pass the MethodTypeArguments to the SpecializingMemberReference only if