From 31f58f9a133dbca025b9b04dc93e89ff29705f43 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 27 Apr 2006 17:28:01 +0000 Subject: [PATCH] Update to Boo 0.7.6. Fixed various bugs in Boo code completion. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.0@1356 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Boo/BooBinding/Project/Src/BooProject.cs | 7 ++ .../Project/Src/CodeCompletion/BooResolver.cs | 13 ++ .../CodeCompletion/VariableLookupVisitor.cs | 14 ++- .../Boo/BooBinding/Test/ResolverTests.cs | 118 ++++++++++++++++-- 4 files changed, 139 insertions(+), 13 deletions(-) diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooProject.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooProject.cs index 8905c4013f..fb1d739860 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooProject.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/BooProject.cs @@ -102,5 +102,12 @@ namespace Grunwald.BooBinding return BooAmbience.Instance; } } + + [Browsable(false)] + public bool Ducky { + get { + return GetProperty("Ducky", false); + } + } } } 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 ac706d6028..317bd23394 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs @@ -63,6 +63,19 @@ namespace Grunwald.BooBinding.CodeCompletion return cu; } } + + /// + /// Gets if duck typing is enabled for the Boo project. + /// + public bool IsDucky { + get { + BooProject p = pc.Project as BooProject; + if (p != null) + return p.Ducky; + else + return false; + } + } #endregion #region Initialization diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/VariableLookupVisitor.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/VariableLookupVisitor.cs index fe3d985e40..2125022648 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/VariableLookupVisitor.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/VariableLookupVisitor.cs @@ -26,25 +26,27 @@ namespace Grunwald.BooBinding.CodeCompletion DeclarationFound(node.Declaration.Name, node.Declaration.Type, node.Initializer, node.LexicalInfo); } - LexicalInfo GetEndSourceLocation(Node node) + SourceLocation GetEndSourceLocation(Node node) { - if (node.LexicalInfo.IsValid) return node.LexicalInfo; + if (node.EndSourceLocation.IsValid) return node.EndSourceLocation; if (node is CallableBlockExpression) { return GetEndSourceLocation((node as CallableBlockExpression).Body); + } else if (node is ForStatement) { + return GetEndSourceLocation((node as ForStatement).Block); } else if (node is Block) { StatementCollection st = (node as Block).Statements; if (st.Count > 0) { return GetEndSourceLocation(st[st.Count - 1]); } } - return node.LexicalInfo; + return node.EndSourceLocation; } public override void OnCallableBlockExpression(CallableBlockExpression node) { if (node.LexicalInfo.Line <= resolver.CaretLine && GetEndSourceLocation(node).Line >= resolver.CaretLine - 1) { foreach (ParameterDeclaration param in node.Parameters) { - DeclarationFound(param.Name, param.Type, null, param.LexicalInfo); + DeclarationFound(param.Name, param.Type ?? (resolver.IsDucky ? new SimpleTypeReference("duck") : new SimpleTypeReference("object")), null, param.LexicalInfo); } base.OnCallableBlockExpression(node); } @@ -225,7 +227,9 @@ namespace Grunwald.BooBinding.CodeCompletion if (declarationType != null) { Add(declarationName, declarationType); } else if (initializer != null) { - Add(declarationName, initializer, false); + if (!knownVariableNames.Contains(declarationName)) { + Add(declarationName, initializer, false); + } } } diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Test/ResolverTests.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Test/ResolverTests.cs index a453a028b4..f1acccad45 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Test/ResolverTests.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Test/ResolverTests.cs @@ -52,9 +52,10 @@ namespace Grunwald.BooBinding.Tests booLangPC.ReferencedContents.Add(ProjectContentRegistry.Mscorlib); } - ResolveResult Resolve(string prog, ExpressionResult er, string marker) + const string fileName = "tempFile.boo"; + + void Register(string prog) { - const string fileName = "tempFile.boo"; DefaultProjectContent pc = new DefaultProjectContent(); ParserService.ForceProjectContent(pc); pc.ReferencedContents.Add(ProjectContentRegistry.Mscorlib); @@ -63,10 +64,13 @@ namespace Grunwald.BooBinding.Tests ICompilationUnit cu = new BooParser().Parse(pc, fileName, prog); ParserService.UpdateParseInformation(cu, fileName, false, false); cu.Classes.ForEach(pc.AddClassToNamespaceList); - + } + + void GetPos(string prog, string marker, out int line, out int column) + { int index = prog.IndexOf(marker); - int line = 1; - int column = 0; + line = 1; + column = 0; for (int i = 0; i < index; i++) { column++; if (prog[i]=='\n') { @@ -74,6 +78,13 @@ namespace Grunwald.BooBinding.Tests column = 0; } } + } + + ResolveResult Resolve(string prog, ExpressionResult er, string marker) + { + Register(prog); + int line, column; + GetPos(prog, marker, out line, out column); BooResolver r = new BooResolver(); return r.Resolve(er, line, column, fileName, prog); @@ -91,8 +102,8 @@ namespace Grunwald.BooBinding.Tests "\t/*2*/\n" + "\tclosure2 = def(e as DateTime):\n" + "\t\treturn e.Year\n" + - "\trecursiveClosure = def():\n" + - "\t\treturn recursiveClosure()\n" + + "\trecursiveClosure = def(myObject):/*inRecursiveClosure*/\n" + + "\t\treturn recursiveClosure(myObject)\n" + "\t/*3*/\n"; [Test] @@ -162,7 +173,14 @@ namespace Grunwald.BooBinding.Tests // preventing the StackOverflow. LocalResolveResult rr = Resolve("recursiveClosure", "/*3*/"); Assert.IsFalse(rr.IsParameter); - Assert.AreEqual("delegate():?", rr.ResolvedType.FullyQualifiedName); + Assert.AreEqual("delegate(myObject:Object):?", rr.ResolvedType.FullyQualifiedName); + } + + [Test] + public void ClosureTypelessArgument() + { + LocalResolveResult rr = Resolve("myObject", "/*inRecursiveClosure*/"); + Assert.AreEqual("System.Object", rr.ResolvedType.FullyQualifiedName); } #endregion @@ -196,5 +214,89 @@ namespace Grunwald.BooBinding.Tests Assert.IsNull(Resolve(regressionProg, new ExpressionResult("boo640a"), "/*1*/")); } #endregion + + #region CtrlSpace + void CtrlSpace(string prog, params string[] expected) + { + CtrlSpace(new string[0], prog, expected); + } + + void CtrlSpace(string[] unExpected, string prog, params string[] expected) + { + Register(prog); + int line, column; + GetPos(prog, "/*mark*/", out line, out column); + BooResolver r = new BooResolver(); + System.Collections.ArrayList ar; + ar = r.CtrlSpace(line, column, fileName, prog, ExpressionContext.Default); + foreach (string e in unExpected) { + foreach (object o in ar) { + if (e.Equals(o)) + Assert.Fail("Didn't expect " + e); + if (o is IMember && (o as IMember).Name == e) { + Assert.Fail("Didn't expect " + e); + } + if (o is IClass && (o as IClass).Name == e) { + Assert.Fail("Didn't expect " + e); + } + } + } + foreach (string e in expected) { + bool ok = false; + foreach (object o in ar) { + if (e.Equals(o)) { + if (ok) Assert.Fail("double entry " + e); + ok = true; + } + if (o is IMember && (o as IMember).Name == e) { + if (ok) Assert.Fail("double entry " + e); + ok = true; + } + if (o is IClass && (o as IClass).Name == e) { + if (ok) Assert.Fail("double entry " + e); + ok = true; + } + } + if (!ok) + Assert.Fail("Expected " + e); + } + } + + [Test] + public void CtrlSpaceScopeExtension() + { + string prog = + "def Foo():\n" + + "\tbar = def():\n" + + "\t\tx = 0\n" + + "\t\t/*mark*/\n"; + CtrlSpace(prog, "bar", "x"); + } + + [Test] + public void DoubleEntryTest() + { + string prog = + "class MyClass:\n" + + "\t_myInt = 0\n" + + "\tdef Foo():\n" + + "\t\t_myInt = 5\n" + + "\t\t/*mark*/\n"; + CtrlSpace(prog, "_myInt"); + } + + [Test] + public void LoopInClosureTest() + { + string prog = + "def Foo():\n" + + "\tfor i in range(5):\n" + + "\t\tbar = def():\n" + + "\t\t\tx = 0\n" + + "\t\t\t/*mark*/\n" + + "\t\t\tprint x"; + CtrlSpace(prog, "x", "bar", "i"); + } + #endregion } }