From 3c50fc4447bcccd51193467aa1f823867c0a48f3 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 15 Jul 2005 19:49:06 +0000 Subject: [PATCH] Fixed C# code completion when an expression had two meanings (eg. type and property: 'Size' in classes deriving from Form) git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@183 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../NRefactoryResolver/NRefactoryResolver.cs | 21 ++++++--- .../Base/Project/Src/Dom/ResolveResult.cs | 31 +++++++++++++ src/Main/Base/Test/NRefactoryResolverTests.cs | 45 +++++++++++++++++++ 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs index a011f0b734..689d84a708 100644 --- a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs +++ b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs @@ -329,6 +329,22 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver if (name != null && name != "") { return new NamespaceResolveResult(callingClass, callingMember, name); } + + ResolveResult result = ResolveIdentifierInternal(identifier); + ResolveResult result2 = null; + + IClass c = SearchType(identifier, callingClass, cu); + if (c != null) { + result2 = new TypeResolveResult(callingClass, callingMember, c.DefaultReturnType, c); + } + + if (result == null) return result2; + if (result2 == null) return result; + return new MixedResolveResult(result, result2); + } + + ResolveResult ResolveIdentifierInternal(string identifier) + { if (callingMember != null) { // LocalResolveResult requires callingMember to be set LocalLookupVariable var = SearchVariable(identifier); if (var != null) { @@ -352,11 +368,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver return result; } - IClass c = SearchType(identifier, callingClass, cu); - if (c != null) { - return new TypeResolveResult(callingClass, callingMember, c.DefaultReturnType, c); - } - // try if there exists a static member in outer classes named typeName List classes = cu.GetOuterClasses(caretLine, caretColumn); foreach (IClass c2 in classes) { diff --git a/src/Main/Base/Project/Src/Dom/ResolveResult.cs b/src/Main/Base/Project/Src/Dom/ResolveResult.cs index ece034dce4..5c8cd79e21 100644 --- a/src/Main/Base/Project/Src/Dom/ResolveResult.cs +++ b/src/Main/Base/Project/Src/Dom/ResolveResult.cs @@ -107,6 +107,37 @@ namespace ICSharpCode.SharpDevelop.Dom } #endregion + #region MixedResolveResult + /// + /// The MixedResolveResult is used when an expression can have multiple meanings, for example + /// "Size" in a class deriving from "Control". + /// + public class MixedResolveResult : ResolveResult + { + ResolveResult primaryResult, secondaryResult; + + public MixedResolveResult(ResolveResult primaryResult, ResolveResult secondaryResult) + : base(primaryResult.CallingClass, primaryResult.CallingMember, primaryResult.ResolvedType) + { + this.primaryResult = primaryResult; + this.secondaryResult = secondaryResult; + } + + public override ArrayList GetCompletionData(IProjectContent projectContent) + { + ArrayList result = primaryResult.GetCompletionData(projectContent); + ArrayList result2 = secondaryResult.GetCompletionData(projectContent); + if (result == null) return result2; + if (result2 == null) return result; + foreach (object o in result2) { + if (!result.Contains(o)) + result.Add(o); + } + return result; + } + } + #endregion + #region LocalResolveResult /// /// The LocalResolveResult is used when an expression was a simple local variable diff --git a/src/Main/Base/Test/NRefactoryResolverTests.cs b/src/Main/Base/Test/NRefactoryResolverTests.cs index b973e9c528..32aea7dc03 100644 --- a/src/Main/Base/Test/NRefactoryResolverTests.cs +++ b/src/Main/Base/Test/NRefactoryResolverTests.cs @@ -207,6 +207,51 @@ End Module #endregion #region Simple Tests + const string arrayListConflictProgram = @"using System.Collections; +class A { + void Test() { + + } + + ArrayList arrayList; + public ArrayList ArrayList { + get { + return arrayList; + } + } +} +"; + + [Test] + public void PropertyTypeConflictTest() + { + ResolveResult result = Resolve(arrayListConflictProgram, "arrayList", 4); + Assert.IsTrue(result is MemberResolveResult); + Assert.AreEqual("System.Collections.ArrayList", result.ResolvedType.FullyQualifiedName); + } + + [Test] + public void PropertyTypeConflictCompletionResultTest() + { + ResolveResult result = Resolve(arrayListConflictProgram, "ArrayList", 4); + // CC should offer both static and non-static results + ArrayList list = result.GetCompletionData(lastPC); + bool ok = false; + foreach (object o in list) { + IMethod method = o as IMethod; + if (method != null && method.Name == "AddRange") + ok = true; + } + Assert.IsTrue(ok, "AddRange should exist"); + ok = false; + foreach (object o in list) { + IMethod method = o as IMethod; + if (method != null && method.Name == "Adapter") + ok = true; + } + Assert.IsTrue(ok, "Adapter should exist"); + } + [Test] public void InheritedInterfaceResolveTest() {