From 3f433a2b4683ca2217890b161b8237538cce4d5d Mon Sep 17 00:00:00 2001 From: mrward Date: Sat, 18 Sep 2010 20:54:45 +0100 Subject: [PATCH] Add support for IronPython completion after typing 'self'. --- .../Project/PythonBinding.csproj | 1 + .../Project/Src/PythonResolver.cs | 2 + .../Project/Src/PythonResolverContext.cs | 4 ++ .../Project/Src/PythonSelfResolver.cs | 33 +++++++++++++ .../Test/PythonBinding.Tests.csproj | 2 + .../Test/Resolver/PythonSelfResolverTests.cs | 49 +++++++++++++++++++ .../Test/Resolver/ResolveSelfTests.cs | 45 +++++++++++++++++ 7 files changed, 136 insertions(+) create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonSelfResolver.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/PythonSelfResolverTests.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveSelfTests.cs diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj index 6e4f0eb411..61ffae8a3f 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj @@ -106,6 +106,7 @@ + diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs index 373a4a146e..ce52a7413a 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs @@ -17,6 +17,7 @@ namespace ICSharpCode.PythonBinding PythonNamespaceResolver namespaceResolver = new PythonNamespaceResolver(); PythonClassResolver classResolver = new PythonClassResolver(); PythonStandardModuleResolver standardModuleResolver = new PythonStandardModuleResolver(); + PythonSelfResolver selfResolver = new PythonSelfResolver(); PythonMethodResolver methodResolver; List resolvers = new List(); @@ -29,6 +30,7 @@ namespace ICSharpCode.PythonBinding resolvers.Add(classResolver); resolvers.Add(standardModuleResolver); resolvers.Add(methodResolver); + resolvers.Add(selfResolver); resolvers.Add(namespaceResolver); } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolverContext.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolverContext.cs index 4b06259ac3..8f85de1d99 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolverContext.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolverContext.cs @@ -52,6 +52,10 @@ namespace ICSharpCode.PythonBinding get { return callingClass; } } + public bool HasCallingClass { + get { return callingClass != null; } + } + public bool NamespaceExistsInProjectReferences(string name) { return projectContent.NamespaceExists(name); diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonSelfResolver.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonSelfResolver.cs new file mode 100644 index 0000000000..638a2b145f --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonSelfResolver.cs @@ -0,0 +1,33 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Dom; + +namespace ICSharpCode.PythonBinding +{ + public class PythonSelfResolver : IPythonResolver + { + public ResolveResult Resolve(PythonResolverContext resolverContext, ExpressionResult expressionResult) + { + if (resolverContext.HasCallingClass) { + if (IsSelfExpression(expressionResult)) { + return CreateResolveResult(resolverContext); + } + } + return null; + } + + bool IsSelfExpression(ExpressionResult expressionResult) + { + return expressionResult.Expression == "self"; + } + + ResolveResult CreateResolveResult(PythonResolverContext resolverContext) + { + IClass callingClass = resolverContext.CallingClass; + IReturnType returnType = callingClass.DefaultReturnType; + return new ResolveResult(callingClass, null, returnType); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj index 1729a491c5..6e1c2e4ba9 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj @@ -348,6 +348,7 @@ + @@ -371,6 +372,7 @@ + diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/PythonSelfResolverTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/PythonSelfResolverTests.cs new file mode 100644 index 0000000000..3c586955de --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/PythonSelfResolverTests.cs @@ -0,0 +1,49 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.PythonBinding; +using ICSharpCode.Scripting.Tests.Utils; +using ICSharpCode.SharpDevelop.Dom; +using NUnit.Framework; + +namespace PythonBinding.Tests.Resolver +{ + [TestFixture] + public class PythonSelfResolverTests + { + PythonSelfResolver resolver; + ExpressionResult expression; + ParseInformation parseInfo; + PythonResolverContext context; + + [Test] + public void Resolve_NoCallingClass_ReturnsNull() + { + CreatePythonSelfResolver(); + CreateParseInfo(); + CreatePythonResolverContext(); + + ResolveResult result = resolver.Resolve(context, expression); + Assert.IsNull(result); + } + + void CreatePythonSelfResolver() + { + resolver = new PythonSelfResolver(); + expression = new ExpressionResult("self"); + } + + void CreateParseInfo() + { + MockProjectContent projectContent = new MockProjectContent(); + DefaultCompilationUnit unit = new DefaultCompilationUnit(projectContent); + parseInfo = new ParseInformation(unit); + } + + void CreatePythonResolverContext() + { + context = new PythonResolverContext(parseInfo); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveSelfTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveSelfTests.cs new file mode 100644 index 0000000000..d49716f4bd --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveSelfTests.cs @@ -0,0 +1,45 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.SharpDevelop.Dom; +using NUnit.Framework; +using UnitTesting.Tests.Utils; + +namespace PythonBinding.Tests.Resolver +{ + [TestFixture] + public class ResolveSelfTests : ResolveTestFixtureBase + { + IClass fooClass; + + protected override ExpressionResult GetExpressionResult() + { + fooClass = compilationUnit.Classes[0]; + return new ExpressionResult("self", ExpressionContext.Default); + } + + protected override string GetPythonScript() + { + return + "class Foo(self)\r\n" + + " def bar(self):\r\n" + + " self\r\n" + + "\r\n"; + } + + [Test] + public void Resolve_ExpressionIsSelf_ResolveResultResolvedTypeUnderlyingClassReturnsFooClass() + { + IClass underlyingClass = resolveResult.ResolvedType.GetUnderlyingClass(); + Assert.AreEqual(fooClass, underlyingClass); + } + + [Test] + public void Resolve_ExpressionIsSelf_ResolveResultCallingClassReturnsFooClass() + { + IClass underlyingClass = resolveResult.CallingClass; + Assert.AreEqual(fooClass, underlyingClass); + } + } +}