diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs index 08ef055673..d38209faa0 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs @@ -347,12 +347,51 @@ namespace Grunwald.BooBinding.CodeCompletion void AddImportedNamespaceContents(ArrayList list) { IClass c; - foreach (KeyValuePair pair in BooAmbience.TypeConversionTable) { - c = GetPrimitiveClass(pc, pair.Key, pair.Value); + foreach (KeyValuePair pair in BooAmbience.ReverseTypeConversionTable) { + c = GetPrimitiveClass(pc, pair.Value, pair.Key); if (c != null) list.Add(c); } + list.Add(new DuckClass(cu)); NRResolver.AddImportedNamespaceContents(list, cu, callingClass); } + + internal class DuckClass : DefaultClass + { + public DuckClass(ICompilationUnit cu) : base(cu, "duck") + { + Documentation = "Use late-binding to access members of this type.
\n'If it walks like a duck and quacks like a duck, it must be a duck.'"; + Modifiers = ModifierEnum.Public; + } + + protected override IReturnType CreateDefaultReturnType() + { + return new DuckReturnType(this); + } + } + + internal class DuckReturnType : AbstractReturnType + { + IClass c; + public DuckReturnType(IClass c) { + this.c = c; + FullyQualifiedName = c.FullyQualifiedName; + } + public override IClass GetUnderlyingClass() { + return c; + } + public override List GetMethods() { + return new List(); + } + public override List GetProperties() { + return new List(); + } + public override List GetFields() { + return new List(); + } + public override List GetEvents() { + return new List(); + } + } #endregion } } diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs index d0e5c8c642..ad3a306a49 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ConvertVisitor.cs @@ -217,9 +217,13 @@ namespace Grunwald.BooBinding.CodeCompletion IMethodOrProperty callingMember, int caretLine, int caretColumn, IProjectContent projectContent) { + System.Diagnostics.Debug.Assert(projectContent != null); if (reference == null) { - LoggingService.Warn("inferred return type!"); - return ReflectionReturnType.Object; + BooProject project = projectContent.Project as BooProject; + if (project != null && project.Ducky) + return new BooResolver.DuckClass(new DefaultCompilationUnit(projectContent)).DefaultReturnType; + else + return ReflectionReturnType.Object; } if (reference is AST.ArrayTypeReference) { AST.ArrayTypeReference arr = (AST.ArrayTypeReference)reference; @@ -230,7 +234,9 @@ namespace Grunwald.BooBinding.CodeCompletion string name = ((AST.SimpleTypeReference)reference).Name; IReturnType rt; int typeParameterCount = (reference is AST.GenericTypeReference) ? ((AST.GenericTypeReference)reference).GenericArguments.Count : 0; - if (BooAmbience.ReverseTypeConversionTable.ContainsKey(name)) + if (name == "duck") + rt = new BooResolver.DuckClass(new DefaultCompilationUnit(projectContent)).DefaultReturnType; + else if (BooAmbience.ReverseTypeConversionTable.ContainsKey(name)) rt = new GetClassReturnType(projectContent, BooAmbience.ReverseTypeConversionTable[name], typeParameterCount); else rt = new SearchClassReturnType(projectContent, callingClass, caretLine, caretColumn, diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs index c262c98871..a7a70a2298 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/InferredReturnType.cs @@ -102,6 +102,11 @@ namespace Grunwald.BooBinding.CodeCompletion result = new ConstructedReturnType(enumerable.DefaultReturnType, new IReturnType[] { new InferredReturnType(node.Expression, context) }); } + public override void OnCallableBlockExpression(CallableBlockExpression node) + { + // ignore return statements in callable blocks + } + public override bool Visit(Node node) { if (result != null && !(result is NullReturnType)) diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Resources/Boo.xshd b/src/Libraries/ICSharpCode.TextEditor/Project/Resources/Boo.xshd index 2e093d2cf0..ee793c29ba 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Resources/Boo.xshd +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Resources/Boo.xshd @@ -173,6 +173,7 @@ + diff --git a/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs b/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs index 1d366bb7c5..652c97c91e 100644 --- a/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs +++ b/src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs @@ -116,16 +116,16 @@ namespace ICSharpCode.SharpDevelop.Dom return ProjectContentRegistry.Mscorlib.GetClass(FullyQualifiedName); } public override List GetMethods() { - return new List(1); + return new List(); } public override List GetProperties() { - return new List(1); + return new List(); } public override List GetFields() { - return new List(1); + return new List(); } public override List GetEvents() { - return new List(1); + return new List(); } } diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs index 1d452610e0..9392dc5e26 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs @@ -37,19 +37,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring // can derive from the class continue; } - foreach (IClass c in pc.Classes) { - int count = c.BaseTypes.Count; - for (int i = 0; i < count; i++) { - string baseTypeName = c.BaseTypes[i].Name; - if (pc.Language.NameComparer.Equals(baseTypeName, baseClassName) || - pc.Language.NameComparer.Equals(baseTypeName, baseClassFullName)) { - IReturnType possibleBaseClass = c.GetBaseType(i); - if (possibleBaseClass.FullyQualifiedName == baseClass.FullyQualifiedName) { - list.Add(c); - } - } - } - } + AddDerivedClasses(pc, baseClass, baseClassName, baseClassFullName, pc.Classes, list); } if (!directDerivationOnly) { List additional = new List(); @@ -63,6 +51,25 @@ namespace ICSharpCode.SharpDevelop.Refactoring } return list; } + + static void AddDerivedClasses(IProjectContent pc, IClass baseClass, string baseClassName, string baseClassFullName, + IEnumerable classList, IList resultList) + { + foreach (IClass c in classList) { + AddDerivedClasses(pc, baseClass, baseClassName, baseClassFullName, c.InnerClasses, resultList); + int count = c.BaseTypes.Count; + for (int i = 0; i < count; i++) { + string baseTypeName = c.BaseTypes[i].Name; + if (pc.Language.NameComparer.Equals(baseTypeName, baseClassName) || + pc.Language.NameComparer.Equals(baseTypeName, baseClassFullName)) { + IReturnType possibleBaseClass = c.GetBaseType(i); + if (possibleBaseClass.FullyQualifiedName == baseClass.FullyQualifiedName) { + resultList.Add(c); + } + } + } + } + } #endregion #region FindReferences